Closed Doomsdayrs closed 4 years ago
Thanks for your suggestion @Doomsdayrs, I edited the name of your issue to be more generic (there is no reason why always on display should only work on the SW3). There is no plan for this as of today because it is a very complex problem that would require a lot of work but I let your issue open to keep track of it.
@FlorentRevest Understood, lots of people can benefit from it if it ever happens 😄
I'm also would like this feature!
Really when I tried AsteroidOS with dory it was possible to say some command (I don't remember it) on the clock to prevent display turn off. But IPS backlight eats battery so I sell them.
You can use: mcetool -D on to enable "demo mode" that will keep the screen on with full brightness. But your CPU won't enter deep sleep mode and the battery will be emptied very quickly. An actually efficient "always on screen" mode would require much more work and deeper integration to various system components.
Exactly! But, a. I'm absolutely sure I was able to set minimal brightness after "mcetool -D on" b. Are you sure if it's possible to deep sleep and update the screen every second? c. Fuck fuel economy! The only way I can use the watch is when display is always on and shows actually seconds. (Otherwise it's just a garbage on my wrist.) Dory with not new battery was enough for about 8-12 hours, But as I understand the main load was an IPS white LED emitter, not CPU. I'd like to test some wathc with OLED screen but don't know which one to choose. The enough operating time between battery charge is 24 hours for me.
a) Yes you can b) It is technically possible (android wear does it) but very complex in practice. Again, it requires a major architectural overhaul that is not in sight for the near future. c) I don't think an OLED screen with asteroid in demo mode, without the CPU entering deep sleep (and kernel putting various buses/devices at sleep as well) can get you 24 hours of battery life, but feel free to experiment.
Could you suggest me the watch with OLED?
I'm afraid I am clueless about that.
Lenok (lg watch r) and bass (lg watch urbane) both have P-OLED displays, became cheap and are nicely supported!
Having this (even a rough version) would be useful on watches that don't support vibration (yet) since it would allow to see more easily if there is a new notification.
The SW3 has a tft display if i am not incorrect
I would also like an always on display mode. only showing the watchface without the background would be extremely useful for watches with OLED screens
@Doomsdayrs the Smartwatch 3 has a transflective display, which is notable because it doesn't need backlight for greyscale images. The Smartwatch 3 may have panel self-refresh which would explain how to have good battery life for always-on mode. If so, the challenge may be figuring out the commands to the display driver IC.
Creating a 'tetra'-specific mechanism for always on display isn't a viable solution. We'd probably need to find the API that wearOS uses to abstract this transflective display's capabilities instead.
Just tried Asteroid on my Zenwatch 3 and I love it, its so smooth and responsive and looks fantastic, great work guys! Apologies for the "me too" post but I too would really like to see an always on, I always thought it was one of Android Wears killer features compared to the competition, would be great to see it on Asteroid.
I looked into the matter and reflashed a lenok to stock wearOS.
When you do top
via adb shell
it is kind of obvious that the process com.google.android.wearable.ambient
only is doing work when the watch is showing the always-on-screen.
Further search brought me to https://developer.android.com/training/wearables/apps/always-on were the usage of AmbientModeSupport
is explained. How exactly the low-power ambient mode works is not explained, maybe someone else will pick on from here and can find more sources now that we have a name for the thing.
I have the strong feeling that it is more simple than we imagined.
All the talk is just about oled displays turing off black pixels.
So use much black and update only every minute and you have your low-power mode on oled? Can't be that simple, can it?
How to find out what com.google.android.wearable.ambient actually does?
As far as I'm concerned this is reason enough to put my watch back in a box. Or just send it to electronic waste. A watch that doesn't tell you the time when you just look at it is a 40 year regression - not exactly what I would call advanced technology.
Indeed, it's sad that there hasn't been much referenced development on this @kmccurley
I've got the display to stay on while letting the soc got to deep-sleep mode!
Currently it's very experimental, but at least there is some progress :)
To get it to work changes are needed for mce
(https://github.com/MagneFire/mce/commits/master), ~lipstick
(https://github.com/MagneFire/lipstick/commits/master)~ and qt5-qpa-hwcomposer-plugin
(https://github.com/MagneFire/qt5-qpa-hwcomposer-plugin/commits/master).
I did look into the decompiled code from ClockworkAmbient. But didn't find anything special. Main things that I noticed from the code are:
setExact
).AmbientService
and AmbientDream
.doOnDreamingStarted()
in AmbientService
seems the most important function. It does:
IAmbientActivityCallbacks
-> enterAmbient()
maybeScheduleNextWakeup
)maybeSendDozeCommand
) (enter deep sleep).Initially I thought that the mce
tool was a great starting point to look into, since it is responsible for screen brightness and screen on/off stuff.
mce
uses a state machine to control the display. This is the main thing to look at(https://github.com/MagneFire/mce/blob/master/modules/display.c#L7559).
At some point it fades the screen to black(STM_WAIT_FADE_TO_BLACK) and turns off the display(mce_fbdev_set_power).
mce
sends a D-Bus command to lipstick
(the compositor) (setUpdatesEnabled() function) which sends a command to the Qt5 backend to turn off the display.
The Qt5 backend uses the libhybris backend to control the display(libhybris uses the hwcomposer module for this). the sleepDisplay
function is used to turn off the display.
All we need to do is change the HWC_POWER_MODE_OFF
to HWC_POWER_MODE_DOZE_SUSPEND
(https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/hwcomposer_defs.h#299) to keep the screen awak while letting the system enter deep sleep.
This is all just a very minimal way to get it to work. Current issues are:
Currently I am using the LPM feature of mce
to lower the brightness before entering deep-sleep. This may or may not be the best solution.
I've tested this for about 4 hours now and the battery drained about 3% with Bluetooth disabled and manually waking the screen every hour.
```
May 15 05:55:55 sturgeon kernel: mdss_dsi_off: Panel power off failed
May 15 05:55:55 sturgeon kernel: ------------[ cut here ]------------
May 15 05:55:55 sturgeon kernel: WARNING: at drivers/video/msm/mdss/mdss_mdp_intf_cmd.c:990 mdss_mdp_cmd_stop+0x374/0x444()
May 15 05:55:55 sturgeon kernel: intf 2 unblank error (-598599664)
May 15 05:55:55 sturgeon kernel: CPU: 0 PID: 33 Comm: kworker/u8:1 Tainted: G W 3.10.40 #1
May 15 05:55:55 sturgeon kernel: Workqueue: autosleep try_to_suspend
May 15 05:55:55 sturgeon kernel: Backtrace:
May 15 05:55:55 sturgeon kernel: [
EDIT: lipstick doesn't actually require any change :)
EDIT2: Turns out that you need to set the display mode to FB_BLANK_VSYNC_SUSPEND
. This fixes the kernel panic and the touch-to-wake not working.
After 2 years, we have a genius! Thank you @MagneFire
So I have got everything mostly working.
There is still a small bug where the time is one minute behind in ambient mode. This happens because the watch goes to sleep before the watchface has completed painting the Canvas'.
I propose the following to solve the issue:
onDisplayAmbientUpdate
event from Lipstick.compositor
onDisplayAmbientUpdate
event from Lipstick.compositor
onPainted
-> signal mainscreen somehow that it is done painting.And if the watchface does not obay the new API we get:
onDisplayAmbientUpdate
event from Lipstick.compositor
onDisplayAmbientUpdate
event from Lipstick.compositor
onDisplayAmbientUpdate
timer.Finally, here is some relevant code that watchfaces can use:
Connections {
target: Lipstick.compositor
onDisplayAmbientEntered:
onDisplayAmbientLeft:
onDisplayAmbientUpdate:
}
Lipstick.compositor.displayAmbient // Is the display currently in ambient mode?
Lipstick.compositor.ambientEnabled
I have adjusted the following components:
wakeup
event.Here is a simple diagram to show what I think the ideal flow should be.
Another small issue has something to do with timed.
When I schedule a alarm event. A dbus signal is send to com.nokia.voland
when the alarm fires. Which always starts the alarm-presenter
from asteroid-alarmclock
. Do you know if there is a proper way to filter clock
events for asteroid-alarmclock
with systemd? This would remove the need for any changes in timed
.
Here is a short demo of it all in action:
Is it usable with one second update (with second hand)?
Currently I have about 40~50% battery left at the end of the day. This is with a one minute update.
Of course it is be possible to change the update to something arbitrary, this will have a significant hit on the battery life though. I think your watch won't make it through the day then...
One thing you can do is disable tilt-to-wake, this will increase the battery life.
Great work, fantastic! I think the burn-in offset between the minutely watchface placements needs to be even bigger. With heavy weight fonts i would guess it is necessary to offset by the width of the thickest element on screen to prevent the center most pixels of those elements/fonts to be always on?
Since i am slow, could you link to the stock watchface you ambienized already so i can see what is happening and learn from the example?
Thanks! :)
I agree on the changes for burn in. I am actually thinking that we may also want to desynchronize the watchface and wallpaper. And maybe add a dark filter for the watchface.
Ambient mode settings will then become something like:
I didn't ambienize any watchface. The demo shows behaviour without any change to the watchfaces. The idea is something I am thinking of implementing. What do you think of this idea? If it isn't really clear I can create a simple prototype for this.
EDIT: Now that I am thinking about it. Different watchfaces have a different usable area. So we may want to let the watchface decide how large burn in prevention area is. For a digital watchface the region can be a lot larger that it is now. But for an analog style watchface the current region might be enough.
Understood! Much easier than i thought. My 2 cents
Thanks for your feedback!
I put together a quick demo of your feedback. What do you think of it?
There is always a balance between having too many options in the settings and providing adequate usability for every use case. I stopped using Asteroid because it wouldn't keep the time showing, but some people might think battery life is more important. This suggests to me that it should be controlled by at least one setting. Other settings like brightness in ambient mode might be deferred if there is a disagreement, but I think having some kind of ambient mode with the time displayed is a showstopper and I'm a big fan of this demo.
@kmccurley I guess the default will be what you see in the short demo. With the only setting you have to change is enabling ambient mode.
Ambient mode, obviously, consumes more batter power. For this reason alone, the default might be to have ambient mode disabled by default. Unless @FlorentRevest finds this a super important feature that should be enabled by default :wink:
All other options are considered advanced
.
Gorgeous @MagneFire ! I second @kmccurley when thinking about special user demands. +1 For the requested settings option to disable the AmbientMode. To overthink a little, i could see users want to end the AmbientMode only by certain actions. E.g. some users complained about "Too much wallpaper/color" and demanded a black wallpaper to be stock. (Which Kido did not grant to my relief) Setting:
EDIT, above could also be used on devices where eg. the button on my lenok is often pressed accidentally to rule it out from ending AmbientMode.
Philosophy wise, i would advise to keep the AmbientMode on for stock delivery
I am all-in for having AmbientMode enabled by default. This is what most users want, this is what should be set as default.
There should be an option to disable AmbientMode and come back to what we have right now (screen off) in asteroid-settings because it's still a setup that can make sense in some situations. However, I think that anything else should be either not-configurable (have sane default) or only configurable from the command line (with mcetool for instance). For example, the brightness of ambient mode or whether we should show a wallpaper in ambient mode or not. By the way I agree with eLtMosen that there should be no wallpaper in ambientmode by default, it saves some battery life, improves the readability and probably makes the screen last longer too.
I will review the patches when my time will permit but I of course share the excitement of everyone here about this feature which we have been missing for a long time. :)
I always have found it to be a great tool when using the watch, simply looking at it for the time instead of having to turn it on with a button. And i find it would be a great addition to the watch itself.
That's just an idea i had for the sw3.