/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 1 8 ĠSch ib st ed ĠProducts Ġ& ĠTechnology ĠAS . ĠLicensed Ġunder Ġthe Ġterms Ġof Ġthe ĠMIT Ġlicense . ĠSee ĠLICENSE Ġin Ġthe Ġproject Ġroot . Ċ Ġ*/ Ċ Ċ package Ġcom . sch ib st ed . account . ui . login Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . res . Resources Ċ import Ġandroid . graphics . Rect Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . os . Parcelable Ċ import Ġandroid . support . annotation . Nullable Ċ import Ġandroid . support . annotation . String Res Ċ import Ġandroid . support . annotation . Visible ForTesting Ċ import Ġandroid . support . v 4 . app . Dialog Fragment Ċ import Ġandroid . support . v 4 . content . Context Compat Ċ import Ġandroid . support . v 7 . app . AppCompatActivity Ċ import Ġandroid . support . v 7 . widget . Toolbar Ċ import Ġandroid . view . Menu Ċ import Ġandroid . view . MenuItem Ċ import Ġandroid . view . View Ċ import Ġandroid . view . View . GONE Ċ import Ġandroid . view . View . VISIBLE Ċ import Ġandroid . view . View Tree Observer Ċ import Ġandroid . view . input method . Input Method Manager Ċ import Ġcom . sch ib st ed . account . Account Service Ċ import Ġcom . sch ib st ed . account . common . tracking . Tracking Data Ċ import Ġcom . sch ib st ed . account . common . tracking . Ui Tracking Ċ import Ġcom . sch ib st ed . account . common . util . Logger Ċ import Ġcom . sch ib st ed . account . engine . controller . Login Controller Ċ import Ġcom . sch ib st ed . account . engine . input . Credentials Ċ import Ġcom . sch ib st ed . account . engine . input . Identifier Ċ import Ġcom . sch ib st ed . account . engine . integration . Result Callback Ċ import Ġcom . sch ib st ed . account . session . User Ċ import Ġcom . sch ib st ed . account . ui . Keyboard Manager Ċ import Ġcom . sch ib st ed . account . ui . R Ċ import Ġcom . sch ib st ed . account . ui . Ui Configuration Ċ import Ġcom . sch ib st ed . account . ui . Ui Util Ċ import Ġcom . sch ib st ed . account . ui . login . flow . password . Flow Selection Listener Ċ import Ġcom . sch ib st ed . account . ui . login . flow . password . Login Contract Impl Ċ import Ġcom . sch ib st ed . account . ui . login . screen . Login Screen Ċ import Ġcom . sch ib st ed . account . ui . login . screen . identification . ui . Abstract Identification Fragment Ċ import Ġcom . sch ib st ed . account . ui . login . screen . identification . ui . Email Identification Fragment Ċ import Ġcom . sch ib st ed . account . ui . navigation . Navigation Ċ import Ġcom . sch ib st ed . account . ui . navigation . Navigation Listener Ċ import Ġcom . sch ib st ed . account . ui . smart lock . Smart lock Impl Ċ import Ġcom . sch ib st ed . account . ui . ui . Flow Fragment Ċ import Ġcom . sch ib st ed . account . ui . ui . Web Fragment Ċ import Ġcom . sch ib st ed . account . util . Deep Link Ċ import Ġcom . sch ib st ed . account . util . Deep Link Handler Ċ import Ġkotlinx . android . synt hetic . main . sch acc _ mobile _ activity _ layout .* Ċ Ċ abstract Ġclass ĠBase Login Activity Ġ: ĠAppCompatActivity (), ĠKeyboard Manager , ĠNavigation Listener Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠTAG Ġ= Ġ"${ Logger . DEFAULT _ TAG }- BL A " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠKEY _ SCREEN Ġ= Ġ" SCREEN " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠKEY _ FLOW _ TYPE Ġ= Ġ" FLOW _ TYPE " ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field ĊĠĠĠĠĠĠĠ Ġval ĠEX TRA _ USER Ġ= Ġ" USER _ USER " ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field ĊĠĠĠĠĠĠĠ Ġval ĠKEY _ CURRENT _ IDENTIFIER Ġ= Ġ" CURRENT _ IDENTIFIER " ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field ĊĠĠĠĠĠĠĠ Ġval ĠKEY _ UI _ CONFIGURATION Ġ= Ġ" UI _ CONFIGURATION " ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Field ĊĠĠĠĠĠĠĠ Ġval ĠKEY _ SM ART LOCK _ CRED ENTIAL S Ġ= Ġ" CRED ENTIAL S " ĊĊĠĠĠĠĠĠĠ Ġconst Ġval ĠKEY _ SM ART LOCK _ RESOL V ING Ġ= Ġ" KEY _ SM ART LOCK _ RESOL V ING " ĊĊĠĠĠĠĠĠĠ Ġ@ Nullable ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġvar Ġtracker : ĠUi Tracking ? Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġdefines Ġthe Ġstate Ġof Ġthe Ġkeyboard Ġvisibility ĊĠĠĠĠ Ġ* Ġ` true ` Ġif Ġthe Ġkeyboard Ġis Ġvisible ĊĠĠĠĠ Ġ* Ġ` false ` Ġotherwise ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġkeyboard Is Open : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġ@ Jvm Field ĊĠĠĠ Ġprotected Ġvar Ġmenu : ĠMenu ? Ġ= Ġnull ĊĠĠĠ Ġ@ Jvm Field ĊĠĠĠ Ġprotected Ġvar Ġscreen : ĠLogin Screen ? Ġ= Ġnull ĊĠĠĠ Ġprotected Ġvar Ġactive Flow Type : ĠFlow Selection Listener . Flow Type ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġcurrent Identifier : ĠIdentifier ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġsmart lock Credentials : ĠCredentials ? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġdefines Ġthe Ġfirst Ġelement Ġof Ġthe Ġlayout , Ġthis Ġis Ġthe Ġmain Ġcontainer Ġof Ġthe Ġactivity ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġactivity Root : ĠView ĊĊĠĠĠ Ġ@ Visible ForTesting ( otherwise Ġ= ĠVis ible ForTesting . PROTECT ED ) ĊĠĠĠ Ġinternal Ġlateinit Ġvar Ġui Configuration : ĠUi Configuration ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġlayout Listener : ĠView Tree Observer . On Global Layout Listener ĊĠĠĠ Ġlateinit Ġvar Ġnavigation Controller : ĠNavigation ĊĠĠĠĠĠĠĠ Ġprotected Ġset ĊĠĠĠ Ġlateinit Ġvar Ġfragment Provider : ĠFragment Provider ĊĠĠĠĠĠĠĠ Ġprotected Ġset ĊĊĠĠĠ Ġprotected Ġvar Ġlogin Controller : ĠLogin Controller ? Ġ= Ġnull ĊĠĠĠ Ġprotected Ġlateinit Ġvar Ġlogin Contract : ĠLogin Contract Impl ĊĠĠĠ Ġprotected Ġvar Ġis Smart lock Running Ġ= Ġfalse ĊĊĠĠĠ Ġinternal Ġvar Ġsmart lock : ĠSmart lock Impl ? Ġ= Ġnull ĊĠĠĠ Ġlateinit Ġvar Ġaccount Service : ĠAccount Service ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ Ġaccount Service Ġ= ĠAccount Service ( application Context ) ĊĊĠĠĠĠĠĠĠ Ġlifecycle . add Observer ( account Service ) ĊĊĠĠĠĠĠĠĠ Ġsmart lock Credentials Ġ= Ġintent . get Parcelable Extra ( KEY _ SM ART LOCK _ CRED ENTIAL S ) ĊĊĠĠĠĠĠĠĠ Ġinitialize Ui Configuration () ĊĠĠĠĠĠĠĠ Ġinitialize Ui () ĊĊĠĠĠĠĠĠĠ Ġnavigation Controller Ġ= ĠNavigation ( this , Ġthis ) ĊĊĠĠĠĠĠĠĠ Ġinitialize Properties From Bundle ( savedInstanceState ) ĊĊĠĠĠĠĠĠĠ Ġfragment Provider Ġ= ĠFragment Provider ( ui Configuration ) ĊĊĠĠĠĠĠĠĠ Ġfollow Deep Link ( intent . data String ) ĊĊĠĠĠĠĠĠĠ Ġlogin Contract Ġ= ĠLogin Contract Impl ( this ) ĊĠĠĠĠĠĠĠ Ġinitialize Smart lock () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinitialize Ui () Ġ{ ĊĠĠĠĠĠĠĠ Ġtheme . apply Style ( R . style . sch acc _ No ActionBar , Ġtrue ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( R . layout . sch acc _ mobile _ activity _ layout ) ĊĠĠĠĠĠĠĠ ĠsetUp ActionBar () ĊĠĠĠĠĠĠĠ Ġactivity Root Ġ= ĠfindViewById ( R . id . activity _ layout ) ĊĠĠĠĠĠĠĠ ĠUi Util . set Language ( this , Ġui Configuration . locale ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinitialize Ui Configuration () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġui Conf : ĠUi Configuration ? Ġ= Ġintent . get Parcelable Extra ( KEY _ UI _ CONFIGURATION ) ĊĠĠĠĠĠĠĠ Ġthis . ui Configuration Ġ= Ġif Ġ( ui Conf Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġui Conf ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . warn ( Logger . DEFAULT _ TAG , Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Configuration Ġnot Ġfound Ġin Ġintent , Ġfalling Ġback Ġto Ġparsing Ġthe Ġmanifest . Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" If Ġthe Ġactivity Ġis Ġcreated Ġfrom Ġa Ġdeep Ġlink , Ġthis Ġis Ġto Ġbe Ġexpected ." ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUi Configuration . Builder . from Manifest ( application Context ). build () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinitialize Properties From Bundle ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( savedInstanceState Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsavedInstanceState . getString ( KEY _ SCREEN )?. let Ġ{ Ġscreen Ġ= ĠLogin Screen . valueOf ( savedInstanceState . getString ( KEY _ SCREEN )) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsavedInstanceState . get Parcelable < Parcelable >( KEY _ CURRENT _ IDENTIFIER )?. let Ġ{ Ġcurrent Identifier Ġ= ĠsavedInstanceState . get Parcelable ( KEY _ CURRENT _ IDENTIFIER ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . is Smart lock Running Ġ= ĠsavedInstanceState . getBoolean ( KEY _ SM ART LOCK _ RESOL V ING ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( savedInstanceState . getInt ( KEY _ FLOW _ TYPE ) Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactive Flow Type Ġ= ĠFlow Selection Listener . Flow Type . LOGIN ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( savedInstanceState . getInt ( KEY _ FLOW _ TYPE ) Ġ== Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactive Flow Type Ġ= ĠFlow Selection Listener . Flow Type . SIGN _ UP ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBase Login Activity . tracker ?. reset Context () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBase Login Activity . tracker ?. flow Variant Ġ= ĠTracking Data . Flow Variant . PASSWORD ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinitialize Smart lock () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( Smart lock Impl . is Smart lock Available () Ġ&& Ġui Configuration . smart lock Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogin Controller Ġ= ĠLogin Controller ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsmart lock Ġ= ĠSmart lock Impl ( this , Ġlogin Controller !! , Ġlogin Contract ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Smart lock Running ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠprogressBar . visibility Ġ= ĠG ONE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠprogressBar . visibility Ġ= ĠVIS IBLE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsmart lock ?. start () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . is Smart lock Running Ġ= Ġsmart lock ?. is Smart lock Res olving Ġ?: Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠprogressBar . visibility Ġ= ĠG ONE ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfollow Deep Link ( data String : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġaction Ġ= ĠDeep Link Handler . resolve Deep Link ( data String ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDeep Link . Validate Account Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalidate Account ( action ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDeep Link . Identifier Provided Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( navigation Controller . current Fragment ?. tag Ġ== ĠLogin Screen . WEB _ FOR G OT _ PASSWORD _ SCREEN . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnavigation Controller . navigate Back To ( Login Screen . PASSWORD _ SCREEN ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( navigation Controller . current Fragment ?. tag Ġ== ĠLogin Screen . IDENT IFICATION _ SCREEN . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfrag Ġ= Ġnavigation Controller . current Fragment Ġas ĠEmail Identification Fragment ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfrag . pref ill Identifier ( action . identifier ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstart Identification Fragment ( flow Selection Listener : ĠFlow Selection Listener ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfragment Ġ= Ġfragment Provider . get OrCreate Identification Fragment ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnavigation Controller . current Fragment , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier Type Ġ= ĠIdentifier . Identifier Type . EMAIL . value , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflow Selection Listener Ġ= Ġflow Selection Listener ) ĊĠĠĠĠĠĠĠ Ġnavigation Controller . navigate To Fragment ( fragment Ġas ĠAbstract Identification Fragment ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġvalidate Account ( state : ĠDeep Link . Validate Account ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLogger . info ( TAG , Ġ{ Ġ" At tempting Ġlogin Ġfrom Ġdeep Ġlink , Ġextracting Ġcode " Ġ}) ĊĠĠĠĠĠĠĠ ĠBase Login Activity . tracker ?. event Action Successful ( Tracking Data . Sp id Action . ACCOUNT _ VER IFI ED ) ĊĊĠĠĠĠĠĠĠ ĠUser . from Session Code ( state . code , Ġui Configuration . redirect Uri . toString (), Ġstate . is Persist able , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResult Callback . from Lambda ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġerror Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . info ( TAG , Ġ{ Ġ" Automatic Ġlogin Ġafter Ġaccount Ġvalidation Ġfailed : Ġ${ error . message }" Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġuser Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . info ( TAG , Ġ{ Ġ" Automatic Ġlogin Ġafter Ġaccount Ġvalidation Ġwas Ġsuccessful " Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBase Login Activity . tracker ?. event Action Successful ( Tracking Data . Sp id Action . LOGIN _ COMPLETED , Ġuser . userId . legacy Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnavigation Controller . finish Flow ( user ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġset Ġup Ġthe Ġkeyboard Ġaction Listener ĊĠĠĠĠ Ġ* Ġ[ Flow Fragment . on Visibility Changed ] Ġis Ġcalled Ġwhen Ġa Ġlayout Ġchange Ġoccurs Ġdue Ġto ĊĠĠĠĠ Ġ* Ġa Ġchange Ġof Ġthe Ġsoft Ġkeyboard Ġvisibility ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun ĠsetUp Keyboard Listener () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkeyboard Threshold Ġ= Ġ 1 5 0 f ĊĠĠĠĠĠĠĠ Ġlayout Listener Ġ= Ġobject Ġ: ĠView Tree Observer . On Global Layout Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġusable Space Ġ= ĠRect () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġpx Keyboard Threshold Ġ= Ġkeyboard Threshold Ġ* Ġ( resources . display Metrics . density D pi Ġ/ Ġ 1 6 0 f ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġvisible Threshold Ġ= ĠMath . round ( px Keyboard Threshold ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġvar ĠisOpen Already Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Global Layout () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactivity Root . getWindow Visible Display Frame ( usable Space ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġheight Diff Ġ= Ġactivity Root . root View . height Ġ- Ġusable Space . height () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkeyboard Is Open Ġ= Ġheight Diff Ġ> Ġvisible Threshold ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( keyboard Is Open Ġ!= ĠisOpen Already ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠisOpen Already Ġ= Ġkeyboard Is Open ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Keyboard Visibility Changed ( keyboard Is Open ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġactivity Root . view Tree Observer . add On Global Layout Listener ( layout Listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Resume () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Resume () ĊĠĠĠĠĠĠĠ ĠsetUp Keyboard Listener () ĊĠĠĠĠĠĠĠ Ġnavigation Controller . register ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Pause () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Pause () ĊĠĠĠĠĠĠĠ Ġactivity Root . view Tree Observer . remove Global On Layout Listener ( layout Listener ) ĊĠĠĠĠĠĠĠ Ġnavigation Controller . unregister () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Save InstanceState ( out State : ĠBundle ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Save InstanceState ( out State ) ĊĠĠĠĠĠĠĠ Ġout State . putString ( KEY _ SCREEN , Ġscreen ?. value ) ĊĠĠĠĠĠĠĠ Ġout State . put Int ( KEY _ FLOW _ TYPE , Ġactive Flow Type ?. let Ġ{ Ġif Ġ( is User Available ()) Ġ 2 Ġelse Ġ 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġout State . put Parcelable ( KEY _ CURRENT _ IDENTIFIER , Ġcurrent Identifier ) ĊĠĠĠĠĠĠĠ Ġout State . put Boolean ( KEY _ SM ART LOCK _ RESOL V ING , Ġthis . is Smart lock Running ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Options ItemSelected ( item : ĠMenuItem ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( item Ġ== Ġmenu ?. find Item ( R . id . close _ flow )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnavigation Controller . finish Navigation () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( item . itemId Ġ== Ġandroid . R . id . home ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Back Pressed () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . on Options ItemSelected ( item ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate Options Menu ( menu : ĠMenu ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . menu Ġ= Ġmenu ĊĠĠĠĠĠĠĠ Ġmenu Inflater . inflate ( R . menu . sch acc _ menu , Ġmenu ) ĊĠĠĠĠĠĠĠ Ġval Ġclose Item Ġ= Ġmenu . find Item ( R . id . close _ flow ) ĊĠĠĠĠĠĠĠ Ġclose Item . icon Ġ= ĠUi Util . get Tint Drawable ( this , Ġclose Item . icon , ĠR . color . sch acc _ toolbar Icons Color ) ĊĠĠĠĠĠĠĠ Ġupdate ActionBar () ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Activity Result ( request Code : ĠInt , ĠresultCode : ĠInt , Ġdata : ĠIntent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Activity Result ( request Code , ĠresultCode , Ġdata ) ĊĠĠĠĠĠĠĠ Ġif Ġ( result Code Ġ== ĠActivity . RESULT _ OK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsmart lock Credentials Ġ= Ġdata . get Parcelable Extra ( Smart lock Impl . EXTRA _ SM ART LOCK _ CRED ENTIAL S ) Ġas ĠParcel able ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( request Code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSmart lock Impl . RC _ CH OOSE _ ACCOUNT Ġ-> Ġsmart lock ?. provide Credential ( smart lock Credentials ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSmart lock Impl . RC _ IDENTIFIER _ ONLY Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsmart lock ?. provide Hint ( smart lock Credentials ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfragment Provider Ġ= ĠFragment Provider ( ui Configuration ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Identification Fragment ( if Ġ( this Ġis ĠFlow Selection Listener ) Ġthis Ġelse Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠprogressBar . visibility Ġ= ĠG ONE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . is Smart lock Running Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsmart lock ?. on Failure () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġsetup Ġthe Ġ[ Toolbar ] Ġdepending Ġon Ġclient Ġconfigurations ĊĠĠĠĠ Ġ* Ġif Ġthe Ġ[ Toolbar ] Ġis Ġprovided Ġby Ġthe ĠTheme Ġthe ĠUI Ġflow Ġwill Ġuse Ġit ĊĠĠĠĠ Ġ* Ġelse Ġa Ġ[ Toolbar ] Ġneed Ġto Ġbe Ġset Ġup . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun ĠsetUp ActionBar () Ġ{ ĊĠĠĠĠĠĠĠ Ġset Support ActionBar ( toolbar ) ĊĠĠĠĠĠĠĠ Ġtoolbar _ title . setTextColor ( Context Compat . getColor ( this , ĠR . color . sch acc _ primary Header )) ĊĠĠĠĠĠĠĠ Ġtoolbar _ back _ arrow . setOnClickListener Ġ{ Ġon Back Pressed () Ġ} ĊĠĠĠĠĠĠĠ Ġsupport ActionBar ?. set Display Show Title Enabled ( false ) ĊĠĠĠĠĠĠĠ Ġsupport ActionBar ?. elevation Ġ= Ġ 1 f ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġis Keyboard Open (): ĠBoolean Ġ= Ġkeyboard Is Open ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCloses Ġdown Ġthe Ġkeyboard ĊĠĠĠĠ Ġ* ĠOn Ġsome Ġdevices Ġkeyboard Ġmay Ġstill Ġbe Ġshowing Ġup , Ġeven Ġon Ġscreen Ġwithout Ġfield Ġto Ġfill Ġin ĊĠĠĠĠ Ġ* ĠBecause Ġthe Ġkeyboard Ġis Ġnot Ġpart Ġof Ġthe Ġapplication Ġa Ġdifferent Ġbehavior Ġmight Ġoccurs Ġdepending ĊĠĠĠĠ Ġ* Ġon Ġthe Ġsystem Ġimplementation . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġclose Keyboard () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġimm Ġ= Ġget System Service ( Context . INPUT _ METHOD _ SERVICE ) Ġas ĠInput Method Manager ĊĠĠĠĠĠĠĠ Ġimm . hide Soft Input From Window ( window . decor View . window Token , Ġ 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate ActionBar () Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate Title ( screen ) ĊĠĠĠĠĠĠĠ Ġmenu ?. find Item ( R . id . close _ flow )?. isVisible Ġ= Ġui Configuration . is Closing Allowed ĊĠĠĠĠĠĠĠ Ġif Ġ( screen Ġ== ĠLogin Screen . IDENT IFICATION _ SCREEN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtoolbar _ back _ arrow . visibility Ġ= ĠView . GONE ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtoolbar _ back _ arrow . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUpdate Ġthe Ġtitle Ġof Ġthe Ġactivity Ġdepending Ġon Ġthe Ġscreen Ġdisplayed ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġscreen Ġthe Ġscreen Ġcurrently Ġdisplayed ĊĠĠĠĠ Ġ* Ġ@ see ĠLogin Screen ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġupdate Title ( screen : ĠLogin Screen ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ String Res ĊĠĠĠĠĠĠĠ Ġval Ġtitle : ĠInt Ġ= Ġwhen Ġ( screen ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . IDENT IFICATION _ SCREEN Ġ-> Ġif Ġ( this . ui Configuration . sign Up Enabled ) ĠR . string . sch acc _ identification _ title Ġelse ĠR . string . sch acc _ identification _ login _ only _ title ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . PASSWORD _ SCREEN Ġ-> Ġif Ġ( is User Available ()) ĠR . string . sch acc _ register _ title Ġelse ĠR . string . sch acc _ welcome _ back _ title ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . TC _ SCREEN Ġ-> ĠR . string . sch acc _ terms _ title ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . REQUIRED _ FIELDS _ SCREEN Ġ-> ĠR . string . sch acc _ required _ fields _ title ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . CHECK _ IN BOX _ SCREEN Ġ-> ĠR . string . sch acc _ inbox _ check _ inbox _ title ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . WEB _ FOR G OT _ PASSWORD _ SCREEN Ġ-> ĠR . string . sch acc _ web _ forgot _ password _ title ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . WEB _ NEED _ HELP _ SCREEN Ġ-> ĠR . string . sch acc _ web _ need _ help _ title ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . VER IFICATION _ SCREEN Ġ-> ĠR . string . sch acc _ verification _ title ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . WEB _ TC _ SCREEN Ġ-> Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġif Ġ( Smart lock Impl . is Smart lock Available ()) ĠR . string . sch acc _ identification _ login _ only _ title Ġelse Ġthrow ĠResources . NotFoundException (" Resource Ġnot Ġfound ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtoolbar _ title . text Ġ= ĠgetString ( title ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Keyboard Visibility Changed ( keyboard Open : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( navigation Controller . current Fragment Ġis ĠFlow Fragment <* >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( navigation Controller . current Fragment Ġas ĠFlow Fragment < *> ). on Visibility Changed ( keyboard Open ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Back Pressed () Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( screen ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . VER IFICATION _ SCREEN , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . PASSWORD _ SCREEN , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogin Screen . CHECK _ IN BOX _ SCREEN Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Identifier Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġis User Available () Ġ= Ġactive Flow Type Ġ== ĠFlow Selection Listener . Flow Type . SIGN _ UP ĊĊĠĠĠ Ġoverride Ġfun Ġon WebView Navigation Requested ( where : ĠWeb Fragment , Ġlogin Screen : ĠLogin Screen ) Ġ{ ĊĠĠĠĠĠĠĠ Ġnavigation Controller . navigate To WebView ( where , Ġlogin Screen ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Dialog Navigation Requested ( where : ĠDialog Fragment ) Ġ{ ĊĠĠĠĠĠĠĠ Ġnavigation Controller . navigation To Dialog ( where ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Navigate Back Requested () Ġ{ ĊĠĠĠĠĠĠĠ Ġon Back Pressed () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Navigation Done ( screen : ĠLogin Screen ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . screen Ġ= Ġscreen ĊĠĠĠĠĠĠĠ Ġupdate ActionBar () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon New Intent ( intent : ĠIntent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on New Intent ( intent ) ĊĠĠĠĠĠĠĠ Ġfollow Deep Link ( intent . data String ) ĊĠĠĠ Ġ} Ċ } Ċ