/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 ĠThe ĠMatrix . org ĠFoundation ĠC . I . C . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġorg . matrix . android . sdk . internal . session . sync Ċ Ċ import Ġandroid . os . System Clock Ċ import Ġokhttp 3 . ResponseBody Ċ import Ġorg . matrix . android . sdk . api . extensions . try OrNull Ċ import Ġorg . matrix . android . sdk . api . logger . Logger Tag Ċ import Ġorg . matrix . android . sdk . api . session . Session Ċ import Ġorg . matrix . android . sdk . api . session . in its ync . Init Sync Step Ċ import Ġorg . matrix . android . sdk . api . session . in its ync . Sync Status Service Ċ import Ġorg . matrix . android . sdk . api . session . statistics . Statistic Event Ċ import Ġorg . matrix . android . sdk . api . session . sync . Initial Sync Strategy Ċ import Ġorg . matrix . android . sdk . api . session . sync . initial Sync Strategy Ċ import Ġorg . matrix . android . sdk . api . session . sync . model . Lazy Room Sync Ep hemeral Ċ import Ġorg . matrix . android . sdk . api . session . sync . model . Sync Response Ċ import Ġorg . matrix . android . sdk . internal . di . Session Files Directory Ċ import Ġorg . matrix . android . sdk . internal . di . UserId Ċ import Ġorg . matrix . android . sdk . internal . network . Global Error Receiver Ċ import Ġorg . matrix . android . sdk . internal . network . TimeOut Interceptor Ċ import Ġorg . matrix . android . sdk . internal . network . execute Request Ċ import Ġorg . matrix . android . sdk . internal . network . to Failure Ċ import Ġorg . matrix . android . sdk . internal . session . Session Listeners Ċ import Ġorg . matrix . android . sdk . internal . session . dispatch To Ċ import Ġorg . matrix . android . sdk . internal . session . filter . Filter Repository Ċ import Ġorg . matrix . android . sdk . internal . session . home server . Get Home Server Capabilities Task Ċ import Ġorg . matrix . android . sdk . internal . session . in its ync . Default Sync Status Service Ċ import Ġorg . matrix . android . sdk . internal . session . in its ync . report Sub task Ċ import Ġorg . matrix . android . sdk . internal . session . sync . parsing . Initial Sync Response Parser Ċ import Ġorg . matrix . android . sdk . internal . session . user . User Store Ċ import Ġorg . matrix . android . sdk . internal . task . Task Ċ import Ġorg . matrix . android . sdk . internal . util . log Duration Ċ import Ġorg . matrix . android . sdk . internal . util . time . Clock Ċ import Ġretrofit 2 . Response Ċ import Ġretrofit 2 . await Response Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . io . File Ċ import Ġjava . net . Socket TimeoutException Ċ import Ġjavax . inject . Inject Ċ Ċ private Ġval Ġlogger Tag Ġ= ĠLogger Tag (" Sync Task ", ĠLogger Tag . SYNC ) Ċ Ċ internal Ġinterface ĠSync Task Ġ: ĠTask < Sync Task . Params , ĠSync Response > Ġ{ ĊĊĠĠĠ Ġdata Ġclass ĠParams ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtimeout : ĠLong , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpresence : ĠSync Presence ?, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġafter Pause : ĠBoolean ĊĠĠĠ Ġ) Ċ } Ċ Ċ internal Ġclass ĠDefault Sync Task Ġ@ Inject Ġconstructor ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġsync API : ĠSync API , ĊĠĠĠĠĠĠĠ Ġ@ UserId Ġprivate Ġval ĠuserId : ĠString , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfilter Repository : ĠFilter Repository , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġsync Response Handler : ĠSync Response Handler , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġdefault Sync Status Service : ĠDefault Sync Status Service , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġsync Token Store : ĠSync Token Store , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġget Home Server Capabilities Task : ĠGet Home Server Capabilities Task , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġuser Store : ĠUser Store , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġsession : ĠSession , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġsession Listeners : ĠSession Listeners , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġsync Task Se qu encer : ĠSync Task Se qu encer , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġglobal Error Receiver : ĠGlobal Error Receiver , ĊĠĠĠĠĠĠĠ Ġ@ Session Files Directory ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfile Directory : ĠFile , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġsync Response Parser : ĠInitial Sync Response Parser , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġroom Sync Ep hemeral Temporary Store : ĠRoom Sync Ep hemeral Temporary Store , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġclock : ĠClock , Ċ ) Ġ: ĠSync Task Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġworking Dir Ġ= ĠFile ( file Directory , Ġ" is ") ĊĠĠĠ Ġprivate Ġval Ġinitial Sync Status Repository : ĠInitial Sync Status Repository Ġ= ĠFile Initial Sync Status Repository ( working Dir , Ġclock ) ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġexecute ( params : ĠSync Task . Params ): ĠSync Response Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsync Task Se qu encer . post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Sync ( params ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdo Sync ( params : ĠSync Task . Params ): ĠSync Response Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). d (" Sync Ġtask Ġstarted Ġon ĠThread : Ġ${ Thread . currentThread (). name }") ĊĊĠĠĠĠĠĠĠ Ġval Ġrequest Params Ġ= ĠHashMap < String , ĠString >() ĊĠĠĠĠĠĠĠ Ġvar Ġtimeout Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġsync Token Store . getLast Token () ĊĠĠĠĠĠĠĠ Ġif Ġ( token Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Params [" since "] Ġ= Ġtoken ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtimeout Ġ= Ġparams . timeout ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrequest Params [" timeout "] Ġ= Ġtimeout . toString () ĊĠĠĠĠĠĠĠ Ġrequest Params [" filter "] Ġ= Ġfilter Repository . get Filter () ĊĠĠĠĠĠĠĠ Ġparams . presence ?. let Ġ{ Ġrequest Params [" set _ presence "] Ġ= Ġit . value Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġis Initial Sync Ġ= Ġtoken Ġ== Ġnull ĊĠĠĠĠĠĠĠ Ġif Ġ( is Initial Sync ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġmight Ġwant Ġto Ġget Ġthe Ġuser Ġinformation Ġin Ġparallel Ġtoo ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġuser Ġ= Ġtry OrNull Ġ{ Ġsession . profile Service (). get Profile As User ( userId ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuser Store . create OrUpdate ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠuserId Ġ= ĠuserId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠdisplayName Ġ= Ġuser ?. displayName , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġavatar Url Ġ= Ġuser ?. avatar Url ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Sync Status Service . start Root ( Init Sync Step . Import ing Account , Ġ 1 0 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠMaybe Ġrefresh Ġthe Ġhome server Ġcapabilities Ġdata Ġwe Ġknow ĊĠĠĠĠĠĠĠ Ġget Home Server Capabilities Task . execute ( Get Home Server Capabilities Task . Params ( force Refresh Ġ= Ġfalse )) ĊĊĠĠĠĠĠĠĠ Ġval Ġread TimeOut Ġ= Ġ( params . timeout Ġ+ ĠTIME OUT _ M ARGIN ). coerce At Least ( TimeOut Interceptor . DEFAULT _ LONG _ TIMEOUT ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġsync Response To Return : ĠSync Response ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġsync Statistics Data Ġ= ĠSync Statistics Data ( is Initial Sync , Ġparams . after Pause ) ĊĠĠĠĠĠĠĠ Ġif Ġ( is Initial Sync ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). d (" INIT _ SYNC Ġwith Ġfilter : Ġ${ request Params [" filter "] }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinit Sync Strategy Ġ= Ġinitial Sync Strategy ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog Duration (" INIT _ SYNC Ġstrategy : Ġ$ init Sync Strategy ", Ġlogger Tag , Ġclock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( init Sync Strategy Ġis ĠInitial Sync Strategy . Optim ized ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġroom Sync Ep hemeral Temporary Store . reset () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġworking Dir . mkdir s () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġdownload Init Sync Response ( request Params , Ġsync Statistics Data ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Response To Return Ġ= Ġreport Sub task ( default Sync Status Service , ĠInit Sync Step . Import ing Account , Ġ 1 , Ġ 0 . 7 F ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Sync File ( file , Ġinit Sync Strategy ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDelete Ġall Ġfiles ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġworking Dir . delete Re cursively () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsync Response Ġ= Ġlog Duration (" INIT _ SYNC ĠRequest ", Ġlogger Tag , Ġclock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecute Request ( global Error Receiver ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync API . sync ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams Ġ= Ġrequest Params , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġread TimeOut Ġ= Ġread TimeOut ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġcannot Ġdistinguish Ġrequest Ġand Ġdownload Ġin Ġthis Ġcase . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Statistics Data . request Init Sync Time Ġ= ĠSystem Clock . elapsed Realtime () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Statistics Data . download Init Sync Time Ġ= Ġsync Statistics Data . request Init Sync Time ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog Duration (" INIT _ SYNC ĠDatabase Ġinsertion ", Ġlogger Tag , Ġclock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Response Handler . handle Response ( sync Response , Ġtoken , Ġdefault Sync Status Service ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Response To Return Ġ= Ġsync Response ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Sync Status Service . end All () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). d (" Start Ġincremental Ġsync Ġrequest Ġwith Ġsince Ġtoken Ġ$ token ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Sync Status Service . setStatus ( Sync Status Service . Status . Incremental Sync Idle ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsync Response Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecute Request ( global Error Receiver ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync API . sync ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams Ġ= Ġrequest Params , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġread TimeOut Ġ= Ġread TimeOut ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). e ( throwable , Ġ" Incremental Ġsync Ġrequest Ġerror ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Sync Status Service . setStatus ( Sync Status Service . Status . Incremental Sync Error ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġthrowable ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnb Rooms Ġ= Ġsync Response . rooms ?. invite . or Empty (). size Ġ+ Ġsync Response . rooms ?. join . or Empty (). size Ġ+ Ġsync Response . rooms ?. leave . or Empty (). size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnb To Device Ġ= Ġsync Response . to Device ?. events . or Empty (). size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Batch Ġ= Ġsync Response . next Batch ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). d ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Incremental Ġsync Ġrequest Ġparsing , Ġ$ nb Rooms Ġroom ( s ) Ġ$ nb To Device Ġto Device ( s ). ĠGot Ġnext Batch : Ġ$ next Batch " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Sync Status Service . setStatus ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSync Status Service . Status . Incremental Sync Parsing ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrooms Ġ= Ġnb Rooms , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Device Ġ= Ġnb To Device ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsync Response Handler . handle Response ( sync Response , Ġtoken , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsync Response To Return Ġ= Ġsync Response ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). d (" Incremental Ġsync Ġdone ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Sync Status Service . setStatus ( Sync Status Service . Status . Incremental Sync Done ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsync Statistics Data . t reatment Sync Time Ġ= ĠSystem Clock . elapsed Realtime () ĊĠĠĠĠĠĠĠ Ġsync Statistics Data . nb Of Rooms Ġ= Ġsync Response To Return ?. rooms ?. join ?. size Ġ?: Ġ 0 ĊĠĠĠĠĠĠĠ Ġsend Statistics ( sync Statistics Data ) ĊĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). d (" Sync Ġtask Ġfinished Ġon ĠThread : Ġ${ Thread . currentThread (). name }") ĊĠĠĠĠĠĠĠ Ġ// ĠShould Ġthrow Ġif Ġnull Ġas Ġit 's Ġa Ġmandatory Ġvalue . ĊĠĠĠĠĠĠĠ Ġreturn Ġsync Response To Return !! ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġdownload Init Sync Response ( request Params : ĠMap < String , ĠString >, Ġsync Statistics Data : ĠSync Statistics Data ): ĠFile Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġworking File Ġ= ĠFile ( working Dir , Ġ" init Sync . json ") ĊĠĠĠĠĠĠĠ Ġval Ġstatus Ġ= Ġinitial Sync Status Repository . get Step () ĊĠĠĠĠĠĠĠ Ġif Ġ( working File . exists () Ġ&& Ġstatus Ġ>= ĠInitial Sync Status . STEP _ DOWN LOADED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). d (" INIT _ SYNC Ġfile Ġis Ġalready Ġhere ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport Sub task ( default Sync Status Service , ĠInit Sync Step . Downloading , Ġ 1 , Ġ 0 . 3 f ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEmpty Ġtask ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Sync Status Repository . set Step ( Initial Sync Status . STEP _ DOWNLOAD ING ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsync Response Ġ= Ġlog Duration (" INIT _ SYNC ĠPerform Ġserver Ġrequest ", Ġlogger Tag , Ġclock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Sub task ( default Sync Status Service , ĠInit Sync Step . Server Comp uting , Ġ 1 , Ġ 0 . 2 f ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Sync Response ( request Params , ĠMAX _ NUMBER _ OF _ RETRY _ AFTER _ TIMEOUT ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsync Statistics Data . request Init Sync Time Ġ= ĠSystem Clock . elapsed Realtime () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sync Response . is Successful ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog Duration (" INIT _ SYNC ĠDownload Ġand Ġsave Ġto Ġfile ", Ġlogger Tag , Ġclock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Sub task ( default Sync Status Service , ĠInit Sync Step . Downloading , Ġ 1 , Ġ 0 . 1 f ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Response . body ()?. byte Stream ()?. use Ġ{ ĠinputStream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġworking File . output Stream (). use Ġ{ ĠoutputStream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinputStream . copy To ( output Stream ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġsync Response . to Failure ( global Error Receiver ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ ĠTim ber . tag ( logger Tag . value ). w (" INIT _ SYNC Ġrequest Ġfailure : Ġ$ this ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsync Statistics Data . download Init Sync Time Ġ= ĠSystem Clock . elapsed Realtime () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Sync Status Repository . set Step ( Initial Sync Status . STEP _ DOWN LOADED ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġworking File ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġget Sync Response ( request Params : ĠMap < String , ĠString >, Ġmax NumberOf Retries : ĠInt ): ĠResponse < ResponseBody > Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġretry Ġ= Ġmax NumberOf Retries ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġretry -- ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsync API . sync Stream ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams Ġ= Ġrequest Params ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). await Response () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( throwable Ġis ĠSocket TimeoutException Ġ&& Ġretry Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). w (" INIT _ SYNC Ġtimeout Ġretry Ġleft : Ġ$ retry ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). e ( throwable , Ġ" INIT _ SYNC Ġtimeout , Ġno Ġretry Ġleft , Ġor Ġother Ġerror ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġthrowable ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġhandle Sync File ( working File : ĠFile , Ġinit Sync Strategy : ĠInitial Sync Strategy . Optim ized ): ĠSync Response Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġlog Duration (" INIT _ SYNC Ġhandle Sync File ()", Ġlogger Tag , Ġclock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsync Response Ġ= Ġlog Duration (" INIT _ SYNC ĠRead Ġfile Ġand Ġparse ", Ġlogger Tag , Ġclock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Response Parser . parse ( init Sync Strategy , Ġworking File ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Sync Status Repository . set Step ( Initial Sync Status . STEP _ PAR SED ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLog Ġsome Ġstats ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnb Of Joined Rooms Ġ= Ġsync Response . rooms ?. join ?. size Ġ?: Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnb Of Joined Rooms In File Ġ= Ġsync Response . rooms ?. join ?. values ?. count Ġ{ Ġit . ep hemeral Ġis ĠLazy Room Sync Ep hemeral . Stored Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . tag ( logger Tag . value ). d (" INIT _ SYNC Ġ$ nb Of Joined Rooms Ġrooms , Ġ$ nb Of Joined Rooms In File Ġep hemeral Ġstored Ġinto Ġfiles ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog Duration (" INIT _ SYNC ĠDatabase Ġinsertion ", Ġlogger Tag , Ġclock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Response Handler . handle Response ( sync Response , Ġnull , Ġdefault Sync Status Service ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Sync Status Repository . set Step ( Initial Sync Status . STEP _ SUCCESS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsync Response ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAg gregator Ġto Ġsend Ġstat Ġevent . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġclass ĠSync Statistics Data ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Init Sync : ĠBoolean , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis After Pause : ĠBoolean ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠstartTime Ġ= ĠSystem Clock . elapsed Realtime () ĊĠĠĠĠĠĠĠ Ġvar Ġrequest Init Sync Time Ġ= ĠstartTime ĊĠĠĠĠĠĠĠ Ġvar Ġdownload Init Sync Time Ġ= ĠstartTime ĊĠĠĠĠĠĠĠ Ġvar Ġtreatment Sync Time Ġ= ĠstartTime ĊĠĠĠĠĠĠĠ Ġvar Ġnb Of Rooms : ĠInt Ġ= Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsend Statistics ( data : ĠSync Statistics Data ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsend Statistic Event ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( data . is Init Sync ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( Statistic Event . Initial Sync Request ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Duration Ms Ġ= Ġ( data . request Init Sync Time Ġ- Ġdata . startTime ). toInt (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdownload Duration Ms Ġ= Ġ( data . download Init Sync Time Ġ- Ġdata . request Init Sync Time ). toInt (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtreatment Duration Ms Ġ= Ġ( data . t reatment Sync Time Ġ- Ġdata . download Init Sync Time ). toInt (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnb Of Joined Rooms Ġ= Ġdata . nb Of Rooms , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStat istic Event . Sync T reatment ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġduration Ms Ġ= Ġ( data . t reatment Sync Time Ġ- Ġdata . startTime ). toInt (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġafter Pause Ġ= Ġdata . is After Pause , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnb Of Joined Rooms Ġ= Ġdata . nb Of Rooms ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsend Statistic Event ( statistic Event : ĠStat istic Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsession . dispatch To ( session Listeners ) Ġ{ Ġsession , Ġlistener Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . on Statistics Event ( session , Ġstatistic Event ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ NUMBER _ OF _ RETRY _ AFTER _ TIMEOUT Ġ= Ġ 5 0 ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTIME OUT _ M ARGIN : ĠLong Ġ= Ġ 1 0 _ 0 0 0 ĊĠĠĠ Ġ} Ċ } Ċ