I am impressed by the amazing progress Android’s UI has made since its inception. With each iteration, likewise in software as in hardware, its usability and aesthetics have steadily improved to the point where I can now confidently buy one for my mom to replace the iPhone I recommended to her only last year.
On the other hand, one particular "feature" I intensely dislike is the screen-off animation that emulates the brief white flash you see when an old CRT TV monitor is powering off. Introduced in Gingerbread (2.3), it seems not to bother most people as much as it bothers me, and even seems to be quite popular (e.g., this thread).
As a CyanogenMod fan, I was quite happy with the straightforward checkbox in the Settings app in CyanogenMod 9 that toggled whether to play this animation. In CM10, this option was removed, but there was an easy hack involving changing window animation scale in the developer settings, as explained in the second link above.
So when I updated to CM10.1 M1, I was very unpleasantly surprised to find that this hack does not work any more either. I tried to immediately downgrade to CM10, but then discovered that doing so requires a full data wipe (of course…). A quick search pulled up this thread which proposes a simple prop edit, but the following posts in the thread suggest mixed results.
So, stuck with CM10.1, and really disgusted at this turn of events, I finally decided to put on my hax0r gloves and get this annoying "feature" out of my face once and for all.
I went to androidxref.com and started searching the Android source code for "screen off animation". (OK, I actually started out with grep, but it didn’t take me long to realize androidxref.com was about sixty million times faster - it’s really pretty cool.)
I quickly found why changing the window animation scale in Jelly Bean 4.1 (and
CM10) disables the screen-off animation. The two snippets of of code
implementing this behavior are at
line 470 and
In Jelly Bean 4.2 (and CM10.1), however, these parts of the code have been
completely refactored. The snippet of code that launches the screen-off
animation is now found at
DisplayPowerController.java. Note that this new
class has been factored out of the old
PowerManagerService class, and both
have moved into a separate
Disclaimer: I am NOT responsible for anything that happens to your phone or you or your house or your relationship with your wife if you follow the instructions down here. If you don’t know what you’re doing and are scared of bricking your phone, just give up and go watch Superbowl. Please.
What did not change, I found, is that this code gets packaged into
/system/framework/services.jar on the Android system. So, let’s take a look at
this file as found in the CM10.1 image on my phone:
# Copy services.jar from phone to current directory. adb pull /system/framework/services.jar # Disassemble. apktool d services.jar
apktool is a tool that
extracts and disassembles Android APK/JAR files, and is available for Linux,
Windows and OS X.) This produces a directory,
services.jar.out, which contains
the disassembled code of
services.jar we just pulled from a connected phone. I
dived into the
DisplayPowerController code and edited the else clause at
to essentially just say
setScreenOn(false); directly instead of running
the animation first. If you look at the dissassembled code, you’d realize Dalvik
bytecode is really quite readable and easy to hack, especially since the line
number hints allow you to directly map a line in the Java source code to the
corresponding Dalvik instructions. I just had the Java source file on
androidxref.com open in a browser tab for reference
and killed instructions line by line. You can
download my patch here and apply
it like this:
patch -d services.jar.out -Np1 < path/to/disable_screen_off_animation.patch
Now re-assemble the code and push it back on to the device:
# Re-assemble modified sources as services-mod.jar. apktool b services.jar.out services-mod.jar # Copy services-mod.jar to /sdcard/ on phone. adb push services-mod.jar /sdcard/ # Remount /system partition as read-write in order to modify it. adb shell su -c 'mount -o rw,remount /system' # Overwrite original services.jar on phone with services-mod.jar as root. adb shell su -c 'cp /sdcard/services-mod.jar /system/framework/services.jar' # Reboot phone for this to take effect. adb reboot
When the phone reboots, it will say Android is upgrading and will rebuild Dalvik cache for each application, so it might take a while. But hey, it’s worth it.
The final product, if you just want to replace the
services.jar on your phone, is here:
CyanogenMod 10.1 M1 - tested on Galaxy Nexus (maguro) and Nexus S (crespo), should work on other phones as well (can’t promise - let me know):
CyanogenMod 10.1 M2 - tested on Galaxy Nexus (maguro), should work on other phones as well (can’t promise - let me know):
CyanogenMod 10.1 M3 - tested on Galaxy Nexus (maguro), should work on other phones as well (can’t promise - let me know):
CyanogenMod 10.1 RC1 - tested on Galaxy Nexus (maguro), should work on other phones as well (can’t promise - let me know):
Stock 4.2.2 (takju/JDQ39) - for "takju" factory image from Google
Note: use this to replace
Stock 4.2.2 (yakju/JDQ39) - for "yakju" factory image from Google
Note: use this to replace
services-mod.jar to your phone like this (obviously assuming you
have adb working and root):
# Copy services-mod.jar to /sdcard/ on phone. adb push services-mod.jar /sdcard/ # Remount /system partition as read-write in order to modify it. adb shell su -c 'mount -o rw,remount /system' # Overwrite original services.jar on phone with services-mod.jar as root. adb shell su -c 'cp /sdcard/services-mod.jar /system/framework/services.jar' # Reboot phone for this to take effect. adb reboot
Or, I suppose, you could just use ES File Explorer with root mode enabled, mount
/system as read-write and copy the file to
Note that a reboot is needed after you replace the
services.jar whatever you
do, and upon the first reboot the "Android is upgrading" dialog will pop up.