/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 1 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 Ġcom . android . tools . idea . editor s . literals . internal Ċ Ċ import Ġcom . android . annotations . concurrency . Worker Thread Ċ import Ġcom . android . tools . analytics . Percent iles Ċ import Ġcom . android . tools . analytics . Usage Tracker Ċ import Ġcom . android . tools . idea . editor s . literals . Live L iterals Monitor Handler Ċ import Ġcom . google . common . cache . Cache Builder Ċ import Ġcom . google . common . collect . Ev ict ing Queue Ċ import Ġcom . google . common . math . Quant iles Ċ import Ġcom . google . wire less . android . sdk . stats . Android Studio Event Ċ import Ġcom . google . wire less . android . sdk . stats . Live L iterals Event Ċ import Ġcom . intellij . openapi . Disposable Ċ import Ġcom . intellij . openapi . application . Application Manager Ċ import Ġcom . intellij . openapi . project . Project Ċ import Ġcom . intellij . openapi . util . Key Ċ import Ġcom . intellij . util . concurrency . App Executor Util Ċ import Ġorg . jetbrains . annotations . Test Only Ċ import Ġjava . util . Enum Map Ċ import Ġjava . util . concurrent . Executor Ċ import Ġjava . util . concurrent . Future Ċ import Ġjava . util . concurrent . Scheduled ExecutorService Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ /** Ċ Ġ* ĠDefault Ġtime Ġthat Ġwill Ġbe Ġused Ġto Ġreport Ġevents Ġto Ġthe ĠStudio Ġstats Ġserver . Ċ Ġ*/ Ċ private Ġconst Ġval ĠDEFAULT _ REPORT _ TIME _ INTERVAL Ġ= Ġ 3 0 L Ċ private Ġval ĠDEFAULT _ REPORT _ TIME _ INTERVAL _ UNIT Ġ= ĠTimeUnit . SECONDS Ċ Ċ @ Worker Thread Ċ private Ġfun Ġreport ToServer ( event : ĠLive L iterals Event ) Ġ{ ĊĠ Ġval Ġstudio Event Ġ= ĠAndroid Studio Event . newBuilder () ĊĠĠĠ Ġ. set Category ( Android Studio Event . Event Category . DEPLOY MENT ) ĊĠĠĠ Ġ. set Kind ( Android Studio Event . Event Kind . LI VE _ LITERAL S _ EVENT ) ĊĠĠĠ Ġ. set Live L iterals Event ( event ) ĊĠ ĠUsage Tracker . log ( studio Event ) Ċ } Ċ Ċ fun ĠLive L iterals Monitor Handler . DeviceType . proto Type (): ĠLive L iterals Event . Live L iterals DeviceType Ġ= Ġwhen ( this ) Ġ{ ĊĠ ĠLive L iterals Monitor Handler . DeviceType . EM UL ATOR Ġ-> ĠLive L iterals Event . Live L iterals DeviceType . EM UL ATOR ĊĠ ĠLive L iterals Monitor Handler . DeviceType . PHYSICAL Ġ-> ĠLive L iterals Event . Live L iterals DeviceType . PHYSICAL ĊĠ ĠLive L iterals Monitor Handler . DeviceType . PRE VIEW Ġ-> ĠLive L iterals Event . Live L iterals DeviceType . PRE VIEW ĊĠ ĠLive L iterals Monitor Handler . DeviceType . UNKNOWN Ġ-> ĠLive L iterals Event . Live L iterals DeviceType . UNKNOWN _ DEVICE _ TYPE Ċ } Ċ Ċ /** Ċ Ġ* ĠRecord Ġof Ġthe Ġdeployment Ġof Ġa Ġliteral Ġcontaining Ġthe Ġtime Ġit Ġtook Ġand Ġthe Ġnumber Ġof Ġproblems Ġif Ġany . Ċ Ġ* Ġ@ param ĠdeviceId Ġdevice Ġid Ġto Ġwhich Ġthe Ġliteral Ġwas Ġpushed Ġto . Ċ Ġ* Ġ@ param Ġpush Id Ġunique Ġpush Ġid Ġfor Ġa Ġgiven Ġdevice Ġto Ġtrack Ġthe Ġliteral Ġdeployment . Ċ Ġ* Ġ@ param Ġtime Ms Ġtime Ġin Ġmilliseconds Ġthat Ġtook Ġto Ġdeploy Ġthe Ġliteral . Ċ Ġ* Ġ@ param Ġproblem Count Ġnumber Ġof Ġproblems Ġfound Ġwhile Ġdeploying Ġor Ġ 0 Ġif Ġit Ġwas Ġsuccessful . Ċ Ġ*/ Ċ data Ġclass ĠDeploy Record ( val ĠdeviceId : ĠString , Ġval Ġpush Id : ĠString , Ġval Ġtime Ms : ĠLong , Ġval Ġproblem Count : ĠInt ) Ċ Ċ /** Ċ Ġ* ĠStats Ġfor Ġa Ġsubset Ġof Ġthe Ġ[ Deploy Record ] s . Ċ Ġ*/ Ċ class ĠDeploy Record Stats Ġinternal Ġconstructor ( val Ġrecords : ĠCollection < Deploy Record >) Ġ{ ĊĠ Ġ/** ĊĠĠ Ġ* ĠReturns Ġthe Ġ[ percentile ] Ġpercent ile Ġfor Ġthe Ġdeployment Ġtime . ĊĠĠ Ġ*/ ĊĠ Ġ@ Suppress (" Un stable Api Usage ") ĊĠ Ġfun Ġdeploy Time ( percentile : ĠInt ): ĠLong Ġ= Ġif Ġ( records . isNotEmpty ()) ĊĠĠĠ ĠQuant iles . percent iles (). index ( percentile ). compute ( last Deployment Times Ms ()). to Long () ĊĠ Ġelse ĊĠĠĠ Ġ- 1 ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠReturns Ġa Ġnumber Ġof Ġthe Ġlast Ġdeployment Ġtimes Ġfor Ġthis Ġsubset . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġlast Deployment Times Ms (): ĠList < Long > Ġ= Ġrecords . map Ġ{ Ġit . time Ms Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠInterface Ġfor Ġreading ĠLive ĠL iterals Ġdiagnostics . Ċ Ġ*/ Ċ interface ĠLive L iterals Diagnostics Read Ġ{ ĊĠ Ġ/** ĊĠĠ Ġ* ĠTotal Ġcount Ġof Ġliteral Ġdeployments Ġ[ successful Deployment Count ] Ġ+ Ġ[ failed Deployment Count ]. ĊĠĠ Ġ*/ ĊĠ Ġfun Ġdeployment Count (): ĠLong Ġ= Ġsuccessful Deployment Count () Ġ+ Ġfailed Deployment Count () ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠNumber Ġof Ġsuccessfully Ġdeployed Ġliterals . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġsuccessful Deployment Count (): ĠLong ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠNumber Ġof Ġsuccessfully Ġfailed Ġliterals . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġfailed Deployment Count (): ĠLong ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠA Ġset Ġof Ġthe Ġlast Ġexecuted Ġdeployments . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġlast Deployments (): ĠList < Deploy Record > ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠReturns Ġthe Ġlist Ġof Ġdevices Ġids Ġthat Ġrecently Ġdeployed Ġliterals . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġlast Re corded Devices (): ĠCollection < String > Ġ= Ġlast Deployments (). map Ġ{ Ġit . deviceId Ġ}. distinct () ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠReturns Ġ[ Deploy Record Stats ] Ġfor Ġrecent Ġdeployed Ġliterals . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġlast Deployment Stats (): ĠDeploy Record Stats Ġ= ĠDeploy Record Stats ( last Deployments ()) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠReturns Ġ[ Deploy Record Stats ] Ġfor Ġrecent Ġdeployed Ġliterals Ġfor Ġa Ġspecific Ġdevice . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġlast Deployment Stats For Device ( deviceId : ĠString ): ĠDeploy Record Stats Ġ= ĠDeploy Record Stats ( ĊĠĠĠ Ġlast Deployments (). filter Ġ{ Ġit . deviceId Ġ== ĠdeviceId Ġ}) Ċ } Ċ Ċ /** Ċ Ġ* ĠInterface Ġfor Ġclients Ġproviding Ġstats Ġabout ĠLive ĠL iterals . Ċ Ġ*/ Ċ interface ĠLive L iterals Diagnostics Write Ġ: ĠLive L iterals Monitor Handler Ċ Ċ /** Ċ Ġ* ĠInterface Ġfor Ġmetrics Ġthat Ġare Ġnot Ġtied Ġto Ġthe Ġproject . Ċ Ġ*/ Ċ interface ĠLive L iterals Application Diagnostics Write Ġ{ ĊĠ Ġ/** ĊĠĠ Ġ* ĠThe Ġuser Ġhas Ġmanually Ġchanged Ġthe Ġstate Ġof ĠLive ĠL iterals . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġuser Changed Live L iterals State ( enabled : ĠBoolean ) Ċ } Ċ Ċ private Ġclass ĠRemote Stats Collector ( ms Provider : Ġ() Ġ-> ĠLong ) Ġ{ ĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġprivate Ġval ĠEST IM ATION _ TARGET S Ġ= Ġdouble ArrayOf ( 0 . 5 , Ġ 0 . 9 , Ġ 0 . 9 9 ) ĊĠĠĠ Ġprivate Ġconst Ġval ĠNUM _ RAW _ SAMPLES Ġ= Ġ 8 0 ĊĠ Ġ} ĊĊĠ Ġprivate Ġval Ġcreated Ġ= Ġms Provider () ĊĠ Ġval Ġdeploy Time Ms Percent iles Ġ= ĠPercent iles ( EST IM ATION _ TARGET S , ĠNUM _ RAW _ SAMPLES ) ĊĠ Ġval Ġproblems Percent iles Ġ= ĠPercent iles ( EST IM ATION _ TARGET S , ĠNUM _ RAW _ SAMPLES ) ĊĠ Ġvar Ġsuccessful Deployments Ġ= Ġ 0 ĊĠ Ġvar Ġfailed Deployments Ġ= Ġ 0 ĊĠ Ġvar Ġactive Devices Ġ= Ġ 0 ĊĊĠ Ġfun Ġis Ol der Than ( time : ĠLong , Ġunit : ĠTimeUnit , Ġms Provider : Ġ() Ġ-> ĠLong ) Ġ= Ġ( ms Provider () Ġ- Ġcreated ) Ġ> Ġunit . to Millis ( time ) ĊĊĠ Ġfun Ġbuild Proto ( device Type : ĠLive L iterals Monitor Handler . DeviceType ): ĠLive L iterals Event . Live L iterals Deploy Stats Ġ= ĠLive L iterals Event . Live L iterals Deploy Stats . newBuilder () ĊĠĠĠ Ġ. set DeviceType ( device Type . proto Type ()) ĊĠĠĠ Ġ. set Deployment Time Ms ( deploy Time Ms Percent iles . export ()) ĊĠĠĠ Ġ. set NumberOf Problems ( problems Percent iles . export ()) ĊĠĠĠ Ġ. set Successful Deployments ( successful Deployments ) ĊĠĠĠ Ġ. set Failed Deployments ( failed Deployments ) ĊĠĠĠ Ġ. set Devices Count ( active Devices ) ĊĠĠĠ Ġ. build () Ċ } Ċ Ċ private Ġfun Ġpush Key ( deviceId : ĠString , Ġpush Id : ĠString ) Ġ= Ġ"$ deviceId :$ push Id " Ċ Ċ private Ġclass ĠLive L iterals Diagnostics Remote Reporter Impl ( private Ġval Ġms Provider : Ġ() Ġ-> ĠLong , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon Report : Ġ( Live L iterals Event ) Ġ-> ĠUnit , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Scheduler : ĠScheduled ExecutorService , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Interval : ĠLong , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Interval Unit : ĠTimeUnit ) Ġ: ĠLive L iterals Diagnostics Write , ĠDis posable Ġ{ ĊĠ Ġprivate Ġval Ġdeployment Start Times Ġ= ĠCache Builder . newBuilder () ĊĠĠĠ Ġ. expire After Access ( 1 0 , ĠTimeUnit . SECONDS ) ĊĠĠĠ Ġ. build < String , ĠLong >() ĊĠ Ġprivate Ġval Ġactive Devices Ġ= Ġmutable Map Of < String , ĠLive L iterals Monitor Handler . DeviceType >() ĊĠ Ġprivate Ġvar Ġcurrent Stats Collector Ġ= ĠEnum Map < Live L iterals Monitor Handler . DeviceType , ĠRemote Stats Collector >( ĊĠĠĠ ĠLive L iterals Monitor Handler . DeviceType :: class . java ) ĊĠ Ġprivate Ġvar Ġscheduled Report : ĠFuture < *> Ġ= Ġreport Scheduler . schedule With Fixed Delay (:: report ToServer , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Interval , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Interval , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Interval Unit ) ĊĊĠ Ġoverride Ġfun Ġlive L iterals Monitor Started ( deviceId : ĠString , Ġdevice Type : ĠLive L iterals Monitor Handler . DeviceType ) Ġ{ ĊĠĠĠ Ġactive Devices [ deviceId ] Ġ= Ġdevice Type ĊĠĠĠ Ġval ĠnumberOf Devices Ġ= Ġactive Devices . count Ġ{ Ġit . value Ġ== Ġdevice Type Ġ} ĊĠĠĠ Ġval Ġstats Ġ= Ġcurrent Stats Collector . compute If Absent ( device Type ) Ġ{ ĠRemote Stats Collector ( ms Provider ) Ġ} ĊĠĠĠ Ġstats ?. active Devices Ġ= ĠnumberOf Devices . coerce At Least ( stats . active Devices ) ĊĠĠĠ Ġon Report ( Live L iterals Event . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set EventType ( Live L iterals Event . Live L iterals EventType . START ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set DeviceType ( device Type . proto Type ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġlive L iterals Monitor Stopped ( deviceId : ĠString ) Ġ{ ĊĠĠĠ Ġval Ġdevice Type Ġ= Ġactive Devices . remove ( deviceId ) Ġ?: Ġreturn ĊĠĠĠ Ġon Report ( Live L iterals Event . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set EventType ( Live L iterals Event . Live L iterals EventType . STOP ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set DeviceType ( device Type . proto Type ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠ Ġ} ĊĊĠ Ġ@ Synchron ized ĊĠ Ġoverride Ġfun Ġlive Literal Push Started ( deviceId : ĠString , Ġpush Id : ĠString ) Ġ{ ĊĠĠĠ Ġdeployment Start Times . put ( push Key ( deviceId , Ġpush Id ), Ġms Provider ()) ĊĠ Ġ} ĊĊĠ Ġ@ Synchron ized ĊĠ Ġfun Ġreport ToServer () Ġ{ ĊĠĠĠ Ġcurrent Stats Collector . forEach Ġ{ Ġ( type To Report , Ġstats To Report ) Ġ-> ĊĠĠĠĠĠ Ġval Ġstats Proto Ġ= Ġstats To Report . build Proto ( type To Report ) ĊĊĠĠĠĠĠ Ġon Report ( Live L iterals Event . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set EventType ( Live L iterals Event . Live L iterals EventType . DEPLOY _ STATS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set DeviceType ( type To Report . proto Type ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. addAll Deploy Stats ( listOf ( stats Proto )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠĠĠ Ġ} ĊĠĠĠ Ġcurrent Stats Collector . clear () ĊĠ Ġ} ĊĊĠ Ġ@ Synchron ized ĊĠ Ġoverride Ġfun Ġlive Literal P ushed ( deviceId : ĠString , Ġpush Id : ĠString , Ġproblems : ĠCollection < Live L iterals Monitor Handler . Problem >) Ġ{ ĊĠĠĠ Ġval Ġkey Ġ= Ġpush Key ( deviceId , Ġpush Id ) ĊĠĠĠ Ġval Ġtime Ms Ġ= Ġdeployment Start Times . get If Present ( key )?. let Ġ{ ĊĠĠĠĠĠ Ġms Provider () Ġ- Ġit ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġdevice Type Ġ= Ġactive Devices [ deviceId ] Ġ?: ĠLive L iterals Monitor Handler . DeviceType . UNKNOWN ĊĠĠĠ Ġval Ġstats Ġ= Ġcurrent Stats Collector . compute If Absent ( device Type ) Ġ{ ĠRemote Stats Collector ( ms Provider ) Ġ} ĊĊĠĠĠ Ġif Ġ( problems . isEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġstats . successful Deployments ++ ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠ Ġstats . failed Deployments ++ ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġtime Ms ?. let Ġ{ Ġstats . deploy Time Ms Percent iles . add Sample ( it . toDouble ()) Ġ} ĊĠĠĠ Ġstats . problems Percent iles . add Sample ( problems . size . toDouble ()) ĊĠ Ġ} ĊĊĠ Ġ@ Synchron ized ĊĠ Ġoverride Ġfun Ġdispose () Ġ{ ĊĠĠĠ Ġscheduled Report . cancel ( true ) ĊĠ Ġ} Ċ } Ċ Ċ @ Suppress (" Un stable Api Usage ") Ċ private Ġclass ĠLive L iterals Diagnostics Local Impl ( private Ġval Ġms Provider : Ġ() Ġ-> ĠLong ) ĊĠ Ġ: ĠLive L iterals Diagnostics Read , ĠLive L iterals Diagnostics Write Ġ{ ĊĠ Ġprivate Ġval Ġdeployment Start Times Ġ= ĠCache Builder . newBuilder () ĊĠĠĠ Ġ. expire After Access ( 1 0 , ĠTimeUnit . SECONDS ) ĊĠĠĠ Ġ. build < String , ĠLong >() ĊĊĠ Ġprivate Ġval Ġlast Deployments Ġ= ĠEv ict ing Queue . create < Deploy Record >( 1 0 0 ) ĊĠ Ġprivate Ġvar Ġsuccessful Deployments Ġ= Ġ 0 L ĊĠ Ġprivate Ġvar Ġfailed Deployments Ġ= Ġ 0 L ĊĊĠ Ġ@ Synchron ized ĊĠ Ġoverride Ġfun Ġsuccessful Deployment Count (): ĠLong Ġ= Ġsuccessful Deployments ĊĊĠ Ġ@ Synchron ized ĊĠ Ġoverride Ġfun Ġfailed Deployment Count (): ĠLong Ġ= Ġfailed Deployments ĊĊĠ Ġ@ Synchron ized ĊĠ Ġoverride Ġfun Ġlast Deployments (): ĠList < Deploy Record > Ġ= Ġlast Deployments . toList () ĊĊĠ Ġoverride Ġfun Ġlive L iterals Monitor Started ( deviceId : ĠString , Ġdevice Type : ĠLive L iterals Monitor Handler . DeviceType ) Ġ{ ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġlive L iterals Monitor Stopped ( deviceId : ĠString ) Ġ{ ĊĠ Ġ} ĊĊĠ Ġ@ Synchron ized ĊĠ Ġoverride Ġfun Ġlive Literal Push Started ( deviceId : ĠString , Ġpush Id : ĠString ) Ġ{ ĊĠĠĠ Ġdeployment Start Times . put ( push Key ( deviceId , Ġpush Id ), Ġms Provider ()) ĊĠ Ġ} ĊĊĠ Ġ@ Synchron ized ĊĠ Ġoverride Ġfun Ġlive Literal P ushed ( deviceId : ĠString , Ġpush Id : ĠString , Ġproblems : ĠCollection < Live L iterals Monitor Handler . Problem >) Ġ{ ĊĠĠĠ Ġval Ġkey Ġ= Ġpush Key ( deviceId , Ġpush Id ) ĊĠĠĠ Ġval Ġtime Ms Ġ= Ġdeployment Start Times . get If Present ( key )?. let Ġ{ ĊĠĠĠĠĠ Ġms Provider () Ġ- Ġit ĊĠĠĠ Ġ} Ġ?: Ġreturn ĊĊĠĠĠ Ġdeployment Start Times . invalidate ( key ) ĊĊĠĠĠ Ġif Ġ( problems . isEmpty ()) ĊĠĠĠĠĠ Ġsuccessful Deployments ++ ĊĠĠĠ Ġelse ĊĠĠĠĠĠ Ġfailed Deployments ++ ĊĊĠĠĠ Ġlast Deployments . add ( Deploy Record ( deviceId , Ġpush Id , Ġtime Ms , Ġproblems . size )) ĊĠ Ġ} Ċ } Ċ Ċ private Ġclass ĠLive L iterals Diagnostics Impl ( ĊĠ Ġprivate Ġval Ġremote Reporter Impl : ĠLive L iterals Diagnostics Remote Reporter Impl , ĊĠ Ġprivate Ġval Ġlocal Reporter Impl : ĠLive L iterals Diagnostics Local Impl ?) ĊĠ Ġ: ĠLive L iterals Diagnostics Read , ĠLive L iterals Diagnostics Write Ġ{ ĊĠ Ġoverride Ġfun Ġsuccessful Deployment Count (): ĠLong Ġ= Ġlocal Reporter Impl ?. successful Deployment Count () Ġ?: Ġ- 1 ĊĠ Ġoverride Ġfun Ġfailed Deployment Count (): ĠLong Ġ= Ġlocal Reporter Impl ?. failed Deployment Count () Ġ?: Ġ- 1 ĊĠ Ġoverride Ġfun Ġlast Deployments (): ĠList < Deploy Record > Ġ= Ġlocal Reporter Impl ?. last Deployments () Ġ?: Ġempty List () ĊĊĠ Ġoverride Ġfun Ġlive L iterals Monitor Started ( deviceId : ĠString , Ġdevice Type : ĠLive L iterals Monitor Handler . DeviceType ) Ġ{ ĊĠĠĠ Ġremote Reporter Impl . live L iterals Monitor Started ( deviceId , Ġdevice Type ) ĊĠĠĠ Ġlocal Reporter Impl ?. live L iterals Monitor Started ( deviceId , Ġdevice Type ) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġlive L iterals Monitor Stopped ( deviceId : ĠString ) Ġ{ ĊĠĠĠ Ġremote Reporter Impl . live L iterals Monitor Stopped ( deviceId ) ĊĠĠĠ Ġlocal Reporter Impl ?. live L iterals Monitor Stopped ( deviceId ) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġlive Literal Push Started ( deviceId : ĠString , Ġpush Id : ĠString ) Ġ{ ĊĠĠĠ Ġremote Reporter Impl . live Literal Push Started ( deviceId , Ġpush Id ) ĊĠĠĠ Ġlocal Reporter Impl ?. live Literal Push Started ( deviceId , Ġpush Id ) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġlive Literal P ushed ( deviceId : ĠString , Ġpush Id : ĠString , Ġproblems : ĠCollection < Live L iterals Monitor Handler . Problem >) Ġ{ ĊĠĠĠ Ġremote Reporter Impl . live Literal P ushed ( deviceId , Ġpush Id , Ġproblems ) ĊĠĠĠ Ġlocal Reporter Impl ?. live Literal P ushed ( deviceId , Ġpush Id , Ġproblems ) ĊĠ Ġ} Ċ Ċ } Ċ Ċ object ĠLive L iterals Diagnostics Manager Ġ{ ĊĠ Ġprivate Ġval ĠKEY Ġ= ĠKey . create < Live L iterals Diagnostics Impl >(" Live L iterals Diagnostics Manager ") ĊĊĠ Ġprivate Ġfun Ġget Impl ( project : ĠProject , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġms Provider : Ġ() Ġ-> ĠLong Ġ= Ġ{ ĠSystem . currentTimeMillis () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Report : Ġ( Live L iterals Event ) Ġ-> ĠUnit Ġ= Ġ:: report ToServer , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Scheduler : ĠScheduled ExecutorService Ġ= ĠApp Executor Util . getApp Scheduled ExecutorService (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Interval : ĠLong Ġ= ĠDEFAULT _ REPORT _ TIME _ INTERVAL , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Interval Unit : ĠTimeUnit Ġ= ĠDEFAULT _ REPORT _ TIME _ INTERVAL _ UNIT ): ĠLive L iterals Diagnostics Impl Ġ{ ĊĠĠĠ Ġval Ġdiagnostics Ġ= Ġproject . getUser Data ( KEY ) ĊĠĠĠ Ġif Ġ( diagnostics Ġ!= Ġnull ) Ġreturn Ġdiagnostics ĊĊĠĠĠ Ġval Ġremote Reporter Ġ= ĠLive L iterals Diagnostics Remote Reporter Impl ( ms Provider , Ġon Report , Ġreport Scheduler , Ġreport Interval , Ġreport Interval Unit ) ĊĠĠĠ Ġval Ġlocal Reporter Ġ= Ġif Ġ( Application Manager . getApplication (). is Internal ) ĊĠĠĠĠĠ ĠLive L iterals Diagnostics Local Impl ( ms Provider ) ĊĠĠĠ Ġelse ĊĠĠĠĠĠ Ġnull ĊĊĠĠĠ Ġreturn ĠLive L iterals Diagnostics Impl ( remote Reporter , Ġlocal Reporter ). also Ġ{ ĊĠĠĠĠĠ Ġproject . put UserData ( KEY , Ġit ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Jvm Static ĊĠ Ġfun Ġget Read Instance ( project : ĠProject ): ĠLive L iterals Diagnostics Read Ġ= Ġget Impl ( project ) ĊĊĠ Ġ@ Jvm Static ĊĠ Ġfun Ġget Write Instance ( project : ĠProject ): ĠLive L iterals Diagnostics Write Ġ= Ġget Impl ( project ) ĊĊĠ Ġprivate Ġfun Ġget Application Write Instance ( on Report : Ġ( Live L iterals Event ) Ġ-> ĠUnit , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor : ĠExecutor ): ĠLive L iterals Application Diagnostics Write Ġ= Ġobject Ġ: ĠLive L iterals Application Diagnostics Write Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġuser Changed Live L iterals State ( enabled : ĠBoolean ) Ġ{ ĊĠĠĠĠĠ Ġexecutor . execute Ġ{ ĊĠĠĠĠĠĠĠ Ġon Report ( Live L iterals Event . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set EventType ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( enabled ) ĠLive L iterals Event . Live L iterals EventType . USER _ ENABLE Ġelse ĠLive L iterals Event . Live L iterals EventType . USER _ DISABLE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Jvm Static ĊĠ Ġfun Ġget Application Write Instance (): ĠLive L iterals Application Diagnostics Write Ġ= Ġget Application Write Instance (:: report ToServer , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠApp Executor Util . getApp ExecutorService ()) ĊĊĠ Ġ@ Test Only ĊĠ Ġ@ Jvm Static ĊĠ Ġfun Ġget Write Instance For Test ( project : ĠProject , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġms Provider : Ġ() Ġ-> ĠLong , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Report : Ġ( Live L iterals Event ) Ġ-> ĠUnit , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Scheduler : ĠScheduled ExecutorService , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Interval : ĠLong , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Interval Unit : ĠTimeUnit ): ĠLive L iterals Diagnostics Write Ġ= ĊĠĠĠ Ġget Impl ( project , Ġms Provider , Ġon Report , Ġreport Scheduler , Ġreport Interval , Ġreport Interval Unit ) ĊĊĠ Ġ@ Test Only ĊĠ Ġ@ Jvm Static ĊĠ Ġfun Ġget Application Write Instance For Test ( on Report : Ġ( Live L iterals Event ) Ġ-> ĠUnit , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor : ĠExecutor ): ĠLive L iterals Application Diagnostics Write Ġ= ĊĠĠĠ Ġget Application Write Instance ( on Report , Ġexecutor ) Ċ }