/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 0 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġcom . best . desk clock . uid ata Ċ Ċ import Ġandroid . content . Broadcast Receiver Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . Intent Filter Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . Looper Ċ import Ġandroid . text . format . Date Utils Ċ import Ġandroidx . annotation . Visible ForTesting Ċ Ċ import Ġcom . best . desk clock . Log Utils Ċ import Ġcom . best . desk clock . Utils Ċ Ċ import Ġjava . util . concurrent . Copy On Write ArrayList Ċ import Ġjava . util . Calendar Ċ Ċ /** Ċ Ġ* ĠAll Ġcallbacks Ġto Ġbe Ġdelivered Ġat Ġrequested Ġtimes Ġon Ġthe Ġmain Ġthread Ġif Ġthe Ġapplication Ġis Ġin Ġthe Ċ Ġ* Ġforeground Ġwhen Ġthe Ġcallback Ġtime Ġpasses . Ċ Ġ*/ Ċ internal Ġclass ĠPeriod ic Callback Model ( context : ĠContext ) Ġ{ ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġenum Ġclass ĠPeriod Ġ{ ĊĠĠĠĠĠĠĠ ĠMIN UTE , ĠQU AR TER _ HOUR , ĠHO UR , ĠM ID N IGHT ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠRes chedules Ġcallbacks Ġwhen Ġthe Ġdevice Ġtime Ġchanges . Ġ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġm Time Changed Receiver : ĠBroadcast Receiver Ġ= ĠTime Changed Receiver () ĊĊĠĠĠ Ġprivate Ġval Ġm Periodic Run n ables : ĠMutable List < Periodic Runnable > Ġ= ĠCopy On Write ArrayList () ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠRes chedules Ġcallbacks Ġwhen Ġthe Ġdevice Ġtime Ġchanges . ĊĠĠĠĠĠĠĠ Ġval Ġtime Changed Broadcast Filter Ġ= ĠIntent Filter () ĊĠĠĠĠĠĠĠ Ġtime Changed Broadcast Filter . addAction ( Intent . ACTION _ TIME _ CHANGED ) ĊĠĠĠĠĠĠĠ Ġtime Changed Broadcast Filter . addAction ( Intent . ACTION _ DATE _ CHANGED ) ĊĠĠĠĠĠĠĠ Ġtime Changed Broadcast Filter . addAction ( Intent . ACTION _ TIME ZONE _ CHANGED ) ĊĠĠĠĠĠĠĠ Ġcontext . register Receiver ( m Time Changed Receiver , Ġtime Changed Broadcast Filter ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġrunnable Ġto Ġbe Ġcalled Ġevery Ġminute ĊĠĠĠĠ Ġ* Ġ@ param Ġoffset Ġan Ġoffset Ġapplied Ġto Ġthe Ġminute Ġto Ġcontrol Ġwhen Ġthe Ġcallback Ġoccurs ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġadd Minute Callback ( run nable : ĠRunnable , Ġoffset : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġadd Periodic Callback ( run nable , ĠPeriod . MINUTE , Ġoffset ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġrunnable Ġto Ġbe Ġcalled Ġevery Ġquarter - hour ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġadd Qu arter Hour Callback ( run nable : ĠRunnable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠCallback s Ġ* can * Ġoccur Ġearly Ġso Ġpad Ġin Ġan Ġextra Ġ 1 0 0 ms Ġon Ġthe Ġquarter - hour Ġcallback ĊĠĠĠĠĠĠĠ Ġ// Ġto Ġensure Ġthe Ġsampled Ġwall clock Ġtime Ġreflect s Ġthe Ġsubsequent Ġquarter - hour . ĊĠĠĠĠĠĠĠ Ġadd Periodic Callback ( run nable , ĠPeriod . QU AR TER _ HOUR , Ġ 1 0 0 L ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġrunnable Ġto Ġbe Ġcalled Ġevery Ġhour ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġadd Hour Callback ( run nable : ĠRunnable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠCallback s Ġ* can * Ġoccur Ġearly Ġso Ġpad Ġin Ġan Ġextra Ġ 1 0 0 ms Ġon Ġthe Ġhour Ġcallback Ġto Ġensure ĊĠĠĠĠĠĠĠ Ġ// Ġthe Ġsampled Ġwall clock Ġtime Ġreflect s Ġthe Ġsubsequent Ġhour . ĊĠĠĠĠĠĠĠ Ġadd Periodic Callback ( run nable , ĠPeriod . HOUR , Ġ 1 0 0 L ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġrunnable Ġto Ġbe Ġcalled Ġevery Ġmid night ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġadd Mid night Callback ( run nable : ĠRunnable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠCallback s Ġ* can * Ġoccur Ġearly Ġso Ġpad Ġin Ġan Ġextra Ġ 1 0 0 ms Ġon Ġthe Ġmid night Ġcallback Ġto Ġensure ĊĠĠĠĠĠĠĠ Ġ// Ġthe Ġsampled Ġwall clock Ġtime Ġreflect s Ġthe Ġsubsequent Ġday . ĊĠĠĠĠĠĠĠ Ġadd Periodic Callback ( run nable , ĠPeriod . MID N IGHT , Ġ 1 0 0 L ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġrunnable Ġto Ġbe Ġcalled Ġperiodically ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġadd Periodic Callback ( run nable : ĠRunnable , Ġperiod : ĠPeriod , Ġoffset : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġperiodic Runnable Ġ= ĠPeriod ic Runnable ( run nable , Ġperiod , Ġoffset ) ĊĠĠĠĠĠĠĠ Ġm Periodic Run n ables . add ( periodic Runnable ) ĊĠĠĠĠĠĠĠ Ġperiodic Runnable . schedule () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġrunnable Ġto Ġno Ġlonger Ġbe Ġcalled Ġperiodically ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġremove Periodic Callback ( run nable : ĠRunnable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( periodic Runnable Ġin Ġm Periodic Run n ables ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( periodic Runnable . m Delegate Ġ=== Ġrunnable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġperiodic Runnable . un Schedule () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Periodic Run n ables . remove ( periodic Runnable ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠS chedules Ġthe Ġexecution Ġof Ġthe Ġgiven Ġdelegate ĠRunnable Ġat Ġthe Ġnext Ġcallback Ġtime . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġclass ĠPeriod ic Runnable ( ĊĠĠĠĠĠĠĠ Ġval Ġm Delegate : ĠRunnable , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġm Period : ĠPeriod , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġm Offset : ĠLong ĊĠĠĠ Ġ) Ġ: ĠRunnable Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOGGER . i (" Executing Ġperiodic Ġcallback Ġfor Ġ% s Ġbecause Ġthe Ġperiod Ġended ", Ġm Period ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Delegate . run () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġschedule () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġrun And Res chedule () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOGGER . i (" Executing Ġperiodic Ġcallback Ġfor Ġ% s Ġbecause Ġthe Ġtime Ġchanged ", Ġm Period ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġun Schedule () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Delegate . run () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġschedule () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġschedule () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdelay Ġ= Ġget Delay ( System . currentTimeMillis (), Ġm Period , Ġm Offset ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . post Delayed ( this , Ġdelay ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġun Schedule () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . remove Callbacks ( this ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRes chedules Ġcallbacks Ġwhen Ġthe Ġdevice Ġtime Ġchanges . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġinner Ġclass ĠTime Changed Receiver Ġ: ĠBroadcast Receiver () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Receive ( context : ĠContext , Ġintent : ĠIntent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( periodic Runnable Ġin Ġm Periodic Run n ables ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġperiodic Runnable . run And Res chedule () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠLOGGER Ġ= ĠLog Utils . Logger (" Periodic ") ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠQU AR TER _ HOUR _ IN _ M ILL IS Ġ= Ġ 1 5 Ġ* ĠDate Utils . MINUTE _ IN _ M ILL IS ĊĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġs Handler : ĠHandler ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturn Ġthe Ġdelay Ġuntil Ġthe Ġgiven Ġ` period ` Ġel ap ses Ġadjusted Ġby Ġthe Ġgiven Ġ` offset `. ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġnow Ġthe Ġcurrent Ġtime ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġperiod Ġthe Ġfrequency Ġwith Ġwhich Ġcallbacks Ġshould Ġbe Ġgiven ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġoffset Ġan Ġoffset Ġto Ġadd Ġto Ġthe Ġnormal Ġperiod ; Ġallows Ġthe Ġcallback Ġto ĊĠĠĠĠĠĠĠĠ Ġ* Ġbe Ġmade Ġrelative Ġto Ġthe Ġnormally Ġscheduled Ġperiod Ġend ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġthe Ġtime Ġdelay Ġfrom Ġ` now ` Ġto Ġschedule Ġthe Ġcallback ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġget Delay ( now : ĠLong , Ġperiod : ĠPeriod , Ġoffset : ĠLong ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġperiod Start Ġ= Ġnow Ġ- Ġoffset ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( period ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPeriod . MINUTE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Minute Ġ= Ġperiod Start Ġ- Ġperiod Start Ġ% ĠDate Utils . MINUTE _ IN _ M ILL IS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Minute Ġ= Ġlast Minute Ġ+ ĠDate Utils . MINUTE _ IN _ M ILL IS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Minute Ġ- Ġnow Ġ+ Ġoffset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPeriod . QU AR TER _ HOUR Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Qu arter Hour Ġ= Ġperiod Start Ġ- Ġperiod Start Ġ% ĠQU AR TER _ HOUR _ IN _ M ILL IS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Qu arter Hour Ġ= Ġlast Qu arter Hour Ġ+ ĠQU AR TER _ HOUR _ IN _ M ILL IS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Qu arter Hour Ġ- Ġnow Ġ+ Ġoffset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPeriod . HOUR Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Hour Ġ= Ġperiod Start Ġ- Ġperiod Start Ġ% ĠDate Utils . HOUR _ IN _ M ILL IS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Hour Ġ= Ġlast Hour Ġ+ ĠDate Utils . HOUR _ IN _ M ILL IS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Hour Ġ- Ġnow Ġ+ Ġoffset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPeriod . MID N IGHT Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Mid night Ġ= ĠCalendar . getInstance () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Mid night . time In Millis Ġ= Ġperiod Start ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Mid night . add ( Calendar . DATE , Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Mid night [ Calendar . HOUR _ OF _ DAY ] Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Mid night [ Calendar . MINUTE ] Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Mid night [ Calendar . SECOND ] Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Mid night [ Calendar . MILLI SECOND ] Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Mid night . time In Millis Ġ- Ġnow Ġ+ Ġoffset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġhandler : ĠHandler ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUtils . enforce Main Looper () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( s Handler Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġs Handler Ġ= ĠHandler ( Looper . my Looper () !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġs Handler !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }