package Ġcom . alf resco . content . data Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroidx . work . Backoff Policy Ċ import Ġandroidx . work . Constraints Ċ import Ġandroidx . work . Existing Work Policy Ċ import Ġandroidx . work . Network Type Ċ import Ġandroidx . work . One Time Work RequestBuilder Ċ import Ġandroidx . work . Work Info Ċ import Ġandroidx . work . Work Manager Ċ import Ġcom . alf resco . coroutines . as Flow Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Job Ċ import Ġkotlinx . coroutines . delay Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlinx . coroutines . flow . collect Ċ import Ġkotlinx . coroutines . flow . map Ċ import Ġkotlinx . coroutines . launch Ċ Ċ class ĠSync Service ( ĊĠĠĠ Ġprivate Ġval Ġcontext : ĠContext , ĊĠĠĠ Ġprivate Ġval Ġscope : ĠCor outine Scope Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġlast Sync Time : ĠLong Ġ= Ġ 0 L ĊĠĠĠ Ġprivate Ġvar Ġpending Sync : ĠJob ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġscheduled Sync : ĠJob ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġval Ġwork Manager Ġ= ĠWork Manager . getInstance ( context ) ĊĠĠĠ Ġprivate Ġvar Ġlatest Work Info : ĠWork Info ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġlatest Upload Work Info : ĠWork Info ? Ġ= Ġnull ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġscope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobserve Work ( UNIQUE _ SYNC _ WORK _ NAME ). collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlatest Work Info Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġobserve Work ( UNIQUE _ UPLOAD _ WORK _ NAME ). collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlatest Upload Work Info Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExec utes Ġsync Ġfiltering Ġout Ġextra Ġcalls Ġwithin Ġ[ TRIGGER _ DELAY ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġsync () Ġ{ ĊĠĠĠĠĠĠĠ Ġcancel Pending Sync () ĊĠĠĠĠĠĠĠ Ġcancel Scheduled Sync () ĊĠĠĠĠĠĠĠ Ġpending Sync Ġ= Ġscope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( TRIGGER _ DELAY ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecute () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExec utes Ġsync Ġwithout Ġdelay . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġsync Now ( override Network : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcancel Pending Sync () ĊĠĠĠĠĠĠĠ Ġcancel Scheduled Sync () ĊĠĠĠĠĠĠĠ Ġexecute ( override Network ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠS chedules Ġsync Ġafter Ġ[ FO REG ROUND _ DELAY ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġschedule Foreground Sync () Ġ{ ĊĠĠĠĠĠĠĠ Ġcancel Scheduled Sync () ĊĠĠĠĠĠĠĠ Ġscheduled Sync Ġ= Ġscope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( FO REG ROUND _ DELAY ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsync Or Wait () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExec utes Ġif Ġat Ġleast Ġ[ FO REG ROUND _ DELAY ] Ġhas Ġpassed Ġsince Ġlast Ġsync . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġsync IfNeeded () Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠcurrentTime Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠ Ġif Ġ( currentTime Ġ- Ġlast Sync Time Ġ> ĠFO REG ROUND _ DELAY ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsync Or Wait () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExec utes Ġsync Ġif Ġthere 's Ġno Ġpending Ġsync Ġjob . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġsync Or Wait () Ġ{ ĊĠĠĠĠĠĠĠ Ġpending Sync . let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ== Ġnull Ġ|| Ġit . is Completed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecute () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġexecute ( override Network : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlast Sync Time Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠ Ġschedule Sync Work ( override Network ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠRes chedule Ġa Ġtimed Ġsync ĊĠĠĠĠĠĠĠ Ġschedule Foreground Sync () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcancel Scheduled Sync () Ġ{ ĊĠĠĠĠĠĠĠ Ġscheduled Sync ?. cancel () ĊĠĠĠĠĠĠĠ Ġscheduled Sync Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcancel Pending Sync () Ġ{ ĊĠĠĠĠĠĠĠ Ġpending Sync ?. cancel () ĊĠĠĠĠĠĠĠ Ġpending Sync Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġschedule Sync Work ( override Network : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnetwork Type Ġ= Ġif Ġ( Settings ( context ). can Sync Over Meter ed Network Ġ|| Ġoverride Network ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNetwork Type . CONNECTED ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNetwork Type . UN METER ED ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġpolicy Ġ= Ġif Ġ( latest Work Info ?. state Ġ== ĠWork Info . State . RUNNING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠExisting Work Policy . APPEND ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠExisting Ġwork Ġmay Ġstart Ġbefore Ġscheduling Ġnew Ġwork Ġcausing Ġa Ġcancellation ĊĠĠĠĠĠĠĠĠĠĠĠ ĠExisting Work Policy . REPLACE ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġconstraints Ġ= ĠConstraints . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Required Network Type ( network Type ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠOne Time Work RequestBuilder < Sync Worker >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Constraints ( constraints ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġwork Manager ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. begin Unique Work ( UNIQUE _ SYNC _ WORK _ NAME , Ġpolicy , Ġrequest ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. enqueue () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExec utes Ġupload Ġwithout Ġdelay . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġupload () Ġ{ ĊĠĠĠĠĠĠĠ Ġschedule Upload Work () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSimilar Ġto Ġ[ sync IfNeeded ] Ġbut Ġjust Ġcalls Ġ[ upload ] Ġdirectly . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġupload IfNeeded () Ġ= Ġupload () ĊĊĠĠĠ Ġprivate Ġfun Ġschedule Upload Work () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnetwork Type Ġ= ĠNetwork Type . CONNECTED ĊĊĠĠĠĠĠĠĠ Ġval Ġpolicy Ġ= Ġif Ġ( latest Upload Work Info ?. state Ġ== ĠWork Info . State . RUNNING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠExisting Work Policy . APPEND ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠExisting Ġwork Ġmay Ġstart Ġbefore Ġscheduling Ġnew Ġwork Ġcausing Ġa Ġcancellation ĊĠĠĠĠĠĠĠĠĠĠĠ ĠExisting Work Policy . REPLACE ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġconstraints Ġ= ĠConstraints . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Required Network Type ( network Type ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠOne Time Work RequestBuilder < Upload Worker >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Constraints ( constraints ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Backoff Criteria ( Backoff Policy . EXP ON ENTIAL , ĠUP LOAD _ BACK OFF _ DELAY , ĠTimeUnit . SECONDS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġwork Manager ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. begin Unique Work ( UNIQUE _ UPLOAD _ WORK _ NAME , Ġpolicy , Ġrequest ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. enqueue () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġobserve Work ( unique Work Name : ĠString ): ĠFlow < Work Info ?> Ġ= ĊĠĠĠĠĠĠĠ Ġwork Manager ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Work Infos For Unique Work LiveData ( unique Work Name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. as Flow () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġlist Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist ?. find Ġ{ Ġit . state Ġ== ĠWork Info . State . RUNNING Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġlist ?. find Ġ{ Ġ! it . state . is Finished Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġlist ?. first OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTR IG GER _ DELAY Ġ= Ġ 1 0 _ 0 0 0 L ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠFO REG ROUND _ DELAY Ġ= Ġ 9 0 0 _ 0 0 0 L Ġ// Ġ 1 5 Ġ* Ġ 6 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠUP LOAD _ BACK OFF _ DELAY Ġ= Ġ 6 0 L ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠUNIQUE _ SYNC _ WORK _ NAME Ġ= Ġ" sync " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠUNIQUE _ UPLOAD _ WORK _ NAME Ġ= Ġ" upload " ĊĊĠĠĠĠĠĠĠ Ġfun Ġobserve ( context : ĠContext ): ĠFlow < Sync State ?> Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠWork Manager ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. getInstance ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Work Infos For Unique Work LiveData ( UNIQUE _ SYNC _ WORK _ NAME ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. as Flow () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġlist Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist ?. find Ġ{ Ġit . state Ġ== ĠWork Info . State . RUNNING Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġlist ?. find Ġ{ Ġ! it . state . is Finished Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġlist ?. first OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit ?. let Ġ{ ĠSync State . from ( it . state ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġrace Ġcondition Ġwork Ġis Ġcancelled Ġbut Ġsync Ġservice Ġmay Ġstill Ġtrigger Ġit ĊĠĠĠĠĠĠĠ Ġfun Ġcancel ( context : ĠContext ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠWork Manager ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. getInstance ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. cancel Unique Work ( UNIQUE _ SYNC _ WORK _ NAME ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġenum Ġclass ĠSync State Ġ{ ĊĠĠĠĠĠĠĠ ĠEn queued , ĊĠĠĠĠĠĠĠ ĠRunning , ĊĠĠĠĠĠĠĠ ĠBlock ed , ĊĠĠĠĠĠĠĠ ĠFinished ; ĊĊĠĠĠĠĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġfrom ( work Info State : ĠWork Info . State ?): ĠSync State Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( work Info State ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWork Info . State . EN QUE U ED Ġ-> ĠEn queued ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWork Info . State . RUNNING Ġ-> ĠRunning ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWork Info . State . BLOCK ED Ġ-> ĠBlock ed ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠFinished ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ