package Ġse . loc ut us . sl . re alt id hem . service Ċ Ċ import Ġandroid . app . Service Ċ import Ġandroid . app widget . App Widget Manager Ċ import Ġandroid . os . IB inder Ċ import Ġse . loc ut us . sl . re alt id hem . events . Wake Lock Re ce ie ver Ċ import Ġjava . util . logging . Logger Ċ import Ġandroid . app . Pending Intent Ċ import Ġandroid . content .* Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . Looper Ċ import Ġandroid . os . Power Manager Ċ import Ġandroidx . core . app . Notification Compat Ċ import Ġse . loc ut us . proto . Ng Ċ import Ġse . loc ut us . sl . re alt id hem . R Ċ import Ġse . loc ut us . sl . re alt id hem . activity . WIDGET _ CONFIG _ PRE FS Ċ import Ġse . loc ut us . sl . re alt id hem . events . ST ALE _ M ILL IS Ċ import Ġse . loc ut us . sl . re alt id hem . events . Widget Broadcast Receiver Ċ import Ġse . loc ut us . sl . re alt id hem . widget .* Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġkotlin . concurrent . timer Task Ċ Ċ const Ġval ĠDEFAULT _ ALWAYS _ UPDATE _ TIMEOUT _ M ILL IS Ġ= Ġ 6 0 Ġ* Ġ 1 0 0 0 Ġ* Ġ 5 Ċ const Ġval ĠSERVICE _ NOTIFICATION _ ID Ġ= Ġ 1 3 3 7 Ċ Ċ class ĠBackground Updater Service Ġ: ĠService () Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠLOG Ġ= ĠLogger . getLogger ( Background Updater Service :: class . java . name ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġvar Ġwake Lock Receiver : ĠW ake Lock Re ce ie ver Ġ= ĠW ake Lock Re ce ie ver ( this ) ĊĠĠĠ Ġprivate Ġval Ġmain Handler Ġ= ĠHandler ( Looper . get Main Looper ()) ĊĠĠĠ Ġprivate Ġvar Ġtimer Task Ġ: ĠTimer Task ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġval Ġtimer Ġ= ĠTimer () ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġprefs Ġ: ĠSharedPreferences ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġpower Manager Ġ: ĠPower Manager ĊĠĠĠ Ġprivate Ġval Ġauto Update Sequence EndTime Ġ= ĠConcurrent HashMap < Int , ĠLong >() ĊĠĠĠ Ġprivate Ġval Ġself Learning Timeout s Ġ= ĠConcurrent HashMap < Int , ĠLong >() ĊĠĠĠ Ġprivate Ġval Ġwidget Configs Ġ= ĠConcurrent HashMap < Int , ĠNg . Widget Configuration >() ĊĊĠĠĠ Ġ// Ġhttps :// github . com / ro bo lectric / ro bo lectric / issues / 3 7 6 3 ĊĠĠĠ Ġinternal Ġvar Ġwidget Id Provider Ġ: Ġ() Ġ-> ĠInt Array Ġ= Ġ{ ĠgetAll Widget Ids ( this ) Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonStart Command ( intent : ĠIntent ?, Ġflags : ĠInt , Ġstart Id : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ ĠLOG . info (" Received Ġintent Ġ$ intent ") ĊĠĠĠĠĠĠĠ Ġif Ġ( intent ?. has Extra ( App Widget Manager . EXTRA _ APP WIDGET _ ID ) Ġ== Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTyp ical Ġcase Ġis Ġa Ġwidget Ġupdate Ġintent Ġalarm Ġtriggering . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġintent . getInt Extra ( App Widget Manager . EXTRA _ APP WIDGET _ ID , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . info (" Received Ġextra Ġwidget Id Ġ$ id ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġself Learning Timeout s [ id ] Ġ= ĠSystem . currentTimeMillis () Ġ+ ĠUPDATE _ TIME _ M ILL IS ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġall Widget Ids Ġ= Ġwidget Id Provider () ĊĠĠĠĠĠĠĠ ĠLOG . info (" Widget ĠI ds Ġ${ all Widget Ids . toList () }") ĊĠĠĠĠĠĠĠ Ġvar Ġupdate Any Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġfor Ġ( widget Id Ġin Ġall Widget Ids ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( should Update ( widget Id )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Any Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(! update Any ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . warning (" Service Ġstart Ġwithout ĠWidget s Ġto Ġupdate , Ġstopping ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop Self ( start Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠSTART _ STICK Y ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠStart Ġautomatic Ġupdates Ġright Ġaway . ĊĠĠĠĠĠĠĠ Ġif Ġ( power Manager . is Interactive ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Auto Update Sequence () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcreate Fore Ground Notification () ĊĊĠĠĠĠĠĠĠ Ġreturn ĠSTART _ STICK Y ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Fore Ground Notification () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdisable I Ġ= ĠIntent ( this , ĠBackground Updater Service :: class . java ). apply Ġ{ Ġaction Ġ= Ġ" test " Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġp disable Ġ= ĠPending Intent . getService ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdisable I , Ġ 0 ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġenable I Ġ= ĠIntent ( this , ĠBackground Updater Service :: class . java ). apply Ġ{ Ġaction Ġ= Ġ" test 2 " Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġp enable Ġ= ĠPending Intent . getService ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġenable I , Ġ 0 ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġnotification Ġ= ĠNotification Compat . Builder ( this , Ġ" 1 2 3 ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Small Icon ( R . mip map . ic _ launcher ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. addAction ( R . mip map . ic _ launcher , Ġ" Disable ", Ġp disable ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. addAction ( R . mip map . ic _ launcher , Ġ" Enable ", Ġp enable ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. setContent Title ( getString ( R . string . auto _ updates _ running )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ. setContent Intent ( pending Intent ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġstart Foreground ( SERVICE _ NOTIFICATION _ ID , Ġnotification ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Once () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtouch Handler Ġ= ĠWidget Broadcast Receiver . get Touch Handler ( this ) ĊĠĠĠĠĠĠĠ Ġvar Ġupdated Widget Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġfor Ġ( widget Id Ġin ĠgetAll Widget Ids ( this )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( should Update ( widget Id )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . info (" Automatic Ġupdate Ġof Ġwidget Ġ$ widget Id ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtouch Handler . widget Tou ched ( widget Id , Ġ"", Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdated Widget Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(! updated Widget ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . info (" No Ġwidgets Ġleft Ġto Ġupdate ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠgetConfig For ( widget Id : ĠInt ) Ġ: ĠNg . Widget Configuration Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! widget Configs . containsKey ( widget Id )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwidget Configs [ widget Id ] Ġ= Ġload Widget Config OrDefault ( prefs , Ġwidget Id ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġwidget Configs [ widget Id ] !! ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshould Update ( widget Id Ġ: ĠInt ) Ġ: ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġupdate Mode Ġ= ĠgetConfig For ( widget Id ). update Settings . update Mode ĊĠĠĠĠĠĠĠ Ġif Ġ( update Mode Ġ== ĠNg . Update Settings . Update Mode . MAN UAL _ UPDATE _ MODE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( update Mode Ġ== ĠNg . Update Settings . Update Mode . LEAR NING _ UPDATE _ MODE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġself Learning Timeout s . containsKey ( widget Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& ĠSystem . currentTimeMillis () Ġ<= Ġself Learning Timeout s [ widget Id ] !! ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( update Mode Ġ== ĠNg . Update Settings . Update Mode . ALWAYS _ UPDATE _ MODE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! auto Update Sequence EndTime . containsKey ( widget Id )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġauto Update Sequence EndTime [ widget Id ] Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠMake Ġconfigure able . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . currentTimeMillis () Ġ+ ĠDEFAULT _ ALWAYS _ UPDATE _ TIMEOUT _ M ILL IS ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠSystem . currentTimeMillis () Ġ<= Ġauto Update Sequence EndTime [ widget Id ] !! ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstart Auto Update Sequence () Ġ{ ĊĠĠĠĠĠĠĠ ĠLOG . info (" Starting Ġautomatic Ġupdates ") ĊĠĠĠĠĠĠĠ Ġtimer Task Ġ= Ġtimer Task { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmain Handler . post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Once () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠMake Ġthese Ġconstants ? ĊĠĠĠĠĠĠĠ Ġtimer . schedule ( timer Task , Ġ 2 0 0 , ĠST ALE _ M ILL IS Ġ+ Ġ 1 0 0 0 L ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġhas Auto Updates Running () Ġ: ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtimer Task Ġ!= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstop Auto Update Sequence () Ġ{ ĊĠĠĠĠĠĠĠ ĠLOG . info (" Stopping Ġautomatic Ġupdates ") ĊĠĠĠĠĠĠĠ Ġif Ġ( timer Task Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtimer Task !!. cancel () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtimer Task Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate () Ġ{ ĊĠĠĠĠĠĠĠ ĠLOG . info (" On Create ") ĊĠĠĠĠĠĠĠ Ġprefs Ġ= Ġget SharedPreferences ( WIDGET _ CONFIG _ PRE FS , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġpower Manager Ġ= Ġget System Service ( Context . POWER _ SERVICE ) Ġas ĠPower Manager ĊĠĠĠĠĠĠĠ Ġval Ġintent Filter Ġ= ĠIntent Filter () ĊĠĠĠĠĠĠĠ Ġintent Filter . addAction ( Intent . ACTION _ SCREEN _ ON ) ĊĠĠĠĠĠĠĠ Ġintent Filter . addAction ( Intent . ACTION _ SCREEN _ OFF ) ĊĠĠĠĠĠĠĠ Ġintent Filter . addAction ( Intent . ACTION _ USER _ PRESENT ) ĊĠĠĠĠĠĠĠ Ġregister Receiver ( wake Lock Receiver , Ġintent Filter ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . onCreate () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Destroy () Ġ{ ĊĠĠĠĠĠĠĠ ĠLOG . info (" On Destroy ") ĊĠĠĠĠĠĠĠ Ġunregister Receiver ( wake Lock Receiver ) ĊĠĠĠĠĠĠĠ Ġstop Auto Update Sequence () ĊĠĠĠĠĠĠĠ Ġsuper . on Destroy () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Bind ( intent : ĠIntent ): ĠI Binder Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" not Ġimplemented !") ĊĠĠĠ Ġ} Ċ Ċ } Ċ