In logcat I found the following lines:
06-12 13:22:09.250 2484-2510/system_process I/Terry-FB: strSuspendImgFileName = /storage/sdcard1/suspend_others.jpg
06-12 13:22:09.250 2484-2510/system_process I/Terry-FB: strEPubFolder + "/" + strDefaultImgFileName = /data/data/de.telekom.epub/files//suspend_others.jpg
06-12 13:22:09.250 2484-2510/system_process I/Terry-FB: strLocaleImgFolder + "/" + strDefaultImgFileName = /system/usr/sleep/drawable-de-nodpi/suspend_others.jpg
06-12 13:22:09.250 2484-2510/system_process I/Terry-FB: strEPubFolder + "/" + strChargeImgFileName = /data/data/de.telekom.epub/files//suspend_charging_others.jpg
06-12 13:22:09.250 2484-2510/system_process I/Terry-FB: strLocaleImgFolder + "/" + strChargeImgFileName = /system/usr/sleep/drawable-de-nodpi/suspend_charging_others.jpg
06-12 13:22:09.250 2484-2510/system_process I/Terry-FB: strLocaleImgFolder + "/" + strFullImgFileName = /system/usr/sleep/drawable-de-nodpi/suspend_batteryfull_others.jpg
Apparently this is where it loads the image that is shown during sleep. Using grep I found the code in /system/framework/android.policy.jar.
So I decompiled this file using JADX and found the lines where the screen is cleared and overwritten in ShowSleepScreenEx(). Since recompiling code that was decompiled with JADX is rather cumbersome I used apktool to decompile the jar into smali code, where I removed the call to ShowSleepScreenEx(). Using "apktool build" I recreated the jar file and pushed it back to the device. Voila: the screen is no longer cleared when the device goes to sleep.
I did not find a way to turn the screen off programmatically, so I simply set the screen timeout to a low value using
adb shell settings put system screen_off_timeout 1000
(Well, it turns out the minimum is 10s, but stubborn as I am I still set it to 1s :-))
Using ALarmManager I wake up every minute to update the time.
The usual methods for turning on the screen (SCREEN_DIM_WAKE_LOCK, WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) did not work on this device for some reason, so I found a different one:
I cross-compiled libevdev and evemu and simulate pressing the power button:
public class AlarmWorker extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
try {
Process proc = Runtime.getRuntime().exec(new String[]{"/system/bin/evemu-event",
"--sync", "/dev/input/event0", "--type", "EV_KEY", "--code", "KEY_POWER", "--value", "1"});
proc.waitFor();
SystemClock.sleep(50);
proc = Runtime.getRuntime().exec(new String[]{ "/system/bin/evemu-event",
"--sync", "/dev/input/event0", "--type", "EV_KEY", "--code", "KEY_POWER", "--value", "0" });
proc.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
Instead of 2 days the battery now lasts 5 days on one charge.