Archivo

Archivo del autor

No se pudo encontrar montaje de controlador de memoria cgroups

martes, 15 de agosto de 2023 Sin comentarios

Tras actualizar el software de OpenSuse Tumbleweed me he encontrado con el siguiente error al intentar iniciar los contenedores LXC:

libvirtError: error interno: No se pudo encontrar montaje de controlador de memoria cgroups

Supongo que debe estar relacionado con la actualización de software LXC más que con el kernel, porque volver a la versión anterior no lo resolvía. Sin embargo, lo que sí lo resolvía era añadir los siguientes parámetros en el inicio del kernel:

cgroup_enable=memory systemd.unified_cgroup_hierarchy=0

Y se puede comprobar cómo cambia el resultado al ejecutar este comando antes y después:

cat /proc/cgroups | column -t

mount | grep cgroup

Supuestamente, el tenerlo activado nos permite controlar y limitar el acceso a los recursos de la máquina host por parte de los guest, con lo que no entiendo si está hecho a posta porque han habido cambios que ya no necesitan estos parámetros y lo implementan de otra forma o es un simple fallo en la última versión.

Categories: GNU/Linux, LXC, OpenSuse Tags:

Abrir puertos en Oracle Cloud

martes, 8 de agosto de 2023 Sin comentarios

En las instancias de servidor de Oracle Cloud, cuando despliegas alguna de sus imágenes, tienen preconfiguradas una serie de reglas en el cortafuegos que impiden la comunicación a los servicios más básicos como HTTP/HTTPS.

Puede llegar a ser realmente confuso porque, antes de averiguar que en una instalación limpia ya hay reglas de cortafuegos, hemos tenido que abrir puertos y configurar la red en el panel de control de Oracle. Así que podemos dejar el cortafuegos totalmente abierto y gestionar la entrada/salida desde el panel de control.

Con estos comando quitaríamos las reglas:

iptables -I INPUT -j ACCEPT

iptables-save > /etc/iptables/rules.v4

O si sólo queremos abrir ciertos puertos:

iptables -I INPUT 6 -m state –state NEW -p tcp –dport 80 -j ACCEPT sudo netfilter-persistent save

netfilter-persistent save

Para más información, hay un hilo de reddit donde se discute el tema.

Zyxel NSA-325 V2 con OpenWRT y discos de 20TB

sábado, 5 de agosto de 2023 Sin comentarios

Dejando atrás la limitación del sistema operativo que traía de fabrica para intentar sobrepasar el límite del sistema de ficheros ext2 y lograr hacer un RAID 0 con dos discos duros de 20TB he llegado a la conclusión de que no se puede.

Se puede formar un RAID 0 sin mayores inconvenientes instalado las herramientas disponibles en OpenWRT y utilizando este comando como en cualquier sistema Linux:

mdadm –create –verbose /dev/md0 –level=0 –raid-devices=2 /dev/sda /dev/sdb

Pero a la hora de darle formato a ese raid es cuando empiezan los problemas. Con ext4, en el proceso de inicialización del journaling, directamente se para con un error, algo que se puede saltar para que finalice el proceso y con XFS no hay inconvenientes. Pero a la hora de montar la unidad /dev/md0, en ambos, salta un error diciendo que el fichero es demasiado grande («file to large»). Intuyo que todo está relacionado con el hecho de utilizar un sistema operativo de 32bit por culpa de una CPU que no soporta instrucciones de 64bit.

Curiosamente, podemos formatear y montar el raid si utilizamos el sistema de ficheros exFAT, pero cuando empiezas a copiar ficheros en él empieza a dar errores y tiempos de espera muy largos, algo que lo hace inusable.

Supongo que este ZyXEL se quedará con dos discos de 8TB como máximo.

 

Zyxel NSA-325 V2 pasa a OpenWRT

viernes, 28 de julio de 2023 Sin comentarios

Hace 8 años compré por un precio más que razonable un NAS de 2 bahías de Zyxel que me permitió hacer bastantes más cosas de las oficiales gracias a repositorios de la comunidad. Pero todo tiene un límite, concretamente en lo que se refiere a su compatibilidad con discos duros de gran capacidad. Resulta que el sistema de archivos que utiliza es ext2, el cual permite un tamaño de volumen máximo de 16TiB, algo que me impedía hacer uso de dos discos duros de 20TB. Frustrado por ello busqué alternativas y encontré la posibilidad de instalar OpenWRT reescribiendo la NAND, lo cuál me permitía hacer uso de ext3 entre otras muchas cosas.

Para llevar a cabo la operación, me enfrenté con documentación incompleta desde el punto de vista de alguien que no lo había hecho nunca. Se hablaba de utilizar una conexión serie USB, de poner comandos en un terminal, hacer uso de un pendrive antiguo y de soldar cosas. Al final fue relativamente sencillo, sin soldar ni comprar nada adicional porque ya tenía en mi posesión una Raspberry Pi 2 para hacer el trabajo de conector serie USB.

Importante

El proceso puede dejar inservible el dispositivo NAS e incluso la Raspberry Pi si confundís algún cable. Así que cada uno es responsable de lo que hace.

Obtención de la MAC

Durante el proceso habrá que configurar la MAC del NAS a mano, con lo que antes de empezar sería buena idea obtenerlo.

Sacar la placa base

Para sacar la placa base hay que extraer las bahías de los discos duros, sacar un par de tornillos de la base, deslizar una parte de la carcasa sobre la otra y seguir desatornillando un poco más, nada difícil ni nada clicks. Hay un vídeo muy ilustrativo de los primeros pasos:

Conectar la Raspberry Pi

Teniendo en cuenta de que en mi caso estaba usando una Rasperry Pi 2 B y que sun GPIO difiere de otros modelos, la conexión me quedó así:

 

En caso de utilizar un adaptador USB serie, la conexión sería como esta:

Preparando un pendrive

Parece ser que esto es algo que da bastantes problemas, donde algunas personas han tenido que recurrir a pendrive antiguos anteriores al 2.0, pero yo me he arreglado con un Sandisk de 16GB que tenía por ahí. Lo tendremos que formatear en FAT32 y depositaremos en él dos ficheros:

  • Los ficheros de u-boot en su versión 18.06.0 porque las más recientes parecen tener un bug que afecta al arranque con USB.
  • El firmware de OpenWRT (la más reciente, a día de hoy la versión 22.03.5).

Colocaremos el pendrive en la placa base del NAS, procurando que sea uno de los puertos traseros 2.0.

Preparando la Raspeberry Pi

Arrancamos la Raspberry Pi (en mi caso llevaba una Hyperbian), nos logueamos y, utilizando el comando «raspi-config», dentro de «Interface options» -> «Serial Port», desactivamos el puerto serie para el login shell y activamos el puerto serie por hardware. Reiniciamos las Raspberry Pi y ya la tenemos lista.

Flasheando

Le damos corriente al NAS a través de su adaptador habitual y lo encendemos desde su botón. Desde la Raspberry Pi descargamos el u-boot y le damos una orden con él a través del USB serie que hemos montado con los cables:

wget https://archive.openwrt.org/releases/18.06.0/targets/kirkwood/generic/u-boot-nsa325/u-boot.kwb

kwboot -p -t -b u-boot.kwb -o 5 -B 115200 /dev/ttyAMA0

Nos pedirá que reiniciemos el dispositivo NAS de Zyxel, con lo que le quitaremos la corriente y se la volveremos a dar. Nos mostrará el progreso de flasheo y cuando haya terminado cargará una especie de shell interactiva en la cual tendremos que dar algunas órdenes.

usb reset
fatload usb 0 0x1000000 u-boot.kwb
nand erase 0x0 0x100000
nand write 0x1000000 0x00000 0x100000
reset

Seguiremos configurando algunas variables de entorno:

setenv mtdparts ‘mtdparts=orion_nand:0x00c0000(uboot),0x80000(uboot_env),0x7ec0000(ubi)’
setenv bootcmd ‘run setenv bootargs; ubi part ubi; ubi read 0x800000 kernel; bootm 0x800000’
saveenv
reset

Le configuraremos la MAC que tenía:

setenv ethaddr AB:CD:EF:00:00:00
saveenv

Flashearemos el fichero «openwrt-22.03.5-kirkwood-zyxel_nsa325-squashfs-factory.bin» que habíamos descargado:

usb reset
fatload usb 0 0x2000000 openwrt-22.03.5-kirkwood-zyxel_nsa325-squashfs-factory.bin
nand erase.part ubi
nand write 0x2000000 ubi 0x600000

Una vez finalizado podremos reiniciarlo con el siguiente comando:

reset

El sistema arrancará y ya tendremos disponible desde el navegador una interfaz web para configurarlo.

Fuentes:

Documentación de OpenWRT

Apuntes de Panticz.de

Trygkey N95

lunes, 10 de abril de 2023 Sin comentarios

En esta ocasión es un Intel N95 de 15W y 4 núcleos equipado con 8GB de DDR4, que me costó algo menos de 223€ en Amazon.

Lo primero que me sorprendió cuando lo abrí es que llevase un módulo de memoria Crucial de 3200Mhz que no deja de ser una marca reconocida. A parte incorpora un disipador bastante mejor que el que he visto en otros equipos de similares características, lo que lo hace mantener un temperatura bastante razonable de unos 40º con carga ligera, muy por debajo de los 60º del NiPoGi.

 

Lleva una tarjeta de red Realtek RTL8111 con velocidades de 800Mbits/seg, de lo más rápido que he visto en este tipo de equipos. El M.2 es de tipo NVME con una velocidad de casi 600MB/seg. de la marca Maxio.

El procesador se comporta estupendamente para tareas multimedia con su soporte por hardware del códec AV1.

Categories: MiniPC Tags:

NiPoGi N95

domingo, 9 de abril de 2023 Sin comentarios

En este caso se trata de un miniPC con el Intel N95 de 15W y 4 núcleos equipado con 16GB de DDR4, que me costó un poco menos de 240€ en Amazon y que acabó siendo devuelto.

El procesador da soporte por hardware a la decodificación del códec AV1 pero la construcción no parece permitirle una buena circulación de aire, permaneciendo fácilmente por encima de 60º sin casi carga. Parece que lleva la misma solución térmica que el N5105 que es de 10W cuando el N95 es de 15W. Esto se resumía en un constante ruido de ventilador y, de ser usado por periodos largos de tiempo, en throttling.

La tarjeta de red es una Realtek que alcanza velocidades ligeramente por encima de 750Mbits/seg lejos del Gigabit.

El disco M.2 es de tipo SATA, un Kowin E2000 de 512GB con velocidades de 500MB/seg. Incorpora un módulo de memoria RAM SODIMM DDR4 de 16GB de 2667Mhz.

 

Lo acabé devolviendo porque las temperaturas eran altas y, sobretodo, porque emitía un zumbido eléctrico muy molesto cuando estaba apagado pero conectado a la corriente.

Categories: MiniPC Tags:

AK1Pro N5105

sábado, 8 de abril de 2023 Sin comentarios

Últimamente me ha dado por probar equipos MiniPC económicos con muy bajo consumo que puedan desempeñar tareas polivalentes ligeras, pero sobretodo multimedia. En este caso se trata de un equipo con un Intel N5105 de 10W y 4 núcleos con 16GB de RAM DDR4 que me costó algo menos de 190€ en Amazon. Pagar más por él no merece mucho la pena debido a los nuevos procesadores que han ido saliendo de nueva generación.

Hay que partir del hecho de que es un equipo con un procesador modesto pero bastante solvente para hacer tareas ofimáticas ligeras o para ver plataformas de streaming. Cuando lo compras suele venir con Windows 11 activado pero funciona perfectamente con Windows 10 si instalamos los drivers correspondientes (que se pueden descargar de un foro oficial bastante útil )

Hay varios factores que he podido analizar desde una live de Ubuntu y de los que dejo captura. La velocidad de la tarjeta de red (una Realtek RTL8111) ronda los 700Mbits/seg, algo lejos del Gigabit pero suficiente para la mayoría de los casos.

La CPU es un Intel N5105 que no funciona nada mal y que se mantiene a unos 55º con poca carga y cuyo ventilador sube a tope para mantenerlo a 70º cuando se le estresa. La GPU (JasperLake), en el apartado que me interesaba de decodificación de vídeo, soporta la mayoría de códecs salvo el AV1.

La memoria RAM que incorpora es un módulo SODIMM de 16GB DDR4 a 2667Mhz de Kinsotn y el M.2 2280 es un Kimtigo KT-B900 de 512GB SATA con velocidades de casi 475MB/seg. No es seguro que se le pueda conectar un M.2 de tipo NVME por lo que he leído por el foro, pero tampoco creo que le haga falta.

En cuanto a la construcción me parece más que razonable aunque se podría haber mejorado la entrada y salida de aire. Hay que tener en cuenta que permite la instalación de un SSD en la parte de abajo de la caja que se comunica con la placa base a través de un USB tipo C. Esa parte de la carcasa yo la he acabado retirando porque no necesitaba conectar un SSD y parecía mejorar un poco el paso del aire.

Algo que no se ve sin abrirlo es que en la placa base hay un conector SATA y un botón que probablemente resetea la BIOS accesible desde fuera a través de jack de audio. También indicar que el equipo emite un zumbido eléctrico muy ligero cuando está en suspensión pero ninguno cuando está apagado.

Categories: MiniPC Tags:

Rompiendo contraseñas de documentos de MS Word

sábado, 4 de marzo de 2023 Sin comentarios

Hace 15 años dejé protegidos con contraseña una serie de documentos de Microsoft Word (versión XP/2003) que impedían su apertura. Con el pasar del tiempo y la contínua renovación de contraseñas, en algún momento puntual, dejé de recordar qué contraseña usé para proteger dichos documentos.

Pensé que en la actualidad no sería difícil encontrar algún mecanismo para romper el sistema de contraseñas que usaba MS Office en 2003 (MD5 + RC4) y me puse manos a la obra en busca de algún programa que me facilitase la tarea. Había dos planteamientos:

  • Eliminando la solicitud de la contraseña.
  • Ataque por fuerza bruta para averiguar la contraseña.

En el primer caso encontré algún artículo en Internet que, mediante la edición del documento .doc con un editor hexadecimal, eliminando la zona en la que se albergaba la contraseña se deshabilitaba la solicitud de la misma, pero no encontraba los patrones con los cuales identificarla y, tras varios intentos, aquello se convirtió en un callejón sin salida. Al menos averigüe que Office 2003 sigue funcionando en Windows 10 y de forma bastante rápida.

El segundo caso me llevó algo más de tiempo porque el mercado está lleno de páginas webs milagrosas y programas en versión demo que sólo me sirvieron para saber que la contraseña tenía más de 6 caracteres y que por fuerza bruta, con un AMD 5900X de 12 núcleos, me llevaría al menos 36 horas. Pero luego descubrí que existía una combinación de software libre bastante más potente.

Primero necesitaríamos extraer el hash de la contraseña del fichero .doc. Este trabajo lo puede hacer un script que podremos descargar desde esta URL y luego utilizaremos el proyecto de HashCat para obtener nuestro objetivo.

Teniéndolo todo en un mismo directorio, los comandos a utilizar serían los siguientes:

python3 office2hashcat.py ficheroObjetivo.doc > hash.txt

./hashcat.bin -a 3 -m 9700 hash.txt

El primer comando extrae de forma inmediata el hash de la contraseña y lo almacena en un fichero de texto «hash.txt» y tendrá el siguiente aspecto:

$oldoffice$1*04477077758555626246182730342136*b1b72ff351e41a7c68f6b45c4e938bd6*0d95331895e99f73ef8b6fbc4a78ac1a

Con lo anterior y consultando la información de la wiki de HashCat sabremos que nuestro hash-mode será el 9700 (-m 9700). Además, como carecemos de diccionario de palabras o sospechamos que no sería de utilidad para encontrar la contraseña,  indicaremos que nuestro modo de ataque será por fuerza bruta (-a 3).

Como contamos con una RTX 3800, HashCat saca provecho de ello y la utiliza para empezar el ataque que nos informa que durará como máximo alrededor de 90 minutos, bastante menos que las 36 horas que nos daban algunos programas en su versión demo. Pero el asombro llega por partida doble cuando el programa termina con éxito al cabo de 15 minutos y nos provee de una contraseña que en mi vida hubiese utilizado. Esto último se debe a las posibles colisiones que existen cuando contamos con cifrados débiles, donde dos palabras diferentes pueden tener el mismo hash.

Finalmente, la contraseña obtenida nos permite abrir esos ficheros sin mayores problemas.

Conclusiones:

  • La cantidad de desinformación, de páginas web fachada y porquería inútil es cada vez mayor en Internet. Resulta dolorosamente penoso el uso de buscadores hoy en día.
  • La contraseña que crees que no vas a olvidar en tu vida no existe, el paso de los años hace estragos en la memoria.
  • Con un hardware comercial a la mano de mucha gente se pueden romper contraseñas en minutos, donde sólo la longitud de la misma y la dureza del cifrado ponen trabas.

Arranque lento en Opensuse

jueves, 19 de enero de 2023 Sin comentarios

Estaba observando que el arranque en Opensuse estaba tardando más de lo usual y utilizando los comandos:

systemd-analyze blame

systemd-analyze plot > /tmp/plot.svg

Detecté que el culpable residia en «postfix.service» principalmente. Se resolvía cambiando el fichero de configuración «/etc/postfix/main.cf» y cambiando el siguiente el valor de configuración:

inet_protocols = ipv4

Después de esto, el servicio «NetworkManager-wait-online» era el que estaba entorpeciendo el arranque. Como no tenía ninguna entrada en fstab que dependiese de la interfaz de red, apliqué los siguientes comandos:

systemctl disable NetworkManager-wait-online.service

systemctl mask NetworkManager-wait-online.service

Finalmente el sistema ahora es capaz de arrancar en poco más de 2 segundos.

Categories: OpenSuse Tags: , ,

Temas AOD en Miui

martes, 6 de diciembre de 2022 2 comentarios

En MIUI se puede escoger un tema en concreto para la función AOD de algunos terminales con animaciones e información. Si quieres fabricar el tuyo propio la documentación oficial es francamente escasa y la mayor parte en chino. Pero una vez consigues un ejemplo funcional el resto es relativamente fácil.

Según la documentación oficial, la estructura del fichero .mtz que tenemos que generar es la siguiente:

Básicamente se trata de un fichero ZIP (método de compresión deflate) al que se le ha cambiado la extensión por .MTZ que contiene un fichero «description.xml» como este:

<?xml version=’1.0′ encoding=’utf-8′ standalone=’yes’ ?>
<MIUI-Theme>
<title>Mi primer AOD</title>
<designer>Cristian</designer>
<author>Cristian</author>
<version>1.0</version>
<uiVersion>12</uiVersion>
<keywords></keywords>
</MIUI-Theme>

El fichero que aparece en el diagrama con el nombre «aod» es también un fichero ZIP (método de compresión deflate) al que se le ha quitado su extensión y que contiene una carpeta «content» y un fichero «aod_description.xml» como este:

<?xml version=’1.0′ encoding=’utf-8′ standalone=’yes’ ?>
<MIUI_Theme_Values>
<!– 类型;百变框架 maml_style –>
<theme_type>maml_style</theme_type>

<!– 是否支持显示农历开关;1 支持,0 不支持,默认为0 –>
<support_lunar_calendar>1</support_lunar_calendar>
<!– 是否支持显示电量开关 –>
<support_battery>1</support_battery>
<!– 是否支持显示通知开关 –>
<support_notification>1</support_notification>

<!– 开关初始状态:显示农历-关闭 –>
<lunar_calendar_enable>0</lunar_calendar_enable>
<!– 开关初始状态:显示电量-开启 –>
<battery_enable>1</battery_enable>
<!– 开关初始状态:显示通知-开启 –>
<notification_enable>1</notification_enable>

</MIUI_Theme_Values>

En el fichero anterior se definen ciertas opciones iniciales y capacidades de las que dispone nuestro tema.

Por otro lado, dentro de la carpeta «content» tenemos la implementación de nuestro AOD. En mi caso se ve así:

Lo interesante ocurre en el fichero «manifest.xml»:

<?xml version=»1.0″ encoding=»utf-8″?>
<Aod frameRate=»60″ screenWidth=»1080″ version=»1″ extraScales=»sw880-den440:0.8148,sw1860-den440:1″ extraResources=»sw880-den440::0.91,sw1860-den440::0.5323″>

<!– aod模块注意事项;1.动画触发放在下方 Trigger 中;2.动画时长不超过4s,超过部分将会被强制停止;3.动画仅播放一次,此后每分钟刷新一次时间 –>
<ExternalCommands>
<Trigger action=»init»>
<ExternCommand command=»animationState» strPara=»‘init'» />
</Trigger>
<Trigger action=»play»>
<AnimationCommand target=»aodAni» command=»play»/>
<AnimationCommand target=»hourAni» command=»play»/>
<AnimationCommand target=»minuteAni» command=»play»/>
</Trigger>
</ExternalCommands>

<VariableBinders>
<!– 查询通知 –>
<ContentProviderBinder name=»data» uri=»content://aod.notification/notifications» columns=»icon» countName=»hasnotifications»>
<Variable name=»notice_icon0″ type=»blob.bitmap» column=»icon» row=»0″/>
<Variable name=»notice_icon1″ type=»blob.bitmap» column=»icon» row=»1″/>
<Variable name=»notice_icon2″ type=»blob.bitmap» column=»icon» row=»2″/>
<Variable name=»notice_icon3″ type=»blob.bitmap» column=»icon» row=»3″/>
</ContentProviderBinder>
</VariableBinders>

<Var name=»aodAni»>
<VariableAnimation loop=»false» initPause=»true»>
<AniFrame value=»0″ time=»0″/>
<AniFrame value=»1″ time=»1500″/>
</VariableAnimation>
</Var>
<Var name=»hourAni»>
<VariableAnimation loop=»false» initPause=»true»>
<AniFrame value=»0″ time=»0″ />
<AniFrame value=»0″ time=»1000″ easeType=»CubicEaseOut»/>
<AniFrame value=»1″ time=»1500″/>
</VariableAnimation>
</Var>
<Var name=»minuteAni»>
<VariableAnimation name=»minuteAnimation» loop=»false» initPause=»true»>
<AniFrame value=»0″ time=»0″ />
<AniFrame value=»0″ time=»1200″ easeType=»CubicEaseOut»/>
<AniFrame value=»1″ time=»1700″/>
<Triggers>
<Trigger action=»end» condition=»#minuteAnimation.current_frame==-1″>
<!– 动画结束之后记得给系统发个命令 –>
<ExternCommand command=»animationState» strPara=»‘finish'» />
</Trigger>
</Triggers>
</VariableAnimation>
</Var>

<Image x=»540″ y=»360″ align=»center» alignV=»center» srcid=»#aodAni*12″ src=»img/num.webp» />
<Image x=»540″ y=»360″ align=»center» alignV=»center» pivotX=»18″ pivotY=»300″ rotation=»(#hourAni-1)*40+#hour12*30+#minute/2″ src=»hour.webp» alpha=»#hourAni*255″ />
<Image x=»540″ y=»360″ align=»center» alignV=»center» pivotX=»29″ pivotY=»300″ rotation=»(#minuteAni-1)*40+#minute*6″ src=»minute.webp» alpha=»#minuteAni*255″ />

<!– 时间 –>
<Group visibility=»eq(#time_format,0)» >
<DateTime x=»540″ y=»700″ format=»hh:mm» size=»110″ color=»#ffffff» align=»center» alignV=»center»/>
</Group>

<Var name=»es_week_xiaoxie» expression=»ifelse(eq(#day_of_week,1),’Domingo’,eq(#day_of_week,2),’Lunes’,eq(#day_of_week,3),’Martes’,eq(#day_of_week,4),’Miércoles’,eq(#day_of_week,5),’Jueves’,eq(#day_of_week,6),’Viernes’,’Sábado’)» type=»string»/>

<Var name=»es_month_jianxie» expression=»ifelse(eq(#month,0),’Enero’,eq(#month,1),’Febrero’,eq(#month,2),’Marzo’,eq(#month,3),’Abril’,eq(#month,4),’Mayo’,eq(#month,5),’Junio’,eq(#month,6),’Julio’,eq(#month,7),’Agosto’,eq(#month,8),’Septiembre’,eq(#month,9),’Octubre’,eq(#month,10),’Noviembre’,’Diciembre’)» type=»string»/>

<Group visibility=»eq(#time_format,1)»>
<DateTime x=»540″ y=»700″ format=»kk:mm» size=»110″ color=»#ffffff» align=»center» alignV=»center»/>
</Group>
<!– 日期、农历 –>
<Text x=»540″ y=»770″ color=»#ffffff» size=»32″ textExp=»@es_week_xiaoxie+’ ‘ +#day_of_week+’ de ‘+@es_month_jianxie+’ de ‘+#year» align=»center» bold=»true»/>
<Text x=»540″ y=»776″ color=»#ffffff» size=»32″ textExp=»@es_week_xiaoxie+’ ‘+#date+’ de ‘+@es_month_jianxie+’ de ‘ #year» align=»center» alignV=»bottom» bold=»true»/>
<!–<DateTime x=»540″ y=»776″ align=»center» alignV=»center» color=»#ffffffff» size=»40″ format=»M月d日 E» bold=»true»/>–>
<DateTime x=»540″ y=»830″ align=»center» alignV=»center» color=»#ffffffff» size=»40″ format=»YY年 N月e» bold=»true» visibility=»#lunar_calendar_enable»/>
<!– 电量 –>
<Group y=»886″ w=»1080″ h=»50″ alignV=»center» visibility=»#battery_enable»>
<Var name=»batteryColor» expression=»ifelse(#battery_state==1||#battery_state==3,’#ff4CB012′,’#ffffffff’)» type=»string» />
<Text x=»540″ y=»25″ align=»right» alignV=»center» color=»#ffffffff» size=»33″ textExp=»#battery_level+’%'» bold=»true»/>
<Rectangle x=»552″ y=»25″ w=»68″ h=»30″ alignV=»center» strokeColor=»#ffffffff» weight=»3″ strokeAlign=»inner» cornerRadius=»15″/>
<Group x=»558″ y=»25″ w=»0.56*#battery_level» h=»18″ alignV=»center» clip=»true»>
<Rectangle w=»56″ h=»18″ fillColor=»@batteryColor» cornerRadius=»9″/>
</Group>
<Image x=»558+28″ y=»25″ align=»center» alignV=»center» src=»lightning.png» visibility=»#battery_state==1||#battery_state==3″ />
</Group>

<!– 本地 预览模式 下显示几条通知;#preview_mode 是否为预览模式 –>
<Var name=»noticeCount» expression=»4″ type=»number» const=»true» />
<!– 通知 –>
<Group x=»ifelse(#preview_mode,-min(#noticeCount-1,3)*60,-min(#hasnotifications-1,3)*60)» visibility=»int(#notification_enable**#preview_mode) || #notification_enable»>
<Image name=»notice_icon0″ x=»540+120*0″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=1||#noticeCount}=1″ srcExp=»ifelse(#preview_mode,’noticeIcon/contacts.png’,»)» />
<Image name=»notice_icon1″ x=»540+120*1″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=2||#noticeCount}=2″ srcExp=»ifelse(#preview_mode,’noticeIcon/mms.png’,»)» />
<Image name=»notice_icon2″ x=»540+120*2″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=3||#noticeCount}=3″ srcExp=»ifelse(#preview_mode,’noticeIcon/email.png’,»)» />
<Image name=»notice_icon3″ x=»540+120*3″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=4||#noticeCount}=4″ srcExp=»ifelse(#preview_mode,’noticeIcon/theme.png’,»)» />
</Group>

</Aod>

Al faltar documentación esta parte es la más complicada de sacar y la vas haciendo fijándote en temas ya hechos. En principio los fotogramas de la animación están separados y se ejecutan en bucle parándose en uno en concreto, con lo cual la imagen que obtendremos en el AOD no siempre corresponderá al mismo fotograma, lo que ayuda a mantener la salud de las pantallas AMOLED.

 

Categories: Android Tags: , ,