package Ġde . r ki . cor on aw arn app . util . security Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . SharedPreferences Ċ import Ġandroidx . core . content . edit Ċ import Ġde . r ki . cor on aw arn app . storage . DATABASE _ NAME Ċ import Ġde . r ki . cor on aw arn app . util . errors . cause s Ċ import Ġorg . joda . time . Instant Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . io . File Ċ import Ġjava . security . General Security Exception Ċ import Ġjavax . inject . Inject Ċ import Ġjavax . inject . Singleton Ċ Ċ /** Ċ Ġ* ĠThis Ġtool Ġdetermines Ġthe Ġnarrow Ġscope Ġfor Ġwhich Ġwe Ġwill Ġrecovery Ġfrom Ġan Ġencryption Ġerror Ċ Ġ* Ġby Ġreset ting Ġour Ġencrypted Ġdata . Ċ Ġ* ĠThis Ġwill Ġallow Ġusers Ġcurrently Ġaffected Ġby Ġit , Ġthat Ġupdate Ġthe Ġapp , Ġto Ġkeep Ġusing Ġit Ġwithout Ċ Ġ* Ġrequiring Ġany Ġmanual Ġactions Ġfrom Ġtheir Ġside . Ċ Ġ* Ċ Ġ* Ġhttps :// github . com / cor ona - warn - app / c wa - app - android / issues / 6 4 2 Ċ Ġ*/ Ċ @ Singleton Ċ class ĠEncryption Error Reset Tool Ġ@ Inject Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġcontext : ĠContext Ċ ) Ġ{ ĊĠĠĠ Ġ// Ġhttps :// cs . android . com / android / platform / super project / +/ master : frameworks / base / core / java / android / app / Context Impl . java ; d rc = 3 b 8 e 8 d 7 6 3 1 5 f 6 7 1 8 a 9 8 2 d 5 e 6 a 0 1 9 b 3 aa 4 f 6 3 4 bcd ; l = 6 2 6 ĊĠĠĠ Ġprivate Ġval Ġencrypted Preferences File Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġapp base Dir Ġ= Ġcontext . files Dir . parent File !! ĊĠĠĠĠĠĠĠ Ġval Ġshared Prefs Dir Ġ= ĠFile ( app base Dir , Ġ" shared _ prefs ") ĊĠĠĠĠĠĠĠ ĠFile ( shared Prefs Dir , Ġ"${ Security Constants . ENCRYPT ED _ SHARED _ PREFER ENCES _ FILE }. xml ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġval Ġencrypted Database File Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġcontext . get Database Path ( DATABASE _ NAME ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġval Ġprefs : ĠSharedPreferences Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġcontext . get SharedPreferences (" encryption _ error _ reset _ tool ", ĠContext . MODE _ PRIVATE ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġis Reset Window Cons umed : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġprefs . getBoolean ( P KEY _ EA 1 8 5 1 _ W AS _ WINDOW _ CON SU MED , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ= Ġprefs . edit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput Boolean ( P KEY _ EA 1 8 5 1 _ W AS _ WINDOW _ CON SU MED , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġreset Performed At : ĠInstant ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġprefs . getLong ( P KEY _ EA 1 8 5 1 _ RESET _ PER FOR MED _ AT , Ġ- 1 ). let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ== Ġ- 1 L ) Ġnull Ġelse ĠInstant . of Epoch Milli ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ= Ġprefs . edit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput Long ( P KEY _ EA 1 8 5 1 _ RESET _ PER FOR MED _ AT , Ġvalue . millis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove ( P KEY _ EA 1 8 5 1 _ RESET _ PER FOR MED _ AT ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġis Reset Notice ToBe Shown : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġprefs . getBoolean ( P KEY _ EA 1 8 5 1 _ SHOW _ RESET _ NOTICE , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ= Ġprefs . edit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput Boolean ( P KEY _ EA 1 8 5 1 _ SHOW _ RESET _ NOTICE , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtry Reset If Ne cessary ( error : ĠThrowable ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . w ( error , Ġ" is Recovery W arr anted () ") ĊĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġonly Ġreset Ġfor Ġthe Ġfirst Ġerror Ġencountered Ġafter Ġupgrading Ġto Ġ 1 . 4 . 0 + ĊĠĠĠĠĠĠĠ Ġif Ġ( is Reset Window Cons umed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . v (" Reset Ġwindow Ġhas Ġbeen Ġconsumed Ġ-> Ġno Ġreset .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis Reset Window Cons umed Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġval Ġkey Exception Ġ= Ġerror . cause s (). single OrNull Ġ{ Ġit Ġis ĠGeneral Security Exception Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( key Exception Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . v (" Error Ġhas Ġno ĠGeneral Security Exception Ġas Ġcause Ġ-> Ġno Ġreset .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġhttps :// github . com / google / t ink / blob / a 8 ec 7 4 d 0 8 3 0 6 8 cd 5 e 1 eb ed 8 6 fd 8 2 5 4 6 3 0 6 1 7 b 5 9 2 / java _ src / src / main / java / com / google / crypto / t ink / a ead / A ead Wrapper . java # L 8 3 ĊĠĠĠĠĠĠĠ Ġif Ġ( key Exception . message ?. trim ()?. equals (" de cryption Ġfailed ") Ġ!= Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . v (" Not Ġthe ĠGeneral Security Exception Ġwe Ġare Ġlooking Ġfor Ġ-> Ġno Ġreset .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! encrypted Preferences File . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġerror Ġwe Ġare Ġlooking Ġfor Ġcan Ġonly Ġhappen Ġif Ġthere Ġalready Ġis Ġan Ġencrypted Ġpreferences Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . w ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Error Ġfits , Ġbut Ġwhere Ġis Ġthe Ġexisting Ġpreference Ġfile Ġ(% s )? Ġ-> Ġno Ġreset .", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencrypted Preferences File ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠSo Ġwe Ġhave Ġa ĠGeneral Security Exception (" de cryption Ġfailed ") Ġand Ġexisting Ġpreferences ĊĠĠĠĠĠĠĠ Ġ// ĠAnd Ġthis Ġis Ġthe Ġfirst Ġerror Ġwe Ġencountered Ġafter Ġupgrading Ġto Ġ 1 . 4 . 0 , Ġlet 's Ġdo Ġthis ! ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġperform Reset () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġanything Ġgoes Ġwrong , Ġwe Ġreturn Ġfalse , Ġso Ġthat Ġour Ġcaller Ġcan Ġre throw Ġthe Ġoriginal Ġerror . ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e ( e , Ġ" Error Ġwhile Ġperforming Ġthe Ġreset .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġperform Reset (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠDelete Ġencrypted Ġshared Ġpreferences Ġfile ĊĠĠĠĠĠĠĠ Ġif Ġ(! encrypted Preferences File . delete ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . w (" Couldn 't Ġdelete Ġ% s ", Ġencrypted Preferences File ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġencrypted Ġpreferences Ġare Ġa Ġpr erequis ite Ġfor Ġthis Ġerror Ġcase ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġwe Ġcan 't Ġdelete Ġthat , Ġwe Ġhave Ġto Ġassume Ġour Ġreset Ġapproach Ġfailed . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠThe Ġuser Ġmay Ġhave Ġencountered Ġthe Ġerror Ġeven Ġbefore Ġa Ġdatabase Ġwas Ġcreated . ĊĠĠĠĠĠĠĠ Ġif Ġ( encrypted Database File . exists () Ġ&& Ġ! encrypted Database File . delete ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . w (" Couldn 't Ġdelete Ġ% s ", Ġencrypted Database File ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThere Ġwas Ġa Ġdatabase , Ġbut Ġwe Ġcouldn 't Ġdelete Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġdatabase Ġis Ġin accessible Ġwithout Ġthe Ġmatching Ġpreferences Ġ( which Ġwe Ġjust Ġdeleted ). ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreset Performed At Ġ= ĠInstant . now () ĊĠĠĠĠĠĠĠ Ġis Reset Notice ToBe Shown Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠP KEY _ EA 1 8 5 1 _ RESET _ PER FOR MED _ AT Ġ= Ġ" ea 1 8 5 1 . reset . per formed At " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠP KEY _ EA 1 8 5 1 _ W AS _ WINDOW _ CON SU MED Ġ= Ġ" ea 1 8 5 1 . reset . window consumed " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠP KEY _ EA 1 8 5 1 _ SHOW _ RESET _ NOTICE Ġ= Ġ" ea 1 8 5 1 . reset . shown ot ice " ĊĠĠĠ Ġ} Ċ } Ċ