package Ġorg . bt el man . control sdk . models Ċ Ċ import Ġandroid . app . Notification Manager Ċ import Ġandroid . content . Context Ċ import Ġandroid . os .* Ċ import Ġandroidx . annotation . Call Super Ċ import Ġandroidx . core . app . Notification Compat Ċ import Ġkotlinx . coroutines . Global Scope Ċ import Ġkotlinx . coroutines . async Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġkotlinx . coroutines . suspend C ancellable Coroutine Ċ import Ġorg . bt el man . control sdk . R Ċ import Ġorg . bt el man . control sdk . enums . Component Status Ċ import Ġorg . bt el man . control sdk . interfaces . Component EventListener Ċ import Ġorg . bt el man . control sdk . interfaces . I Component Ċ import Ġorg . bt el man . control sdk . services . Control SDK Service Ċ import Ġorg . bt el man . log util . kotlin . Log Util Ċ import Ġjava . util . concurrent . atomic . Atomic Boolean Ċ import Ġkotlin . coroutines . resume Ċ import Ġkotlin . coroutines . resume With Exception Ċ import Ġkotlin . random . Random Ċ Ċ /** Ċ Ġ* ĠBase Ġcomponent Ġobject Ġto Ġuse Ġto Ġextend Ġfunctionality Ġof Ġyour Ġrobot . Ċ Ġ* Ċ Ġ* ĠRuns Ġon Ġits Ġown Ġthreads , Ġas Ġlong Ġas Ġthis . handler Ġis Ġused Ċ Ġ* ĠEx . Ġcan Ġbe Ġused Ġas Ġan Ġinterface Ġfor ĠLED s Ġbased Ġoff Ġof Ġcontrol Ġmessages Ċ Ġ*/ Ċ abstract Ġclass ĠComponent Ġ: ĠI Component Ġ{ ĊĠĠĠ Ġprotected Ġvar Ġcontext : ĠContext ? Ġ= Ġnull ĊĠĠĠ Ġprotected Ġvar Ġevent Dispatcher Ġ: ĠComponent EventListener ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġhandler Thread Ġ: ĠHandler Thread ? Ġ= Ġnull ĊĊĠĠĠ Ġprotected Ġval Ġlog Ġ= ĠLog Util (" Control SDK Component Ġ: Ġ${ java Class . name }", ĠControl SDK Service . logger ID ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠConstructor Ġthat Ġthe Ġservice Ġwill Ġuse Ġto Ġstart Ġthe Ġcomponent . ĠFor Ġcustom Ġactions , Ġplease Ġuse Ġon Initialize Component ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Suppress (" Convert Secondary Constructor To Primary ") ĊĠĠĠ Ġconstructor () ĊĊĠĠĠ Ġprotected Ġlateinit Ġvar Ġhandler Ġ: ĠHandler ĊĊĠĠĠ Ġprivate Ġvar Ġasync : ĠBoolean Ġ= Ġtrue ĊĊĠĠĠ Ġprivate Ġvar Ġthread Priority Ġ: ĠInt Ġ= ĠProcess . THREAD _ PRIORITY _ DEFAULT ĊĊĠĠĠ Ġprivate Ġvar Ġ_ status : ĠComponent Status Ġ= ĠComponent Status . DISABLED _ FROM _ SETTINGS ĊĠĠĠ Ġvar Ġstatus Ġ: ĠComponent Status ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ_ status ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif (_ status Ġ== Ġvalue ) Ġreturn Ġ// Only Ġset Ġstate Ġif Ġchanged ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ status Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . v { ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Update ĠStatus Ġ$ value Ġ: Ġ${ event Dispatcher ?. let Ġ{ Ġ" Sending Ġup wards " Ġ} Ġ?: Ġ" dispatcher Ġnull "} " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġevent Dispatcher ?. handle Message ( getType (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSTATUS _ EVENT , Ġstatus , Ġthis ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġstatus Ġ= ĠComponent Status . DISABLED ĊĠĠĠ Ġ} ĊĠĠĠ Ġprotected Ġval Ġenabled Ġ= ĠAtomic Boolean ( false ) ĊĊĠĠĠ Ġprotected Ġabstract Ġfun Ġenable Internal () ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġdisable Internal () ĊĊĠĠĠ Ġopen Ġfun Ġget Initial Status () Ġ: ĠComponent Status { ĊĠĠĠĠĠĠĠ Ġreturn ĠComponent Status . ST ABLE ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġset EventListener ( listener : ĠComponent EventListener ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . d { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" set EventListener " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġevent Dispatcher Ġ= Ġlistener ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġopen Ġfun ĠgetName () Ġ: ĠString { ĊĠĠĠĠĠĠĠ Ġreturn Ġjava Class . simple Name ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprotected Ġfun Ġreset () Ġ{ Ġ// TODO Ġthis Ġcould Ġpotentially Ġcreate Ġthread Ġlocks ? ĊĠĠĠĠĠĠĠ Ġlog . d { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" reset " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdisable (). await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġenable (). await () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalled Ġwhen Ġcomponent Ġshould Ġstartup . ĠWill Ġreturn Ġwithout Ġaction Ġif Ġalready Ġenabled ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġenable () Ġ= ĠGlobal Scope . async { ĊĠĠĠĠĠĠĠ Ġlog . d { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" enable " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif ( enabled . get AndSet ( true )) Ġreturn @ async Ġfalse ĊĠĠĠĠĠĠĠ Ġstatus Ġ= Ġget Initial Status () ĊĠĠĠĠĠĠĠ Ġawait Callback < Boolean > Ġ{ Ġenable With Callback ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn @ async Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalled Ġwhen Ġcomponent Ġshould Ġshut Ġdown ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠWill Ġreturn Ġwithout Ġaction Ġif Ġalready Ġenabled ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġdisable () Ġ= ĠGlobal Scope . async { ĊĠĠĠĠĠĠĠ Ġif (! enabled . get AndSet ( false )) Ġreturn @ async Ġfalse ĊĠĠĠĠĠĠĠ Ġlog . d { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" disable " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġawait Callback < Boolean > Ġ{ Ġdisable With Callback ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġstatus Ġ= ĠComponent Status . DISABLED ĊĠĠĠĠĠĠĠ Ġreturn @ async Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġenable With Callback ( callback : ĠCallback < Boolean > ){ ĊĠĠĠĠĠĠĠ Ġhandler . post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġenable Internal () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Error ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ġ= ĠComponent Status . ERROR ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . onComplete ( true ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdisable With Callback ( callback : ĠCallback < Boolean > ){ ĊĠĠĠĠĠĠĠ Ġhandler . post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdisable Internal () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcatch Ġ( e Ġ: ĠException ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Error ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ġ= ĠComponent Status . ERROR ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . remove Callbacks And Messages ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . onComplete ( true ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinterface ĠCallback < T > Ġ{ ĊĠĠĠĠĠĠĠ Ġfun ĠonComplete ( result : ĠT ) ĊĠĠĠĠĠĠĠ Ġfun Ġon Exception ( e : ĠException ?) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġ< T > Ġawait Callback ( block : Ġ( Callback < T >) Ġ-> ĠUnit ) Ġ: ĠT Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuspend C ancellable Coroutine Ġ{ Ġcont Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock ( object Ġ: ĠCallback < T > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonComplete ( result : ĠT ) Ġ= Ġcont . resume ( result ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Exception ( e : ĠException ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe ?. let Ġ{ Ġcont . resume With Exception ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Handler ( lo oper : ĠL ooper ) Ġ: ĠHandler { ĊĠĠĠĠĠĠĠ Ġreturn ĠHandler ( lo oper ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Message ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalled Ġwhen Ġwe Ġhave Ġnot Ġreceived Ġa Ġresponse Ġfrom Ġthe Ġserver Ġin Ġa Ġwhile ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġtimeout (){} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHandle Ġmessage Ġsent Ġto Ġthis Ġcomponent 's Ġhandler ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġhandle Message ( message : ĠMessage ): ĠBoolean { ĊĠĠĠĠĠĠĠ Ġvar Ġresult Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġif ( message . what Ġ== ĠControl SDK Service . EVENT _ BRO ADCAST ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( message . obj Ġas ? ĠComponent Event Object )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġhandle External Message ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHandle Ġa Ġmessage Ġfrom Ġoutside Ġof Ġthe Ġcomponent . ĊĠĠĠĠ Ġ* ĠUsed Ġso Ġwe Ġcould Ġgrab Ġcontrol Ġevents Ġor Ġt ts Ġcommands Ġand Ġsimilar ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġhandle External Message ( message : ĠComponent Event Object ) Ġ: ĠBoolean { ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdispatch Message ( message : ĠMessage ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnew Message Ġ= ĠMessage . obtain ( message ) ĊĠĠĠĠĠĠĠ Ġnew Message . target Ġ= Ġhandler ĊĠĠĠĠĠĠĠ Ġnew Message . send To Target () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUsed Ġto Ġretrieve ĠContext Ġand Ġprovide Ġan Ġinitialization Ġbundle . ĠMust Ġbe Ġcalled , Ġprefer ably Ġfirst ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Call Super ĊĠĠĠ Ġoverride Ġfun Ġon Initialize Component ( application Context : ĠContext , Ġbundle Ġ: ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif ( async ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandler Thread Ġ= ĠHandler Thread ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġjava Class . simple Name ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ). also Ġ{ Ġit . start () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandler Ġ= Ġcreate Handler ( handler Thread !!. lo oper ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . post Ġ{ Ġ// set Ġthread Ġpriority Ġof Ġhandler Thread ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠProcess . set Thread Priority ( thread Priority ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandler Ġ= Ġcreate Handler ( Control SDK Service . default Looper ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlog . d { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" on Initialize Component " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcontext Ġ= Ġapplication Context ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Removed () Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . d { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" on Removed " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// TODO Ġsend Ġcomponent Ġerrors Ġup wards ĊĠĠĠ Ġopen Ġfun Ġthrow Error ( e Ġ: ĠException ){ ĊĠĠĠĠĠĠĠ Ġlog . e (" Error ", Ġe ) ĊĠĠĠĠĠĠĠ Ġif (! Control SDK Service . allow Notification For Exceptions ) Ġreturn ĊĠĠĠĠĠĠĠ Ġcontext ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠerrorMessage Ġ= ĠgetType (). toString (). toLowerCase () Ġ+" Ġ"+ Ġit . getString ( R . string . component Cr ashed Text ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnotification Ġ= ĠNotification Compat . Builder ( it , ĠControl SDK Service . CONTROL _ SERVICE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setContent Title ( it . getString ( R . string . component Cr ashed )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setContent Text ( errorMessage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Small Icon ( android . R . drawable . stat _ notify _ error ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setStyle ( Notification Compat . Big TextStyle () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. big Text ("$ errorMessage \ n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Please Ġreport Ġthis Ġto Ġthe Ġdeveloper Ġif Ġyou Ġbelieve Ġthis Ġshould Ġnot Ġbe Ġhappening :\ n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . message )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġservice Ġ= Ġit . getSystem Service ( Context . NOTIFICATION _ SERVICE ) Ġas ĠNotification Manager ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservice . notify ( Random . nextInt (), Ġnotification . build ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ// some Ġhandler Ġevents Ġ( what ) ĊĠĠĠĠĠĠĠ Ġ// some Ġconstant Ġstrings ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠSTATUS _ EVENT Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠEVENT _ MAIN Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠMESSAGE _ TIMEOUT Ġ= Ġ 2 ĊĊĠĠĠĠĠĠĠ Ġfun Ġinstantiate ( application Context : ĠContext , Ġholder : ĠComponent Holder <* >) Ġ: ĠComponent Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcomponent Ġ: ĠComponent Ġ= Ġholder . clazz . newInstance () Ġas ĠComponent ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent . thread Priority Ġ= Ġholder . thread Priority ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent . async Ġ= Ġholder . async ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcomponent . on Initialize Component ( application Context , Ġholder . data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcomponent ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ