/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠAC IN Q ĠSAS Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġfr . ac in q . phoenix . settings Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . view . Gravity Ċ import Ġandroid . view . LayoutInflater Ċ import Ġandroid . view . View Ċ import Ġandroid . view . ViewGroup Ċ import Ġandroid . widget . TableRow Ċ import Ġandroid . widget . TextView Ċ import Ġandroidx . annotation . Ui Thread Ċ import Ġandroidx . bio metric . Bio metric Manager Ċ import Ġandroidx . lifecycle .* Ċ import Ġandroidx . navigation . fragment . find Nav Controller Ċ import Ġfr . ac in q . phoenix . Base Fragment Ċ import Ġfr . ac in q . phoenix . R Ċ import Ġfr . ac in q . phoenix . databinding . Fragment Settings Display Seed Binding Ċ import Ġfr . ac in q . phoenix . security . Pin Dialog Ċ import Ġfr . ac in q . phoenix . utils .* Ċ import Ġfr . ac in q . phoenix . utils . encrypt . Encrypted Seed Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġorg . slf 4 j . Logger Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġorg . sp ong ycastle . util . en coders . Hex Ċ Ċ class ĠDisplay Seed Fragment Ġ: ĠBase Fragment () Ġ{ ĊĊĠ Ġoverride Ġval Ġlog : ĠLogger Ġ= ĠLoggerFactory . getLogger ( this :: class . java ) ĊĊĠ Ġprivate Ġlateinit Ġvar Ġm Binding : ĠFragment Settings Display Seed Binding ĊĠ Ġprivate Ġlateinit Ġvar Ġmodel : ĠDisplay Seed ViewModel ĊĊĠ Ġprivate Ġvar Ġm Pin Dialog : ĠPin Dialog ? Ġ= Ġnull ĊĊĠ Ġoverride Ġfun ĠonCreate View ( in flater : ĠLayoutInflater , Ġcontainer : ĠViewGroup ?, ĠsavedInstanceState : ĠBundle ?): ĠView Ġ{ ĊĠĠĠ Ġm Binding Ġ= ĠFragment Settings Display Seed Binding . inflate ( in flater , Ġcontainer , Ġfalse ) ĊĠĠĠ Ġm Binding . lifecycle Owner Ġ= Ġthis ĊĠĠĠ Ġm Binding . instructions . text Ġ= ĠConverter . html ( getString ( R . string . display seed _ instructions )) ĊĠĠĠ Ġreturn Ġm Binding . root ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġon Activity Created ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠ Ġsuper . on Activity Created ( savedInstanceState ) ĊĠĠĠ Ġmodel Ġ= ĠViewModel Provider ( this ). get ( Display Seed ViewModel :: class . java ) ĊĠĠĠ Ġm Binding . model Ġ= Ġmodel ĊĠĠĠ Ġmodel . state . observe ( view Lifecycle Owner , ĠObserver Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠ Ġif Ġ( state Ġ== ĠDisplay Seed State . INIT ) Ġ{ ĊĠĠĠĠĠĠĠ Ġunlock Wallet () ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}) ĊĠĠĠ Ġmodel . words . observe ( view Lifecycle Owner , ĠObserver Ġ{ Ġwords Ġ-> ĊĠĠĠĠĠ Ġm Binding . words Table . removeAll Views () ĊĠĠĠĠĠ Ġvar Ġi Ġ= Ġ 0 ĊĠĠĠĠĠ Ġwhile Ġ( i Ġ< Ġwords . size Ġ/ Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrow Ġ= ĠTable Row ( context ) ĊĠĠĠĠĠĠĠ Ġrow . gravity Ġ= ĠGr avity . CENTER ĊĠĠĠĠĠĠĠ Ġrow . layout Params Ġ= ĠTable Row . LayoutParams ( TableRow . LayoutParams . MATCH _ PARENT , ĠTable Row . LayoutParams . WRAP _ CONTENT ) ĊĠĠĠĠĠĠĠ Ġrow . addView ( build Word View ( i , Ġwords [ i ], Ġtrue )) ĊĠĠĠĠĠĠĠ Ġrow . addView ( build Word View ( i Ġ+ Ġwords . size Ġ/ Ġ 2 , Ġwords [ i Ġ+ Ġ( words . size Ġ/ Ġ 2 )], Ġfalse )) ĊĠĠĠĠĠĠĠ Ġm Binding . words Table . addView ( row ) ĊĠĠĠĠĠĠĠ Ġi Ġ+= Ġ 1 ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}) ĊĠĠĠ Ġmodel . errorMessage . observe ( view Lifecycle Owner , ĠObserver Ġ{ ĊĠĠĠĠĠ Ġm Binding . error View . text Ġ= ĠgetString ( R . string . display seed _ error , Ġit ) ĊĠĠĠ Ġ}) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun ĠonStart () Ġ{ ĊĠĠĠ Ġsuper . onStart () ĊĠĠĠ Ġrefresh Backup Warning () ĊĠĠĠ Ġcontext ?. let Ġ{ ĊĠĠĠĠĠ Ġm Binding . backup Warning Button . setOnClickListener Ġ{ Ġ_ Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( m Binding . backup Warning Checkbox . isChecked ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ ĠP refs . set Mn emon ics Seen Timestamp ( it , ĠSystem . currentTimeMillis ()) ĊĠĠĠĠĠĠĠĠĠ Ġrefresh Backup Warning () ĊĠĠĠĠĠĠĠĠĠ Ġfind Nav Controller (). navigate ( R . id . global _ action _ any _ to _ main ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġm Binding . unlock Button . setOnClickListener Ġ{ Ġunlock Wallet () Ġ} ĊĠĠĠ Ġm Binding . backup Warning Checkbox . setOn Checked ChangeListener Ġ{ Ġ_, Ġis Checked Ġ-> Ġmodel . user Has Saved Seed . value Ġ= Ġis Checked Ġ} ĊĠĠĠ Ġm Binding . action Bar . setOn Back Action ( View . OnClickListener Ġ{ Ġfind Nav Controller (). pop Back Stack () Ġ}) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġon Stop () Ġ{ ĊĠĠĠ Ġsuper . on Stop () ĊĠĠĠ Ġm Pin Dialog ?. dismiss () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġunlock Wallet () Ġ{ ĊĠĠĠ Ġif Ġ( model . state . value Ġ== ĠDisplay Seed State . INIT ) Ġ{ ĊĠĠĠĠĠ Ġcontext ?. let Ġ{ Ġctx Ġ-> ĊĠĠĠĠĠĠĠ Ġm Pin Dialog Ġ= Ġget Pin Dialog () ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠ ĠP refs . use Bio metrics ( ctx ) Ġ&& ĠBio metric Manager . from ( ctx ). can Authenticate () Ġ== ĠBio metric Manager . BIO METRIC _ SUCCESS Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Bio metric Auth ( negative Callback Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Pin Dialog ?. reset () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Pin Dialog ?. show () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}, Ġsuccess Callback Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . state . value Ġ= ĠDisplay Seed State . UNLOCK ING ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpin Ġ= ĠKe yst ore Helper . decrypt Pin ( ctx )?. toString ( Charsets . UTF _ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . get Seed ( ctx , Ġpin !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" could Ġnot Ġdecrypt Ġpin : Ġ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . state . value Ġ= ĠDisplay Seed State . ERROR ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . errorMessage . value Ġ= ĠgetString ( R . string . display seed _ error ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠ ĠP refs . getIs Seed Encrypted ( ctx ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Pin Dialog ?. reset () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Pin Dialog ?. show () ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . state . value Ġ= ĠDisplay Seed State . UNLOCK ING ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . get Seed ( ctx , ĠConstants . DEFAULT _ PIN ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġrefresh Backup Warning () Ġ{ ĊĠĠĠ Ġcontext ?. let Ġ{ ĊĠĠĠĠĠ Ġmodel . show User Backup Warning . value Ġ= ĠP refs . get Mn emon ics Seen Timestamp ( it ) Ġ== Ġ 0 L ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġget Pin Dialog (): ĠPin Dialog ? Ġ{ ĊĠĠĠ Ġreturn Ġm Pin Dialog Ġ?: Ġget Pin Dialog ( object Ġ: ĠPin Dialog . Pin Dialog Callback Ġ{ ĊĠĠĠĠĠ Ġoverride Ġfun Ġon Pin Confirm ( dialog : ĠPin Dialog , Ġpin Code : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontext ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġmodel . state . value Ġ= ĠDisplay Seed State . UNLOCK ING ĊĠĠĠĠĠĠĠĠĠ Ġmodel . get Seed ( it , Ġpin Code ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdialog . dismiss () ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun Ġon Pin Cancel ( dialog : ĠPin Dialog ) Ġ{} ĊĠĠĠ Ġ}) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġbuild Word View ( i : ĠInt , Ġword : ĠString , Ġhas Right Padding : ĠBoolean ): ĠTextView Ġ{ ĊĠĠĠ Ġval Ġbottom Padding Ġ= Ġresources . get Dimension Pixel Size ( R . dim en . space _ xx s ) ĊĠĠĠ Ġval Ġright Padding Ġ= Ġif Ġ( has Right Padding ) Ġresources . get Dimension Pixel Size ( R . dim en . space _ lg ) Ġelse Ġ 0 ĊĠĠĠ Ġval ĠtextView Ġ= ĠTextView ( context ) ĊĠĠĠ ĠtextView . layout Params Ġ= ĠTable Row . LayoutParams ( TableRow . LayoutParams . WRAP _ CONTENT , ĠTable Row . LayoutParams . WRAP _ CONTENT ) ĊĠĠĠ ĠtextView . text Ġ= ĠConverter . html ( getString ( R . string . new seed _ words _ td , Ġi Ġ+ Ġ 1 , Ġword )) ĊĠĠĠ ĠtextView . set Padding ( 0 , Ġ 0 , Ġright Padding , Ġbottom Padding ) ĊĠĠĠ Ġreturn ĠtextView ĊĠ Ġ} Ċ } Ċ Ċ enum Ġclass ĠDisplay Seed State Ġ{ ĊĠ ĠINIT , ĠUN LOCK ING , ĠDONE , ĠERROR Ċ } Ċ Ċ class ĠDisplay Seed ViewModel Ġ: ĠViewModel () Ġ{ ĊĠ Ġprivate Ġval Ġlog Ġ= ĠLoggerFactory . getLogger ( Display Seed ViewModel :: class . java ) ĊĊĠ Ġval Ġstate Ġ= ĠMutable LiveData ( Display Seed State . INIT ) ĊĠ Ġval ĠerrorMessage Ġ= ĠMutable LiveData ("") ĊĠ Ġval Ġwords Ġ= ĠMutable LiveData < List < String >>() ĊĊĠ Ġval Ġshow User Backup Warning Ġ= ĠMutable LiveData ( true ) ĊĠ Ġval Ġuser Has Saved Seed Ġ= ĠMutable LiveData ( false ) ĊĊĠ Ġ@ Ui Thread ĊĠ Ġfun Ġget Seed ( context : ĠContext , Ġpin : ĠString ) Ġ{ ĊĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠ Ġwith Context ( Dispatch ers . Default ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġwords . post Value ( String ( Hex . decode ( Encrypted Seed . read Seed File ( context , Ġpin )), ĠChar sets . UTF _ 8 ). split (" Ġ")) ĊĠĠĠĠĠĠĠĠĠ Ġstate . post Value ( Display Seed State . DONE ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġlog . error (" could Ġnot Ġread Ġseed : Ġ", Ġt ) ĊĠĠĠĠĠĠĠĠĠ Ġstate . post Value ( Display Seed State . ERROR ) ĊĠĠĠĠĠĠĠĠĠ ĠerrorMessage . post Value ( t . message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ