package Ġcash . z . ecc . android . sdk . ext Ċ Ċ import Ġandroid . content . Context Ċ import Ġcash . z . ecc . android . sdk . ext . Z cash Sdk . MAX _ BACK OFF _ INTERVAL Ċ import Ġkotlinx . coroutines . delay Ċ import Ġjava . io . File Ċ import Ġkotlin . random . Random Ċ Ċ /** Ċ Ġ* ĠExecute Ġthe Ġgiven Ġblock Ġand Ġif Ġit Ġfails , Ġretry Ġup Ġto Ġ[ retries ] Ġmore Ġtimes . ĠIf Ġnone Ġof Ġthe Ċ Ġ* Ġretries Ġsucceed Ġthen Ġthrow Ġthe Ġfinal Ġerror , Ġwhich Ġcan Ġbe Ġwrapped Ġin Ġorder Ġto Ġadd Ġmore Ġcontext . Ċ Ġ* Ċ Ġ* Ġ@ param Ġretries Ġthe Ġnumber Ġof Ġtimes Ġto Ġretry Ġthe Ġblock Ġafter Ġthe Ġfirst Ġattempt Ġfails . Ċ Ġ* Ġ@ param Ġexception Wrapper Ġa Ġfunction Ġthat Ġcan Ġwrap Ġthe Ġfinal Ġfailure Ġto Ġadd Ġmore Ġuseful Ġinformation Ċ Ġ* Ġor Ġcontext . ĠDefault Ġbehavior Ġis Ġto Ġjust Ġreturn Ġthe Ġfinal Ġexception . Ċ Ġ* Ġ@ param Ġinitial Delay Millis Ġthe Ġinitial Ġamount Ġof Ġtime Ġto Ġwait Ġbefore Ġthe Ġfirst Ġretry . Ċ Ġ* Ġ@ param Ġblock Ġthe Ġcode Ġto Ġexecute , Ġwhich Ġwill Ġbe Ġwrapped Ġin Ġa Ġtry / catch Ġand Ġretried Ġwhenever Ġan Ċ Ġ* Ġexception Ġis Ġthrown Ġup Ġto Ġ[ retries ] Ġattempts . Ċ Ġ*/ Ċ suspend Ġinline Ġfun Ġretry Up To ( retries : ĠInt , Ġexception Wrapper : Ġ( Throwable ) Ġ-> ĠThrowable Ġ= Ġ{ Ġit Ġ}, Ġinitial Delay Millis : ĠLong Ġ= Ġ 5 0 0 L , Ġblock : Ġ( Int ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġvar Ġfailed Attempts Ġ= Ġ 0 ĊĠĠĠ Ġwhile Ġ( failed Attempts Ġ<= Ġretries ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock ( failed Attempts ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfailed Attempts ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( failed Attempts Ġ> Ġretries ) Ġthrow Ġexception Wrapper ( t ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġduration Ġ= Ġ( initial Delay Millis . toDouble () Ġ* ĠMath . pow ( 2 . 0 , Ġfailed Attempts . toDouble () Ġ- Ġ 1 )). to Long () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtw ig (" failed Ġdue Ġto Ġ$ t Ġretry ing Ġ($ failed Attempts /$ retries ) Ġin Ġ${ duration } s ...") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( duration ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠExecute Ġthe Ġgiven Ġblock Ġand Ġif Ġit Ġfails , Ġretry Ġup Ġto Ġ[ retries ] Ġmore Ġtimes , Ġusing Ġthread Ġsleep Ċ Ġ* Ġinstead Ġof Ġsus pending . ĠIf Ġnone Ġof Ġthe Ġretries Ġsucceed Ġthen Ġthrow Ġthe Ġfinal Ġerror . ĠThis Ġfunction Ċ Ġ* Ġis Ġintended Ġto Ġbe Ġcalled Ġwith Ġno Ġparameters , Ġi . e ., Ġit Ġis Ġdesigned Ġto Ġuse Ġits Ġdefaults . Ċ Ġ* Ċ Ġ* Ġ@ param Ġretries Ġthe Ġnumber Ġof Ġtimes Ġto Ġretry . ĠTypically , Ġthis Ġshould Ġbe Ġlow . Ċ Ġ* Ġ@ param Ġsleep Time Ġthe Ġamount Ġof Ġtime Ġto Ġsleep Ġin Ġbetween Ġretries . ĠTypically , Ġthis Ġshould Ġbe Ġan Ċ Ġ* Ġamount Ġof Ġtime Ġthat Ġis Ġhard Ġto Ġper ceive . Ċ Ġ* Ġ@ param Ġblock Ġthe Ġblock Ġof Ġlogic Ġto Ġtry . Ċ Ġ*/ Ċ inline Ġfun Ġretry Simple ( retries : ĠInt Ġ= Ġ 2 , Ġsleep Time : ĠLong Ġ= Ġ 2 0 L , Ġblock : Ġ( Int ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġvar Ġfailed Attempts Ġ= Ġ 0 ĊĠĠĠ Ġwhile Ġ( failed Attempts Ġ<= Ġretries ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock ( failed Attempts ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfailed Attempts ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( failed Attempts Ġ> Ġretries ) Ġthrow Ġt ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtw ig (" failed Ġdue Ġto Ġ$ t Ġsimply Ġretry ing Ġ($ failed Attempts /$ retries ) Ġin Ġ${ sleep Time } ms ...") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( sleep Time ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠExecute Ġthe Ġgiven Ġblock Ġand Ġif Ġit Ġfails , Ġretry Ġwith Ġan Ġexponential Ġbackoff . Ċ Ġ* Ċ Ġ* Ġ@ param ĠonError Listener Ġa Ġcallback Ġthat Ġgets Ġthe Ġfirst Ġshot Ġat Ġprocessing Ġany Ġerror Ġand Ġcan Ġv eto Ċ Ġ* Ġthe Ġretry Ġbehavior Ġby Ġreturning Ġfalse . Ċ Ġ* Ġ@ param Ġinitial Delay Millis Ġthe Ġinitial Ġdelay Ġbefore Ġretry ing . Ċ Ġ* Ġ@ param Ġmax Delay Millis Ġthe Ġmaximum Ġdelay Ġbetween Ġretries . Ċ Ġ* Ġ@ param Ġblock Ġthe Ġlogic Ġto Ġrun Ġonce Ġand Ġthen Ġrun Ġagain Ġif Ġit Ġfails . Ċ Ġ*/ Ċ suspend Ġinline Ġfun Ġretry With Backoff ( no inline ĠonError Listener : Ġ(( Throwable ) Ġ-> ĠBoolean )? Ġ= Ġnull , Ġinitial Delay Millis : ĠLong Ġ= Ġ 1 0 0 0 L , Ġmax Delay Millis : ĠLong Ġ= ĠMAX _ BACK OFF _ INTERVAL , Ġblock : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġvar Ġsequence Ġ= Ġ 0 Ġ// Ġcount Ġup Ġto Ġthe Ġmax Ġand Ġthen Ġreset Ġto Ġhalf . ĠSo Ġthat Ġwe Ġdon 't Ġrepeat Ġthe Ġmax Ġbut Ġwe Ġalso Ġdon 't Ġrepeat Ġtoo Ġmuch . ĊĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblock () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġoffer Ġto Ġlistener Ġfirst ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( onError Listener ?. invoke ( t ) Ġ== Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġt ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsequence ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġinitial Delay ^( sequence / 4 ) Ġ+ Ġj itter ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġduration Ġ= ĠMath . pow ( initial Delay Millis . toDouble (), Ġ( sequence . toDouble () Ġ/ Ġ 4 . 0 )). to Long () Ġ+ ĠRandom . next Long ( 1 0 0 0 L ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( duration Ġ> Ġmax Delay Millis ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġduration Ġ= Ġmax Delay Millis Ġ- ĠRandom . next Long ( 1 0 0 0 L ) Ġ// Ġinclude Ġj itter Ġbut Ġdon 't Ġexceed Ġmax Ġdelay ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsequence Ġ/= Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtw ig (" Failed Ġdue Ġto Ġ$ t Ġcaused Ġby Ġ${ t . cause } Ġbacking Ġoff Ġand Ġretry ing Ġin Ġ${ duration } ms ...") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtw ig ( t ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( duration ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠReturn Ġtrue Ġif Ġthe Ġgiven Ġdatabase Ġalready Ġexists . Ċ Ġ* Ċ Ġ* Ġ@ return Ġtrue Ġwhen Ġthe Ġgiven Ġdatabase Ġexists Ġin Ġthe Ġgiven Ġcontext . Ċ Ġ*/ Ċ internal Ġfun Ġdb Exists ( app Context : ĠContext , Ġdb FileName : ĠString ): ĠBoolean Ġ{ ĊĠĠĠ Ġreturn ĠFile ( app Context . get Database Path ( db FileName ). absolute Path ). exists () Ċ } Ċ