package Ġsoftware . ting le . api . authentication Ċ Ċ import Ġandroid . util . Log Ċ import Ġcom . google . firebase . auth . Firebase Auth Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . delay Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġkotlinx . coroutines . tasks . await Ċ import Ġokhttp 3 . Request Ċ import Ġjava . util .* Ċ Ċ open Ġclass ĠFirebase Authentication Provider Ġ: ĠAuthentication Header Provider () Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAuthor ize Ġa Ġrequest Ġbefore Ġexecuting ĊĠĠĠĠ Ġ* Ġ@ param Ġrequest Ġthe Ġrequest Ġmessage Ġto Ġbe Ġauthorized ĊĠĠĠĠ Ġ* Ġ@ return Ġthe Ġparameter ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġget Parameter ( request : ĠRequest . Builder ): ĠString Ġ{ ĊĊĠĠĠĠĠĠĠ Ġvar ĠaccessToken : ĠString ĊĠĠĠĠĠĠĠ Ġrun Blocking ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠaccessToken Ġ= Ġacquire AccessToken () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠaccessToken ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġacquire AccessToken (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġbackoff Ġ= Ġ( BACK OFF _ MILLI _ SECONDS Ġ+ Ġs Random . nextInt ( 1 0 0 0 )). to Long () ĊĠĠĠĠĠĠĠ Ġval Ġuser Ġ= ĠFirebase Auth . getInstance (). currentUser Ġ?: Ġreturn Ġ"" ĊĠĠĠĠĠĠĠ Ġval Ġtoken Task Ġ= Ġuser . getId Token ( false ) ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 1 .. MAX _ AT TEMP TS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Attempt Ġ#$ i Ġto Ġacquire ĠFirebase ĠAuth ĠToken ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtoken Task . await () Ġ// Ġmake Ġthe Ġthe Ġtoken Ġrequest Ġand Ġwait Ġfor Ġthe Ġresults ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( token Task . is Successful ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtoken Task . result ?. token ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġ"" Ġ// ĠWe Ġare Ġdone Ġhere , Ġthe Ġresult Ġwas Ġsuccessful ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Failed Ġto Ġacquire Ġauth Ġcode Ġon Ġattempt Ġ#$ i Ġ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( i Ġ== ĠMAX _ AT TEMP TS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . v ( TAG , Ġ" Sleep ing Ġfor Ġ$ backoff Ġms Ġbefore Ġretry ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( backoff ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e 1 : ĠInterruptedException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfinished Ġbefore Ġwe Ġcomplete Ġ- Ġexit . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Thread Ġinterrupted : Ġabort Ġremaining Ġretries !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . currentThread (). interrupt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġincrease Ġbackoff Ġexponent ially ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbackoff Ġ*= Ġ 2 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ"" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠTAG Ġ= ĠFirebase Authentication Provider :: class . simple Name ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ AT TEMP TS Ġ= Ġ 3 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠBACK OFF _ MILLI _ SECONDS Ġ= Ġ 2 0 0 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġs Random Ġ= ĠRandom () ĊĠĠĠ Ġ} Ċ }