/* Ċ Ġ* Ġ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 . content . Component Name Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . Intent .* Ċ import Ġandroid . os .* Ċ import Ġandroid . util . Log Ċ import Ġcom . google . android . gms . common . api . Common StatusCode s Ċ import Ġcom . google . android . gms . common . api . Status Ċ import Ġcom . google . android . gms . near by . ex posure notification . Exposure Notification StatusCode s Ċ import Ġcom . google . android . gms . near by . ex posure notification . Exposure Notification StatusCode s .* Ċ import Ġcom . google . android . gms . near by . ex posure notification . Exposure Summary Ċ import Ġcom . google . android . gms . near by . ex posure notification . Temporary Exposure Key Ċ import Ġcom . google . android . gms . near by . ex posure notification . internal .* Ċ 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 . Temporary Exposure Key Export Ċ import Ġorg . micro g . gms . near by . ex posure notification . proto . Temporary Exposure Key Proto Ċ import Ġjava . util .* Ċ import Ġjava . util . zip . Zip InputStream Ċ import Ġkotlin . math . round ToInt Ċ Ċ class ĠEx posure Notification ServiceImpl ( private Ġval Ġcontext : ĠContext , Ġprivate Ġval ĠpackageName : ĠString ) Ġ: ĠIN ear by Exposure Notification Service . Stub () Ġ{ ĊĠĠĠ Ġ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 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> Ġdatabase . grant Permission ( packageName , ĠPackage Utils . first Signature Digest ( context , ĠpackageName ) !! , Ġ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 Ġconfirm Permission ( permission : ĠString ): ĠStatus Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( packageName Ġ== Ġcontext . packageName ) Ġreturn ĠStatus . SUCCESS ĊĠĠĠĠĠĠĠ Ġreturn ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! database . has Permission ( packageName , ĠPackage Utils . first Signature Digest ( context , ĠpackageName ) !! , Ġpermission )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStatus ( RESOL UTION _ REQUIRED , Ġ" Permission ĠEN #$ permission Ġrequired .", Ġpending Confirm ( permission )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStatus . SUCCESS ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġstart ( params : ĠStart Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( Exposure Preferences ( context ). enabled ) Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġstatus Ġ= Ġconfirm Permission ( CONFIRM _ ACTION _ START ) ĊĠĠĠĠĠĠĠ Ġif Ġ( status . is Success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Preferences ( context ). enabled Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> Ġdatabase . note App Action ( packageName , Ġ" start ") Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( status ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġstop ( params : ĠStop Params ) Ġ{ ĊĠĠĠĠĠĠĠ ĠEx posure Preferences ( context ). enabled Ġ= Ġfalse ĊĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . note App Action ( packageName , Ġ" stop ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġis Enabled ( params : ĠIs Enabled Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS , Ġ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 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstatus Ġ= Ġconfirm Permission ( CONFIRM _ ACTION _ KEYS ) ĊĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstatus . is Success Ġ-> ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . all 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 Ġstore Di agnosis Key Export ( token : ĠString , Ġexport : ĠTemporary Exposure Key Export ): ĠInt Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Import ing Ġkeys Ġfrom Ġfile Ġ${ export . start _ timestamp ?. let Ġ{ ĠDate ( it Ġ* Ġ 1 0 0 0 ) Ġ}} Ġto Ġ${ export . end _ timestamp ?. let Ġ{ ĠDate ( it Ġ* Ġ 1 0 0 0 ) Ġ}} ") ĊĠĠĠĠĠĠĠ Ġdatabase . batch Store Di agnosis Key ( packageName , Ġtoken , Ġexport . keys . map Ġ{ Ġit . to Key () Ġ}) ĊĠĠĠĠĠĠĠ Ġdatabase . batch Update Di agnosis Key ( packageName , Ġtoken , Ġexport . rev ised _ keys . map Ġ{ Ġit . to Key () Ġ}) ĊĠĠĠĠĠĠĠ Ġexport . keys . size Ġ+ Ġexport . rev ised _ keys . size ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġprovide Di agnosis Keys ( params : ĠProvide Di agnosis Keys Params ) Ġ{ ĊĠĠĠĠĠĠĠ ĠThread ( Runnable Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( params . configuration Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . store Configuration ( packageName , Ġparams . token , Ġparams . configuration ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstart Ġ= ĠSystem . currentTimeMillis () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġkeys ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . keys ?. let Ġ{ Ġdatabase . batch Store Di agnosis Key ( packageName , Ġparams . token , Ġit ) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠKey Ġfiles ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġkeys Ġ= Ġparams . keys ?. size Ġ?: Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( file Ġin Ġparams . key Files . or Empty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠZip InputStream ( Parcel FileDescriptor . Auto Close InputStream ( file )). use Ġ{ Ġstream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= Ġstream . next Entry Ġ?: Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entry . name Ġ== Ġ" export . bin ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ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 Ġfile Keys Ġ= Ġstore Di agnosis Key Export ( params . token , ĠTemporary Exposure Key Export . ADAPTER . decode ( stream )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkeys Ġ+= Ġfile Keys ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" export . bin Ġhad Ġinvalid Ġprefix ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstream . close Entry () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġwhile Ġ( true ); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Failed Ġparsing Ġfile ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtime Ġ= Ġ( System . currentTimeMillis () Ġ- Ġstart ). toDouble () Ġ/ Ġ 1 0 0 0 . 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ"$ packageName /${ params . token } Ġprovided Ġ$ keys Ġkeys Ġ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 ", Ġparams . token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" request _ keys _ size ", Ġparams . keys ?. size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" request _ key Files _ size ", Ġparams . key Files ?. size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput (" request _ keys _ count ", Ġkeys ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toString ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdatabase . finish Matching ( packageName , Ġparams . token ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHandler ( Looper . get Main Looper ()). post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . SUCCESS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmatch Ġ= Ġdatabase . findAll Measured Ex pos ures ( packageName , Ġparams . token ). isNotEmpty () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintent Ġ= ĠIntent ( if Ġ( match ) ĠACTION _ EX POS URE _ STATE _ UPDATED Ġelse ĠACTION _ EX POS URE _ NOT _ FOUND ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent . putExtra ( EXTRA _ TOKEN , Ġparams . token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent .` package ` Ġ= ĠpackageName ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Sending Ġ$ intent ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . send Ordered Broadcast ( intent , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}). start () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Exposure Summary ( params : ĠGet Exposure Summary Params ): ĠUnit Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġconfiguration Ġ= Ġdatabase . load Configuration ( packageName , Ġparams . token ) ĊĠĠĠĠĠĠĠ Ġif Ġ( configuration Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . INTERNAL _ ERROR , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġex pos ures Ġ= Ġdatabase . findAll Measured Ex pos ures ( packageName , Ġparams . token ). merge () ĊĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= ĠEx posure Summary . Exposure Summary Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Days Since Last Exposure ( ex pos ures . map Ġ{ Ġit . days Since Exposure Ġ}. min ()?. 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 ()?. 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 () ĊĊĠĠĠĠĠĠĠ Ġ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 ): ĠUnit Ġ= ĠEx posure Database . with ( context ) Ġ{ Ġdatabase Ġ-> ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠNotify Ġuser ? ĊĠĠĠĠĠĠĠ Ġval Ġconfiguration Ġ= Ġdatabase . load Configuration ( packageName , Ġparams . token ) ĊĠĠĠĠĠĠĠ Ġif Ġ( configuration Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . callback . on Result ( Status . INTERNAL _ ERROR , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Callback Ġfailed ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġdatabase . findAll Measured Ex pos ures ( packageName , Ġparams . token ). merge (). map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . to Exposure Information ( configuration ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ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 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Transact ( code : ĠInt , Ġdata : ĠParcel , Ġreply : ĠParcel ?, Ġflags : ĠInt ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( super . on Transact ( code , Ġdata , Ġreply , Ġflags )) Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on Transact Ġ[ unknown ]: Ġ$ code , Ġ$ data , Ġ$ flags ") ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} Ċ } Ċ