/* Ċ Ġ* ĠSPDX - File Copyright Text : Ġ 2 0 2 0 , Ġmicro G ĠProject ĠTeam Ċ Ġ* ĠSPDX - License - Identifier : ĠApache - 2 . 0 Ċ Ġ*/ Ċ Ċ package Ġorg . micro g . gms . near by . ex posure notification Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . app . Pending Intent Ċ import Ġandroid . bluetooth . Bluetooth Adapter Ċ import Ġandroid . content .* Ċ import Ġandroid . location . Location Manager Ċ import Ġandroid . os .* Ċ import Ġandroid . util . Base 6 4 Ċ import Ġandroid . util . Log Ċ import Ġandroidx . core . location . Location Manager Compat Ċ import Ġandroidx . lifecycle . Lifecycle Ċ import Ġandroidx . lifecycle . Lifecycle Coroutine Scope Ċ import Ġandroidx . lifecycle . Lifecycle Owner Ċ import Ġandroidx . lifecycle . lifecycle Scope Ċ import Ġcom . google . android . gms . common . api . Status Ċ import Ġcom . google . android . gms . near by . ex posure notification .* Ċ import Ġcom . google . android . gms . near by . ex posure notification . Exposure Notification StatusCode s .* Ċ import Ġcom . google . android . gms . near by . ex posure notification . internal .* Ċ import Ġkotlinx . coroutines .* Ċ import Ġorg . json . JSONArray Ċ import Ġorg . json . JSONObject Ċ import Ġorg . micro g . gms . common . Package Utils Ċ import Ġorg . micro g . gms . near by . ex posure notification . Constants .* Ċ import Ġorg . micro g . gms . near by . ex posure notification . proto . TE K Signature List Ċ import Ġorg . micro g . gms . near by . ex posure notification . proto . Temporary Exposure Key Export Ċ import Ġorg . micro g . gms . near by . ex posure notification . proto . Temporary Exposure Key Proto Ċ import Ġorg . micro g . gms . utils . warn On Transaction Issues Ċ import Ġjava . io . File Ċ import Ġjava . io . InputStream Ċ import Ġjava . security . Key Factory Ċ import Ġjava . security . Message Digest Ċ import Ġjava . security . Signature Ċ import Ġjava . security . spec . X 5 0 9 Encoded KeySpec Ċ import Ġjava . util . zip . Zip Entry Ċ import Ġjava . util . zip . Zip File Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . round ToInt Ċ import Ġkotlin . random . Random Ċ Ċ class ĠEx posure Notification ServiceImpl ( private Ġval Ġcontext : ĠContext , Ġprivate Ġval Ġlifecycle : ĠLifecycle , Ġprivate Ġval ĠpackageName : ĠString ) Ġ: ĠIN ear by Exposure Notification Service . Stub (), ĠLifecycle Owner Ġ{ ĊĊĠĠĠ Ġ// ĠTable Ġof Ġback - end Ġpublic Ġkeys , Ġused Ġto Ġverify Ġthe Ġsignature Ġof Ġthe Ġdiag no sed ĠT EK s . ĊĠĠĠ Ġ// ĠThe Ġtable Ġis Ġindexed Ġby Ġpackage Ġnames . ĊĠĠĠ Ġprivate Ġval Ġbackend PubKey For Package Ġ= Ġmap Of < String , ĠString >( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" ch . admin . bag . dp 3 t . dev " Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" MF kw E wY HK o Z Iz j 0 CA QY IK o Z Iz j 0 DA Qc DQ g AE s Fc En OP Y 4 AO AK k pv 9 HS d W 2 Br h UC Ww L 1 5 Hp qu 5 z H aW y 1 Wno 2 KR 8 G 6 d Y J 8 QO 0 uZ u 1 M 6 j 8 z 6 NG XF V Z cp w 7 t Ye XA q Q ==", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" ch . admin . bag . dp 3 t . test " Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" MF kw E wY HK o Z Iz j 0 CA QY IK o Z Iz j 0 DA Qc DQ g AE s Fc En OP Y 4 AO AK k pv 9 HS d W 2 Br h UC Ww L 1 5 Hp qu 5 z H aW y 1 Wno 2 KR 8 G 6 d Y J 8 QO 0 uZ u 1 M 6 j 8 z 6 NG XF V Z cp w 7 t Ye XA q Q ==", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" ch . admin . bag . dp 3 t . ab nah me " Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" MF kw E wY HK o Z Iz j 0 CA QY IK o Z Iz j 0 DA Qc DQ g AE s Fc En OP Y 4 AO AK k pv 9 HS d W 2 Br h UC Ww L 1 5 Hp qu 5 z H aW y 1 Wno 2 KR 8 G 6 d Y J 8 QO 0 uZ u 1 M 6 j 8 z 6 NG XF V Z cp w 7 t Ye XA q Q ==", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" ch . admin . bag . dp 3 t " Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" MF kw E wY HK o Z Iz j 0 CA QY IK o Z Iz j 0 DA Qc DQ g AE K 2 k 9 n Z 8 gu o 7 JP 2 EL P QX n Uk q Dy jj Jm Y mpt 9 Zy 0 HP si G XC dI 3 SF m Lr 2 0 4 K Nz ku IT pp NV 5 P 7 + b XR x ii Y 0 4 NM r E IT g ==", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠC WA , Ġsee Ġhttps :// github . com / cor ona - warn - app / c wa - documentation / issues / 7 4 0 # issuecomment - 9 6 3 2 2 3 0 7 4 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . r ki . cor on aw arn app " Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" MF kw E wY HK o Z Iz j 0 CA QY IK o Z Iz j 0 DA Qc DQ g AE c 7 DE stc UI R cy k 3 5 OY DJ 9 5 / h Tg 3 UV h sa DX KT 0 z K 7 Nh HP X oy zip En Op 3 Gy NX DV pa Pi 3 c Af Qm xe u FM Z AI X 2 + 6 A 5 Xg ==", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠC CT G Ġuses ĠC WA Ġin fr ast uct ure ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . cor ona . tracing " Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" MF kw E wY HK o Z Iz j 0 CA QY IK o Z Iz j 0 DA Qc DQ g AE c 7 DE stc UI R cy k 3 5 OY DJ 9 5 / h Tg 3 UV h sa DX KT 0 z K 7 Nh HP X oy zip En Op 3 Gy NX DV pa Pi 3 c Af Qm xe u FM Z AI X 2 + 6 A 5 Xg ==", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠC CT G - Test Ġbuilds Ġdon 't Ġhave Ġaccess Ġany Ġstaging Ġinfrastructure , Ġso Ġagain ĠC WA Ġkey ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . cor ona . tracing . test " Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" MF kw E wY HK o Z Iz j 0 CA QY IK o Z Iz j 0 DA Qc DQ g AE c 7 DE stc UI R cy k 3 5 OY DJ 9 5 / h Tg 3 UV h sa DX KT 0 z K 7 Nh HP X oy zip En Op 3 Gy NX DV pa Pi 3 c Af Qm xe u FM Z AI X 2 + 6 A 5 Xg ==", ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġ// ĠBack - end Ġpublic Ġkey Ġfor Ġthis Ġpackage ĊĠĠĠ Ġprivate Ġval Ġbackend PublicKey Ġ= Ġbackend PubKey For Package [ packageName ]?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠKey Factory . getInstance (" EC "). generate Public ( X 5 0 9 Encoded KeySpec ( Base 6 4 . decode ( it , ĠBase 6 4 . DEFAULT ))) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Failed Ġto Ġretrieve Ġback - end Ġpublic Ġkey Ġfor Ġ${ packageName }: Ġ" Ġ+ Ġe . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠTable Ġof Ġsupported Ġsignature Ġalgorithms Ġfor Ġthe Ġdiag no sed ĠT EK s . ĊĠĠĠ Ġ// ĠThe Ġtable Ġis Ġindexed Ġby ĠASN . 1 ĠO IDs Ġas Ġspecified Ġin Ġhttps :// tools . ietf . org / html / rfc 5 7 5 8 # section - 3 . 2 ĊĠĠĠ Ġprivate Ġval Ġsig Algo For Oid Ġ= Ġmap Of < String , ĠFunction 0 < Signature >>( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" 1 . 2 . 8 4 0 . 1 0 0 4 5 . 4 . 3 . 2 " Ġto Ġ{ ĠSignature . getInstance (" SHA 2 5 6 with ECD SA ") Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" 1 . 2 . 8 4 0 . 1 0 0 4 5 . 4 . 3 . 4 " Ġto Ġ{ ĠSignature . getInstance (" SHA 5 1 2 with ECD SA ") Ġ}, ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġfun ĠLifecycle Coroutine Scope . launch S af ely ( block : Ġsuspend ĠCor outine Scope . () Ġ-> ĠUnit ): ĠJob Ġ= Ġlaunch When Started Ġ{ Ġtry Ġ{ Ġblock () Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĠLog . w ( TAG , Ġ" Error Ġin Ġcoroutine ", Ġe ) Ġ} Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Lifecycle (): ĠLifecycle Ġ= Ġlifecycle ĊĊĠĠĠ Ġprivate Ġfun Ġpending Confirm ( permission : ĠString ): ĠPending Intent Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġintent Ġ= ĠIntent ( ACTION _ CONFIRM ) ĊĠĠĠĠĠĠĠ Ġintent .` package ` Ġ= Ġcontext . packageName ĊĠĠĠĠĠĠĠ Ġintent . putExtra ( KEY _ CONFIRM _ PACKAGE , ĠpackageName ) ĊĠĠĠĠĠĠĠ Ġintent . putExtra ( KEY _ CONFIRM _ ACTION , Ġpermission ) ĊĠĠĠĠĠĠĠ Ġintent . putExtra ( KEY _ CONFIRM _ RECE IVER , Ġobject Ġ: ĠResult Receiver ( null ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Receive Result ( result Code : ĠInt , Ġresult Data : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Code Ġ== ĠActivity . RESULT _ OK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtemp Granted Permissions . add ( packageName Ġto Ġpermission ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġintent . component Ġ= ĠComponent Name ( context , Ġcontext . package Manager . resolve Activity ( intent , Ġ 0 )?. activity Info ?. name !! ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġe ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Pending : Ġ$ intent ") ĊĠĠĠĠĠĠĠ Ġval Ġpi Ġ= ĠPending Intent . getActivity ( context , Ġpermission . hashCode (), Ġintent , ĠPending Intent . FLAG _ ONE _ SHOT ) ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Pending : Ġ$ pi ") ĊĠĠĠĠĠĠĠ Ġreturn Ġpi ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhas Confirm Activity (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġintent Ġ= ĠIntent ( ACTION _ CONFIRM ) ĊĠĠĠĠĠĠĠ Ġintent .` package ` Ġ= Ġcontext . packageName ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . package Manager . resolve Activity ( intent , Ġ 0 ) Ġ!= Ġnull ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġconfirm Permission ( permission : ĠString , Ġforce : ĠBoolean Ġ= Ġfalse ): ĠStatus Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtemp Granted Permissions . contains ( packageName Ġto Ġpermission ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . grant Permission ( packageName , ĠPackage Utils . first Signature Digest ( context , ĠpackageName ) !! , Ġpermission ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtemp Granted Permissions . remove ( packageName Ġto Ġpermission ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStatus . SUCCESS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ! force Ġ&& Ġdatabase . has Permission ( packageName , ĠPackage Utils . first Signature Digest ( context , ĠpackageName ) !! , Ġpermission ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStatus . SUCCESS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ! has Confirm Activity () Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStatus . SUCCESS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStatus ( RESOL UTION _ REQUIRED , Ġ" Permission ĠEN #$ permission Ġrequired .", Ġpending Confirm ( permission )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Version ( params : ĠGet Version Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , ĠVERSION _ FULL ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Calibration Confidence ( params : ĠGet Calibration Confidence Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , Ġcurrent DeviceInfo . confidence ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġstart ( params : ĠStart Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Authorized Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġit . is App Authorized ( packageName ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġadapter Ġ= ĠBluetooth Adapter . getDefault Adapter () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatus Ġ= Ġif Ġ( is Authorized Ġ&& ĠEx posure Preferences ( context ). enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStatus . SUCCESS ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( adapter Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStatus ( FAILED _ NOT _ SUPPORTED , Ġ" No ĠBluetooth ĠAdapter Ġavailable .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatus Ġ= Ġconfirm Permission ( CONFIRM _ ACTION _ START , Ġ! adapter . isEnabled ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( status . is Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= Ġcontext ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadapter . enable Async ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Preferences ( context ). enabled Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . authorize App ( packageName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" start ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatus ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( status ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġstop ( params : ĠStop Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Authorized Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . is App Authorized ( packageName ). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it ) Ġdatabase . note App Action ( packageName , Ġ" stop ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Authorized ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Preferences ( context ). enabled Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġis Enabled ( params : ĠIs Enabled Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Authorized Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . is App Authorized ( packageName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , Ġis Authorized Ġ&& ĠEx posure Preferences ( context ). enabled ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Temporary Exposure Key History ( params : ĠGet Temporary Exposure Key History Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatus Ġ= Ġconfirm Permission ( CONFIRM _ ACTION _ KEYS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatus . is Success Ġ-> ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . authorize App ( packageName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . export Keys () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġempty List () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" get Temporary Exposure Key History ", ĠJSONObject (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" result ", Ġstatus . statusCode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" response _ keys _ size ", Ġresponse . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( status , Ġresponse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠTemporary Exposure Key Proto . to Key (): ĠTemporary Exposure Key Ġ= ĠTemporary Exposure Key . Temporary Exposure Key Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Key Data ( key _ data ?. toByteArray () Ġ?: Ġthrow ĠIllegalArgumentException (" key Ġdata Ġmissing ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Rol ling Start Interval Number ( rolling _ start _ interval _ number ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIllegalArgumentException (" rolling Ġstart Ġinterval Ġnumber Ġmissing ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Rol ling Period ( rolling _ period Ġ?: Ġthrow ĠIllegalArgumentException (" rolling Ġperiod Ġmissing ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Trans mission Risk Level ( transmission _ risk _ level Ġ?: Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġprivate Ġfun ĠInputStream . copy ToFile ( outputFile : ĠFile ) Ġ{ ĊĠĠĠĠĠĠĠ ĠoutputFile . output Stream (). use Ġ{ Ġoutput Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcopy To ( output ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . flush () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠMessage Digest . digest ( file : ĠFile ): ĠByteArray Ġ= Ġfile . inputStream (). use Ġ{ Ġinput Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġbuf Ġ= ĠByteArray ( 4 0 9 6 ) ĊĠĠĠĠĠĠĠ Ġvar Ġbytes Ġ= Ġinput . read ( buf ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( bytes Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate ( buf , Ġ 0 , Ġbytes ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbytes Ġ= Ġinput . read ( buf ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdigest () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠEx posure Configuration ?. or Default () Ġ= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠEx posure Configuration . Exposure Configuration Builder (). build () ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġbuild Exposure Summary ( token : ĠString ): ĠEx posure Summary Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ(! database . is App Authorized ( packageName )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNot Ġproviding Ġsummary Ġif Ġapp Ġnot Ġauthorized ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ"$ packageName Ġnot Ġyet Ġauthorized ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with ĠEx posure Summary . Exposure Summary Builder (). build () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġpair Ġ= Ġdatabase . load Configuration ( packageName , Ġtoken ) ĊĠĠĠĠĠĠĠ Ġval Ġ( configuration , Ġex pos ures ) Ġ= Ġif Ġ( pair Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpair . second . or Default () Ġto Ġdatabase . findAll Measured Ex pos ures ( pair . first ). merge () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Configuration . Exposure Configuration Builder (). build () Ġto Ġempty List () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠEx posure Summary . Exposure Summary Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Days Since Last Exposure ( ex pos ures . map Ġ{ Ġit . days Since Exposure Ġ}. min OrNull ()?. toInt () Ġ?: Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Matched Key Count ( ex pos ures . map Ġ{ Ġit . key Ġ}. distinct (). size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setMaximum Risk Score ( ex pos ures . map Ġ{ Ġit . get Risk Score ( configuration ) Ġ}. max OrNull ()?. toInt () Ġ?: Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Att enuation Dur ations ( int ArrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġex pos ures . map Ġ{ Ġit . get Att enuation Dur ations ( configuration )[ 0 ] Ġ}. sum (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġex pos ures . map Ġ{ Ġit . get Att enuation Dur ations ( configuration )[ 1 ] Ġ}. sum (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġex pos ures . map Ġ{ Ġit . get Att enuation Dur ations ( configuration )[ 2 ] Ġ}. sum () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Sum m ation Risk Score ( ex pos ures . map Ġ{ Ġit . get Risk Score ( configuration ) Ġ}. sum ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġprovide Di agnosis Keys ( params : ĠProvide Di agnosis Keys Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġparams . token Ġ?: ĠTOKEN _ A ĊĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" provide Di agnosis Keys () Ġwith Ġ$ packageName /$ token ") ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtid Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconfiguration Ġ= Ġparams . configuration ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( configuration Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . store Configuration ( packageName , Ġtoken , Ġconfiguration ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . get OrCreate Token Id ( packageName , Ġtoken ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( tid Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Unknown Ġtoken Ġwithout Ġconfiguration : Ġ$ packageName /$ token ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . INTERNAL _ ERROR ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ launch S af ely ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstart Ġ= ĠSystem . currentTimeMillis () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġkeys ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . keys ?. let Ġ{ Ġdatabase . batch Store Single Di agnosis Key ( tid , Ġit ) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġkeys Ġ= Ġparams . keys ?. size Ġ?: Ġ 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠKey Ġfiles ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtodo Key Files Ġ= Ġarray ListOf < Pair < File , ĠByteArray >>() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( file Ġin Ġparams . key Files . or Empty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcache File Ġ= ĠFile ( context . cacheDir , Ġ" en - key file -${ System . currentTimeMillis ()} -${ Random . nextInt ()}. zip ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠParcel FileDescriptor . Auto Close InputStream ( file ). use Ġ{ Ġit . copy ToFile ( cache File ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhash Ġ= ĠMessage Digest . getInstance (" SHA - 2 5 6 "). digest ( cache File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstored Keys Ġ= Ġdatabase . store Di agnosis File Used ( tid , Ġhash ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stored Keys Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkeys Ġ+= Ġstored Keys . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache File . delete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtodo Key Files . add ( cache File Ġto Ġhash ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Failed Ġparsing Ġfile ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . key File Supplier ?. let Ġ{ Ġkey File Supplier Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Using Ġkey Ġfile Ġsupplier ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( key File Supplier . is Available Ġ&& Ġkey File Supplier . hasNext ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcache File Ġ= ĠFile ( context . cacheDir , Ġ" en - key file -${ System . currentTimeMillis ()} -${ Random . next Long ()}. zip ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠParcel FileDescriptor . Auto Close InputStream ( key File Supplier . next ()). use Ġ{ Ġit . copy ToFile ( cache File ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhash Ġ= ĠMessage Digest . getInstance (" SHA - 2 5 6 "). digest ( cache File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstored Keys Ġ= Ġdatabase . store Di agnosis File Used ( tid , Ġhash ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stored Keys Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkeys Ġ+= Ġstored Keys . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache File . delete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtodo Key Files . add ( cache File Ġto Ġhash ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Failed Ġparsing Ġfile ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Disconnected Ġfrom Ġkey Ġfile Ġsupplier ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( todo Key Files . size Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtime Ġ= Ġ( System . currentTimeMillis () Ġ- Ġstart ). coerce At Least ( 1 ). toDouble () Ġ/ Ġ 1 0 0 0 . 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ"$ packageName /$ token Ġprocessed Ġ$ keys Ġkeys Ġ(${ todo Key Files . size } Ġfiles Ġpending ) Ġin Ġ${ time } s Ġ-> Ġ${ ( keys . toDouble () Ġ/ Ġtime Ġ* Ġ 1 0 0 0 ). round ToInt (). toDouble () Ġ/ Ġ 1 0 0 0 . 0 } Ġkeys / s ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHandler ( Looper . get Main Looper ()). post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnew Keys Ġ= Ġif Ġ( params . keys Ġ!= Ġnull ) Ġdatabase . finish Single Matching ( tid ) Ġelse Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( cache File , Ġhash ) Ġin Ġtodo Key Files ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( backend PublicKey Ġ!= Ġnull Ġ&& Ġ! verify Key File ( cache File )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Skipping Ġnon - verified Ġkey Ġfile ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with Context ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠZip File ( cache File ). use Ġ{ Ġzip Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( entry Ġin Ġzip . entries ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entry . name Ġ== Ġ" export . bin ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstream Ġ= Ġzip . getInputStream ( entry ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprefix Ġ= ĠByteArray ( 1 6 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġtotal Bytes Read Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġbytes Read Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( bytes Read Ġ!= Ġ- 1 Ġ&& Ġtotal Bytes Read Ġ< Ġprefix . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbytes Read Ġ= Ġstream . read ( prefix , Ġtotal Bytes Read , Ġprefix . size Ġ- Ġtotal Bytes Read ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( bytes Read Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtotal Bytes Read Ġ+= Ġbytes Read ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( total Bytes Read Ġ== Ġprefix . size Ġ&& ĠString ( prefix ). trim () Ġ== Ġ" EK ĠExport Ġv 1 ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexport Ġ= ĠTemporary Exposure Key Export . ADAPTER . decode ( stream ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . finish File Matching ( tid , Ġhash , Ġexport . end _ timestamp ?. let Ġ{ Ġit Ġ* Ġ 1 0 0 0 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠSystem . currentTimeMillis (), Ġexport . keys . map Ġ{ Ġit . to Key () Ġ}, Ġexport . rev ised _ keys . map Ġ{ Ġit . to Key () Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkeys Ġ+= Ġexport . keys . size Ġ+ Ġexport . rev ised _ keys . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Keys Ġ+= Ġexport . keys . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" export . bin Ġhad Ġinvalid Ġprefix ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache File . delete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Failed Ġparsing Ġfile ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtime Ġ= Ġ( System . currentTimeMillis () Ġ- Ġstart ). coerce At Least ( 1 ). toDouble () Ġ/ Ġ 1 0 0 0 . 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ"$ packageName /$ token Ġprocessed Ġ$ keys Ġkeys Ġ($ new Keys Ġnew ) Ġin Ġ${ time } s Ġ-> Ġ${ ( keys . toDouble () Ġ/ Ġtime Ġ* Ġ 1 0 0 0 ). round ToInt (). toDouble () Ġ/ Ġ 1 0 0 0 . 0 } Ġkeys / s ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" provide Di agnosis Keys ", ĠJSONObject (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" request _ token ", Ġtoken ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" request _ keys _ size ", Ġparams . keys ?. size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" request _ key Files _ size ", Ġparams . key Files ?. size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" request _ keys _ count ", Ġkeys ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toString ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! database . is App Authorized ( packageName )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNot Ġsending Ġresults Ġvia Ġbroadcast Ġif Ġapp Ġnot Ġauthorized ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ"$ packageName Ġnot Ġyet Ġauthorized ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexposure Summary Ġ= Ġbuild Exposure Summary ( token ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintent Ġ= Ġif Ġ( ex posure Summary . matched Key Count Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent ( ACTION _ EX POS URE _ STATE _ UPDATED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent ( ACTION _ EX POS URE _ NOT _ FOUND ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( token Ġ!= ĠTOKEN _ A ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent . putExtra ( EXTRA _ EX POS URE _ SUM MARY , Ġexposure Summary ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent . putExtra ( EXTRA _ TOKEN , Ġtoken ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent .` package ` Ġ= ĠpackageName ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Sending Ġ$ intent ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . send Ordered Broadcast ( intent , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġverify Key File ( file : ĠFile ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠZip File ( file ). use Ġ{ Ġzip Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġdata Entry : ĠZip Entry ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġsig Entry : ĠZip Entry ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( entry Ġin Ġzip . entries ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( entry . name ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" export . bin " Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( data Entry Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠException (" Zip Ġarchive Ġcontains Ġmore Ġthan Ġone Ġ' export . bin ' Ġentry ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Entry Ġ= Ġentry ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" export . sig " Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sig Entry Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠException (" Zip Ġarchive Ġcontains Ġmore Ġthan Ġone Ġ' export . sig ' Ġentry ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsig Entry Ġ= Ġentry ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠException (" Unexpected Ġentry Ġin Ġzip Ġarchive : Ġ${ entry . name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Entry Ġ== Ġnull Ġ-> Ġthrow ĠException (" Zip Ġarchive Ġdoes Ġnot Ġcontain Ġ' export . bin '") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsig Entry Ġ== Ġnull Ġ-> Ġthrow ĠException (" Zip Ġarchive Ġdoes Ġnot Ġcontain Ġ' export . sin '") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsig Stream Ġ= Ġzip . getInputStream ( sig Entry ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsig List Ġ= ĠT EK Signature List . ADAPTER . decode ( sig Stream ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( sig Ġin Ġsig List . signatures ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Verify ing Ġsignature Ġ${ sig . batch _ num }/${ sig . batch _ size }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsig Info Ġ= Ġsig . signature _ info Ġ?: Ġthrow ĠException (" Signature Ġinformation Ġis Ġmissing ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Signature Ġinfo : Ġalgo =${ sig Info . signature _ algorithm } Ġkey ={ id =${ sig Info . verification _ key _ id }, Ġversion =${ sig Info . verification _ key _ version }} ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsignature Ġ= Ġsig . signature ?. toByteArray () Ġ?: Ġthrow ĠException (" Signature Ġcontents Ġis Ġmissing ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsig Verifier Ġ= Ġ( sig Algo For Oid . get ( sig Info . signature _ algorithm ) Ġ?: Ġthrow ĠException (" Signature Ġalgorithm Ġnot Ġsupported : Ġ${ sig Info . signature _ algorithm } ")) () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsig Verifier . init Verify ( backend PublicKey ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstream Ġ= Ġzip . getInputStream ( data Entry ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuf Ġ= ĠByteArray ( 1 0 2 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnb Read Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( nb Read Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnb Read Ġ= Ġstream . read ( buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( nb Read Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsig Verifier . update ( buf , Ġ 0 , Ġnb Read ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! sig Verifier . verify ( signature )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠException (" Signature Ġdoes Ġnot Ġverify ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Key Ġfile Ġverification Ġfailed : Ġ" Ġ+ Ġe . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Key Ġfile Ġverification Ġsuccessful ") ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Exposure Summary ( params : ĠGet Exposure Summary Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġbuild Exposure Summary ( params . token ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" get Exposure Summary ", ĠJSONObject (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" request _ token ", Ġparams . token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" response _ days _ since ", Ġresponse . days Since Last Exposure ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" response _ matched _ keys ", Ġresponse . matched Key Count ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" response _ max _ risk ", Ġresponse . maximum Risk Score ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" response _ att enuation _ dur ations ", ĠJSONArray (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . att enuation Dur ations In Minutes . forEach Ġ{ Ġput ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" response _ sum m ation _ risk ", Ġresponse . sum m ation Risk Score ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , Ġresponse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Exposure Information ( params : ĠGet Exposure Information Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpair Ġ= Ġdatabase . load Configuration ( packageName , Ġparams . token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġif Ġ( pair Ġ!= Ġnull Ġ&& Ġdatabase . is App Authorized ( packageName )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . findAll Measured Ex pos ures ( pair . first ). merge (). map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . to Exposure Information ( pair . second . or Default ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNot Ġproviding Ġinformation Ġif Ġapp Ġnot Ġauthorized ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ"$ packageName Ġnot Ġyet Ġauthorized ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġempty List () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" get Exposure Information ", ĠJSONObject (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" request _ token ", Ġparams . token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" response _ size ", Ġresponse . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , Ġresponse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠScan Instance . Builder . apply ( sub Exposure : ĠMerged Sub Exposure ): ĠScan Instance . Builder Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Seconds Since Last Scan ( sub Exposure . duration . coerce At Most ( 5 Ġ* Ġ 6 0 ). toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Min Att enuation Db ( sub Exposure . att enuation ) Ġ// ĠFIXME : ĠWe Ġuse Ġthe Ġaverage Ġfor Ġboth , Ġbecause Ġwe Ġdon 't Ġstore Ġthe Ġminimum Ġatt enuation Ġyet ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Typ ical Att enuation Db ( sub Exposure . att enuation ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠList < Merged Sub Exposure >. to Scan Instances (): ĠList < Scan Instance > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġarray ListOf < Scan Instance >() ĊĠĠĠĠĠĠĠ Ġfor Ġ( sub Exposure Ġin Ġthis ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġres . add ( Scan Instance . Builder (). apply ( sub Exposure ). build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sub Exposure . duration Ġ> Ġ 5 Ġ* Ġ 6 0 Ġ* Ġ 1 0 0 0 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġres . add ( Scan Instance . Builder (). apply ( sub Exposure ). set Seconds Since Last Scan (( sub Exposure . duration Ġ- Ġ 5 Ġ* Ġ 6 0 ). coerce At Most ( 5 Ġ* Ġ 6 0 ). toInt ()). build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġres ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠDi agnosis Keys Data Mapping ?. or Default () Ġ= Ġthis Ġ?: ĠDi agnosis Keys Data Mapping () ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġget Exposure Windows Internal ( token : ĠString Ġ= ĠTOKEN _ A ): ĠList < Exposure Window > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( ex pos ures , Ġmapping ) Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtriple Ġ= Ġdatabase . load Configuration ( packageName , Ġtoken ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( triple Ġ!= Ġnull Ġ&& Ġdatabase . is App Authorized ( packageName )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . findAll Measured Ex pos ures ( triple . first ). merge () Ġto Ġtriple . third . or Default () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNot Ġproviding Ġwindows Ġif Ġapp Ġnot Ġauthorized ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ"$ packageName Ġnot Ġyet Ġauthorized ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġempty List < Merged Exposure >() Ġto ĠDi agnosis Keys Data Mapping () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġex pos ures . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinf ect ious ness Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . key . days Since On set Of Sy mptoms Ġ== ĠDAY S _ SIN CE _ ON SET _ OF _ SY MP TO MS _ UNKNOWN ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmapping . inf ect ious ness When Days Since On set Missing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmapping . days Since On set To Inf ect ious ness [ it . key . days Since On set Of Sy mptoms ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠIn fect ious ness . NONE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreport Type Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . key . report Type Ġ== ĠReport Type . UNKNOWN ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmapping . report Type When Missing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . key . report Type ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Window . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Calibration Confidence ( it . confidence ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setDate Millis Since Epoch ( it . key . rolling Start Interval Number . to Long () Ġ* ĠR OL LING _ WINDOW _ LENGTH _ MS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Inf ect ious ness ( inf ect ious ness ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Report Type ( report Type ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Scan Instances ( it . subs . to Scan Instances ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Exposure Windows ( params : ĠGet Exposure Windows Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġget Exposure Windows Internal ( params . token Ġ?: ĠTOKEN _ A ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" get Exposure Windows ", ĠJSONObject (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" request _ token ", Ġparams . token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" response _ size ", Ġresponse . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , Ġresponse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠDaily Sum maries Config . bucket For ( att enuation : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( att enuation Ġ< Ġatt enuation Bucket Threshold Db [ 0 ]) Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠ Ġif Ġ( att enuation Ġ< Ġatt enuation Bucket Threshold Db [ 1 ]) Ġreturn Ġ 1 ĊĠĠĠĠĠĠĠ Ġif Ġ( att enuation Ġ< Ġatt enuation Bucket Threshold Db [ 2 ]) Ġreturn Ġ 2 ĊĠĠĠĠĠĠĠ Ġreturn Ġ 3 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠDaily Sum maries Config . weighted Duration For ( att enuation : ĠInt , Ġseconds : ĠInt ): ĠDouble Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġatt enuation Bucket Weights [ bucket For ( att enuation )] Ġ* Ġseconds ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠCollection < Daily Summary . Exposure Summary Data >. sum (): ĠDaily Summary . Exposure Summary Data Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠDaily Summary . Exposure Summary Data ( map Ġ{ Ġit . maximum Score Ġ}. max OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġ 0 . 0 , Ġsum By Double Ġ{ Ġit . score Sum Ġ}, Ġsum By Double Ġ{ Ġit . weighted Duration Sum Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Daily Sum maries ( params : ĠGet Daily Sum maries Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġget Exposure Windows Internal (). groupBy Ġ{ Ġit . date Millis Since Epoch Ġ}. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmap Ġ= Ġarray ListOf < Daily Summary . Exposure Summary Data >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil ĠReport Type . VALUES ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmap [ i ] Ġ= ĠDaily Summary . Exposure Summary Data ( 0 . 0 , Ġ 0 . 0 , Ġ 0 . 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( entry Ġin Ġit . value . groupBy Ġ{ Ġit . report Type Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( window Ġin Ġentry . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġweighted Duration Ġ= Ġwindow . scan Instances . map Ġ{ Ġparams . config . weighted Duration For ( it . typ ical Att enuation Db , Ġit . seconds Since Last Scan ) Ġ}. sum () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscore Ġ= Ġ( params . config . report Type Weights [ window . report Type ] Ġ?: Ġ 1 . 0 ) Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( params . config . inf ect ious ness Weights [ window . inf ect ious ness ] Ġ?: Ġ 1 . 0 ) Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġweighted Duration ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( score Ġ>= Ġparams . config . minimum Window Score ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmap [ entry . key ] Ġ= ĠDaily Summary . Exposure Summary Data ( max ( map [ entry . key ]. maximum Score , Ġscore ), Ġmap [ entry . key ]. score Sum Ġ+ Ġscore , Ġmap [ entry . key ]. weighted Duration Sum Ġ+ Ġweighted Duration ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDaily Summary (( it . key Ġ/ Ġ( 1 0 0 0 L Ġ* Ġ 6 0 Ġ* Ġ 6 0 Ġ* Ġ 2 4 )). toInt (), Ġmap , Ġmap . sum ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" get Daily Sum maries ", ĠJSONObject (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" response _ size ", Ġresponse . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , Ġresponse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġset Di agnosis Keys Data Mapping ( params : ĠSet Di agnosis Keys Data Mapping Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . store Configuration ( packageName , ĠTOKEN _ A , Ġparams . mapping ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" set Di agnosis Keys Data Mapping ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Di agnosis Keys Data Mapping ( params : ĠGet Di agnosis Keys Data Mapping Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmapping Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtriple Ġ= Ġdatabase . load Configuration ( packageName , ĠTOKEN _ A ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" get Di agnosis Keys Data Mapping ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtriple ?. third ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , Ġmapping . or Default ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Package Configuration ( params : ĠGet Package Configuration Params ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Not Ġyet Ġimplemented : Ġget Package Configuration ") ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" get Package Configuration ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , ĠPackage Configuration . Package Configuration Builder (). set Values ( Bundle . EMPTY ). build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠgetStatus ( params : ĠGet Status Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Authorized Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" getStatus ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . is App Authorized ( packageName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġflags Ġ= Ġhash Set Of < Exposure Notification Status >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġadapter Ġ= ĠBluetooth Adapter . getDefault Adapter () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( adapter Ġ== Ġnull Ġ|| Ġ! adapter . isEnabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags . add ( Exposure Notification Status . BL U ETO OTH _ DISABLED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags . add ( Exposure Notification Status . BL U ETO OTH _ SUPPORT _ UNKNOWN ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( Build . VERSION . SDK _ INT Ġ< Ġ 2 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags . add ( Exposure Notification Status . EN _ NOT _ SUPPORT ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( adapter . bluetooth Le Scanner Ġ== Ġnull ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags . add ( Exposure Notification Status . HW _ NOT _ SUPPORT ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! Location Manager Compat . is Location Enabled ( context . getSystem Service ( Context . LOCATION _ SERVICE ) Ġas ĠLocation Manager )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags . add ( Exposure Notification Status . LOCATION _ DISABLED ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Authorized ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags . add ( Exposure Notification Status . NO _ CON SENT ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Authorized Ġ&& ĠEx posure Preferences ( context ). enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags . add ( Exposure Notification Status . ACTIV ATED ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags . add ( Exposure Notification Status . IN ACTIV ATED ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , ĠEx posure Notification Status . set To Flags ( flags )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġrequest Pre Authorized Temporary Exposure Key History ( params : ĠRequest Pre Authorized Temporary Exposure Key History Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠPro per Ġimplementation ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . C ANCE LED ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġrequest Pre Authorized Temporary Exposure Key Release ( params : ĠRequest Pre Authorized Temporary Exposure Key Release Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠPro per Ġimplementation ĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch S af ely Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status ( FAILED _ KEY _ RELEASE _ NOT _ PRE AUTHORIZ ED )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Transact ( code : ĠInt , Ġdata : ĠParcel , Ġreply : ĠParcel ?, Ġflags : ĠInt ): ĠBoolean Ġ= Ġwarn On Transaction Issues ( code , Ġreply , Ġflags ) Ġ{ Ġsuper . on Transact ( code , Ġdata , Ġreply , Ġflags ) Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġtemp Granted Permissions : ĠMutable Set < Pair < String , ĠString >> Ġ= Ġhash Set Of () ĊĠĠĠ Ġ} Ċ } Ċ