Understanding boot animations in Android

Boot animations on Android devices are (usually) played by the /system/bin/bootanimation executable. As it happens, the source of this executable is available (as part of Android) in the official repository in the platform/frameworks/base section. You can easily check it out with the git clone https://android.googlesource.com/platform/frameworks/base command (however be ready for a 600-700 MB download Smile ). Afterwards you can jump to any released (tagged) version by specifying a tag, eg. git checkout android-4.0.1_r1 will roll back the repo state to the first released version of Ice Cream Sandwich.

Once it's done, you'll find the source of this utility in the base/cmds/bootanimation subdirectory. The essential stuff is in BootAnimation.cpp. I've attached the initial version of this file from all major Android versions for easier reference/review in case somebody is looking for it (as I was).

If you're not really into C++, you can read a pretty nice guide on making boot animations here. It's not yet updated (at the time of writing, ie. 15th July 2012) with Jelly Bean's new features (afaik only the "c" part type is new in this release), but it's still quite detailed.

However if you do look into the sources, you can see that feature-wise (i.e. in the syntax and interpretation of desc.txt) there was no change between Eclair (2.0.*/2.1.*), Froyo (2.2.*), Gingerbread (2.3.*), Honeycomb (3.*) and Ice Cream Sandwich (4.0.*). But Jelly Bean (4.1.*) did bring a few small changes. Up til now the first character of an animation section (ie. a "part") line had to be the "p" letter. From now on it can be any letter. If it's a "c", then the given part will be played (at least once) to it's end despite of the state of the boot process. If it's not a "c", then it'll behave like it did in earlier versions with the "p" letter ... i.e. it'll stop the animation when the boot process finishes.

Using the "c" animation type (it's called "pathType" in the source) makes boot animations more portable since boot time varies between devices (makers and models) and using "c" the boot animation playback time can be independent of the length of the boot process on the given device ... it'll be guaranteed that the boot animation is played back to it's full length (at least once) and not interrupted whenever the boot process finishes. This is true for infinitely looping parts too (ie. where the repeat count for the part is specified as zero) and means that the given part will be played back one time for sure and after that it'll be played till the boot process finishes ... and when this happens, the given part will play to it's end (it's not going to be interrupted in the middle) and the playback will advance to the next part (if there's any).

In case of the Jelly Bean boot animation the desc.txt looks like this:
640 640 24
p 1 0 part0
c 0 0 part1
c 0 0 part2

The first line sets width and height to 640, and the FPS to 24.

The first animation part is in the "part0" directory (it consists of 20 PNG images, starts with a fully black frame and shows a colored "X" appearing), so it'll take 0.83s to be played back. The repeat count is 1 and the animation type ("pathType") is set to "p", meaning that it can be interrupted by a finished boot process ... but most probably there're no devices yet that'd boot Jelly Bean under 1s. Wink

The second animation part is in the "part1" directory, it's type is "c" and is set to repeat infinitely. It consists of 80 PNG images showing the colored "X" animated (each "leg" of the "X" is brighting up for a moment in the animation and the sequence is made to be a perfect loop). Now this segment is repeated (due to the "c" animation type) until the boot process finishes. When this happens, the playback of the segment is finished to the last frame and processing advances to the next segment.

The third (and last) animation part is in the "part2" directory, consists of 10 PNG images, it's type is "c" and is set to repeat infinitely. But actually the repeat count could have been anything since at the time we get here, the boot process is already finished, so the playback of the part will stop after the first time anyway. This animation shows the "X" disappearing, the last frame is fully black (just as the first in the first segment).

So as you can see, the new "c" part type (or "pathType") makes it possible to create "full" animations that are not just interrupted whenever the boot process finishes, but allow for a nice fadeout (finished ending) for the animation.

Btw. the "s" (~sound) lines are not supported by the stock bootanimation code. If your device does interpret these lines, then it's a custom extension made by the manufacturer of your device. Imho portable boot animations do not use any sounds (but actually if you put an "s" line in your desc.txt, the stock Android bootanimation will simply ignore it ... so no worries. Smile ).

Moreover since the image decoding is done by SkImageDecoder, it's entirely possible that besides JPG and PNG files other formats (like BMP, ICO, GIF) are supported as well. It depends on which version of SkImageDecoder was used in Jelly Bean.

Update (2013.03.10): the new Jelly Bean (4.2.*) did not bring any new features, only minor API compatibility changes were made.

AttachmentSize
BootAnimation-v1.6_r1.cpp7.76 KB
BootAnimation-v2.0_r1.cpp15.57 KB
BootAnimation-v2.2_r1.cpp16.28 KB
BootAnimation-v2.3_r1.cpp16.28 KB
BootAnimation-v3.2.4_r1.cpp17.08 KB
BootAnimation-v4.0.1_r1.cpp17.12 KB
BootAnimation-v4.1.1_r1.cpp18.73 KB
BootAnimation-v4.2_r1.cpp18.91 KB

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

battery charging animation (while phone is off)

Hello. This is an excellent article, but I'm trying to find out where are the battery charging animation files (when phone is off) and what executable runs it. Any tips?

Re: battery charging animation (while phone is off)

This could be vendor specific, so I only know the answer for sure for my Galaxy Nexus. The battery charging animation consists of PNG images (just like the bootanimation), but they are not packed up into a ZIP and they are not easily replacable (like the boot animation). The files are in the boot partition.

If you google for the terms "unpack android boot image", you'll find several posts (the best ones are of course on XDA) on the topic.
Eg.
So either you can dump your boot image using your phone or optionally you can download it from your vendor (in case of Google's Galaxy Nexus factory images are available for download and they contain the boot.img image file too). Once you've got your boot image, you've to extract the ramdisk part from it. You can use one of the available tools for this (eg. see unmkbootimg in the above list) or you can just open boot.img in a hex editor and search for the 0x1fb808 bytes. For my Nexus (upgraded to Android 4.2.2) I've found two instances of this pattern, the ramdisk starts at the second one (which is preceded by a bunch of zeros ... approx. 900 bytes of zeros).

Once you got the ramdisk saved into a file, you can easily extract it's contents with gzip and cpio:
mkdir ramdisk && cd ramdisk && gunzip -c ../your-ramdisk-file | cpio -i

In the extracted ramdisk folder look for image files. Something like this should do it:
find . -type f -exec file '{}' \; | fgrep 'image'

For my Nexus boot image ramdisk, this resulted in the following output:
./res/images/charger/battery_0.png: PNG image, 120 x 186, 8-bit/color RGB, non-interlaced
./res/images/charger/battery_1.png: PNG image, 120 x 186, 8-bit/color RGB, non-interlaced
./res/images/charger/battery_2.png: PNG image, 120 x 186, 8-bit/color RGB, non-interlaced
./res/images/charger/battery_3.png: PNG image, 120 x 186, 8-bit/color RGB, non-interlaced
./res/images/charger/battery_4.png: PNG image, 120 x 186, 8-bit/color RGB, non-interlaced
./res/images/charger/battery_5.png: PNG image, 120 x 186, 8-bit/color RGB, non-interlaced
./res/images/charger/battery_charge.png: PNG image, 120 x 186, 8-bit/color RGB, non-interlaced
./res/images/charger/battery_fail.png: PNG image, 120 x 186, 8-bit/color RGB, non-interlaced

And opening these files I could confirm that they are indeed the images of the battery charging animation.

If you already got here, you should be able to find a description (or tool) on how to pack together a modified boot.img that you can flash on your phone and have an altered charging animation. Smile

P.S.: the above command examples are meant for Linux or Unix (or Mac OS X) ... or an extreme Windows user who has Cygwin installed for commandline Wink

P.S.2: hacking a non-Nexus device could be a lot more difficult and I've no experience with it. Eg. flashing the boot partition might require signed boot images (or something like that), because vendors like to have tight control over what software gets on "their" devices (even after you paid for them).

charging monitor

Hi muszo,

Do you have any idea how can I find the script that initiates the battery animation in a no-name , 4.2 JB tab? How can I probe for it? I would like this tab to start automatically on plugging the power source , so I would like to replace the charging monitor script with a script containing the reboot command but I have no clue on how would you start looking for that script in a no-name tab, probably proprietary ROM not AOSP. Manufacturer doesn't want to help and I really need that function.Tab is rooted, of course.
Thank you in advance,
Serge

Re: charging monitor

I'm in a hospital right now, but once I get out, I'll take a look at this (if I don't forget). I've got two tablets with proprietary ROMs, which means I can test my ideas in practice.

Get better soon :)

No problem, I'll go on trying and remember the stuff to you in a week or so. Thanks for your prompt answer.

Interested

Hello,

If you are able to figure out how to auto restart a nexus , I would be interested too.Been stuck with this problem for quite a long myself.Thanks and get well soon.

Re: charging monitor

Here's what I've figured out ...

So far I've looked at four devices that I've access to:
I think that the charging animation is controlled/started by the charger class in init.rc in all four devices. To get to init.rc, you've to either extract the boot ROM from your device or you've to get your hands on a factory image that contains the boot ROM image (boot.img).

The boot ROM contains a ramdisk image and a kernel. You can use the abootimg utility to extract these from the boot ROM image. For three of the above mentioned devices the ramdisk was a gzipped cpio archive, which you can easily decompress and unpack. For the Navon tablet the ramdisk was in some other format, but somebody already figured out the format and created utilities to unpack and repack this ramdisk for various MediaTek devices.

Now if you've got your ramdisk unpacked in a directory, you'll find init.rc in it's root. And it most certainly has these lines in it:
on charger
    class_start charger

If you want to learn about the init.rc syntax, read this. To cut it short, you can define "services" (executables with parameters) and specify service groups called "classes". Now when you plug the charger in your turned off device, the init process is started in "charger" mode and this charger class gets invoked.

My first guess is that defining a new service in init.rc and adding it to the charger class should get it executed upon plugging in the charger.
So something like this should do the trick:
service mycharger /system/bin/sh /system/bin/mycharger.sh
    class charger
    user root
    group root

And of course you've to place you shell script in /system/bin/mycharger.sh.

Or maybe you can directly execute reboot and boot the device into normal mode?
service mycharger /system/bin/reboot
    class charger
    user root
    group root

Or simply replace the "on charger" section alltogether?
on charger
    start mycharger

service mycharger /system/bin/reboot
    class late_start
    user root
    group root
    disabled
    oneshot

Whatever you try, you should have at least an ADB-enabled recovery installed so you've a chance to fix things if you accidentally brick (bootloop, etc.) your device.

Btw. on two of my devices (the Galaxy Nexus and the OnePlus One) there's a "charger" executable in the root of the ramdisk and it has string references to the various charging animation images that are in the "res/images/charger" directory (inside the ramdisk). In case of the other two devices I did not find a "charger" executable. On the Navon (MediaTek) tablet there's a so called "logo" partition (it's contents are in the "logo.bin" file as extracted with the MTK Droid Root & Tools utility) and it contains the charging animation frames. You can extract the contents of this logo.bin file with the same unpack-MTK.pl script that I suggested for the extraction of the boot ROM's contents.

For my MediaTek device, this resulted in a directory called "logo.bin-unpacked" that was full with logo.bin-img[nn].rgb565 files. The latter could be converted into standard PNG files with this:
for i in $(find . -type f -iname '*.rgb565'); do
  b="$(basename "$i" .rgb565)";
  set -- $(du -b "$i")
  case "$1" in
    1228800) s="600x1024";;
    4104) s="38x54";;
    5184) s="48x54";;
    6480) s="135x24";;
    270)  s="135x1";;
  esac
  ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s "$s" -i "$i" -f image2 -vcodec png "$b.png";
done

Re: charging monitor

Hi müzso,
As I'm interested in booting phone when is connected to charger/usb I found information you provided very helpful. I'm using Prestigio PAP4300 MT6575.
Before your steps, I tried with ipod file as is explained in some forum threads. I changed /system/bin/ipod as follows:
cat /system/bin/ipod
#!/system/bin/sh
/system/bin/reboot

This work when running from adb shell, but doesnt start the phone when is turned off and charger/usb is plugged.
So I found your site and managed to export /dev/logo as logo.bin, then extract logo.bin in logo.bin-unpacked directory with the perl script mentioned above.
There were some errors during extracting, but I see .rgb565 files in logo.bin-unpacked directory.

[vasko@sofia Downloads]$ ./unpack-MTK-2.pl logo.bin
MTK-Tools by Bruno Martins
MTK unpack script (last update: 06-01-2015)

Valid logo signature found...
Warning: unexpected logo image file size! Trying to unpack it anyway...

Extracting images to directory 'logo.bin-unpacked'

Number of images found: 4
Image #0 written to 'logo.bin-img[00].rgb565'
Resolution: unknown
Image #1 written to 'logo.bin-img[01].rgb565'
Resolution: unknown
Image #2 written to 'logo.bin-img[02].rgb565'
Resolution: unknown
Image #3 written to 'logo.bin-img[03].rgb565'
Resolution: unknown

Successfully extracted all images.

I'm not sure if my understanding is correct, but I deleted the contents of the files and added reboot command from the above in logo.bin-img[00].rgb565.
Then I tried to repack with:
./repak-MTK-2.pl -logo --no_compression /home/vasko/Downloads/logo.bin-unpacked/ logo2.bin
MTK-Tools by Bruno Martins
MTK repack script (last update: 06-01-2015)

Repacking logo image (without compression)...

Error: couldn't find any .png or .rgb565 file under the specified directory
'/home/vasko/Downloads/logo.bin-unpacked'!

Could you tell me what is wrong and explain how to proceed with new repacked logo.bin if I manage to repack it successfully?

Thank you in advance. Your help will be appreciated.
Vasil

Re: charging monitor

I'm sorry if my comment was misleading. Shock You cannot achieve your goal by modifying the logo partition. The latter merely contains the frames (still images) of the charging animation.

You should get familiar with boot images, get your hands on your boot image (either by extracting it from your phone or downloading it from the web), check out what gets executed on the "charger" event and hijack this with a script/command that (re)boots your phone. Of course to modify the init.rc file in your boot partition, you'll have to unpack the boot image, modify init.rc, repack the boot image and flash the boot image into the boot partition. Quite risky, it's not that hard to brick your phone this way!

boot when charger is plugged

hy,

with my "s6 edge" this does not work! But i dont know why.
i got the original boot.img from the phone - then i extracted the boot.img and edited the init.rc in both ways. one with a extra file in /system/bin/"mycharger.sh" and one where everything is in the init.rc file.
then i repacked everything... but with both new boot.img the phone does not start to boot when i plug it in!

can you give me another advise?

greets

Sorry, I've no idea why it

Sorry, I've no idea why it doesn't work for you. I did not try this method, so I've no first hand experience with the possible issues.
I don't know how one can debug such a problem, because during the boot process probably you cannot write data to the sd card or whatever persistent storage there is. I did a bit of googling (for the terms android debug boot issues) and it seems that you might be able to get some logcat output even during boot. Maybe try that.

4.4 but without "C" tags

Is it possible, if my android device is running a build of 4.4.4, to NOT have the updated Jellybean boot animation executables?
Everytime I've attempted to install a custom animation with a "C" tag in the desc.txt, it freezes on boot, and I have to restore an image.
More specifically, is there a way that I would be able to just update that executable? When I've navigated to the /system/bin/bootanimation executable, it's not readable, and has no extension.

Thanks for your great work on deciphering this!

Re: 4.4 but without "C" tags

It's possible to replace the bootanimation executable, but you need to root your device to do so.
And most probably you'd have to compile a custom modified bootanimation for your 4.4.4 version. Just replacing the old with one from another ROM (or Android version) could put you in a boot loop (since bootanimation probably depends on Android version specific libraries ... I've never checked this, but there's a chance it is so).

Yeah, that's what I figured.

Yeah, that's what I figured. I've got the custom animation I made, and it works as long as I only use the "p" command lines. The device I'm using probably isn't going to get a 5.0 update, so at this point I think I'm gonna have to just suck it up... too bad.
Thanks for the help though!