/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 Ġcom . example . android . u amp . autom otive Ċ Ċ import Ġandroid . content . Intent Ċ import Ġandroid . os . Build Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . text . InputType Ċ import Ġandroid . text . TextUtils Ċ import Ġandroid . text . method . Link Movement Method Ċ import Ġandroid . view . LayoutInflater Ċ import Ġandroid . view . View Ċ import Ġandroid . view . View . AUT OF ILL _ HINT _ USERNAME Ċ import Ġandroid . view . ViewGroup Ċ import Ġandroid . widget . Button Ċ import Ġandroid . widget . ImageView Ċ import Ġandroid . widget . TextView Ċ import Ġandroid . widget . Toast Ċ import Ġandroidx . appcompat . widget . Toolbar Ċ import Ġandroidx . core . text . Html Compat Ċ import Ġandroidx . fragment . app . Fragment Ċ import Ġcom . google . android . gms . auth . api . signin . Google SignIn Ċ import Ġcom . google . android . gms . auth . api . signin . Google SignIn Account Ċ import Ġcom . google . android . gms . auth . api . signin . Google SignIn Options Ċ import Ġcom . google . android . gms . common . Connection Result Ċ import Ġcom . google . android . gms . common . Google Api Availability Ċ import Ġcom . google . android . gms . common . api . ApiException Ċ import Ġcom . google . android . gms . tasks . Task Ċ import Ġcom . google . android . material . text field . TextInput EditText Ċ import Ġcom . google . android . material . text field . TextInput Layout Ċ Ċ const Ġval ĠRC _ SIGN _ IN Ġ= Ġ 9 0 0 1 Ċ const Ġval ĠP LAY _ SERVICES _ RESOL UTION _ REQUEST Ġ= Ġ 9 0 0 0 Ċ Ċ // ĠControl Ġthe Ġsupported Ġsign Ġin Ġflows Ġby Ġto g gling Ġthe Ġconstants Ġbelow . Ċ const Ġval ĠENABLE _ PIN _ SIGN _ IN Ġ= Ġtrue Ċ const Ġval ĠENABLE _ QR _ CODE _ SIGN _ IN Ġ= Ġtrue Ċ const Ġval ĠENABLE _ GOOGLE _ SIGN _ IN Ġ= Ġtrue Ċ const Ġval ĠENABLE _ USERNAME _ PASSWORD _ SIGN _ IN Ġ= Ġtrue Ċ Ċ /** Ċ Ġ* ĠA Ġfragment Ġthat Ġrenders Ġthe Ġlanding Ġscreen Ġfor Ġa Ġsign - in Ġflow . ĠThis Ġscreen Ġcan Ġbe Ġconfigured Ċ Ġ* Ġto Ġdisplay Ġthird - party Ġsign - in , ĠPIN Ġsign - in , ĠQR - code Ġsign - in Ġand / or ĠGoogle Ġsign - in . Ċ Ġ*/ Ċ class ĠSign In Landing Page Fragment Ġ: ĠFragment () Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġinternal Ġconst Ġval ĠCAR _ SIGN _ IN _ IDENTIFIER _ KEY Ġ= Ġ" userID " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġtoolbar : ĠToolbar ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġapp Icon : ĠImageView ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġphone SignIn Button : ĠButton ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġgoogle SignIn Button : ĠButton ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġusername And Password SignIn Button : ĠButton ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġprimary TextView : ĠTextView ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġidentifier Container : ĠText Input Layout ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġidentifier Input : ĠText Input EditText ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġfooter TextView : ĠTextView ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate View ( ĊĠĠĠĠĠĠĠ Ġinflater : ĠLayoutInflater , Ġcontainer : ĠViewGroup ?, ĊĠĠĠĠĠĠĠ ĠsavedInstanceState : ĠBundle ? ĊĠĠĠ Ġ): ĠView ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlayout Ġ= Ġif Ġ( ENABLE _ USERNAME _ PASSWORD _ SIGN _ IN ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠR . layout . sign _ in _ landing _ page _ with _ username _ and _ password ĊĠĠĠĠĠĠĠ Ġelse ĠR . layout . sign _ in _ landing _ page ĊĊĠĠĠĠĠĠĠ Ġreturn Ġinflater . inflate ( layout , Ġcontainer , Ġfalse ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon View Created ( view : ĠView , ĠsavedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on View Created ( view , ĠsavedInstanceState ) ĊĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= Ġrequire Context () ĊĊĠĠĠĠĠĠĠ Ġtoolbar Ġ= Ġview . findViewById ( R . id . toolbar ) ĊĠĠĠĠĠĠĠ Ġapp Icon Ġ= Ġview . findViewById ( R . id . app _ icon ) ĊĠĠĠĠĠĠĠ Ġprimary TextView Ġ= Ġview . findViewById ( R . id . primary _ message ) ĊĠĠĠĠĠĠĠ Ġfooter TextView Ġ= Ġview . findViewById ( R . id . footer ) ĊĠĠĠĠĠĠĠ Ġphone SignIn Button Ġ= Ġview . findViewById ( R . id . phone _ sign _ in _ button ) ĊĠĠĠĠĠĠĠ Ġgoogle SignIn Button Ġ= Ġview . findViewById ( R . id . google _ sign _ in _ button ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( ENABLE _ USERNAME _ PASSWORD _ SIGN _ IN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġusername And Password SignIn Button Ġ= Ġview . findViewById ( R . id . sign _ in _ button ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier Container Ġ= Ġview . findViewById ( R . id . identifier _ container ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier Input Ġ= Ġview . findViewById ( R . id . identifier _ input ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . O ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier Input . set Aut ofill Hints ( AUT OF ILL _ HINT _ USERNAME ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġtoolbar . set Navigation OnClickListener Ġ{ Ġrequire Activity (). finish () Ġ} ĊĊĠĠĠĠĠĠĠ Ġapp Icon . setImage Drawable ( context . get Drawable ( R . drawable . a ural _ logo )) ĊĠĠĠĠĠĠĠ Ġprimary TextView . text Ġ= ĠgetString ( R . string . sign _ in _ primary _ text ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠLinks Ġin Ġfooter Ġtext Ġshould Ġbe Ġclick able . ĊĠĠĠĠĠĠĠ Ġfooter TextView . text Ġ= ĠHtml Compat . from Html ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . getString ( R . string . sign _ in _ footer ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHtml Compat . FROM _ HTML _ MODE _ LEG ACY ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġfooter TextView . movement Method Ġ= ĠLink Movement Method . getInstance () ĊĊĠĠĠĠĠĠĠ Ġconfigure Username And Password SignIn () ĊĠĠĠĠĠĠĠ Ġconfigure Phone SignIn () ĊĠĠĠĠĠĠĠ Ġconfigure Google SignIn () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconfigure Username And Password SignIn () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! ENABLE _ USERNAME _ PASSWORD _ SIGN _ IN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġidentifier Container . hint Ġ= ĠgetString ( R . string . sign _ in _ user _ id _ hint ) ĊĠĠĠĠĠĠĠ Ġidentifier Input . input Type Ġ= ĠInput Type . TYPE _ CLASS _ TEXT ĊĊĠĠĠĠĠĠĠ Ġusername And Password SignIn Button . text Ġ= ĠgetString ( R . string . sign _ in _ next _ button _ label ) ĊĠĠĠĠĠĠĠ Ġusername And Password SignIn Button . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġidentifier Ġ= Ġidentifier Input . text ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( TextUtils . isEmpty ( identifier )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier Input . error Ġ= ĠgetString ( R . string . sign _ in _ username _ error ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġargs Ġ= ĠBundle () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs . putString ( CAR _ SIGN _ IN _ IDENTIFIER _ KEY , Ġidentifier Input . text . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfragment Ġ= ĠUsername And Password SignIn Fragment () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfragment . arguments Ġ= Ġargs ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire Activity (). support FragmentManager . beginTransaction () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( R . id . sign _ in _ container , Ġfragment ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. addTo Back Stack (" landing Page ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. commit () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconfigure Phone SignIn () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! ENABLE _ QR _ CODE _ SIGN _ IN Ġ&& Ġ! ENABLE _ PIN _ SIGN _ IN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġphone SignIn Button . visibility Ġ= ĠView . GONE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġphone SignIn Fragment : ĠFragment ĊĊĠĠĠĠĠĠĠ Ġif Ġ( ENABLE _ QR _ CODE _ SIGN _ IN Ġ&& ĠENABLE _ PIN _ SIGN _ IN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠReduce Ġthe Ġnumber Ġof Ġchoices Ġdisplayed Ġto Ġthe Ġuser Ġin Ġa Ġsingle Ġscreen . ĠIf Ġboth ĠPIN ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġand ĠQR Ġcode Ġsign Ġin Ġis Ġenabled , Ġseparate Ġthe Ġchoice Ġbetween Ġthe Ġtwo Ġoptions Ġto Ġa ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnew Ġscreen . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġphone SignIn Fragment Ġ= ĠPhone SignIn Fragment () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( ENABLE _ PIN _ SIGN _ IN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġphone SignIn Fragment Ġ= ĠPin Code SignIn Fragment () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( ENABLE _ QR _ CODE _ SIGN _ IN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġphone SignIn Fragment Ġ= ĠQ r Code SignIn Fragment () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġphone SignIn Button . text Ġ= ĠgetString ( R . string . phone _ sign _ in _ button _ label ) ĊĠĠĠĠĠĠĠ Ġphone SignIn Button . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire Activity (). support FragmentManager . beginTransaction () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( R . id . sign _ in _ container , Ġphone SignIn Fragment ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. addTo Back Stack (" landing Page ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. commit () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠConfigure Ġthe ĠGoogle Ġsign Ġin Ġoption Ġon Ġthe Ġlanding Ġpage . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ< p > https :// developers . google . com / identity / sign - in / android / start Ġprovides Ġadditional ĊĠĠĠĠ Ġ* Ġinformation Ġon Ġintegr ating ĠGoogle Ġsign Ġin Ġinto Ġyour ĠAndroid Ġapp . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġconfigure Google SignIn () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! ENABLE _ GOOGLE _ SIGN _ IN Ġor Ġ! check Play Services ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgoogle SignIn Button . visibility Ġ= ĠView . GONE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġg so Ġ= ĠGoogle SignIn Options . Builder ( Google SignIn Options . DEFAULT _ SIGN _ IN ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. requestId Token ( getString ( R . string . server _ client _ id )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. request Email () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġgoogle SignIn Button . text Ġ= ĠgetString ( R . string . google _ sign _ in _ button _ label ) ĊĊĠĠĠĠĠĠĠ Ġgoogle SignIn Button . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm Google SignIn Client Ġ= ĠGoogle SignIn . getClient ( require Context (), Ġg so ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsign In Intent Ġ= Ġm Google SignIn Client . signIn Intent ĊĠĠĠĠĠĠĠĠĠĠĠ ĠstartActivity For Result ( signIn Intent , ĠRC _ SIGN _ IN ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Play Services (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġapi Availability Ġ= ĠGoogle Api Availability . getInstance (); ĊĠĠĠĠĠĠĠ Ġval ĠresultCode Ġ= Ġcontext ?. let Ġ{ Ġapi Availability . is Google Play Services Available ( it ) Ġ}; ĊĠĠĠĠĠĠĠ Ġif Ġ( result Code Ġ!= ĠConnection Result . SUCCESS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Code ?. let Ġ{ Ġapi Availability . is User Res olvable Error ( it ) Ġ} Ġ== Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactivity ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapi Availability . getError Dialog ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit , ĠresultCode , ĠP LAY _ SERVICES _ RESOL UTION _ REQUEST ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ?. show () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}; ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ; ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ; ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Activity Result ( request Code : ĠInt , ĠresultCode : ĠInt , Ġdata : ĠIntent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Activity Result ( request Code , ĠresultCode , Ġdata ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( request Code Ġ== ĠRC _ SIGN _ IN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtask Ġ= ĠGoogle SignIn . get Signed In Account From Intent ( data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Google SignIn ( task ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Google SignIn ( completed Task : ĠTask < Google SignIn Account >) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaccount Ġ= Ġcompleted Task . getResult ( ApiException :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Suppress (" unused _ variable ") Ġval Ġid Token Ġ= Ġaccount ?. id Token ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSend ĠID ĠToken Ġto Ġserver Ġand Ġvalidate . ĊĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠApiException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe ĠApiException Ġstatus Ġcode Ġindicates Ġthe Ġdetailed Ġfailure Ġreason . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠPlease Ġrefer Ġto Ġthe ĠGoogle SignIn StatusCode s Ġclass Ġreference Ġfor Ġmore Ġinformation . ĊĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire Context (), ĠgetString ( R . string . sign _ in _ failed _ message , Ġe . statusCode ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . LENGTH _ SHORT ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. show () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }