package Ġorg . opp ia . android . testing . time Ċ Ċ import Ġandroid . annotation . Suppress Lint Ċ import Ġandroid . os . System Clock Ċ import Ġorg . opp ia . android . testing . time . Fake Opp ia Clock . Fake Time Mode Ċ import Ġorg . opp ia . android . util . system . Opp ia Clock Ċ import Ġjava . text . SimpleDateFormat Ċ import Ġjava . util . Calendar Ċ import Ġjava . util . Date Ċ import Ġjava . util . TimeZone Ċ import Ġjavax . inject . Inject Ċ import Ġjavax . inject . Singleton Ċ Ċ /** Ċ Ġ* ĠA Ġtest - friendly Ġfake Ġfor Ġ[ Opp ia Clock ] Ġthat Ġprovides Ġbetter ĠRo bo lectric / test Ġtime Ċ Ġ* Ġinter oper ability . Ċ Ġ* Ċ Ġ* ĠNote Ġthat Ġthis Ġfake Ġcan Ġoperate Ġin Ġseveral Ġdistinct Ġtime Ġmodes . ĠSee Ġ[ Fake Time Mode ] Ġfor Ġspecific s . Ċ Ġ* ĠThis Ġfake Ġintention ally Ġdoes Ġnot Ġguarantee Ġperfect Ġinter oper ability Ġwith Ġthe Ġproduction Ġversion Ċ Ġ* Ġof Ġ[ Opp ia Clock ], Ġbut Ġits Ġdefault Ġstate Ġ( e . g . Ġthe Ġinitial Ġclock Ġwithout Ġan Ġaltered Ġtime Ġmode ) Ġdoes Ċ Ġ* Ġguarantee Ġthat . Ċ Ġ*/ Ċ @ Singleton Ċ class ĠFake Opp ia Clock Ġ@ Inject Ġconstructor () Ġ: ĠO pp ia Clock Ġ{ ĊĠ Ġprivate Ġvar Ġfixed Fake Time Ms : ĠLong Ġ= Ġ 0 ĊĠ Ġprivate Ġvar Ġfake Time Mode : ĠFake Time Mode Ġ= ĠFake Time Mode . MODE _ WALL _ CLOCK _ TIME ĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġ// ĠEnsure Ġtests Ġthat Ġrely Ġon Ġthis Ġclock Ġare Ġalways Ġoperating Ġin ĠUTC . ĊĠĠĠ ĠTime Zone . setDefault ( TimeZone . getTime Zone (" UTC ")) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun ĠgetCurrent Time Ms (): ĠLong Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( fake Time Mode ) Ġ{ ĊĠĠĠĠĠ ĠFake Time Mode . MODE _ WALL _ CLOCK _ TIME Ġ-> ĠSystem . currentTimeMillis () ĊĠĠĠĠĠ ĠFake Time Mode . MODE _ FIXED _ FA KE _ TIME Ġ-> Ġfixed Fake Time Ms ĊĠĠĠĠĠ ĠFake Time Mode . MODE _ UP TIME _ M ILL IS Ġ-> ĠSystem Clock . uptime Millis () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠSets Ġthe Ġcurrent Ġwall - clock Ġtime Ġin Ġmilliseconds Ġsince Ġthe ĠUnix Ġepoch , Ġin ĠUTC . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThis Ġcan Ġonly Ġbe Ġused Ġif Ġthe Ġcurrent Ġtime Ġmode Ġis Ġ[ Fake Time Mode . MODE _ FIXED _ FA KE _ TIME ]. ĊĠĠ Ġ*/ ĊĠ Ġfun ĠsetCurrent Time Ms ( currentTime Ms : ĠLong ) Ġ{ ĊĠĠĠ Ġcheck ( fake Time Mode Ġ== ĠFake Time Mode . MODE _ FIXED _ FA KE _ TIME ) Ġ{ ĊĠĠĠĠĠ Ġ" Cannot Ġchange Ġset Ġtime Ġunless Ġtime Ġmode Ġis ĠMODE _ FIXED _ FA KE _ TIME ." ĊĠĠĠ Ġ} ĊĠĠĠ Ġfixed Fake Time Ms Ġ= ĠcurrentTime Ms ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠSets Ġthe Ġclock 's Ġcurrent Ġtime Ġto Ġa Ġnew ĠUTC Ġtimestamp Ġbased Ġon Ġthe Ġspecified Ġone Ġthat Ġtakes ĊĠĠ Ġ* Ġplace Ġat Ġthe Ġsame Ġtime Ġof Ġday Ġon Ġthe Ġsame Ġdate Ġas Ġthe Ġspecified Ġtimestamp , Ġexcept Ġaccounting ĊĠĠ Ġ* Ġfor Ġthe Ġlocal Ġuser 's Ġtimezone . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThis Ġis Ġuseful Ġfor Ġensuring Ġthat Ġlocal Ġcalculations Ġwhich Ġdepend Ġon Ġthe Ġdevice 's Ġtimezone Ġcan ĊĠĠ Ġ* Ġbe Ġtested Ġfor Ġtimestamps Ġthat Ġmust Ġoccur Ġat Ġa Ġparticular Ġtime Ġof Ġday Ġor Ġon Ġa Ġparticular Ġdate . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠNote Ġthat Ġthis Ġhas Ġthe Ġsame Ġrestrictions Ġas Ġ[ setCurrent Time Ms ] Ġwith Ġregards Ġto Ġthis Ġclock 's ĊĠĠ Ġ* Ġtime Ġmode . ĊĠĠ Ġ*/ ĊĠ Ġfun ĠsetCurrent TimeTo Same DateTime ( utc Time Ms : ĠLong ) Ġ{ ĊĠĠĠ ĠsetCurrent Time Ms ( get Utc Time OfDay As Adjust ed Utc Timestamp Account For Timezone ( utc Time Ms )) ĊĠ Ġ} ĊĊĠ Ġ/** ĠSets Ġthe Ġcurrent Ġmode Ġused Ġto Ġcompute Ġtime Ġfor Ġ[ getCurrent Time Ms ] Ġand Ġ[ getCurrent Calendar ]. Ġ*/ ĊĠ Ġfun Ġset Fake Time Mode ( fake Time Mode : ĠFake Time Mode ) Ġ{ ĊĠĠĠ Ġthis . fake Time Mode Ġ= Ġfake Time Mode ĊĠ Ġ} ĊĊĠ Ġ/** ĠReturns Ġthe Ġcurrent Ġtime Ġmode Ġset Ġby Ġ[ set Fake Time Mode ] Ġor Ġdefault ed Ġupon Ġclock Ġinit . Ġ*/ ĊĠ Ġfun Ġget Fake Time Mode () Ġ= Ġfake Time Mode ĊĊĠ Ġ@ Suppress Lint (" SimpleDateFormat ") ĊĠ Ġprivate Ġfun Ġget Utc Time OfDay As Adjust ed Utc Timestamp Account For Timezone ( utc Time Ms : ĠLong ): ĠLong Ġ{ ĊĠĠĠ Ġval Ġformat Ġ= ĠSimpleDateFormat (" yyyy - MM - dd Ġhh : mm Ġa ") ĊĠĠĠ Ġval Ġut c Time As DateTime String Ġ= Ġformat . format ( utc Time Ms ) ĊĠĠĠ Ġval Ġdate Ġ= ĊĠĠĠĠĠ Ġformat . parse ( utc Time As DateTime String ) ĊĠĠĠĠĠĠĠ Ġ?: Ġerror (" Expected Ġto Ġparse Ġdate Ġfor Ġtime : Ġ$ utc Time As DateTime String ") ĊĠĠĠ Ġreturn Ġget Local To Utc Date ( date ) Ġ?: Ġerror (" Failed Ġto Ġconvert Ġdate Ġto ĠUTC : Ġ$ date ") ĊĠ Ġ} ĊĊĠ Ġ@ Suppress Lint (" SimpleDateFormat ") ĊĠ Ġprivate Ġfun Ġget Local To Utc Date ( date : ĠDate ): ĠLong ? Ġ{ ĊĠĠĠ Ġval Ġcalendar Ġ= ĠCalendar . getInstance () ĊĠĠĠ Ġcalendar . time Ġ= Ġdate ĊĠĠĠ Ġcalendar . time Zone Ġ= ĠTime Zone . getTime Zone (" UTC ") ĊĠĠĠ Ġval Ġtime Ġ= Ġcalendar . time ĊĠĠĠ Ġval Ġoutput Format Ġ= ĠSimpleDateFormat (" yyyy - MM - dd ' T ' HH : mm : ss . SS S ' Z '") ĊĠĠĠ Ġoutput Format . time Zone Ġ= ĠTime Zone . getTime Zone (" UTC ") ĊĠĠĠ Ġval Ġnew Date Ġ= ĠSimpleDateFormat (" yyyy - MM - dd ' T ' HH : mm : ss . SS S ' Z ' "). parse ( output Format . format ( time )) ĊĠĠĠ Ġreturn Ġnew Date ?. time ĊĠ Ġ} ĊĊĠ Ġ/** ĠDetermines Ġthe Ġtype Ġof Ġmode Ġthe Ġclock Ġshould Ġoperate Ġin . Ġ*/ ĊĠ Ġenum Ġclass ĠFake Time Mode Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIndicates Ġthat Ġthe Ġfake Ġclock Ġshould Ġuse Ġthe Ġsystem Ġwall Ġclock Ġfor Ġtracking Ġtime . ĠThis Ġis Ġthe ĊĠĠĠĠ Ġ* Ġdefault Ġbehavior Ġsince Ġit Ġmatches Ġthe Ġproduction Ġversion Ġof Ġ[ Opp ia Clock ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ ĠMODE _ WALL _ CLOCK _ TIME , ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIndicates Ġthat Ġthe Ġfake Ġclock Ġshould Ġdefault Ġto Ġan Ġinitial Ġtime Ġof Ġ 0 Ġand Ġonly Ġreturn Ġthe Ġtime ĊĠĠĠĠ Ġ* Ġset Ġby Ġ[ setCurrent Time Ms ]. ĠThis Ġis Ġthe Ġonly Ġmode Ġthat Ġcan Ġbe Ġused Ġif Ġthe Ġtest Ġw ishes Ġto ĊĠĠĠĠ Ġ* Ġchange Ġtime . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ ĠMODE _ FIXED _ FA KE _ TIME , ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIndicates Ġthat Ġthe Ġfake Ġclock Ġshould Ġuse Ġ[ System Clock . uptime Millis ] Ġto Ġprovide Ġtime , Ġinstead . ĊĠĠĠĠ Ġ* ĠThis Ġdoes Ġnot Ġmatch Ġproduction Ġbehavior Ġsince Ġu ptime Ġmillis Ġwon 't Ġsurv ive Ġdevice Ġrestart s . ĊĠĠĠĠ Ġ* ĠHowever , Ġthis Ġgenerally Ġwill Ġwork Ġbetter Ġin ĠRo bo lectric Ġtests Ġsince Ġthose Ġhave Ġa Ġdis parity ĊĠĠĠĠ Ġ* Ġissue Ġwhere in Ġ[ System . currentTimeMillis ] Ġuses Ġreal Ġwall - clock Ġtime Ġand Ġu ptime Ġmillis Ġuses Ġa ĊĠĠĠĠ Ġ* Ġfake Ġtime . ĠThe Ġlatter Ġis Ġused Ġto Ġcoordinate Ġtest Ġtiming Ġ( such Ġas Ġwith Ġthe Ġtest Ġcoroutine ĊĠĠĠĠ Ġ* Ġdispatcher Ġutility ). ĠThis Ġmode Ġshould Ġbe Ġused Ġif Ġthe Ġuser Ġw ishes Ġto Ġen es ure Ġpredict able Ġtime ĊĠĠĠĠ Ġ* Ġadvance ment Ġwithout Ġrelying Ġon Ġthe Ġactual Ġspeed Ġat Ġwhich Ġthe Ġtest Ġruns . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠAny Ġdata Ġthat Ġstores Ġa Ġcopy Ġof Ġcurrent Ġtime Ġderived Ġfrom Ġthis Ġmode Ġcannot Ġbe Ġreli ably Ġshared ĊĠĠĠĠ Ġ* Ġacross Ġtest Ġboundaries Ġsince Ġeach Ġindividual Ġtest Ġis Ġtreated Ġlike Ġa Ġdevice Ġrestart Ġfrom Ġthe ĊĠĠĠĠ Ġ* Ġperspective Ġof Ġu ptime Ġtracking . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ ĠMODE _ UP TIME _ M ILL IS ĊĠ Ġ} Ċ } Ċ