package Ġcom . iv an ov sky . pass notes . presentation . service Ċ Ċ import Ġandroid . app . Notification Ċ import Ġandroid . app . Notification Channel Ċ import Ġandroid . app . Notification Manager Ċ import Ġandroid . app . Pending Intent Ċ import Ġandroid . app . Service Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . os . Build Ċ import Ġandroid . os . IB inder Ċ import Ġandroidx . core . app . Notification Compat Ċ import Ġcom . iv an ov sky . pass notes . R Ċ import Ġcom . iv an ov sky . pass notes . data . Observer Bus Ċ import Ġcom . iv an ov sky . pass notes . data . entity . FileDescriptor Ċ import Ġcom . iv an ov sky . pass notes . domain . entity . Database Status Ċ import Ġcom . iv an ov sky . pass notes . domain . inter actor . service . Lock Service Interactor Ċ import Ġcom . iv an ov sky . pass notes . presentation . service . model . Service State Ċ import Ġcom . iv an ov sky . pass notes . extensions . get Notification Manager Ċ import Ġcom . iv an ov sky . pass notes . injection . Global Injector . inject Ċ import Ġcom . iv an ov sky . pass notes . presentation . Application Launch Mode Ċ import Ġcom . iv an ov sky . pass notes . presentation . main . MainActivity Ċ import Ġcom . iv an ov sky . pass notes . presentation . main . Main Screen Args Ċ import Ġcom . iv an ov sky . pass notes . presentation . service . model . Lock Service Command Ċ import Ġcom . iv an ov sky . pass notes . util . Intent Utils . default Pending Intent Flags Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . Job Ċ import Ġkotlinx . coroutines . launch Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . util . concurrent . atomic . Atomic Reference Ċ Ċ class ĠLock Service Ġ: ĠService (), ĠObserver Bus . Database Status Observer Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġinter actor : ĠLock Service Interactor Ġby Ġinject () ĊĠĠĠ Ġprivate Ġval Ġobserver Bus : ĠObserver Bus Ġby Ġinject () ĊĊĠĠĠ Ġprivate Ġval Ġjob Ġ= ĠJob () ĊĠĠĠ Ġprivate Ġval Ġscope Ġ= ĠCor outine Scope ( Dispatch ers . Main Ġ+ Ġjob ) ĊĊĠĠĠ Ġoverride Ġfun Ġon Database Status Changed ( status : ĠDatabase Status ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( isRunning ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= ĠgetMessage By Database Status ( status ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart ( message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Bind ( intent : ĠIntent ?): ĠI Binder ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate () ĊĠĠĠĠĠĠĠ ĠTim ber . d (" onCreate :") ĊĠĠĠĠĠĠĠ Ġobserver Bus . register ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonStart Command ( intent : ĠIntent ?, Ġflags : ĠInt , Ġstart Id : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcommand Ġ= Ġintent ?. get Parcelable Extra < Lock Service Command >( EXTRA _ COMMAND ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġreturn ĠSTART _ NOT _ STICK Y ĊĊĠĠĠĠĠĠĠ ĠTim ber . d (" onStart Command : Ġ% s ", Ġcommand :: class . java . simple Name ) ĊĊĠĠĠĠĠĠĠ Ġprocess Command ( command ) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠSTART _ NOT _ STICK Y ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Destroy () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Destroy () ĊĠĠĠĠĠĠĠ ĠTim ber . d (" on Destroy : Ġstate =% s ", ĠgetCurrent State ()) ĊĠĠĠĠĠĠĠ Ġobserver Bus . unregister ( this ) ĊĠĠĠĠĠĠĠ Ġjob . cancel () ĊĠĠĠĠĠĠĠ Ġif Ġ( isRunning ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop ( call Stop Self Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġprocess Command ( command : ĠLock Service Command ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( command ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLock Service Command . Show Notification Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Show Notification Command () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLock Service Command . Stop Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Stop Command () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLock Service Command . Sync And Lock Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Sync And Lock Command ( command . file ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrun Show Notification Command () Ġ{ ĊĠĠĠĠĠĠĠ Ġscope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠgetStatus Result Ġ= Ġinter actor . get Database Status () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( getStatus Result . is Failed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( isRunning ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ launch ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart ( getMessage By Database Status ( getStatus Result . obj )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrun Stop Command () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( isRunning ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrun Sync And Lock Command ( file : ĠFile Descriptor ) Ġ{ ĊĠĠĠĠĠĠĠ Ġscope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart ( getString ( R . string . lock _ notification _ text _ synchron izing )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsync Result Ġ= Ġinter actor . sync And Lock ( file ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" sync Result =% s ", Ġsync Result ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sync Result . is Failed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( isRunning ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ launch ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstart ( message : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate . set ( Service State . STARTED ) ĊĠĠĠĠĠĠĠ Ġstart Foreground ( LOCK _ NOTIFICATION _ ID , Ġcreate Notification ( message )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstop ( call Stop Self : ĠBoolean Ġ= Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate . set ( Service State . STOP PED ) ĊĠĠĠĠĠĠĠ Ġstop Foreground ( true ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( call Stop Self ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop Self () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Notification ( message : ĠString ): ĠNotification Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . O ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchannel Ġ= ĠNotification Channel ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Channel Id (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠgetString ( R . string . lock _ notification _ channel ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠNotification Manager . IMPORT ANCE _ LOW ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescription Ġ= ĠgetString ( R . string . lock _ notification _ channel _ description ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Notification Manager (). create Notification Channel ( channel ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġcontent Intent Ġ= ĠPending Intent . getActivity ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Content Intent (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Pending Intent Flags () ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġaction Intent Ġ= ĠPending Intent . get Broadcast ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Lock Button Intent (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Pending Intent Flags () ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġbuilder Ġ= ĠNotification Compat . Builder ( this , Ġget Channel Id ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. setContent Title ( getString ( R . string . app _ name )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. setContent Text ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Small Icon ( R . drawable . ic _ lock _ open _ white _ 2 4 dp ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. setContent Intent ( content Intent ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. addAction ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . drawable . ic _ lock _ grey _ 6 0 0 _ 2 4 dp , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠgetString ( R . string . lock _ database ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaction Intent ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġbuilder . build () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Content Intent (): ĠIntent Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠMainActivity . create Start Intent ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMain Screen Args ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapp Mode Ġ= ĠApplication Launch Mode . NORMAL ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Lock Button Intent (): ĠIntent Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠIntent ( this , ĠDatabase Lock Broadcast Receiver :: class . java ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Channel Id (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġapplication Context . packageName Ġ+ Ġ"_ notification _ channel " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Running () Ġ= Ġ( getCurrent State () Ġ!= ĠService State . STOP PED ) ĊĊĠĠĠ Ġprivate Ġfun ĠgetMessage By Database Status ( status : ĠDatabase Status ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( status Ġ== ĠDatabase Status . POST P ON ED _ CHANG ES ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠgetString ( R . string . lock _ notification _ text _ not _ synchronized ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠgetString ( R . string . lock _ notification _ text _ normal ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠLOCK _ NOTIFICATION _ ID Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠEX TRA _ COMMAND Ġ= Ġ" command " ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġstate Ġ= ĠAtomic Reference < Service State >() ĊĊĠĠĠĠĠĠĠ Ġfun ĠgetCurrent State (): ĠService State Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate . get () Ġ?: ĠService State . STOP PED ĊĊĠĠĠĠĠĠĠ Ġfun Ġrun Command ( context : ĠContext , Ġcommand : ĠLock Service Command ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( getCurrent State () Ġ== ĠService State . STOP PED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate . set ( Service State . AW A IT ING _ FOR _ START ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . start Service ( create Intent ( context , Ġcommand )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġcreate Intent ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext : ĠContext , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommand : ĠLock Service Command ? ĊĠĠĠĠĠĠĠ Ġ): ĠIntent Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠIntent ( context , ĠLock Service :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( command Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput Extra ( EXTRA _ COMMAND , Ġcommand ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }