package Ġme . yc dev . android . lib . common . ipc Ċ Ċ import Ġandroid . content . Component Name Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . Service Connection Ċ import Ġandroid . content . pm . Application Info Ċ import Ġandroid . content . pm . Resolve Info Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . IB inder Ċ import Ġandroid . os . Looper Ċ import Ġandroid . os . Message Ċ import Ġandroid . os . System Clock Ċ import Ġandroidx . annotation . Int Def Ċ import Ġandroidx . annotation . Visible ForTesting Ċ import Ġandroidx . annotation . Worker Thread Ċ import Ġme . yc dev . android . lib . common . manager . Listener Manager Ċ import Ġme . yc dev . android . lib . common . utils . Preconditions Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . util . concurrent . atomic . Atomic Integer Ċ Ċ /** Ċ Ġ* Ġ@ constructor Ċ Ġ* Ġ@ param ĠserviceName ĠUsed Ġto Ġprint Ġlogs Ġonly . Ċ Ġ* Ġ@ param Ġconnect Looper ĠThe Ġlo oper Ġused Ġto Ġconnect / reconnect Ġtarget ĠService . Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBy Ġdefault , Ġit 's Ġthe Ġmain Ġlo oper . Ċ Ġ*/ Ċ abstract Ġclass ĠService Connector < I Service Interface > Ġprotected Ġconstructor ( ĊĠĠĠ Ġc xt : ĠContext , ĊĠĠĠ Ġprotected Ġvar ĠserviceName : ĠString , ĊĠĠĠ Ġval Ġconnect Looper : ĠL ooper Ġ= ĠL ooper . get Main Looper () Ċ ) Ġ{ ĊĠĠĠ Ġprotected Ġvar Ġapp Context : ĠContext Ġ= Ġc xt . application Context ĊĊĠĠĠ Ġprotected Ġvar Ġstate Listeners Ġ= ĠListener Manager < Connect State Listener >( true ) ĊĠĠĠ Ġprivate Ġval Ġconnect Wait Lock Ġ= ĠAny () ĊĠĠĠ Ġprivate Ġval Ġstate Ġ= ĠAtomicInteger ( STATE _ DIS CONNECTED ) ĊĠĠĠ Ġprivate Ġvar Ġconnect StartTime : ĠLong Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġservice Connection : ĠService Connection ? Ġ= Ġnull ĊĊĠĠĠ Ġvar Ġservice : ĠIService Interface ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġ@ Connect State ĊĠĠĠ Ġval Ġconnect State : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġstate . get () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet ĠIntent Ġto Ġbind Ġthe Ġtarget Ġservice . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġget Service Intent (): ĠIntent ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠConvert Ġthe ĠI Binder Ġobject Ġto Ġinterface . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġas Interface ( service : ĠI Binder ): ĠIService Interface ĊĊĠĠĠ Ġprotected Ġopen Ġfun Ġvalidate Permission ( permission : ĠString ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue Ġ// ĠSkip Ġto Ġvalidate Ġpermission Ġby Ġdefault ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġis Service Exist (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġintent Ġ= Ġget Service Intent () ĊĠĠĠĠĠĠĠ Ġval Ġservices List Ġ= Ġapp Context . package Manager . query Intent Services ( intent , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġservices List . size Ġ> Ġ 0 Ġ&& Ġselect Target Service ( services List ) Ġ!= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSub Ġclass Ġcan Ġrewrite Ġthe Ġcandidate Ġservices Ġselect Ġlogic . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġfun Ġselect Target Service ( services List : ĠList < Resolve Info >): ĠComponent Name ? Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). i ("[ % s ] ĠC andidate Ġservices : Ġ% d ", ĠserviceName , Ġservices List . size ) ĊĠĠĠĠĠĠĠ ĠPreconditions . check Argument ( services List . isNotEmpty ()) ĊĠĠĠĠĠĠĠ Ġvar Ġservice Info Ġ= Ġservices List [ 0 ]. service Info ĊĠĠĠĠĠĠĠ Ġfor Ġ( info Ġin Ġservices List ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! validate Permission ( info . service Info . permission )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). w ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Skip Ġnot - matched Ġpermission Ġcandidate : Ġ% s , Ġperm : Ġ% s ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinfo . service Info . name , Ġinfo . service Info . permission ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( info . service Info . application Info . flags Ġand ĠApplication Info . FLAG _ SYSTEM Ġ== ĠApplication Info . FLAG _ SYSTEM ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservice Info Ġ= Ġinfo . service Info Ġ// Ġsearch Ġthe Ġsystem Ġcandidate ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). i ("[ % s ] ĠService Ġfrom Ġsystem Ġfound Ġand Ġselect Ġit ", ĠserviceName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( validate Permission ( service Info . permission )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠComponent Name ( service Info . packageName , Ġservice Info . name ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdd Ġa Ġconnect Ġstate Ġlistener , Ġusing Ġ[ Listener Manager ] Ġto Ġmanager Ġlisteners . ĊĠĠĠĠ Ġ* ĠCallback s Ġwill Ġbe Ġinvoked Ġin Ġ[. get Connect Looper ] Ġthread . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġadd Listener ( listener : ĠConnect State Listener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Listeners . addListener ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove Listener ( listener : ĠConnect State Listener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Listeners . remove Listener ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġconnect () Ġ{ ĊĠĠĠĠĠĠĠ Ġconnect Service IfNeeded ( false ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdisconnect () Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). i ("[ % s ] Ġdisconnect Ġservice ...", ĠserviceName ) ĊĠĠĠĠĠĠĠ Ġconnect Handler . remove Messages ( MSG _ CONNECT _ TIMEOUT _ CHECK ) ĊĠĠĠĠĠĠĠ Ġconnect Handler . remove Messages ( MSG _ RE CONNECT ) ĊĠĠĠĠĠĠĠ Ġconnect Handler . remove Messages ( MSG _ NOTIFY _ LIST EN ERS ) ĊĠĠĠĠĠĠĠ Ġservice Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġif Ġ( service Connection Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapp Context . unbind Service ( service Connection !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservice Connection Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġupdate Connect State ( STATE _ DIS CONNECTED ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconnect Service IfNeeded ( re bind : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( service Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). d ("[ % s ] Ġservice Ġis Ġconnected ", ĠserviceName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(! re bind ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! state . compare AndSet ( STATE _ DIS CONNECTED , ĠSTATE _ CONNECT ING )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). d ("[ % s ] ĠService Ġis Ġunder Ġconnecting ", ĠserviceName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Connect State ( STATE _ CONNECT ING ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġconnect StartTime Ġ= ĠSystem Clock . elapsed Realtime () ĊĊĠĠĠĠĠĠĠ Ġval Ġintent Ġ= Ġget Service Intent () ĊĠĠĠĠĠĠĠ Ġval Ġservices List Ġ= Ġapp Context . package Manager . query Intent Services ( intent , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġif Ġ( services List . size Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). w ("[ % s ] Ġno Ġservice Ġcomponent Ġavailable , Ġcannot Ġconnect ", ĠserviceName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Connect State ( STATE _ DIS CONNECTED ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġcandidate Service Ġ= Ġselect Target Service ( services List ) ĊĠĠĠĠĠĠĠ Ġif Ġ( candidate Service Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. w ("[ % s ] Ġno Ġexpected Ġservice Ġcomponent Ġfound , Ġcannot Ġconnect ", ĠserviceName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Connect State ( STATE _ DIS CONNECTED ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġmust Ġset Ġexplicit Ġcomponent Ġbefore Ġbind / start Ġservice ĊĠĠĠĠĠĠĠ Ġintent . component Ġ= Ġcandidate Service ĊĊĠĠĠĠĠĠĠ Ġservice Connection Ġ= Ġobject Ġ: ĠService Connection Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġvar Ġm Connect Lost Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Service Connected ( cn : ĠComponent Name , Ġservice : ĠI Binder ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). i ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"[ % s ] Ġservice Ġconnected , Ġcn : Ġ% s , Ġm Connect Lost : Ġ% s ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠserviceName , Ġcn , Ġm Connect Lost ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! m Connect Lost ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġupdate Ġ' m Service ' Ġfirst , Ġand Ġthen Ġupdate Ġthe Ġconnect Ġstate Ġand Ġnotify ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis @ Service Connector . service Ġ= Ġas Interface ( service ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnect Handler . remove Messages ( MSG _ CONNECT _ TIMEOUT _ CHECK ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Connect State ( STATE _ CONNECTED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ// Ġelse : Ġwaiting Ġfor Ġreconnect ing Ġusing Ġnew ĠService Connection Ġobject ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Service Disconnected ( cn : ĠComponent Name ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). i ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"[ % s ] Ġservice Ġdisconnected , Ġcn : Ġ% s , Ġm Connect Lost : Ġ% s ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠserviceName , Ġcn , Ġm Connect Lost ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Connect Lost ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠU nb ind Ġthe Ġservice Ġand Ġbind Ġit Ġagain Ġlater ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Connect Lost Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdisconnect () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnect Handler . send Empty Message Delayed ( MSG _ RE CONNECT , Ġ 1 0 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). i ("[ % s ] Ġconnecting Ġservice ...", ĠserviceName ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! app Context . bind Service ( intent , Ġservice Connection !! , ĠContext . BIND _ AUTO _ CREATE )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). w ("[ % s ] Ġcannot Ġconnect ", ĠserviceName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Connect State ( STATE _ DIS CONNECTED ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnect Handler . remove Messages ( MSG _ CONNECT _ TIMEOUT _ CHECK ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnect Handler . send Empty Message Delayed ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMSG _ CONNECT _ TIMEOUT _ CHECK , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCONNECT _ TIMEOUT _ CHECK _ INTERVAL ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Connect State (@ Connect State ĠnewState : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( newState Ġ!= ĠSTATE _ CONNECT ING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate . set ( newState ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġconnect Handler . obtain Message ( MSG _ NOTIFY _ LIST EN ERS , ĠnewState , Ġ 0 ). send To Target () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠWaiting Ġfor Ġthe Ġservice Ġconnected Ġwith Ġtimeout . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġtimeout Millis ĠTimeout Ġin Ġmilliseconds Ġto Ġwait Ġfor Ġthe Ġservice Ġconnected . ĊĠĠĠĠ Ġ* Ġ 0 Ġmeans Ġno Ġwaiting Ġand Ġ- 1 Ġmeans Ġno Ġtimeout . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġfun ĠwaitFor Connected ( timeout Millis : ĠLong Ġ= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠ ĠPreconditions . check Non MainThread () ĊĠĠĠĠĠĠĠ Ġif Ġ( service Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). d ("[ % s ] Ġalready Ġconnected ", ĠserviceName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġsynchronized ( connect Wait Lock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnect () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġsleep Time : ĠLong Ġ= Ġ 5 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġtime Elapsed : ĠLong Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconnect State Ġ= Ġstate . get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). d ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"[ % s ] Ġchecking , Ġservice : Ġ% s , Ġstate : Ġ% d , Ġtime : Ġ% d /% d ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠserviceName , Ġservice , Ġconnect State , Ġtime Elapsed , Ġtimeout Millis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( connect State Ġ== ĠSTATE _ CONNECTED Ġ|| Ġconnect State Ġ== ĠSTATE _ DIS CONNECTED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( timeout Millis Ġin Ġ 0 .. time Elapsed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnect () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( sleep Time ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠInterruptedException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). w ( e , Ġ" inter rupted ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtime Elapsed Ġ+= Ġsleep Time ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsleep Time Ġ*= Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sleep Time Ġ> Ġ 1 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsleep Time Ġ= Ġ 1 0 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġconnect Handler Ġ= Ġobject Ġ: ĠHandler ( connect Looper ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġhandle Message ( msg : ĠMessage ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( msg . what ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMSG _ RE CONNECT Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). d ("[ % s ] Ġdelayed Ġreconnect Ġfires ...", ĠserviceName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnect () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMSG _ NOTIFY _ LIST EN ERS Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Connect State Ġval ĠnewState Ġ= Ġmsg . arg 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). d (" State Ġchanged : Ġ% s ", Ġstr Connect State ( newState )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Listeners . notify Listeners Ġ{ Ġlistener Ġ-> Ġlistener . on StateChanged ( newState ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMSG _ CONNECT _ TIMEOUT _ CHECK Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). d (" checking Ġconnect Ġtimeout ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcur State Ġ= Ġstate . get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( System Clock . elapsed Realtime () Ġ- Ġconnect StartTime Ġ>= ĠFOR CE _ RE BIND _ TIME ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( TAG ). d ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"[ % s ] Ġconnect Ġtimeout , Ġstate : Ġ% s ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠserviceName , Ġcur State ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cur State Ġ== ĠSTATE _ CONNECT ING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġforce Ġto Ġre bind Ġthe Ġservice ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnect Service IfNeeded ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cur State Ġ== ĠSTATE _ CONNECT ING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . send Empty Message Delayed ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMSG _ CONNECT _ TIMEOUT _ CHECK , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCONNECT _ TIMEOUT _ CHECK _ INTERVAL ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Retention ( Annotation Retention . SOURCE ) ĊĠĠĠ Ġ@ Int Def ( STATE _ DIS CONNECTED , ĠSTATE _ CONNECT ING , ĠSTATE _ CONNECTED ) ĊĠĠĠ Ġannotation Ġclass ĠConnect State ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" Service Connector " ĊĊĠĠĠĠĠĠĠ Ġconst Ġval ĠSTATE _ DIS CONNECTED Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠSTATE _ CONNECT ING Ġ= Ġ 2 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠSTATE _ CONNECTED Ġ= Ġ 3 ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMSG _ RE CONNECT Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMSG _ NOTIFY _ LIST EN ERS Ġ= Ġ 2 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMSG _ CONNECT _ TIMEOUT _ CHECK Ġ= Ġ 3 ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠCONNECT _ TIMEOUT _ CHECK _ INTERVAL : ĠLong Ġ= Ġ 5 0 0 0 Ġ// Ġ 5 s ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠFOR CE _ RE BIND _ TIME : ĠLong Ġ= Ġ 3 0 Ġ* Ġ 1 0 0 0 L Ġ// Ġ 3 0 Ġseconds ĊĊĠĠĠĠĠĠĠ Ġfun Ġstr Connect State ( state : ĠInt ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSTATE _ DIS CONNECTED Ġ-> Ġ" disconnected " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSTATE _ CONNECT ING Ġ-> Ġ" connecting " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSTATE _ CONNECTED Ġ-> Ġ" connected " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ" unknown " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ