package Ġme . yc dev . android . lib . common . ipc Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . Looper Ċ import Ġandroid . os . System Clock Ċ import Ġandroidx . test . core . app . Application Provider Ċ import Ġandroidx . test . ext . junit . runners . Android JUnit 4 Ċ import Ġandroidx . test . filters . Large Test Ċ import Ġandroidx . test . filters . Small Test Ċ import Ġcom . google . common . truth . Truth . assertThat Ċ import Ġme . yc dev . android . lib . common . demo . service . ID emo Service Ċ import Ġme . yc dev . android . lib . common . demo . service . Local ServiceClient Ċ import Ġme . yc dev . android . lib . common . demo . service . Remote ServiceClient Ċ import Ġme . yc dev . android . lib . common . demo . service . operation . Hello Operation Ċ import Ġme . yc dev . android . lib . common . utils . Thread Manager Ċ import Ġorg . junit . Test Ċ import Ġorg . junit . runner . RunWith Ċ import Ġjava . util . concurrent . Count DownLatch Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ @ RunWith ( Android JUnit 4 :: class ) Ċ @ Large Test Ċ class ĠService Client Base Test Ġ{ ĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġ@ Small Test ĊĠĠĠ Ġ@ Throws ( InterruptedException :: class ) ĊĠĠĠ Ġfun Ġworker Thread () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= ĠApplication Provider . getApplicationContext < Context >() ĊĠĠĠĠĠĠĠ Ġval Ġclient Ġ= ĠRemote ServiceClient ( context ) ĊĠĠĠĠĠĠĠ Ġclient . setAuto Disconnect ( false , Ġ 0 L ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠService Ġnot Ġconnected ĊĠĠĠĠĠĠĠ Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . add Operation ( object Ġ: ĠI pc Operation < ID emo Service > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġexecute ( service : ĠID emo Service ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( service ). isNotNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( Looper . my Looper ()). is Same Instance As ( Thread Manager . instance . remote Service Request I pc Looper ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWaiting Ġfor Ġservice Ġconnected Ġand Ġoperation Ġexecuted ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . await () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠService Ġalready Ġconnected ĊĠĠĠĠĠĠĠ Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . add Operation ( object Ġ: ĠI pc Operation < ID emo Service > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġexecute ( service : ĠID emo Service ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( service ). isNotNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( Looper . my Looper ()). is Same Instance As ( Thread Manager . instance . remote Service Request I pc Looper ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWaiting Ġfor Ġservice Ġconnected Ġand Ġoperation Ġexecuted ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . await () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġclient . disconnect () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġ@ Small Test ĊĠĠĠ Ġfun Ġis Auto Disconnect Enabled () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= ĠApplication Provider . getApplicationContext < Context >() ĊĠĠĠĠĠĠĠ Ġval Ġclient Ġ= ĠRemote ServiceClient ( context ) ĊĠĠĠĠĠĠĠ ĠassertThat ( client . is Auto Disconnect Enabled ). isFalse () ĊĊĠĠĠĠĠĠĠ Ġclient . setAuto Disconnect ( true , Ġ 1 0 0 0 L ) ĊĠĠĠĠĠĠĠ ĠassertThat ( client . is Auto Disconnect Enabled ). isTrue () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġ@ Large Test ĊĠĠĠ Ġ@ Throws ( InterruptedException :: class ) ĊĠĠĠ Ġfun Ġset Auto Disconnect _ enable () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdisconnect Timeout : ĠLong Ġ= Ġ 1 0 0 0 Ġ// Ġ 1 Ġsecond ĊĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= ĠApplication Provider . getApplicationContext < Context >() ĊĠĠĠĠĠĠĠ Ġval Ġclient Ġ= ĠRemote ServiceClient ( context ) ĊĠĠĠĠĠĠĠ Ġclient . setAuto Disconnect ( true , Ġdisconnect Timeout ) ĊĠĠĠĠĠĠĠ ĠassertThat ( client . is Auto Disconnect Enabled ). isTrue () ĊĠĠĠĠĠĠĠ Ġval Ġtime Start : ĠLong ĊĊĠĠĠĠĠĠĠ Ġ// ĠMake Ġthe Ġservice Ġbe Ġconnected Ġand Ġoperation Ġbe Ġexecuted ĊĠĠĠĠĠĠĠ Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( client . service Connector . service ). isNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . add Operation ( Hello Operation (" Hello , Ġworld "). set Notifier ( latch )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . await () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( client . service Connector . service ). isNotNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtime Start Ġ= ĠSystem Clock . elapsed Realtime () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠWaiting Ġfor Ġthe Ġservice Ġdisconnected Ġand Ġcheck Ġthe Ġtimeout ĊĠĠĠĠĠĠĠ Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . service Connector . addListener ( object Ġ: ĠConnect State Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon StateChanged ( newState : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( newState Ġ== ĠService Connector . STATE _ DIS CONNECTED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtime Used Ġ= ĠSystem Clock . elapsed Realtime () Ġ- Ġtime Start ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( time Used ). is GreaterThan ( disconnect Timeout ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( time Used ). is LessThan ( disconnect Timeout Ġ+ Ġ 5 0 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġget Service Connector () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= ĠApplication Provider . getApplicationContext < Context >() ĊĠĠĠĠĠĠĠ Ġval Ġclient Ġ= ĠRemote ServiceClient ( context ) ĊĠĠĠĠĠĠĠ ĠassertThat ( client . service Connector ). isNotNull () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġ@ Throws ( InterruptedException :: class ) ĊĠĠĠ Ġfun Ġconnect _ disconnect () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= ĠApplication Provider . getApplicationContext < Context >() ĊĠĠĠĠĠĠĠ Ġval Ġclient Ġ= ĠRemote ServiceClient ( context ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġconnect ĊĠĠĠĠĠĠĠ Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . service Connector . addListener ( object Ġ: ĠConnect State Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon StateChanged ( newState : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( newState Ġ== ĠService Connector . STATE _ CONNECTED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMake Ġsure Ġthe Ġservice Ġwill Ġnot Ġbe Ġconnected Ġif Ġno Ġconnect Ġand Ġno Ġoperations ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . await ( 5 0 0 , ĠTimeUnit . MILLISECONDS ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( latch . count ). isEqualTo ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . connect () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . await ( 5 0 0 , ĠTimeUnit . MILLISECONDS ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( latch . count ). isEqualTo ( 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġdisconnect ĊĠĠĠĠĠĠĠ Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . service Connector . addListener ( object Ġ: ĠConnect State Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon StateChanged ( newState : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( newState Ġ== ĠService Connector . STATE _ DIS CONNECTED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . disconnect () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . await () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġ@ Throws ( InterruptedException :: class ) ĊĠĠĠ Ġfun Ġadd Operation _ remote Service () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= ĠApplication Provider . getApplicationContext < Context >() ĊĠĠĠĠĠĠĠ Ġval Ġclient Ġ= ĠRemote ServiceClient ( context ) ĊĠĠĠĠĠĠĠ Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠĠĠĠĠ Ġclient . add Operation ( Hello Operation (" Hello "). set Notifier ( latch )) ĊĠĠĠĠĠĠĠ Ġl atch . await () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġ@ Throws ( InterruptedException :: class ) ĊĠĠĠ Ġfun Ġadd Operation _ locale Service () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= ĠApplication Provider . getApplicationContext < Context >() ĊĠĠĠĠĠĠĠ Ġval Ġclient Ġ= ĠLocal ServiceClient ( context ) ĊĠĠĠĠĠĠĠ Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠĠĠĠĠ Ġclient . add Operation ( Hello Operation (" Hello "). set Notifier ( latch )) ĊĠĠĠĠĠĠĠ Ġl atch . await () ĊĠĠĠ Ġ} Ċ } Ċ