package Ġbackend . services Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . util . Log Ċ import Ġbackend . services . notifications . Backend Services Notifications Client Ċ import Ġbackend . services . rc . Backend Services Remote Config Client Ċ import Ġbackend . services . shared . un Safe Ok HttpClient Ċ import Ġokhttp 3 . Ok HttpClient Ċ import Ġokhttp 3 . Request Ċ import Ġorg . json . JSONObject Ċ import Ġru . g ild or . coroutines . okhttp . await Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġkotlin . concurrent . thread Ċ Ċ internal Ġconst Ġval ĠSHARE D _ PREFER ENCES _ NAME Ġ= Ġ" backend . services " Ċ private Ġconst Ġval ĠSHARE D _ PRE FS _ KEY _ VERSION _ CODE Ġ= Ġ" version _ code " Ċ private Ġconst Ġval ĠSHARE D _ PRE FS _ KEY _ PROJECT _ ID Ġ= Ġ" project _ id " Ċ private Ġconst Ġval ĠSHARE D _ PRE FS _ KEY _ BASE _ URL Ġ= Ġ" base _ url " Ċ private Ġconst Ġval ĠSHARE D _ PRE FS _ KEY _ TIMEOUT Ġ= Ġ" timeout " Ċ private Ġconst Ġval ĠSHARE D _ PRE FS _ KEY _ IN SECURE Ġ= Ġ" in secure " Ċ private Ġconst Ġval ĠSHARE D _ PRE FS _ KEY _ NOTIFICATION _ ICON Ġ= Ġ" notification _ icon " Ċ Ċ class ĠNot OK Exception ( message : ĠString ?) Ġ: ĠException ( message ) Ċ Ċ object ĠClient Ġ{ ĊĠĠĠ Ġpublic Ġvar Ġoptions : ĠClient Options ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġlateinit Ġvar ĠhttpClient : ĠOk HttpClient ĊĠĠĠ Ġinternal Ġvar Ġupdate Ġ= Ġfalse ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġpublic Ġfun Ġinit ( context : ĠContext , Ġopts : ĠClient Options ? Ġ= Ġnull ): ĠClient Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( opts Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoptions Ġ= ĠClient Options . load ( context ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoptions Ġ= Ġopts ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Ġ= Ġoptions ?. save ( context ) Ġ== Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBackend Services Notifications Client . create Notification Channel ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopts . notification Channel Name ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġinit HttpClient () ĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinit HttpClient () Ġ{ ĊĠĠĠĠĠĠĠ ĠhttpClient Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( if Ġ(! options !!. in secure ) ĠOk HttpClient . Builder () Ġelse Ġun Safe Ok HttpClient ()). call Timeout ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions !!. timeout , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTimeUnit . SECONDS ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ). build () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun ĠhttpRequest ( path : ĠString ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġ"${ options !!. baseUrl }${ path }" ĊĠĠĠĠĠĠĠ ĠLog . d ( java Class . simple Name , Ġ" httpRequest (): Ġsending Ġrequest Ġto Ġ$ url ") ĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠRequest . Builder (). url ( url ). build () ĊĠĠĠĠĠĠĠ Ġval Ġres Ġ= ĠhttpClient . new Call ( request ). await () ĊĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġres . body !!. string () Ċ // ĠĠĠĠĠĠĠ ĠLog . d ( java Class . simple Name , Ġ"${ res . code } Ġ--- Ġ Ġ$ body ") ĊĠĠĠĠĠĠĠ Ġval Ġresult Json Ġ= ĠJSONObject ( body ) ĊĠĠĠĠĠĠĠ Ġif Ġ( result Json [" ok "] Ġ!= Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠNot OK Exception ( result Json [" error "] Ġas ĠString ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( result Json . has (" result ")) Ġresult Json [" result "] Ġelse Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġfun Ġnew Message Data ( context : ĠContext , Ġmessage Data : ĠMap < String , ĠString >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġmessage Data [" type "] Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġif Ġ(! message Data . containsKey (" data ")) Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġdata Ġ= ĠJSONObject ( message Data [" data "]) ĊĠĠĠĠĠĠĠ Ġinit ( context ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" rc " Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBackend Services Remote Config Client . update SharedPreferences ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions !!. projectId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ(_ : Ġjava . lang . Exception ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" notification " Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBackend Services Notifications Client . create Notification ( data )?. show ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠClient Options ( ĊĠĠĠ Ġval Ġversion Code : ĠInt , ĊĠĠĠ Ġval ĠprojectId : ĠString , ĊĠĠĠ Ġval ĠbaseUrl : ĠString , ĊĠĠĠ Ġval Ġtimeout : ĠLong , ĊĠĠĠ Ġval Ġin secure : ĠBoolean , ĊĠĠĠ Ġval Ġnotification Channel Name : ĠString ?, ĊĠĠĠ Ġval Ġnotification Icon : ĠInt , Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġproject Regex Ġ= ĠRegex ("^ [ A - Za - z 0 - 9 ._ - ]+ ") ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! project Regex . matches ( projectId )) Ġthrow ĠException (" bad Ġproject Ġid ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġfun Ġsave ( context : ĠContext ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġshared Preferences Ġ= Ġcontext . get SharedPreferences ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSHARE D _ PREFER ENCES _ NAME , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠContext . MODE _ PRIVATE ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġold Version Code Ġ= Ġshared Preferences . getInt ( SHARED _ PRE FS _ KEY _ VERSION _ CODE , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġval Ġupdate Ġ= Ġold Version Code Ġ> Ġ 0 Ġ&& Ġversion Code Ġ> Ġold Version Code ĊĊĠĠĠĠĠĠĠ Ġshared Preferences . edit () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. put Int ( SHARED _ PRE FS _ KEY _ VERSION _ CODE , Ġversion Code ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. putString ( SHARED _ PRE FS _ KEY _ PROJECT _ ID , ĠprojectId ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. putString ( SHARED _ PRE FS _ KEY _ BASE _ URL , ĠbaseUrl ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. put Long ( SHARED _ PRE FS _ KEY _ TIMEOUT , Ġtimeout ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. put Boolean ( SHARED _ PRE FS _ KEY _ IN SECURE , Ġin secure ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. put Int ( SHARED _ PRE FS _ KEY _ NOTIFICATION _ ICON , Ġnotification Icon ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. commit () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġupdate ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġpublic Ġfun Ġload ( context : ĠContext ): ĠClient Options Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshared Preferences Ġ= Ġcontext . get SharedPreferences ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSHARE D _ PREFER ENCES _ NAME , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContext . MODE _ PRIVATE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġversion Code Ġ= Ġshared Preferences . getInt ( SHARED _ PRE FS _ KEY _ VERSION _ CODE , Ġ 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠprojectId Ġ= Ġshared Preferences . getString ( SHARED _ PRE FS _ KEY _ PROJECT _ ID , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠException (" bad Ġproject Ġid ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠbaseUrl Ġ= Ġshared Preferences . getString ( SHARED _ PRE FS _ KEY _ BASE _ URL , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠException (" bad Ġbase Ġurl ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtimeout Ġ= Ġshared Preferences . getLong ( SHARED _ PRE FS _ KEY _ TIMEOUT , Ġ 1 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġin secure Ġ= Ġshared Preferences . getBoolean ( SHARED _ PRE FS _ KEY _ IN SECURE , Ġfalse ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnotification Icon Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshared Preferences . getInt ( SHARED _ PRE FS _ KEY _ NOTIFICATION _ ICON , Ġ 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠClient Options ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġversion Code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠprojectId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠbaseUrl , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtimeout , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin secure , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnotification Icon , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }