forrestguice / SuntimesWidget

Android app (and widget collection) that displays sunlight and moonlight times.
GNU General Public License v3.0
348 stars 61 forks source link

Live Wallpaper for widgets (so can be used on lockscreen) #513

Open ericfont opened 3 years ago

ericfont commented 3 years ago

I'd really like to have a Suntimes display in my lockscreen. I don't think the current Android/Lineage version allows regular widgets to display in the lockscreen (I think for security reasons), but live wallpaper can display in the lockscreen as a workaround. Maybe if simple enough could make a version of each widget as a live wallpaper. I might even make an attempt coding a wallpaper design that works for me and that avoids overlapping my phone's lockscreen notifications area.

ericfont commented 3 years ago

I also wonder if it is possible to have a Suntimes display as an "ambient display", though I wonder if that has to be built into lineage OS. (A minimalistic ambient display that for instance tells me how long till sunrise would be nice to be displayed throughout nighttime). Though actually I see the alarm clock time is displayed in ambient display...which is sufficient info if the alarm clock was set with suntimes! So a special suntimes ambient display is probably not really necessaey.

ericfont commented 3 years ago

I'm thinking maybe a useful simple minimalistic non-intrusive live wallpaper would be a bar along an edge of the screen a few pixels thick like a thin version of your 1x4 widget:

Screenshot_20211028-001840_Trebuchet.png

Could provide customization options for details like: -the particular edge -the thickness -whether to display text & icons for sunrise & sunset -maybe relative time since sunrise -maybe draw relative to current time (in which case the bar would gradually scroll as time passes -whether to display notches for hours (and whether those notches are timezone notches or notches relative to a suntime event, or maybe two sets of notches in opposite directions) -maybe what reference time or suntime alarm to set the bar relative to. (I personally would start my bar from my sunrise alarm so I have my bar relative to when I start my day) -maybe display alarm icons if I have an alarm relative to a suntime -maybe display calendar icon for upcoming calendar event start times -maybe icon for a bedtime which user could set relative to the next suntime alarm -maybe specify how many hours the bar should be...like maybe I might want to have an 16-hour bar. Or maybe have a 8-hour bar which after time exceeds it starts the next 8-hours.

I'm thinking maybe I should make this live wallpaper as my own separate extension apk which depends on your main app, sortof like you have suntimes calendar. Maybe I'll call it "SunTime Progress Bar Wallpaper". I haven't looked at your code but I assume the suntime events and alarms can be queried with a simple function call from the user's installed SunTime app.

forrestguice commented 3 years ago

This sounds like a neat idea.

Thinking aloud, maybe a generic solution is to implement a "widget host" within a live wallpaper. Its normally something your launcher does. I'm not sure that will actually work though. It might be subject to the same restrictions (and that's why widgets aren't on the lock screen to begin with). If it did work, it would be possible to display any widget.

Maybe if simple enough could make a version of each widget as a live wallpaper.

This is probably the easiest way - one widget at a time. Also maybe a maintenance headache. The bar graph you mention is a good candidate though. Its basically just a Bitmap (drawn w/ Java Canvas api), and the widget a RemoteViews that puts that bitmap into an ImageView. The live wallpaper version will need to draw that bmp directly to its own Canvas.

I assume the suntime events and alarms can be queried with a simple function call from the user's installed SunTime app

There is a ContentProvider that provides access to other apps. There are a couple other addons in addition to SuntimesCalendars; Solunar Periods, and Natural Hour. There was a lot of code duplication, which led to SuntimesAddon.

I think Natural Hour might be closest to the goal - as an existing addon, it could probably be extended to add a live wallpaper relatively easily.

forrestguice commented 3 years ago

This seemed like fun and I had some time. There's now a live wallpaper implementation in the NaturalHour wallpaper branch.

ericfont commented 3 years ago

Great, if you can provide me an apk I'd be happy to test and provide feedback...I don't have my computer setup to build android apps at the moment or else I would myself.

forrestguice commented 3 years ago

Sure. I think we can use the debug builds automatically created by the CI.

From https://github.com/forrestguice/NaturalHour/pull/10 click Show All Checks -> Details, then click Summary (left side). There should be a list of 'artifacts' - app should be an unsigned debug build.

The wallpaper seems to work well enough, but probably needs options for alignment. Its currently hardcoded to the top of the screen. A smaller version might bounce from one corner of the screen to the other. Lots of possibilities.. Its not exactly the widget you wanted though, but it demonstrates its feasible.

ericfont commented 3 years ago

Hey this is great...it works! There it is on my lockscreen:

Screenshot_20211102-021739.png

And yeah it is a bit too busy for a regular wallpaper. Though if I can get around to it make a minimalistic trimmed down version.

I am thinking that maybe the whole convert widget(s) to live wallpaper thing would be most effectively done by the OS, so that every single app's widgets could be made into a live wallpaper.

ericfont commented 3 years ago

Hmm...i woke up ~8 hours later but my wallpaper reverted back to default. Maybe some glitch caused it to crash while i was sleeping.

I also notice when rotating the screen, your live wallpaper does reorient itself to point upwards. However it doesn't resize itself to fit within the screen's new dimensions until i press the power button to turn off the screen or trigger a screen redraw.

forrestguice commented 3 years ago

my wallpaper reverted back to default. Maybe some glitch caused it to crash while i was sleeping.

That's a possibility. I've noticed it revert back if it stops running for any reason (crashes). If so there will be something in the logcat.

Another possibility is battery optimization intentionally killed it. Its technically just another Service which Android can stop at any time, but some phones are worse than others (https://dontkillmyapp.com/). If so maybe white-listing the app from the "Battery optimization" page will keep it running. The actual battery use should be minimal. It only (re)draws every 30s when visible.

it doesn't resize itself to fit within the screen's new dimensions

This should be fixed now. Another debug apk is available (same place).

ericfont commented 3 years ago

ok thanks, I see my android did have battery optimization enabled for Suntimes, and so I have now disabled it. (I only saw the main app Suntimes listed in the battery optimization page, not the widget apps, though.)

I've downloaded the new apk and will see if I have any more crashes and if so will post the logcat.

ericfont commented 3 years ago

I just noticed that the suntimes wallpaper is not displaying on my phone...so maybe it crashed sometime in the last 8 hours. I've extracted logcat from adb, and I'm posting the logcat output | grep suntimes:

11-03 13:30:09.471  1197  2196 I ActivityManager: Killing 584:com.forrestguice.suntimeswidget/u0a242 (adj 985): empty #17
11-03 13:35:07.789  1197  1366 I ActivityManager: Start proc 6896:com.forrestguice.suntimeswidget/u0a242 for broadcast {com.forrestguice.suntimeswidget/com.forrestguice.suntimeswidget.SuntimesWidget2}
11-03 14:44:16.450  6896  6910 E .suntimeswidge: failed to connect to jdwp control socket: Connection refused
11-03 14:44:18.480  6896  6910 E .suntimeswidge: failed to connect to jdwp control socket: Connection refused
11-03 14:44:20.518  6896  6910 E .suntimeswidge: failed to connect to jdwp control socket: Connection refused
11-03 14:44:22.522  6896  6910 E .suntimeswidge: failed to connect to jdwp control socket: Connection refused
11-03 14:44:24.559  6896  6910 E .suntimeswidge: failed to connect to jdwp control socket: Connection refused
11-03 14:44:25.898  1197  1822 I ActivityManager: Killing 6896:com.forrestguice.suntimeswidget/u0a242 (adj 975): empty #17
11-03 14:44:25.927     0     0 I         : [20211103_14:44:25.926845]@1 process 6896:.suntimeswidget, 6921:Profile Saver send sig:17 to process 711:main
11-03 14:45:12.688  1197  1366 I ActivityManager: Start proc 11478:com.forrestguice.suntimeswidget/u0a242 for broadcast {com.forrestguice.suntimeswidget/com.forrestguice.suntimeswidget.SuntimesWidget2}
11-03 14:45:12.721 11478 11478 I .suntimeswidge: The ClassLoaderContext is a special shared library.
11-03 14:45:12.764 11478 11478 D WidgetUpdate: onReceive: suntimes.SUNTIMES_WIDGET_UPDATE2(21): class com.forrestguice.suntimeswidget.SuntimesWidget2_3x1
11-03 14:45:12.820 11478 11478 D WidgetUpdate: setUpdateAlarm: November 3, 2:50:12 PM --> suntimes.SUNTIMES_WIDGET_UPDATE2(21) :: 5m
11-03 14:45:12.830 11478 11478 D WidgetUpdate: onReceive: suntimes.SUNTIMES_WIDGET_UPDATE2(20): class com.forrestguice.suntimeswidget.SuntimesWidget2_3x3
11-03 14:45:12.993 11478 11478 D WidgetUpdate: setUpdateAlarm: November 3, 2:50:12 PM --> suntimes.SUNTIMES_WIDGET_UPDATE2(20) :: 5m

I don't know if that is useful at all. I also notice a "beginning of crash" message in my logcat but it was from a time where I think the wallpaper was working correctly:

--------- beginning of crash
11-02 21:43:01.663   886   886 F libc    : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 886 (vendor.lineage.), pid 886 (vendor.lineage.)
11-02 21:43:01.687  1001  1001 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
11-02 21:43:01.687  1001  1001 F DEBUG   : LineageOS Version: '18.1-20211028-NIGHTLY-kebab'
11-02 21:43:01.687  1001  1001 F DEBUG   : Build fingerprint: 'OnePlus/OnePlus8T_EEA/OnePlus8T:11/RP1A.201005.001/2011101425:user/release-keys'
11-02 21:43:01.687  1001  1001 F DEBUG   : Revision: '0'
11-02 21:43:01.687  1001  1001 F DEBUG   : ABI: 'arm64'
11-02 21:43:01.687  1001  1001 F DEBUG   : Timestamp: 2021-11-02 21:43:01-0400
11-02 21:43:01.687  1001  1001 F DEBUG   : pid: 886, tid: 886, name: vendor.lineage.  >>> /vendor/bin/hw/vendor.lineage.livedisplay@2.1-service.oneplus <<<
11-02 21:43:01.687  1001  1001 F DEBUG   : uid: 1000
11-02 21:43:01.687  1001  1001 F DEBUG   : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
11-02 21:43:01.687  1001  1001 F DEBUG   : Abort message: 'PictureAdjustment backend not ready, exiting.'
11-02 21:43:01.687  1001  1001 F DEBUG   :     x0  0000000000000000  x1  0000000000000376  x2  0000000000000006  x3  0000007fc9783cf0
11-02 21:43:01.687  1001  1001 F DEBUG   :     x4  0000000000000000  x5  0000000000000000  x6  0000000000000000  x7  00000000000007a0
11-02 21:43:01.687  1001  1001 F DEBUG   :     x8  00000000000000f0  x9  e724c43e73812f91  x10 0000000000000000  x11 ffffffc0ffffffdf
11-02 21:43:01.687  1001  1001 F DEBUG   :     x12 0000000000000001  x13 000000000000002e  x14 002738487fbf2800  x15 00004ff1e6d4d25a
11-02 21:43:01.687  1001  1001 F DEBUG   :     x16 0000007f65214c80  x17 0000007f651f6c10  x18 0000007f662c0000  x19 0000000000000376
11-02 21:43:01.687  1001  1001 F DEBUG   :     x20 0000000000000376  x21 00000000ffffffff  x22 0000007f65b6f000  x23 0000007f65b6f000
11-02 21:43:01.687  1001  1001 F DEBUG   :     x24 b400007df5108858  x25 0000000000000000  x26 0000000000000000  x27 0000000000000000
11-02 21:43:01.687  1001  1001 F DEBUG   :     x28 0000000000000000  x29 0000007fc9783d70
11-02 21:43:01.687  1001  1001 F DEBUG   :     lr  0000007f651a92a0  sp  0000007fc9783cd0  pc  0000007f651a92cc  pst 0000000000001000
11-02 21:43:01.689  1001  1001 F DEBUG   : backtrace:
11-02 21:43:01.689  1001  1001 F DEBUG   :       #00 pc 000000000004e2cc  /apex/com.android.runtime/lib64/bionic/libc.so (abort+164) (BuildId: be9c72fe4db37cd191b589b74d090d13)
11-02 21:43:01.689  1001  1001 F DEBUG   :       #01 pc 00000000000062b0  /system/lib64/liblog.so (__android_log_default_aborter+12) (BuildId: b5b2ed9d2859e7c956635d8bdb685c6f)
11-02 21:43:01.689  1001  1001 F DEBUG   :       #02 pc 0000000000012fa4  /apex/com.android.vndk.v30/lib64/libbase.so (android::base::LogMessage::~LogMessage()+320) (BuildId: 5716b4ddd53a6120ac86a7ed7586c3ef)
11-02 21:43:01.689  1001  1001 F DEBUG   :       #03 pc 0000000000006238  /vendor/bin/hw/vendor.lineage.livedisplay@2.1-service.oneplus (vendor::lineage::livedisplay::V2_0::sdm::PictureAdjustment::PictureAdjustment(std::__1::shared_ptr<vendor::lineage::livedisplay::V2_0::sdm::SDMController>)+240) (BuildId: 48cb4704d83eecc9f87030ea3086543b)
11-02 21:43:01.689  1001  1001 F DEBUG   :       #04 pc 00000000000093e0  /vendor/bin/hw/vendor.lineage.livedisplay@2.1-service.oneplus (main+336) (BuildId: 48cb4704d83eecc9f87030ea3086543b)
11-02 21:43:01.689  1001  1001 F DEBUG   :       #05 pc 000000000004988c  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+108) (BuildId: be9c72fe4db37cd191b589b74d090d13)
--------- beginning of system

the only other mentions of the word "crash" were for a different app.

forrestguice commented 3 years ago

Hrm.. those some interesting log messages. I'm not sure they are all related. The first set was generated by your (suntimes) widgets. It looks relatively normal, except those lines "failed to connect to jdwp control socket" - I'm not sure what that's about (or even is).

The second one (crash) is likely the wallpaper (hard to say), but there's nothing there to help us. Instead, try grepping for 'naturalhour'. It owns the live wallpaper process and not suntimes (which doesn't run directly in this case, only its contentprovider). Maybe there is something in the lines preceding the crash.

The same goes for the battery optimization stuff - its "natural hour" should be excluded ("not optimized") vs Suntimes. It doesn't hurt to whitelist Suntimes too though, but the consequences are limited to the alarms (may be delayed up to 15min, or failing to reschedule after a reboot, etc). BTW, I think that's a confusing UI.. it displays the whitelist first, then forces you to select "all apps" and search for the app you want to exclude.

ericfont commented 3 years ago

grepping for naturalhour returns nothing. neither if I just grep for natural or grep for hour.

ericfont commented 3 years ago

The same goes for the battery optimization stuff - its "natural hour" should be excluded ("not optimized") vs Suntimes. It doesn't hurt to whitelist Suntimes too though,

Ah...I see I had earlier just whitelisted (i.e. set to "Not optimized") the Suntimes app but forgot to whitelist Natural Hour. Now I have whitelisted (i.e. set to "Not optimized") the Natural Hour app too and will restart everything and look out for crashes.

forrestguice commented 3 years ago

Yeah.. I'm not sure. Seems like the lines are truncated. Actually, grepping for 'suntimes' should return lines for naturalhour (as well as the other widgets). The full package in question is com.forrestguice.suntimes.naturalhour. There should be at least one log message in there; D/NaturalHourWallpaperEngine: draw: <w,h> every time it draws to the screen.

ericfont commented 3 years ago

ok. Just providing for the record I've rebooted my phone after applying the suntimes and have read logcat and grepped suntimes:

logcat_reboot_20211103_suntimes.txt

So that will provide me a reference for what the logcat looks like when it was working, that way I have a better idea what is an unusual message.

ericfont commented 3 years ago

I just noticed if i have my phone horizontal before i turn the screen on, then the lockscreen has the widget centered to fit inside the screen...which is good...

But if i then unlock my screen and then rotate my phone to be vertical, then the wallpaper doesn't resize immediate and so is cutoff:

Screenshot_20211103-154503_Trebuchet.png

But forcing a screen redraw by turning screen off and on does fix the wallpaper to fit in the new dimensions. This is with that last apk from github CI.

ericfont commented 3 years ago

For example, first is a screenshot of lockscreen when viewing my phone in horizontal mode:

Screenshot_20211103-154924.png

Next screenshot after unlocking phone:

Screenshot_20211103-154932_Trebuchet.png

Which seems fine...until i rotate the screen to be vertical, then i get:

Screenshot_20211103-154503_Trebuchet.png

forrestguice commented 3 years ago

lol. It seems I'm gonna be a "live wallpaper lifecycle" expert by the time this thing is working right. The last 'fix' was to trigger a redraw from onSurfaceChanged, but it doesn't seem to be called in this case.

I'll take a closer look. I think part of the difficulty is I don't have an actual device that allows the home screen to rotate. I don't think I would have noticed if you weren't testing.

ericfont commented 3 years ago

ha. and this is interesting...if I wait 15 seconds after turning my phone vertical, then the redraw finally triggers so it looks nice.

And yeah don't feel like you have to waste too much time figuring out the quirks of android's system...I was just reporting this glitch because it was a glitch but it honestly isn't that big of a deal if it is just a matter of waiting for the redraw or forcing a redraw by turning screen on and off.

forrestguice commented 3 years ago

ahh. That makes sense, since the draw loop runs every 30s. ..so if happen to be looking away that long, you'll never notice ;) Maybe if the wallpaper ran more frequently (animation, several times a second) its not something that would ever come up.

ericfont commented 3 years ago

Yup...the 30 second draw loop makes sense. Cause the delay happens both when going from horizontal to vertical and from vertical to horizontal...and the delay seemed to me to be a random number of seconds from 5 to 30 seconds! Anyway, probably not even worth fixing.