package Ġtw . gov . cdc . ex posure notifications . activity Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . app . AlertDialog Ċ import Ġandroid . app . DatePicker Dialog Ċ import Ġandroid . content . Intent Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . text . InputType Ċ import Ġandroid . view . Menu Ċ import Ġcom . google . android . gms . near by . ex posure notification . Temporary Exposure Key Ċ import Ġcom . google . common . base . Join er Ċ import Ġcom . google . common . base . Strings Ċ import Ġcom . google . common . collect . ImmutableList Ċ import Ġcom . google . common . io . Base Encoding Ċ import Ġkotlinx . android . synt hetic . main . activity _ upload .* Ċ import Ġokhttp 3 . MediaType Ċ import Ġokhttp 3 . RequestBody Ċ import Ġokhttp 3 . ResponseBody Ċ import Ġorg . json . JSONArray Ċ import Ġorg . json . JSONException Ċ import Ġorg . json . JSONObject Ċ import Ġorg . th reet en . bp . LocalDate Ċ import Ġorg . th reet en . bp . Zone Offset Ċ import Ġretrofit 2 . Call Ċ import Ġretrofit 2 . Callback Ċ import Ġretrofit 2 . Response Ċ import Ġtw . gov . cdc . ex posure notifications . R Ċ import Ġtw . gov . cdc . ex posure notifications . Secrets Ċ import Ġtw . gov . cdc . ex posure notifications . api . API Service Ċ import Ġtw . gov . cdc . ex posure notifications . common . Log Ċ import Ġtw . gov . cdc . ex posure notifications . common . Preference Manager Ċ import Ġtw . gov . cdc . ex posure notifications . common . Request Code Ċ import Ġtw . gov . cdc . ex posure notifications . common . Utils Ċ import Ġtw . gov . cdc . ex posure notifications . common . Utils . toBe gin Of The Day Ċ import Ġtw . gov . cdc . ex posure notifications . common . Utils . to EndOf The Day Ċ import Ġtw . gov . cdc . ex posure notifications . key upload . Api Constants . Upload V 1 Ċ import Ġtw . gov . cdc . ex posure notifications . key upload . Api Constants . Verify V 1 Ċ import Ġtw . gov . cdc . ex posure notifications . key upload . Upload Ċ import Ġtw . gov . cdc . ex posure notifications . near by . Exposure Notification Manager Ċ import Ġtw . gov . cdc . ex posure notifications . network . Di agnosis Key Ċ import Ġtw . gov . cdc . ex posure notifications . network . Padding Ċ import Ġtw . gov . cdc . ex posure notifications . storage . Di agnosis Entity Ċ import Ġtw . gov . cdc . ex posure notifications . storage . Di agnosis Entity . TestResult Ċ import Ġtw . gov . cdc . ex posure notifications . storage . Di agnosis Entity . Travel Status Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġjava . security . Invalid Key Exception Ċ import Ġjava . security . NoSuch AlgorithmException Ċ import Ġjava . util .* Ċ import Ġjavax . crypto . Mac Ċ import Ġjavax . crypto . spec . SecretKey Spec Ċ Ċ class ĠUpload Activity Ġ: ĠBase Activity () Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" Upload Activity " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠTODO : ĠRemove Ġor Ġsave Ġto Ġpref Ġor Ġsomewhere ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġdi agnosis : ĠDi agnosis Entity ĊĊĠĠĠ Ġprivate Ġval Ġsend Button Ġby Ġlazy Ġ{ Ġupload _ send _ button Ġ} ĊĠĠĠ Ġprivate Ġval Ġcode Text Ġby Ġlazy Ġ{ Ġupload _ code _ edit _ text Ġ} ĊĠĠĠ Ġprivate Ġval ĠstartDate Text Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġupload _ date _ start _ edit _ text . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput Type Ġ= ĠInput Type . TYPE _ NULL ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġval ĠendDate Text Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġupload _ date _ end _ edit _ text . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput Type Ġ= ĠInput Type . TYPE _ NULL ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar ĠstartDate Ġ= ĠCalendar . getInstance (). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġadd ( Calendar . DAY _ OF _ MONTH , Ġ- 1 4 ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġvar ĠendDate Ġ= ĠCalendar . getInstance () ĊĊĠĠĠ Ġprivate Ġenum Ġclass ĠState Ġ{ ĊĠĠĠĠĠĠĠ ĠINITIAL , ĠCODE _ VER IFI ED ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġstate Ġ= ĠState . INITIAL ĊĊĠĠĠ Ġprivate Ġvar Ġrecent Keys : ĠList < Temporary Exposure Key >? Ġ= Ġnull ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( R . layout . activity _ upload ) ĊĠĠĠĠĠĠĠ Ġset Support ActionBar ( toolbar ) ĊĊĠĠĠĠĠĠĠ Ġsupport ActionBar ?. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Display Home As Up Enabled ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Display Show Home Enabled ( true ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcurrent Focus ?. clear Focus () ĊĊĠĠĠĠĠĠĠ ĠstartDate Text . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDate Picker Dialog ( this , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġ_, Ġyear , Ġmonth OfYear , Ġday OfMonth Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartDate Text . setText ( getString ( R . string . date _ yyyy _ mm _ dd , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġyear , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmonth OfYear Ġ+ Ġ 1 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġday OfMonth )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartDate . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset ( Calendar . YEAR , Ġyear ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset ( Calendar . MONTH , Ġmonth OfYear ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset ( Calendar . DAY _ OF _ MONTH , Ġday OfMonth ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartDate . get ( Calendar . YEAR ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartDate . get ( Calendar . MONTH ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartDate . get ( Calendar . DAY _ OF _ MONTH )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCalendar . getInstance (). add ( Calendar . DAY _ OF _ MONTH , Ġ- 1 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdate Picker . min Date Ġ= ĠCalendar . getInstance (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd ( Calendar . DAY _ OF _ MONTH , Ġ- 1 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. time In Millis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdate Picker . max Date Ġ= ĠendDate . time In Millis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. show () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠendDate Text . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDate Picker Dialog ( this , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġ_, Ġyear , Ġmonth OfYear , Ġday OfMonth Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠendDate Text . setText ( getString ( R . string . date _ yyyy _ mm _ dd , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġyear , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmonth OfYear Ġ+ Ġ 1 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġday OfMonth )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠendDate . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset ( Calendar . YEAR , Ġyear ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset ( Calendar . MONTH , Ġmonth OfYear ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset ( Calendar . DAY _ OF _ MONTH , Ġday OfMonth ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠendDate . get ( Calendar . YEAR ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠendDate . get ( Calendar . MONTH ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠendDate . get ( Calendar . DAY _ OF _ MONTH )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCalendar . getInstance (). add ( Calendar . DAY _ OF _ MONTH , Ġ- 1 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdate Picker . min Date Ġ= ĠstartDate . time In Millis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdate Picker . max Date Ġ= ĠDate (). time ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. show () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġsend Button . setOnClickListener Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( startDate Text . text . isNull Or Blank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUtils . show Hint Dialog ( this , ĠR . string . upload _ date _ start _ enter _ hint ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ setOnClickListener ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( endDate Text . text . isNull Or Blank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUtils . show Hint Dialog ( this , ĠR . string . upload _ date _ end _ enter _ hint ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ setOnClickListener ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( code Text . text . isNull Or Blank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUtils . show Hint Dialog ( this , ĠR . string . enter _ verification _ code ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ setOnClickListener ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Button . isEnabled Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow ProgressBar () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . INITIAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubmit Code () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . CODE _ VER IFI ED Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Keys IfNeeded () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsubmit Code () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcode Ġ= Ġcode Text . text . toString () ĊĠĠĠĠĠĠĠ Ġval Ġupload Ġ= ĠUpload . newBuilder ( code ). build () ĊĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġverification Code RequestBody ( upload ) ĊĠĠĠĠĠĠĠ Ġval Ġbody Request Ġ= ĠRequest Body . create ( MediaType . parse (" application / json "), Ġbody . toString ()) ĊĊĠĠĠĠĠĠĠ ĠAPI Service . verification Server . submit Code ( body Ġ= Ġbody Request ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. enqueue ( object Ġ: ĠCallback < ResponseBody > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Response ( call : ĠCall < ResponseBody >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse : ĠResponse < ResponseBody >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" submit Code Ġon Response Ġ$ response ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Body Ġ= Ġresponse . body () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response . is Successful Ġ&& Ġresponse Body Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġverified Upload Ġ= Ġcapture Verification Code Response ( upload , ĠJSONObject ( response Body . string ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdi agnosis Ġ= Ġget Di agnosis Entity ( verified Upload Ġ= Ġverified Upload , Ġcode Ġ= Ġcode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . CODE _ VER IFI ED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Keys IfNeeded () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Upload Result Dialog ( Upload Result . FAILED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Failure ( call : ĠCall < ResponseBody >, Ġt : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" submit Code Ġon Failure Ġ$ t ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Upload Result Dialog ( Upload Result . FAILED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġenum Ġclass ĠUpload Result Ġ{ ĊĠĠĠĠĠĠĠ ĠSUCCESS , ĊĠĠĠĠĠĠĠ ĠFAILED , ĊĠĠĠĠĠĠĠ ĠFAILED _ NO _ FILES , ĊĠĠĠĠĠĠĠ ĠFAILED _ NO _ GRAN TED _ TE K ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Upload Result Dialog ( result : ĠUpload Result ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsuccess Ġ= Ġwhen Ġ( result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUpload Result . SUCCESS Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUpload Result . FAILED Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Text . isEnabled Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . INITIAL ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUpload Result . FAILED _ NO _ FILES , ĠUpload Result . FAILED _ NO _ GRAN TED _ TE K Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Text . isEnabled Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsend Button . isEnabled Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġhide ProgressBar () ĊĠĠĠĠĠĠĠ ĠAlertDialog . Builder ( this ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsetTitle ( if Ġ( success ) ĠR . string . upload _ success Ġelse ĠR . string . upload _ fail ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Ġ== ĠUpload Result . FAILED _ NO _ FILES ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Message ( R . string . upload _ fail _ message _ no _ files ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Positive Button ( R . string . confirm ) Ġ{ Ġ_, Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Upload Success () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Cancel able ( false ) ĊĠĠĠĠĠĠĠ Ġ}. create (). show () ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġon Upload Success () Ġ{ ĊĠĠĠĠĠĠĠ Ġset Result ( Activity . RESULT _ OK ) ĊĠĠĠĠĠĠĠ Ġfinish () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠAction Bar ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate Options Menu ( menu : ĠMenu ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġmenu Inflater . inflate ( R . menu . no _ item , Ġmenu ) ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . onCreate Options Menu ( menu ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Support Navigate Up (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġon Back Pressed () ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Activity Result ( request Code : ĠInt , ĠresultCode : ĠInt , Ġdata : ĠIntent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( request Code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġuser Ġconsent Ġfor Ġretrieving ĠT EK s Ġis Ġgranted Ġfor Ġ 2 4 Ġhours . ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRequest Code . REQUEST _ RESOL UTION _ EN _ TE K _ HISTORY Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Code Ġ== ĠActivity . RESULT _ OK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġresolution Ġwas Ġcompleted . ĠAttempt Ġto Ġre - retrieve Ġthe Ġkeys Ġagain . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Notification Manager . get Temporary Exposure Key History ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThere Ġwas Ġan Ġissue Ġwith Ġthe Ġuser Ġaccepting Ġthe Ġprompt . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Upload Result Dialog ( Upload Result . FAILED _ NO _ GRAN TED _ TE K ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Activity Result ( request Code , ĠresultCode , Ġdata ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSubmit ĠCode ĊĠĠĠĠ Ġ*/ ĊĊĠĠĠ Ġprivate Ġval ĠSUPPORT ED _ TEST _ TYPES : ĠJSONArray Ġ= ĠJSONArray ( ĊĠĠĠĠĠĠĠ ĠImmutableList . of ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Result . CON FI R MED . to Api Type (), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Result . LIKELY . to Api Type (), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Result . NEGATIVE . to Api Type () ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġ@ Throws ( JSONException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġverification Code RequestBody ( upload : ĠUpload ): ĠJSONObject Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" verification Code RequestBody ") ĊĠĠĠĠĠĠĠ Ġreturn ĠPadding . add Padding ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJSONObject () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Verify V 1 . VER IFICATION _ CODE , Ġupload . verification Code ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Verify V 1 . ACCEPT _ TEST _ TYPES , ĠSUPPORT ED _ TEST _ TYPES ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcapture Verification Code Response ( upload : ĠUpload , Ġresponse : ĠJSONObject ): ĠUpload Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" capture Verification Code Response ") ĊĠĠĠĠĠĠĠ Ġif Ġ( upload . is Cover Traffic ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIgnore Ġresponses Ġfor Ġcover Ġtraffic Ġrequests . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġupload ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġwith Response Ġ= Ġupload . to Builder () ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response . has ( Verify V 1 . TEST _ TYPE ) Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ! Strings . isNull OrEmpty ( response . getString ( Verify V 1 . TEST _ TYPE )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Response . set Test Type ( response . getString ( Verify V 1 . TEST _ TYPE )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response . has ( Verify V 1 . VER IFICATION _ TOKEN ) Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ! Strings . isNull OrEmpty ( response . getString ( Verify V 1 . VER IFICATION _ TOKEN )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Response . set Long Term Token ( response . getString ( Verify V 1 . VER IFICATION _ TOKEN )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response . has ( Verify V 1 . ON SET _ DATE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġ! Strings . isNull OrEmpty ( response . getString ( Verify V 1 . ON SET _ DATE )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLocalDate . parse () Ġdefaults Ġto Ġiso - 8 6 0 1 Ġdate Ġformat Ġ" YYYY - MM - DD ", Ġas Ġreturned Ġby ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġverification Ġserver Ġfor Ġsy mptom Date . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Response . set Sy mptom On set ( LocalDate . parse ( response . getString ( Verify V 1 . ON SET _ DATE ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwith Response . build () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠJSON Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠBetter Ġexception ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRuntimeException ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Di agnosis Entity ( verified Upload : ĠUpload , Ġcode : ĠString ): ĠDi agnosis Entity Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" get Di agnosis Entity ") ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġsuccessful , Ġcapture Ġthe Ġlong Ġterm Ġtoken Ġand Ġsome Ġdi agnosis Ġfacts Ġinto Ġexposure notifications . storage . ĊĠĠĠĠĠĠĠ Ġval Ġbuilder : ĠDi agnosis Entity . Builder Ġ= ĠDi agnosis Entity . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Verification Code ( code ). setIs Code From Link ( false ) ĊĠĠĠĠĠĠĠ Ġ// ĠThe Ġlong Ġterm Ġtoken Ġis Ġrequired . ĊĠĠĠĠĠĠĠ Ġbuilder . set Long Term Token ( verified Upload . long Term Token ()) ĊĠĠĠĠĠĠĠ Ġ// ĠSy mptom Ġon set Ġmay Ġor Ġmay Ġnot Ġbe Ġprovided Ġby Ġthe Ġverification Ġserver . ĊĠĠĠĠĠĠĠ Ġif Ġ( verified Upload . sy mptom On set () Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . setIs Server On setDate ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . setOn setDate ( verified Upload . sy mptom On set ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Has Sy mptoms ( Di agnosis Entity . Has Sy mptoms . YES ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠTest Ġtype Ġis Ġcurrently Ġalways Ġprovided Ġby Ġthe Ġverification Ġserver , Ġbut Ġthat Ġseems ĊĠĠĠĠĠĠĠ Ġ// Ġlike Ġsomething Ġthat Ġcould Ġchange . ĠLet 's Ġcheck . ĊĠĠĠĠĠĠĠ Ġif Ġ( verified Upload . test Type () Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . set TestResult ( TestResult . of ( verified Upload . test Type () !! )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġbuilder . build () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġget ĠCert ĊĠĠĠĠ Ġ*/ ĊĊĠĠĠ Ġprivate Ġfun Ġrequest Keys IfNeeded () Ġ{ ĊĠĠĠĠĠĠĠ Ġrecent Keys ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Received Keys ( it ) ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEx posure Notification Manager . get Temporary Exposure Key History ( this @ Upload Activity ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Received Keys ( keys : ĠList < Temporary Exposure Key >) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Con verting ĠT EK s Ġinto ĠDi agnosis Keys ...") ĊĠĠĠĠĠĠĠ Ġrecent Keys Ġ= Ġkeys ĊĠĠĠĠĠĠĠ Ġval Ġbuilder : ĠImmutableList . Builder < Di agnosis Key > Ġ= ĠImmutableList . Builder < Di agnosis Key >() ĊĊĠĠĠĠĠĠĠ Ġval Ġtime In Millis To Interval Number Ġ= Ġ{ Ġtime In Millis : ĠLong Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtime In Millis Ġ/ Ġ 1 0 0 0 Ġ/ Ġ 6 0 Ġ/ Ġ 1 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġstart Interval Number Ġ= Ġtime In Millis To Interval Number ( startDate . toBe gin Of The Day (). time In Millis ) ĊĠĠĠĠĠĠĠ Ġval Ġend Inter Val Number Ġ= Ġtime In Millis To Interval Number ( endDate . to EndOf The Day (). time In Millis ) ĊĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" interval Ġ[$ start Interval Number , Ġ$ end Inter Val Number ]") ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( k Ġin Ġkeys ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( k . rolling Start Interval Number Ġ+ Ġk . rolling Period Ġ>= Ġstart Interval Number Ġ&& Ġk . rolling Start Interval Number Ġ<= Ġend Inter Val Number ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" add Ġkey Ġ$ k ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . add ( Di agnosis Key . newBuilder (). set Key Bytes ( k . key Data ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Interval Number ( k . rolling Start Interval Number ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Rol ling Period ( k . rolling Period ) Ġ// ĠAccept ing Ġthe Ġdefault Ġtransmission Ġrisk Ġfor Ġnow , Ġwhich Ġthe ĠDi agnosis Key . Builder ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcomes Ġwith Ġpre - set . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġdi agnosis Keys Ġ= Ġbuilder . build () ĊĠĠĠĠĠĠĠ Ġif Ġ( di agnosis Keys . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Upload Result Dialog ( Upload Result . FAILED _ NO _ FILES ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Cert And Upload Keys ( di agnosis Keys ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Cert And Upload Keys ( di agnosis Keys : ĠImmutableList < Di agnosis Key >) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" get Cert And Upload Keys ") ĊĠĠĠĠĠĠĠ Ġval Ġupload Ġ= ĠUpload . newBuilder ( di agnosis Keys , Ġdi agnosis . verification Code ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Long Term Token ( di agnosis . long Term Token ). set Sy mptom On set ( di agnosis . on setDate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Certificate ( di agnosis . certificate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Has Tr ave led ( Travel Status . TR AVE LED Ġ== Ġdi agnosis . travel Status ). build () ĊĊĠĠĠĠĠĠĠ Ġif Ġ( Strings . isNull OrEmpty ( upload . certificate ())) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsubmit Keys For Cert ( upload ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupload ( upload ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsubmit Keys For Cert ( upload : ĠUpload ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" submit Keys For Cert ") ĊĊĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġcert RequestBody ( upload ) ĊĠĠĠĠĠĠĠ Ġval Ġbody Request Ġ= ĠRequest Body . create ( MediaType . parse (" application / json "), Ġbody . toString ()) ĊĊĠĠĠĠĠĠĠ ĠAPI Service . verification Server . submit Keys For Cert ( body Ġ= Ġbody Request ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. enqueue ( object Ġ: ĠCallback < ResponseBody > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Response ( call : ĠCall < ResponseBody >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse : ĠResponse < ResponseBody >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" submit Keys For Cert Ġon Response Ġ$ response ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Body Ġ= Ġresponse . body () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response . is Successful Ġ&& Ġresponse Body Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcert ed Upload Ġ= Ġcapture Cert Response ( upload , ĠJSONObject ( response Body . string ())). to Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Revision Token ( Preference Manager . revision Token ). build () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupload ( cert ed Upload ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Upload Result Dialog ( Upload Result . FAILED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Failure ( call : ĠCall < ResponseBody >, Ġt : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" submit Keys For Cert Ġon Failure Ġ$ t ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Upload Result Dialog ( Upload Result . FAILED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( JSONException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġcert RequestBody ( upload : ĠUpload ): ĠJSONObject Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" cert RequestBody ") ĊĠĠĠĠĠĠĠ Ġreturn ĠPadding . add Padding ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJSONObject () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Verify V 1 . VER IFICATION _ TOKEN , Ġupload . long Term Token ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Verify V 1 . HMAC _ KEY , Ġhashed Keys ( upload )) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcapture Cert Response ( upload : ĠUpload , Ġresponse : ĠJSONObject ): ĠUpload Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" capture Cert Response ") ĊĠĠĠĠĠĠĠ Ġif Ġ( upload . is Cover Traffic ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIgnore Ġresponses Ġfor Ġcover Ġtraffic Ġrequests . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġupload ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġwith Response Ġ= Ġupload . to Builder () ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response . has ( Verify V 1 . CERT ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġ! Strings . isNull OrEmpty ( response . getString ( Verify V 1 . CERT )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Response . set Certificate ( response . getString ( Verify V 1 . CERT )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwith Response . build () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠJSON Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠBetter Ġexception ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġjava . lang . RuntimeException ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval ĠCOMM AS Ġ= ĠJoin er . on (',') ĊĠĠĠ Ġprivate Ġval ĠBASE 6 4 Ġ= ĠBase Encoding . base 6 4 () ĊĠĠĠ Ġprivate Ġval ĠHASH _ AL GO Ġ= Ġ" H mac SHA 2 5 6 " ĊĊĠĠĠ Ġprivate Ġfun Ġhashed Keys ( upload : ĠUpload ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" hashed Keys ") ĊĠĠĠĠĠĠĠ Ġval Ġcle art ext Segments : ĠMutable List < String > Ġ= ĠArrayList < String >( upload . keys () !!. size ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( k Ġin Ġupload . keys () !! ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcle art ext Segments . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġjava . lang . String . format ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocale . EN GL ISH , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"% s .% d .% d .% d ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBASE 6 4 . encode ( k . key Bytes ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġk . interval Number , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġk . rolling Period , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġk . transmission Risk ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcle art ext Segments . sort () ĊĠĠĠĠĠĠĠ Ġval Ġcle art ext : ĠString Ġ= ĠCOMM AS . join ( cle art ext Segments ) ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġupload . keys () !!. size . toString () Ġ+ Ġ" Ġkeys Ġfor Ġhashing Ġprior Ġto Ġverification : Ġ[" Ġ+ Ġcle art ext Ġ+ Ġ"] ") ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmac Ġ= ĠMac . getInstance ( HASH _ AL GO ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmac . init ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSecret KeySpec ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBASE 6 4 . decode ( upload . hmac Key Base 6 4 ()), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHASH _ AL GO ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBASE 6 4 . encode ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmac . do Final ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcle art ext . toByteArray ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStandard Charsets . UTF _ 8 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠNoSuch AlgorithmException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠBetter Ġexception ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġjava . lang . RuntimeException ( e ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠInvalid Key Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġjava . lang . RuntimeException ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġupload Ġkeys ĊĠĠĠĠ Ġ*/ ĊĊĠĠĠ Ġprivate Ġfun Ġupload ( upload : ĠUpload ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Up loading Ġkeys Ġand Ġcert Ġto Ġkey server ...") ĊĊĠĠĠĠĠĠĠ Ġif Ġ( upload . keys () !!. isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Zero Ġkeys Ġgiven , Ġskipping .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Upload Result Dialog ( Upload Result . FAILED _ NO _ FILES ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Up loading Ġkeys : Ġ[" Ġ+ Ġupload . keys () !!. size . toString () Ġ+ Ġ"] ") ĊĊĠĠĠĠĠĠĠ Ġval Ġpayload Ġ= Ġcreate Payload ( upload ) ĊĠĠĠĠĠĠĠ Ġval Ġbody Request Ġ= ĠRequest Body . create ( MediaType . parse (" application / json "), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpayload . toString ()) ĊĊĠĠĠĠĠĠĠ ĠAPI Service . key Server . submit Keys ( body Ġ= Ġbody Request ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. enqueue ( object Ġ: ĠCallback < ResponseBody > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Response ( call : ĠCall < ResponseBody >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse : ĠResponse < ResponseBody >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" submit Keys Ġon Response Ġ$ response ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Body Ġ= Ġresponse . body () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response . is Successful Ġ&& Ġresponse Body Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrevision ed Upload Ġ= Ġcapture Revision Token ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse Ġ= ĠJSONObject ( response Body . string ()), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupload Ġ= Ġupload ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSuccessfully Ġsubmitted ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Upload Ġsuccess : Ġ$ revision ed Upload ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠUpdate Ġdi agnosis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdi agnosis Ġ= Ġdi agnosis . to Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Certificate ( revision ed Upload . certificate ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Revision Token ( revision ed Upload . revision Token ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Shared Status ( Di agnosis Entity . Shared . SHARED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrevision ed Upload . revision Token ()?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPreference Manager . revision Token Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Upload Result Dialog ( Upload Result . SUCCESS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Upload Result Dialog ( Upload Result . FAILED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Failure ( call : ĠCall < ResponseBody >, Ġt : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" submit Keys Ġon Failure Ġ$ t ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Upload Result Dialog ( Upload Result . FAILED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Payload ( upload : ĠUpload ): ĠJSONObject Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" create Payload ") ĊĠĠĠĠĠĠĠ Ġvar Ġpayload Ġ= ĠJSONObject () ĊĠĠĠĠĠĠĠ Ġval Ġkeys Json Ġ= ĠJSONArray () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( k Ġin Ġupload . keys () !! ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Adding Ġkey : Ġ$ k Ġto Ġsubmission .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkeys Json . put ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJSONObject () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Upload V 1 . KEY , ĠBASE 6 4 . encode ( k . key Bytes )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Upload V 1 . ROLL ING _ START _ NUM , Ġk . interval Number ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Upload V 1 . ROLL ING _ PERIOD , Ġk . rolling Period ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Upload V 1 . TRAN SM IS SION _ R IS K , Ġk . transmission Risk ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġregion Codes Json Ġ= ĠJSONArray () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( r Ġin Ġupload . regions () !! ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġregion Codes Json . put ( r ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayload ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Upload V 1 . KEYS , Ġkeys Json ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Upload V 1 . HE ALTH _ AUTH ORITY _ ID , Ġif Ġ( API Service . USE _ DEV _ SERVER ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSec rets (). get ZN BO gm Gj ( packageName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSec rets (). get Wc Uv CK Ex ( packageName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Upload V 1 . HMAC _ KEY , Ġupload . hmac Key Base 6 4 ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Upload V 1 . VER IFICATION _ CERT , Ġupload . certificate ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. put ( Upload V 1 . TR AV EL ER , Ġupload . has Tr ave led ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠOn set Ġdate Ġis Ġoptional ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( upload . sy mptom On set () Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġon setDate Interval Ġ= ĠDi agnosis Key . instant To Interval ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupload . sy mptom On set () !!. at Start OfDay ( Zone Offset . UTC ). to Instant () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpayload . put ( Upload V 1 . ON SET , Ġon setDate Interval ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġhave Ġa Ġrevision Ġtoken Ġonly Ġon Ġsecond Ġand Ġsubsequent Ġuploads . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( upload . revision Token () Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpayload . put ( Upload V 1 . REVISION _ TOKEN , Ġupload . revision Token ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayload Ġ= ĠPadding . add Padding ( payload ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpayload ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠJSON Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpayload ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠĠĠ Ġ@ Throws ( Keys Submit FailureException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġcapture Revision Token ( response : ĠJSONObject , Ġupload : ĠUpload ): ĠUpload Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( upload . is Cover Traffic ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupload ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupload . to Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Revision Token ( response . getString ( Upload V 1 . REVISION _ TOKEN )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠJSON Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupload ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ" Server Ġerror " Ġhere Ġis Ġmaybe Ġa Ġbit Ġoptim istic : Ġit Ġassumes Ġthat Ġthe Ġresponse Ġbody Ġwas ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġincorrect , Ġbut Ġit Ġcould Ġbe Ġthat Ġthe Ġapp 's Ġinterpretation Ġof Ġthe Ġresponse Ġis Ġincorrect . Ċ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠKeys Submit FailureException ( Upload Error . SERVER _ ERROR ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }