/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 8 ĠSquare , ĠInc . Ċ Ġ* Ċ Ġ* Ġ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 Ġleak can ary Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . app . Application Ċ import Ġandroid . app . Application . Activity Lifecycle Callbacks Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . util . Log Ċ import Ġandroidx . test . platform . app . Instrumentation Registry . get Instrumentation Ċ import Ġleak can ary . Instrumentation Leak Detector . Result . Analysis Performed Ċ import Ġleak can ary . internal . TestResult Publisher Ċ import Ġorg . junit . runner . Description Ċ import Ġorg . junit . runner . Result Ċ import Ġorg . junit . runner . notification . Failure Ċ import Ġorg . junit . runner . notification . Run Listener Ċ import Ġsh ark . Heap Analysis Ċ import Ġsh ark . Heap Analysis Failure Ċ import Ġsh ark . Heap Analysis Success Ċ import Ġsh ark . Sh ark Log Ċ import Ġjava . lang . reflect . Invocation Handler Ċ import Ġjava . lang . reflect . Proxy Ċ import Ġjava . util . concurrent . Count DownLatch Ċ import Ġjava . util . concurrent . TimeUnit . SECONDS Ċ Ċ /** Ċ Ġ* Ċ Ġ* ĠA ĠJ Unit Ġ[ Run Listener ] Ġthat Ġuses Ġ[ Instrumentation Leak Detector ] Ġto Ġdetect Ġmemory Ġle aks Ġin ĠAndroid Ċ Ġ* Ġinstrument ation Ġtests . ĠIt Ġwaits Ġfor Ġthe Ġend Ġof Ġa Ġtest , Ġand Ġif Ġthe Ġtest Ġsucceeds Ġthen Ġit Ġwill Ċ Ġ* Ġlook Ġfor Ġretained Ġobjects , Ġtrigger Ġa Ġheap Ġdump Ġif Ġneeded Ġand Ġperform Ġan Ġanalysis . Ċ Ġ* Ċ Ġ* Ġ Ġ[ Fail Test On Leak Run Listener ] Ġcan Ġbe Ġsub cl assed Ġto Ġoverride Ġ[ skip Leak Detection Reason ] Ġand Ċ Ġ* Ġ Ġ[ on Analysis Performed ] Ċ Ġ* Ċ Ġ* Ġ@ see ĠInstrument ation Leak Detector Ċ Ġ*/ Ċ open Ġclass ĠFail Test On Leak Run Listener Ġ: ĠRun Listener () Ġ{ ĊĠ Ġprivate Ġvar Ġ_ current Test Description : ĠDescription ? Ġ= Ġnull ĊĠ Ġprivate Ġval Ġcurrent Test Description : ĠDescription ĊĠĠĠ Ġget () Ġ= Ġ_ current Test Description !! ĊĊĠ Ġprivate Ġvar Ġskip Leak Detection Reason : ĠString ? Ġ= Ġnull ĊĊĠ Ġprivate Ġlateinit Ġvar Ġtest Result Publisher : ĠTest Result Publisher ĊĊĠ Ġ@ Volatile ĊĠ Ġprivate Ġvar Ġall Activities Destroyed Latch : ĠCount DownLatch ? Ġ= Ġnull ĊĊĠ Ġoverride Ġfun Ġtest Run Started ( description : ĠDescription ) Ġ{ ĊĠĠĠ Ġtest Result Publisher Ġ= ĠTest Result Publisher . install () ĊĠĠĠ Ġtrack Activities () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġtrack Activities () Ġ{ ĊĠĠĠ Ġval Ġinstrument ation Ġ= Ġget Instrumentation () !! ĊĠĠĠ Ġval Ġapplication Ġ= Ġinstrument ation . target Context . application Context Ġas ĠApplication ĊĠĠĠ Ġapplication . register Activity Lifecycle Callbacks ( object Ġ: ĠActivity Lifecycle Callbacks Ġby Ġno Op Delegate () Ġ{ ĊĊĠĠĠĠĠ Ġvar Ġactivities Waiting For Destroyed Ġ= Ġ 0 ĊĊĠĠĠĠĠ Ġoverride Ġfun Ġon Activity Created ( ĊĠĠĠĠĠĠĠ Ġactivity : ĠActivity , ĊĠĠĠĠĠĠĠ ĠsavedInstanceState : ĠBundle ? ĊĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( activities Waiting For Destroyed Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġall Activities Destroyed Latch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġactivities Waiting For Destroyed ++ ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun Ġon Activity Destroyed ( activity : ĠActivity ) Ġ{ ĊĠĠĠĠĠĠĠ Ġactivities Waiting For Destroyed -- ĊĠĠĠĠĠĠĠ Ġif Ġ( activities Waiting For Destroyed Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġall Activities Destroyed Latch !!. count Down () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġtest Run Finished ( result : ĠResult ) Ġ{ ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġtest Started ( description : ĠDescription ) Ġ{ ĊĠĠĠ Ġ_ current Test Description Ġ= Ġdescription ĊĠĠĠ Ġskip Leak Detection Reason Ġ= Ġskip Leak Detection Reason ( description ) ĊĠĠĠ Ġif Ġ( skip Leak Detection Reason Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġreturn ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠCan Ġbe Ġoverridden Ġto Ġskip Ġleak Ġdetection Ġbased Ġon Ġthe Ġdescription Ġprovided Ġwhen Ġa Ġtest ĊĠĠ Ġ* Ġis Ġstarted . ĠReturn Ġnull Ġto Ġcontinue Ġleak Ġdetection , Ġor Ġa Ġstring Ġdescribing Ġthe Ġreason Ġfor ĊĠĠ Ġ* Ġskipping Ġotherwise . ĊĠĠ Ġ*/ ĊĠ Ġprotected Ġopen Ġfun Ġskip Leak Detection Reason ( description : ĠDescription ): ĠString ? Ġ{ ĊĠĠĠ Ġreturn Ġnull ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġtest Failure ( failure : ĠFailure ) Ġ{ ĊĠĠĠ Ġskip Leak Detection Reason Ġ= Ġ" failed " ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġtest Ignored ( description : ĠDescription ) Ġ{ ĊĠĠĠ Ġskip Leak Detection Reason Ġ= Ġ" was Ġignored " ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġtest Ass umption Failure ( failure : ĠFailure ) Ġ{ ĊĠĠĠ Ġskip Leak Detection Reason Ġ= Ġ" had Ġan Ġassumption Ġfailure " ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġtest Finished ( description : ĠDescription ) Ġ{ ĊĠĠĠ Ġif Ġ( skip Leak Detection Reason Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġdetect Le aks () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ ĠSh ark Log . d Ġ{ Ġ" Skipping Ġleak Ġdetection Ġbecause Ġthe Ġtest Ġ$ skip Leak Detection Reason " Ġ} ĊĠĠĠĠĠ Ġskip Leak Detection Reason Ġ= Ġnull ĊĠĠĠ Ġ} ĊĠĠĠ ĠApp Watcher . object Watcher . clear W atched Objects () ĊĠĠĠ Ġ_ current Test Description Ġ= Ġnull ĊĠĠĠ Ġtest Result Publisher . publish Test Finished () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġdetect Le aks () Ġ{ ĊĠĠĠ Ġval Ġall Activities Destroyed Ġ= Ġall Activities Destroyed Latch ?. await ( 2 , ĠSE CON DS ) Ġ?: Ġtrue ĊĠĠĠ Ġif Ġ(! all Activities Destroyed ) Ġ{ ĊĠĠĠĠĠ ĠSh ark Log . d Ġ{ Ġ" Leak Ġdetection Ġproceed ing Ġwith Ġsome Ġactivities Ġstill Ġnot Ġin Ġdestroyed Ġstate " Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġleak Detector Ġ= ĠInstrument ation Leak Detector () ĊĠĠĠ Ġval Ġresult Ġ= Ġleak Detector . detect Le aks () ĊĊĠĠĠ Ġif Ġ( result Ġis ĠAnalysis Performed ) Ġ{ ĊĠĠĠĠĠ Ġon Analysis Performed ( heap Analysis Ġ= Ġresult . heap Analysis ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ ĠSh ark Log . d Ġ{ Ġ" No Ġheap Ġanalysis Ġperformed " Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠCalled Ġwhen Ġa Ġheap Ġanalysis Ġhas Ġbeen Ġperformed Ġand Ġa Ġresult Ġis Ġavailable . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThe Ġdefault Ġimplementation Ġcall Ġ[ fail Test ] Ġif Ġthe Ġ[ heap Analysis ] Ġfailed Ġor Ġif ĊĠĠ Ġ* Ġ[ Heap Analysis Success . application Le aks ] Ġis Ġnot Ġempty . ĊĠĠ Ġ*/ ĊĠ Ġprotected Ġopen Ġfun Ġon Analysis Performed ( heap Analysis : ĠHeap Analysis ) Ġ{ ĊĠĠĠ Ġwhen Ġ( heap Analysis ) Ġ{ ĊĠĠĠĠĠ Ġis ĠHeap Analysis Failure Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġfail Test ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ current Test Description Ġfailed Ġbecause Ġheap Ġanalysis Ġfailed :\ n " Ġ+ ĠLog . get StackTrace String ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheap Analysis . exception ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠHeap Analysis Success Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġapplication Le aks Ġ= Ġheap Analysis . application Le aks ĊĠĠĠĠĠĠĠ Ġif Ġ( application Le aks . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġfail Test ("$ current Test Description Ġfailed Ġbecause Ġapplication Ġmemory Ġle aks Ġwere Ġdetected :\ n $ heap Analysis ") ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ ĠSh ark Log . d Ġ{ Ġ" Heap Ġanalysis Ġfound Ġ 0 Ġapplication Ġle aks :\ n $ heap Analysis " Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠReports Ġthat Ġthe Ġtest Ġhas Ġfailed , Ġwith Ġthe Ġprovided Ġ[ trace ]. ĊĠĠ Ġ*/ ĊĠ Ġprotected Ġfun Ġfail Test ( trace : ĠString ) Ġ{ ĊĠĠĠ ĠSh ark Log . d Ġ{ Ġtrace Ġ} ĊĠĠĠ Ġtest Result Publisher . publish Test Failure ( current Test Description , Ġtrace ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġinline Ġfun Ġ< re ified ĠT Ġ: ĠAny > Ġno Op Delegate (): ĠT Ġ{ ĊĠĠĠ Ġval Ġjava Class Ġ= ĠT :: class . java ĊĠĠĠ Ġval Ġno Op Handler Ġ= ĠInvocation Handler Ġ{ Ġ_, Ġ_, Ġ_ Ġ-> ĊĠĠĠĠĠ Ġ// Ġno Ġop ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠProxy . new Proxy Instance ( ĊĠĠĠĠĠĠĠ Ġjava Class . class Loader , ĠarrayOf ( java Class ), Ġno Op Handler ĊĠĠĠ Ġ) Ġas ĠT ĊĠ Ġ} Ċ } Ċ