package Ġdesign . code ux . aut ofill _ service Ċ Ċ import Ġandroid . annotation . Target Api Ċ import Ġandroid . app .* Ċ import Ġandroid . app . assist . Ass ist Structure Ċ import Ġandroid . content .* Ċ import Ġandroid . content . pm . PackageManager Ċ import Ġandroid . os .* Ċ import Ġandroid . service . aut ofill .* Ċ import Ġandroid . view .* Ċ import Ġandroid . view . aut ofill .* Ċ Ċ import Ġandroidx . annotation . Requires Api Ċ import Ġmu . Kotlin Logging Ċ import Ġandroid . widget . Remote Views Ċ import Ġandroidx . annotation . Drawable Res Ċ import Ġjava . lang . RuntimeException Ċ import Ġjava . util .* ĊĊ Ċ private Ġval Ġlogger Ġ= ĠKotlin Logging . logger Ġ{} Ċ Ċ @ Requires Api ( api Ġ= ĠBuild . VERSION _ CODES . O ) Ċ class ĠFlutter My Aut ofill Service Ġ: ĠAut ofill Service () Ġ{ ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġautof ill Preference Store : ĠAut ofill Preference Store ĊĠĠĠ Ġprivate Ġvar Ġunlock Label Ġ= Ġ" Aut ofill " ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate () ĊĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Aut ofill Ġservice Ġwas Ġcreated ." Ġ} ĊĠĠĠĠĠĠĠ Ġautof ill Preference Store Ġ= ĠAut ofill Preference Store . getInstance ( application Context ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Connected () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Connected () ĊĠĠĠĠĠĠĠ Ġlogger . debug (" on Connected .") ĊĠĠĠĠĠĠĠ Ġval Ġself Ġ= ĠComponent Name ( this , Ġjava Class ) ĊĊĠĠĠĠĠĠĠ Ġval ĠmetaData Ġ= Ġpackage Manager . getService Info ( self , ĠPackage Manager . GET _ META _ DATA ). metaData ĊĠĠĠĠĠĠĠ ĠmetaData . getString (" design . code ux . aut ofill _ service . unlock _ label ") ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġunlock Label Ġ= Ġit ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlogger . info (" Unlock Ġlabel Ġwill Ġbe Ġ$ unlock Label ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Fill Request ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest : ĠFill Request , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcancellation Signal : ĠC ancellation Signal , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback : ĠFill Callback ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ" Got Ġfill Ġrequest Ġ$ request " Ġ} Ċ // ĠĠĠĠĠĠĠ Ġapplication Context . package Manager . get Launch Intent For Package ( application Context . packageName ) ĊĊĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= Ġrequest . fill Contexts . last () ĊĠĠĠĠĠĠĠ Ġval Ġparser Ġ= ĠAss ist Structure Parser ( context . structure ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġuse Label Ġ= Ġunlock Label ĊĠĠĠĠĠĠĠ Ġif Ġ( parser . field Ids [ Aut ofill InputType . Password ]. isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdetected Fields Ġ= Ġparser . field Ids . flatMap Ġ{ Ġit . value Ġ}. size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" got Ġautof ill Preferences : Ġ${ aut ofill Preference Store . aut ofill Preferences }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! aut ofill Preference Store . aut ofill Preferences . enable Debug ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . on Success ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuse Label Ġ= Ġ" Debug : ĠNo Ġpassword Ġfields Ġdetected Ġ($ detected Fields Ġtotal )." ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġstart Intent Ġ= ĠIntent () ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠFigure Ġthis Ġout Ġhow Ġto Ġdo Ġthis Ġwithout Ġhard Ġcoding Ġeverything .. ĊĠĠĠĠĠĠĠ Ġstart Intent . set ClassName ( application Context , Ġ" com . ca olv . l alia . MainActivity ") ĊĠĠĠĠĠĠĠ Ġstart Intent . action Ġ= ĠIntent . ACTION _ RUN ĊĠĠĠĠĠĠĠ Ġ// " design . code ux . aut ofill _ service _ example . MainActivity ") Ċ // ĠĠĠĠĠĠĠ Ġval Ġstart Intent Ġ= ĠIntent ( Intent . ACTION _ MAIN ). apply Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ` package ` Ġ= Ġapplication Context . packageName Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Creating Ġcustom Ġintent ." Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġstart Intent . flags Ġ= ĠIntent . FLAG _ ACTIVITY _ NEW _ TASK ĊĠĠĠĠĠĠĠ Ġstart Intent . putExtra (" route ", Ġ"/ aut ofill ") ĊĠĠĠĠĠĠĠ Ġstart Intent . putExtra (" initial _ route ", Ġ"/ aut ofill ") ĊĠĠĠĠĠĠĠ Ġparser . packageName ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Intent . putExtra ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" aut ofill PackageName ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġparser . web Domain ?. let Ġ{ Ġstart Intent . putExtra (" aut ofill Web Domain ", Ġit ) Ġ} Ċ // ĠĠĠĠĠĠĠ Ġstart Intent . put Parcelable ArrayList Extra (" aut ofill Ids ", ĠArrayList ( parser . auto Fill Ids )) ĊĠĠĠĠĠĠĠ Ġval Ġintent Sender : ĠIntent Sender Ġ= ĠPending Intent . getActivity ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Intent , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPending Intent . FLAG _ CANCEL _ CURRENT ĊĠĠĠĠĠĠĠ Ġ). intent Sender ĊĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" start Intent :$ start Intent Ġ(${ start Intent . extras }) Ġ- Ġsender : Ġ$ intent Sender " Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġauto Fill Ids Ġ= Ġparser . auto Fill Ids . distinct () ĊĊĠĠĠĠĠĠĠ Ġ// ĠBuild Ġa ĠFill Response Ġobject Ġthat Ġrequires Ġauthentication . ĊĠĠĠĠĠĠĠ Ġval Ġfill Response Builder : ĠFill Response . Builder Ġ= ĠFill Response . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Authentication ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġauto Fill Ids . to Typed Array (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintent Sender , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRemote Views Helper . views With Auth ( packageName , Ġuse Label ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġlogger . info Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" remote View Ġfor ĠpackageName : Ġ$ packageName Ġ-- Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" detected Ġautof ill ĠpackageName : Ġ${ parser . packageName } Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" web Domain : Ġ${ parser . web Domain }" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" auto Fill Ids : Ġ${ auto Fill Ids . size }" ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġfill Response Ġ= Ġfill Response Builder . build () ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcallback . on Success ( fill Response ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠTransaction Too Large Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRuntimeException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Too Ġmany Ġauto Ġfill Ġids Ġdiscovered Ġ${ auto Fill Ids . size } Ġfor Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ parser . web Domain }, Ġ Ġ${ parser . packageName }", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Save Request ( request : ĠSave Request , Ġcallback : ĠSave Callback ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ" on Save Request . Ġbut Ġnot Ġyet Ġimplemented ." Ġ} ĊĠĠĠĠĠĠĠ Ġcallback . on Failure (" Not Ġimplemented ") ĊĠĠĠ Ġ} ĊĊ Ċ } ĊĊ Ċ /** Ċ Ġ* ĠThis Ġis Ġa Ġclass Ġcontaining Ġhelper Ġmethods Ġfor Ġbuilding ĠAut ofill ĠData sets Ġand ĠResponse s . Ċ Ġ*/ Ċ object ĠRemote Views Helper Ġ{ ĊĊĠĠĠ Ġfun Ġview sWith Auth ( packageName : ĠString , Ġtext : ĠString ): ĠRemote Views Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsimple Remote Views ( packageName , Ġtext , ĠR . drawable . ic _ lock _ black _ 2 4 dp ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġview sWith No Auth ( packageName : ĠString , Ġtext : ĠString ): ĠRemote Views Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsimple Remote Views ( packageName , Ġtext , ĠR . drawable . ic _ person _ black _ 2 4 dp ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsimple Remote Views ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠpackageName : ĠString , Ġremote Views Text : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Drawable Res Ġdrawable Id : ĠInt ĊĠĠĠ Ġ): ĠRemote Views Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpresentation Ġ= ĠRemote Views ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠpackageName , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . layout . mult idata set _ service _ list _ item ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġpresentation . setText View Text ( R . id . text , Ġremote Views Text ) ĊĠĠĠĠĠĠĠ Ġpresentation . set ImageView Resource ( R . id . icon , Ġdrawable Id ) ĊĠĠĠĠĠĠĠ Ġreturn Ġpresentation ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠAut ofill He uristic ( ĊĠĠĠĠĠĠĠ Ġval Ġweight : ĠInt , ĊĠĠĠĠĠĠĠ Ġval Ġpredicate : ĠAss ist Structure . View Node .( node : ĠAss ist Structure . View Node ) Ġ-> ĠBoolean Ċ ) Ċ Ċ private Ġfun ĠMutable List < Aut ofill He uristic >. he uristic ( ĊĠĠĠĠĠĠĠ Ġweight : ĠInt , ĊĠĠĠĠĠĠĠ Ġpredicate : ĠAss ist Structure . View Node .( node : ĠAss ist Structure . View Node ) Ġ-> ĠBoolean Ċ ) Ġ= ĊĠĠĠĠĠĠĠ Ġadd ( Aut ofill He uristic ( weight , Ġpredicate )) ĊĊ Ċ @ Target Api ( Build . VERSION _ CODES . O ) Ċ private Ġfun ĠMutable List < Aut ofill He uristic >. aut ofill Hint ( weight : ĠInt , Ġhint : ĠString ) Ġ= ĊĠĠĠĠĠĠĠ Ġhe uristic ( weight ) Ġ{ Ġautof ill Hints ?. contains ( hint ) Ġ== Ġtrue Ġ} Ċ Ċ @ Target Api ( Build . VERSION _ CODES . O ) Ċ private Ġfun ĠMutable List < Aut ofill He uristic >. id Entry ( weight : ĠInt , Ġmatch : ĠString ) Ġ= ĊĠĠĠĠĠĠĠ Ġhe uristic ( weight ) Ġ{ Ġid Entry Ġ== Ġmatch Ġ} Ċ Ċ @ Target Api ( Build . VERSION _ CODES . O ) Ċ private Ġfun ĠMutable List < Aut ofill He uristic >. html Attribute ( weight : ĠInt , Ġattr : ĠString , Ġvalue : ĠString ) Ġ= ĊĠĠĠĠĠĠĠ Ġhe uristic ( weight ) Ġ{ Ġhtml Info ?. attributes ?. first OrNull Ġ{ Ġit . first Ġ== Ġattr Ġ&& Ġit . second Ġ== Ġvalue Ġ} Ġ!= Ġnull Ġ} Ċ Ċ @ Target Api ( Build . VERSION _ CODES . O ) Ċ private Ġfun ĠMutable List < Aut ofill He uristic >. defaults ( hint : ĠString , Ġmatch : ĠString ) Ġ{ ĊĠĠĠ Ġautof ill Hint ( 9 0 0 , Ġhint ) ĊĠĠĠ Ġid Entry ( 8 0 0 , Ġmatch ) ĊĠĠĠ Ġhe uristic ( 7 0 0 ) Ġ{ Ġid Entry ?. toLowerCase ( Locale . ROOT )?. contains (" user ") Ġ== Ġtrue Ġ} Ċ } Ċ Ċ @ Target Api ( Build . VERSION _ CODES . O ) Ċ enum Ġclass ĠAut ofill InputType ( val Ġhe ur istics : ĠList < Aut ofill He uristic >) Ġ{ ĊĠĠĠ ĠEmail ( mutable ListOf < Aut ofill He uristic >(). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġdefaults ( View . AUT OF ILL _ HINT _ EMAIL _ ADDRESS , Ġ" email ") ĊĠĠĠĠĠĠĠ Ġhtml Attribute ( 4 0 0 , Ġ" type ", Ġ" email ") ĊĠĠĠĠĠĠĠ Ġhtml Attribute ( 3 0 0 , Ġ" name ", Ġ" email ") ĊĠĠĠĠĠĠĠ Ġhe uristic ( 2 0 0 ) Ġ{ Ġhint ?. toLowerCase ( java . util . Locale . ROOT )?. contains (" mail ") Ġ== Ġtrue Ġ} ĊĠĠĠ Ġ}), ĊĠĠĠ ĠUser Name ( mutable ListOf < Aut ofill He uristic >(). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġdefaults ( View . AUT OF ILL _ HINT _ USERNAME , Ġ" user ") ĊĠĠĠĠĠĠĠ Ġhtml Attribute ( 4 0 0 , Ġ" name ", Ġ" user ") ĊĠĠĠĠĠĠĠ Ġhtml Attribute ( 4 0 0 , Ġ" name ", Ġ" username ") ĊĠĠĠ Ġ}), ĊĠĠĠ ĠPassword ( mutable ListOf < Aut ofill He uristic >(). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġdefaults ( View . AUT OF ILL _ HINT _ PASSWORD , Ġ" password ") ĊĠĠĠĠĠĠĠ Ġhtml Attribute ( 4 0 0 , Ġ" type ", Ġ" password ") ĊĠĠĠĠĠĠĠ Ġhe uristic ( 5 0 0 ) Ġ{ Ġinput Type . has Flag ( android . text . InputType . TYPE _ TEXT _ VARI ATION _ PASSWORD ) Ġ} ĊĠĠĠĠĠĠĠ Ġhe uristic ( 4 9 9 ) Ġ{ Ġinput Type . has Flag ( android . text . InputType . TYPE _ TEXT _ VARI ATION _ WEB _ PASSWORD ) Ġ} ĊĠĠĠĠĠĠĠ Ġhe uristic ( 4 9 8 ) Ġ{ Ġinput Type . has Flag ( android . text . InputType . TYPE _ TEXT _ VARI ATION _ VISIBLE _ PASSWORD ) Ġ} ĊĠĠĠ Ġ}), Ċ } ĊĊ Ċ inline Ġfun ĠInt ?. has Flag ( flag : ĠInt ) Ġ= Ġthis Ġ!= Ġnull Ġ&& Ġflag Ġand Ġthis Ġ== Ġflag Ċ inline Ġfun ĠInt . with Flag ( flag : ĠInt ) Ġ= Ġthis Ġor Ġflag Ċ inline Ġfun ĠInt . minus Flag ( flag : ĠInt ) Ġ= Ġthis Ġand Ġflag . inv () ĊĊ Ċ data Ġclass ĠMat ched Field ( val Ġhe uristic : ĠAut ofill He uristic , Ġval Ġautof ill Id : ĠAut ofill Id ) ĊĊ