package Ġme . c irq . aper . analyzer Ċ Ċ import Ġme . c irq . aper . RUN N ABLE _ CLASS Ċ import Ġme . c irq . aper . analyzer . report . Rev Step Report Ċ import Ġme . c irq . aper . analyzer . report . Step Report Ċ import Ġme . c irq . aper . entity .* Ċ import Ġme . c irq . aper . util .* Ċ import Ġso ot . Scene Ċ import Ġso ot . S oot Method ĊĊ Ċ enum Ġclass ĠH appen Before Follow Type ( private Ġval Ġdesc : ĠString ) Ġ{ ĊĠĠĠ ĠNo Declare And No Steps (" No ĠDeclare ĠAnd ĠNo ĠSteps "), ĊĠĠĠ ĠNo Declare With Steps (" Not ĠDecl ared ĠBut ĠHas ĠCHECK / REQUEST "), ĊĠĠĠ ĠDecl ared No Steps (" Only ĠDecl ared ĠAnd ĠNo ĠCHECK / REQUEST "), ĊĊĠĠĠ ĠSync Checked Already (" Check ĠS ynchronously ĠAlready "), ĊĠĠĠ ĠAsync Check Before Use (" Check ĠAs ynchronously ĠBefore ĠUse ĠAPI "), ĊĠĠĠ ĠNo Async Check Before Use (" No ĠAs ynchronous ĠCheck ĠBefore ĠUse ĠAPI "), ĊĠĠĠ ĠIs Handle No Check (" No ĠCheck ĠBecause ĠIs ĠHandle ĠAPI "), ĊĊĠĠĠ ĠSync Requested Already (" Request ĠS ynchronously ĠAlready "), ĊĠĠĠ ĠAsync Request Before Use (" Request ĠAs ynchronously ĠBefore ĠUse ĠAPI "), ĊĠĠĠ ĠNo Async Request Before Use (" No ĠAs ynchronous ĠRequest ĠBefore ĠUse ĠAPI "); ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ"[ ${ this . java Class . simple Name }] Ġ$ desc " ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġtype alias ĠH BF ollow Pair < T > Ġ= ĠPair < H appen Before Follow Type , Set < T > ?> Ċ Ċ type alias ĠH BF ollow Sit uation < T > Ġ= ĠSet < H BF ollow Pair < T >> ĊĊ Ċ /** Ċ Ġ* ĠFind Ġwhether Ġdeveloper Ġfollows Ġassumption Ġof Ġlo oper Ġexecution Ġorder Ġto Ġensure Ċ Ġ* Ġ Ġthe Ġpermission Ġis Ġgranted . ĠTypically , Ġ` two ` Ġtypes Ġof Ġorder Ġare Ġconsidered : Ċ Ġ* ĠĠĠĠĠ Ġ+ ĠAndroid Ġapplication Ġlifecycle Ċ Ġ* ĠĠĠĠĠ Ġ+ ĠRunnable / Callable Ġposting Ġlocation Ċ Ġ* Ċ Ġ* ĠTerm ly , Ġcalled Ġthe Ġ" As ynchronous Ġhappened - before Ġanalysis " Ċ Ġ*/ Ċ Ċ object ĠH appen Before Analyzer Ġ{ ĊĊĠĠĠ Ġprivate Ġobject ĠH appen Before Recorder Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġvalues Ġshould Ġhappen Ġbefore Ġkey ĊĠĠĠĠĠĠĠ Ġval Ġhappen _ before : ĠMutable Map < J Method , Mutable Set < J Method >> Ġ= ĠHashMap () ĊĊĠĠĠĠĠĠĠ Ġfun Ġput ( method : ĠJ Method , Ġhb Method : ĠJ Method ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( method Ġ! in Ġhappen _ before ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhappen _ before [ method ] Ġ= ĠHashSet () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhappen _ before [ method ] !!. add ( hb Method ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġget ( method : ĠJ Method ): ĠSet < J Method > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( method Ġ! in Ġhappen _ before ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhappen _ before [ method ] Ġ= ĠHashSet () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġhappen _ before [ method ] !! ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġindicate Ġthe Ġpredicate Ġ" this Ġhappens Ġbefore Ġthat " ĊĠĠĠ Ġprivate Ġin fix Ġfun ĠJ Method . hb ( that : ĠJ Method ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif ( that Ġ! in ĠH appen Before Recorder . h appen _ before ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠH appen Before Recorder . h appen _ before [ that ] Ġ= ĠHashSet () ĊĠĠĠĠĠĠĠ Ġreturn Ġthis Ġin ĠH appen Before Recorder . h appen _ before [ that ] !! ĊĠĠĠ Ġ} ĊĊĊĊĠĠĠ Ġfun Ġasynchronous Analyze ( reports : ĠSet < Step Report >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrev reports : ĠRev Step Report , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdump : ĠBoolean = false ): ĠMap < String , H BF ollow Sit uation < AC all Chain >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġasync Report Ġ= ĠHashMap < String , H BF ollow Sit uation < AC all Chain >>() ĊĠĠĠĠĠĠĠ Ġreports . forEach { Ġreport Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġneeds Ġ= Ġreport . permission Reports . keys ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdeclared Ġ= Ġreport . permission Reports . filter { Ġit . key Ġin Ġneeds Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map { Ġit . key Ġto Ġit . value . is Declared Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toMap () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsync Checked Ġ= Ġreport . permission Reports . values . any { Ġit . check Sites . isNotEmpty () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsync Requested Ġ= Ġreport . permission Reports . values . any { Ġit . request Sites . isNotEmpty () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchecks Ġ= Ġrev reports . check Map . values ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatten (). filter { Ġneeds . intersect ( it . permissions ). isNotEmpty () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequests Ġ= Ġrev reports . request Map . values ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatten (). filter { Ġneeds . intersect ( it . permissions ). isNotEmpty () Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatten (). filter { Ġwhen ( Permission Combination . get ( report . api )) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġeither Ġone Ġin Ġneeds Ġis Ġok Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAny Of Ġ-> Ġneeds . intersect ( it . permissions ). isNotEmpty () Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAll Of Ġ-> Ġneeds . union ( it . permissions ). size == needs . size Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġreport . store Path . toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġft Ġ= Ġanalyze Follow Type ( report . chain , Ġdeclared , Ġchecks , Ġrequests , Ġsync Checked , Ġsync Requested ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġasync Report [ key ] Ġ= Ġft ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif ( dump ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġr Ġ= Ġasync Report . map { Ġ( path , Ġtypes ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġtypes . map { Ġ( type , Ġchain ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchain ?. join ToString ("\ n \ t ", Ġ"$ type \ n \ t "){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . join ToString (" Ġ-> Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġtype ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. join ToString ("\ n --- \ n ", Ġ"\ n --- \ n ", Ġ"\ n \ n ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath + result ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFile Util . write List To ( r , Ġ" async report . txt ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġasync Report ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġanalyze Follow Type ( chain : ĠList < J Method >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdeclared : ĠMap < A Permission , Boolean >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchecks : ĠList < P Call Chain >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequests : ĠList < P Call Chain >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Checked : ĠBoolean , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Requested : ĠBoolean ): ĠH BF ollow Sit uation < AC all Chain > Ġ{ ĊĠĠĠĠĠĠĠ Ġif ( declared . isEmpty ()){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif ( checks . isEmpty () Ġ&& Ġrequests . isEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Of ( Pair ( H appen Before Follow Type . No Declare And No Steps , null )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Of ( Pair ( H appen Before Follow Type . No Declare With Steps , null )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġif ( checks . isEmpty () Ġ&& Ġrequests . isEmpty ()){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġset Of ( Pair ( H appen Before Follow Type . Declared No Steps , null )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtypes Ġ= ĠHashMap < H appen Before Follow Type , Mutable Set < AC all Chain > ?> () ĊĊĠĠĠĠĠĠĠ Ġif ( sync Checked ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtypes [ H appen Before Follow Type . Sync Checked Already ] Ġ= ĠHashSet () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġif ( chain . first (). is Handle Api ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtypes [ H appen Before Follow Type . Is Handle No Check ] Ġ= ĠHashSet () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchecks . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . chain Ġcan H appen Before Ġchain ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( H appen Before Follow Type . Async Check Before Use Ġ! in Ġtypes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtypes [ H appen Before Follow Type . Async Check Before Use ] Ġ= ĠHashSet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtypes [ H appen Before Follow Type . Async Check Before Use ] !!. add ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( H appen Before Follow Type . Async Check Before Use Ġ! in Ġtypes ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtypes [ H appen Before Follow Type . No Async Check Before Use ] Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif ( sync Requested ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtypes [ H appen Before Follow Type . Sync Requested Already ] Ġ= ĠHashSet () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġobviously , Ġthe Ġpermission Ġis Ġrequested Ġthus ĠHANDLE Ġis Ġinvoked ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( chain . first (). is Handle Api ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( H appen Before Follow Type . Async Request Before Use Ġ! in Ġtypes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtypes [ H appen Before Follow Type . Async Request Before Use ] Ġ= ĠHashSet () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor ( it Ġin Ġrequests ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . chain Ġcan H appen Before Ġchain ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( chain . first (). is Handle Api () Ġ&& Ġ! from The Same Component ( chain . first (), Ġit . chain . first ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( H appen Before Follow Type . Async Request Before Use Ġ! in Ġtypes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtypes [ H appen Before Follow Type . Async Request Before Use ] Ġ= ĠHashSet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtypes [ H appen Before Follow Type . Async Request Before Use ] !!. add ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( H appen Before Follow Type . Async Request Before Use Ġ! in Ġtypes ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtypes [ H appen Before Follow Type . No Async Request Before Use ] Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtypes . map { Ġ( k , v ) Ġ-> ĠPair ( k , v ) Ġ}. toSet () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfrom The Same Component ( ma : ĠJ Method , Ġmb : ĠJ Method ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġca Ġ= Ġma . def ining Class . out ter Class () ĊĠĠĠĠĠĠĠ Ġval Ġcb Ġ= Ġmb . def ining Class . out ter Class () ĊĠĠĠĠĠĠĠ Ġreturn Ġca Ġ== Ġcb ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġval Ġm cg : ĠMap < J Class , Set < J Class >> Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ ĠModule CG Analyzer . getModule CG () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġin fix Ġfun ĠList < J Method >. can H appen Before ( that : ĠList < J Method >): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġ` this ` Ġmust Ġbe Ġa Ġpermission Ġmaintaining Ġchain ĊĠĠĠĠĠĠĠ Ġval Ġthis Class Ġ= Ġthis [ 0 ]. def ining Class . out ter Class () ĊĠĠĠĠĠĠĠ Ġval Ġthat Class Ġ= Ġthat [ 0 ]. def ining Class . out ter Class () ĊĊĠĠĠĠĠĠĠ Ġif ( this Class Ġ!= Ġthat Class ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( this Class . is Component () Ġ&& Ġthat Class . is Component ()){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġhappen - before Ġby ĠI CC - graph ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( this Class Ġin Ġm cg ) Ġ&& Ġ( that Class Ġin Ġm cg . getValue ( this Class )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif ( this Class . is Application () Ġ|| Ġthat Class . is Application ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( this Class . isNot Application () Ġ|| Ġthat Class . isNot Application ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġcase Ġwhen Ġonly Ġone Ġis Ġapplication ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis Class . is Application () Ġ&& Ġthat Class . isNot Application () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif ( this Class . is Component () Ġ&& Ġthat Class . isNot Component ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĠĠĠ Ġ// Ġfor Ġunder - estimate ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif ( this Class . isNot Component () Ġ&& Ġthat Class . is Component ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( this Class . isNot Component () Ġ&& Ġthat Class . isNot Component ()) ĠĠĠ Ġ// Ġdummy Ġassert ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ Ġ Ġ// Ġsame Ġout ter Ġclass , Ġanalyze Ġby Ġflow d roid Ġdummy Main ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġthis S oot Method Ġ= ĠScene . v (). getMethod ( this [ 0 ]. so ot Signature ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġthat S oot Method Ġ= ĠScene . v (). getMethod ( that [ 0 ]. so ot Signature ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( this S oot Method Ġ== Ġthat S oot Method ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĠĠĠ Ġ// Ġsame Ġclass , Ġsame Ġmethod , Ġsynchronous ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif ( this [ 0 ]. def ining Class Ġ!= Ġthat [ 0 ]. def ining Class ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġin Ġcase Ġof Ġanonymous Ġclass ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġthat Inner Class Ġ= ĠScene . v (). getS oot Class ( that [ 0 ]. def ining Class . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis Class . is Component () Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRUN N ABLE _ CLASS Ġin Ġthat Inner Class . interfaces Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthat S oot Method . name Ġ== Ġ" run " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis Class . is Component () Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis S oot Method Ġlifecycle H appen Before Ġthat S oot Method ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ // ĠĠĠ Ġprivate Ġfun ĠJ Class . is Component () Ġ= Ġ( this . name . substring Before ("$ ") Ġin ĠModule CG Analyzer . cmp Names ) ĊĠĠĠ Ġprivate Ġfun ĠJ Class . is Component () Ġ= Ġ( this . name Ġin ĠModule CG Analyzer . cmp Names ) ĊĠĠĠ Ġprivate Ġfun ĠJ Class . isNot Component () Ġ= Ġ! this . is Component () ĊĊĠĠĠ Ġprivate Ġfun ĠJ Class . is Application () Ġ= Ġthis Ġ== ĠManifest Analyzer . application Class ĊĠĠĠ Ġprivate Ġfun ĠJ Class . isNot Application () Ġ= Ġ! this . is Application () ĊĊĊĠĠĠ Ġprivate Ġin fix Ġfun ĠS oot Method . lifecycle H appen Before ( that : ĠS oot Method ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdummy Main Ġ= Ġ" dummy Main Class : Ġ${ this . decl aring Class }" ĊĊĠĠĠĠĠĠĠ Ġval Ġthis Parent Ġ= ĠCG Util . get Call To ( this ). unique ToList { Ġit . signature . contains ( dummy Main ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġthat Parent Ġ= ĠCG Util . get Call To ( that ). unique ToList { Ġit . signature . contains ( dummy Main ) Ġ} ĊĠĠĠĠĠĠĠ Ġif ( this Parent . isEmpty () Ġ|| Ġthat Parent . isEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġrequire ( this Parent . size == 1 Ġ&& Ġthat Parent . size == 1 ) ĊĊĠĠĠĠĠĠĠ Ġval Ġthis Dummy Ġ= Ġthis Parent [ 0 ] ĊĠĠĠĠĠĠĠ Ġval Ġthat Dummy Ġ= Ġthat Parent [ 0 ] ĊĠĠĠĠĠĠĠ Ġrequire ( this Dummy . signature Ġ== Ġthat Dummy . signature ) ĊĊĠĠĠĠĠĠĠ Ġval Ġthis J method Ġ= ĠJ Method . from S oot Signature ( this . signature ) ĊĠĠĠĠĠĠĠ Ġval Ġthat J method Ġ= ĠJ Method . from S oot Signature ( that . signature ) ĊĠĠĠĠĠĠĠ Ġreturn Ġthis J method Ġlifecycle H appen Before Ġthat J method Ċ // ĠĠĠĠĠĠĠ Ġvar Ġthis Inv oked Ġ= Ġfalse Ċ // ĠĠĠĠĠĠĠ ĠCFG Util . flow Iterator ( this Dummy ). forEach Ġ{ Ġblock Ġ-> Ċ // ĠĠĠĠĠĠĠĠĠĠĠ ĠCFG Util . findAll Call sites ( block ). forEach Ġ{ Ġ(_, Ġinvoke ) Ġ-> Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( invoke . method . signature Ġ== Ġthis . signature ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis Inv oked Ġ= Ġtrue Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif ( invoke . method . signature == that . signature Ġ&& Ġthis Inv oked ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠJ Class . out ter Class (): ĠJ Class Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġthis . name . substring Before ('$ ') ĊĠĠĠĠĠĠĠ Ġreturn ĠJ Class ( name ) ĊĠĠĠ Ġ} ĊĊĊĊĠĠĠ Ġprivate Ġin fix Ġfun ĠJ Method . lifecycle H appen Before ( that : ĠJ Method ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( this . def ining Class . out ter Class () Ġ== Ġthat . def ining Class . out ter Class ()) ĊĠĠĠĠĠĠĠ Ġval Ġthis Index Ġ= ĠCOMPONENT _ LI FE CYCLE . indexOf ( this . methodName ) ĊĠĠĠĠĠĠĠ Ġval Ġthat Index Ġ Ġ= ĠCOMPONENT _ LI FE CYCLE . indexOf ( that . methodName ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġif ( this Index Ġ< Ġ 0 Ġ&& Ġthat Index Ġ< Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġelse Ġif ( this Index Ġ< Ġ 0 Ġ&& Ġthat Index Ġ>= Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthat Index Ġ> ĠAPP _ METHOD Ġ Ġ// Ġthat Ġis Ġin Ġlater Ġhalf ĊĠĠĠĠĠĠĠ Ġelse Ġif ( this Index Ġ>= Ġ 0 Ġ&& Ġthat Index Ġ< Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis Index Ġ< ĠAPP _ METHOD ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis Index Ġ< Ġthat Index ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġval ĠCOMPONENT _ LI FE CYCLE Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" onCreate ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" on Restart ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" onStart ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" on Resume ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġany Ġother Ġmethods ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" on Pause ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" on Stop ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" on Destroy " ĊĠĠĠ Ġ) ĊĠĠĠ Ġprivate Ġval ĠAPP _ METHOD Ġ= ĠCOMPONENT _ LI FE CYCLE . indexOf (" on Resume ") Ġ+ Ġ 0 . 5 Ċ } Ċ