/* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠSee Ġthe ĠNOTICE Ġfile Ġdistributed Ġwith Ġthis Ġwork Ġfor Ġadditional Ċ Ġ* Ġinformation Ġregarding Ġcopyright Ġownership . Ċ Ġ* Ġ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 Ġio . app ium . espress oser ver . lib . model Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . System Clock Ċ import Ġandroid . text . TextUtils Ċ import Ġandroid . util . Sparse Array Ċ import Ġandroid . util . Xml Ċ import Ġandroid . view . View Ċ import Ġandroid . view . ViewGroup Ċ import Ġandroid . widget . Adapter View Ċ import Ġandroidx . test . core . app . Application Provider . getApplicationContext Ċ import Ġandroidx . compose . ui . semantics . Semantics Node Ċ import Ġandroidx . compose . ui . test . Selection Result Ċ import Ġandroidx . compose . ui . test . Semantics Node Interaction Ċ import Ġandroidx . compose . ui . test . on Root Ċ import Ġio . app ium . espress oser ver . Esp ress o Server Runner Test Ċ import Ġio . app ium . espress oser ver . Esp ress o Server Runner Test . Companion . context Ċ import Ġio . app ium . espress oser ver . lib . drivers . Driver Context Ċ import Ġio . app ium . espress oser ver . lib . handlers . exceptions . App ium Exception Ċ import Ġio . app ium . espress oser ver . lib . handlers . exceptions . XPath Lookup Exception Ċ import Ġio . app ium . espress oser ver . lib . helpers . Android Logger Ċ import Ġio . app ium . espress oser ver . lib . helpers . String Helpers . abbre vi ate Ċ import Ġio . app ium . espress oser ver . lib . helpers . XML Helpers . to NodeName Ċ import Ġio . app ium . espress oser ver . lib . helpers . XML Helpers . to Safe String Ċ import Ġio . app ium . espress oser ver . lib . helpers . extensions . with Permit Ċ import Ġio . app ium . espress oser ver . lib . view action . View Getter Ċ import Ġorg . w 3 c . dom . NodeList Ċ import Ġorg . xml . sax . Input Source Ċ import Ġorg . xml pull . v 1 . Xml Serializer Ċ import Ġjava . io .* Ċ import Ġjava . lang . AssertionError Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Semaphore Ċ import Ġjavax . xml . xpath .* Ċ import Ġkotlin . reflect . full . declared Member Functions Ċ import Ġkotlin . reflect . jvm . is Accessible Ċ Ċ const Ġval ĠNON _ XML _ CHAR _ REPLACE MENT Ġ= Ġ" ?" Ċ const Ġval ĠVIEW _ INDEX Ġ= Ġ" view Index " Ċ const Ġval ĠNAMES PACE Ġ= Ġ"" Ċ val ĠDEFAULT _ VIEW _ CLASS _ NAME Ġ= ĠView :: java Class . name Ċ const Ġval ĠMAX _ TRA VERSAL _ DEPTH Ġ= Ġ 7 0 Ċ const Ġval ĠMAX _ XML _ VALUE _ LENGTH Ġ= Ġ 6 4 Ġ* Ġ 1 0 2 4 Ċ const Ġval ĠXML _ ENCODING Ġ= Ġ" UTF - 8 " Ċ val ĠX PATH : ĠXPath Ġ= ĠXPath Factory . newInstance (). new XPath () ĊĊ Ċ private Ġfun Ġto Xml NodeName ( className : ĠString ?): ĠString Ġ{ ĊĠĠĠ Ġif Ġ( className Ġ== Ġnull Ġ|| ĠclassName . trim Ġ{ Ġit Ġ<= Ġ' Ġ' Ġ}. isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠDEFAULT _ VIEW _ CLASS _ NAME ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġfixed Name Ġ= ĠclassName ĊĠĠĠĠĠĠĠ Ġ. replace (" [$ @ # & ] ". to Regex (), Ġ". ") ĊĠĠĠĠĠĠĠ Ġ. replace ("\\ .+ ". to Regex (), Ġ". ") ĊĠĠĠĠĠĠĠ Ġ. replace ("( ^ \\ .| \\ .$ ) ". to Regex (), Ġ"") ĊĠĠĠ Ġfixed Name Ġ= Ġto NodeName ( fixed Name ) ĊĠĠĠ Ġif Ġ( fixed Name . trim Ġ{ Ġit Ġ<= Ġ' Ġ' Ġ}. isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġfixed Name Ġ= ĠDEFAULT _ VIEW _ CLASS _ NAME ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( fixed Name Ġ!= ĠclassName ) Ġ{ ĊĠĠĠĠĠĠĠ ĠAndroid Logger . info (" Rew rote Ġclass Ġname Ġ'$ className ' Ġto ĠXML Ġnode Ġname Ġ'$ fixed Name '") ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġfixed Name Ċ } ĊĊ Ċ class ĠSource Document Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġroot : ĠAny ? Ġ= Ġnull , ĊĠĠĠ Ġprivate Ġval Ġincluded Attributes : ĠSet < Attributes Enum >? Ġ= Ġnull Ċ ) Ġ{ ĊĠĠĠ Ġ@ Suppress (" Private PropertyName ") ĊĠĠĠ Ġprivate Ġval ĠRES O URCES _ GU ARD Ġ= ĠSem aphore ( 1 ) ĊĊĠĠĠ Ġprivate Ġval Ġview Map : ĠSparse Array < View > Ġ= ĠSparse Array () ĊĠĠĠ Ġprivate Ġvar Ġserializer : ĠXml Serializer ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġtmp Xml Name : ĠString ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġfun Ġset Attribute ( attr Name : ĠAttributes Enum , Ġattr Value : ĠAny ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠDo Ġnot Ġwrite Ġattributes , Ġwhose Ġvalues Ġequal Ġto Ġnull ĊĠĠĠĠĠĠĠ Ġattr Value ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCut Ġoff Ġlonger Ġstrings Ġto Ġavoid ĠO OM Ġerrors ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġxml Value Ġ= Ġabbre vi ate ( to Safe String ( it . toString (), ĠNON _ XML _ CHAR _ REPLACE MENT ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMAX _ XML _ VALUE _ LENGTH ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġserializer ?. attribute ( NAMESPACE , Ġattr Name . toString (), Ġxml Value ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrecord Adapter View Info ( adapter View : ĠAdapter View <* >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġadapter Ġ= Ġadapter View . adapter Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġadapter Count Ġ= Ġadapter . count ĊĠĠĠĠĠĠĠ Ġval Ġadapter Data Ġ= ĠArrayList < String >() ĊĠĠĠĠĠĠĠ Ġvar Ġis Adapter Type Set Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġadapter Count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġadapter Item Ġ= Ġadapter . getItem ( i ) Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadapter Data . add ( adapter Item . toString ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġtype Ġof Ġthe Ġadapter Ġitem ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Adapter Type Set ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Attribute ( Attributes Enum . ADAPTER _ TYPE , Ġadapter Item . java Class . simple Name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Adapter Type Set Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( adapter Data . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Attribute ( Attributes Enum . ADAPTER S , ĠText Utils . join (",", Ġadapter Data )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Attribute Included ( attr : ĠAttributes Enum ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ Ġnull Ġ== Ġincluded Attributes Ġ|| Ġincluded Attributes . contains ( attr ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRe cursively Ġvisit Ġall Ġof Ġthe Ġviews Ġand Ġmap Ġthem Ġto ĠXML Ġelements ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġview Ġ ĠThe Ġroot Ġview ĊĠĠĠĠ Ġ* Ġ@ param Ġdepth ĠThe Ġcurrent Ġtraversal Ġdepth ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġserialize View ( view : ĠView ?, Ġdepth : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( view Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġview Element Ġ= ĠView Element ( view ) ĊĠĠĠĠĠĠĠ Ġval ĠclassName Ġ= Ġview Element . className ĊĠĠĠĠĠĠĠ Ġval ĠtagName Ġ= Ġto Xml NodeName ( className ) ĊĠĠĠĠĠĠĠ Ġserializer ?. start Tag ( NAMESPACE , ĠtagName ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġis Text Or Hint Re corded Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvar Ġis Adapter Info Re corded Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġlinked Map Of ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . INDEX Ġto Ġ{ Ġview Element . index Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . PACKAGE Ġto Ġ{ Ġview Element . packageName Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . CLASS Ġto Ġ{ ĠclassName Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . CONTENT _ DESC Ġto Ġ{ Ġview Element . content Description Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . CHECK ABLE Ġto Ġ{ Ġview Element . is Check able Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . CHECK ED Ġto Ġ{ Ġview Element . isChecked Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . CLICK ABLE Ġto Ġ{ Ġview Element . is Clickable Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . ENABLED Ġto Ġ{ Ġview Element . isEnabled Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . FOCUS ABLE Ġto Ġ{ Ġview Element . is Focus able Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . FOC USED Ġto Ġ{ Ġview Element . is Focused Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . SCROLL ABLE Ġto Ġ{ Ġview Element . is Scroll able Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . LONG _ CLICK ABLE Ġto Ġ{ Ġview Element . is Long Clickable Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . PASSWORD Ġto Ġ{ Ġview Element . is Password Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . SELECTED Ġto Ġ{ Ġview Element . isSelected Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . VISIBLE Ġto Ġ{ Ġview Element . isVisible Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . BOUN DS Ġto Ġ{ Ġview Element . bounds . to Short String () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . TEXT Ġto Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . HINT Ġto Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . RESOURCE _ ID Ġto Ġ{ Ġview Element . resourceId Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . VIEW _ TAG Ġto Ġ{ Ġview Element . view Tag Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . ADAPTER S Ġto Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . ADAPTER _ TYPE Ġto Ġnull ĊĠĠĠĠĠĠĠ Ġ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it . key ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . TEXT , ĠAttributes Enum . HINT Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Text Or Hint Re corded Ġ&& Ġis Attribute Included ( it . key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġview Element . text ?. let Ġ{ Ġtext Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Attribute ( Attributes Enum . TEXT , Ġtext . raw Text ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Attribute ( Attributes Enum . HINT , Ġtext . is Hint ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Text Or Hint Re corded Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . ADAPTER S , ĠAttributes Enum . ADAPTER _ TYPE Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Adapter Info Re corded Ġ&& Ġview Ġis ĠAdapter View < *> Ġ&& Ġis Attribute Included ( it . key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrecord Adapter View Info ( view ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Adapter Info Re corded Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġif Ġ( is Attribute Included ( it . key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Attribute ( it . key , Ġit . value !! ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġserializer ?. attribute ( NAMESPACE , ĠVIEW _ INDEX , Ġview Map . size (). toString ()) ĊĠĠĠĠĠĠĠ Ġview Map . put ( view Map . size (), Ġview ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( depth Ġ< ĠMAX _ TRA VERSAL _ DEPTH ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠVisit Ġthe Ġchildren Ġand Ġbuild Ġthem Ġtoo ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( view Ġis ĠViewGroup ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( index Ġin Ġ 0 Ġuntil Ġview . child Count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserialize View ( view . getChild At ( index ), Ġdepth Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAndroid Logger . warn ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Skipping Ġtraversal Ġof Ġ${ view . java Class . name }' s Ġchildren , Ġsince Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" the Ġcurrent Ġdepth Ġhas Ġreached Ġits Ġmaximum Ġallowed Ġvalue Ġof Ġ$ depth " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġserializer ?. end Tag ( NAMESPACE , ĠtagName ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġserialize Compose Node ( semantics Node : ĠSem antics Node ?, Ġdepth : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( semantics Node Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġnode Element Ġ= ĠCompose Node Element ( semantics Node ) ĊĠĠĠĠĠĠĠ Ġval ĠclassName Ġ= Ġnode Element . className ĊĠĠĠĠĠĠĠ Ġval ĠtagName Ġ= Ġto Xml NodeName ( className ) ĊĠĠĠĠĠĠĠ Ġserializer ?. start Tag ( NAMESPACE , ĠtagName ) ĊĊĠĠĠĠĠĠĠ Ġlinked Map Of ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . CLASS Ġto Ġ{ ĠclassName Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . INDEX Ġto Ġ{ Ġnode Element . index Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . CLICK ABLE Ġto Ġ{ Ġnode Element . is Clickable Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . ENABLED Ġto Ġ{ Ġnode Element . isEnabled Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . FOC USED Ġto Ġ{ Ġnode Element . is Focused Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . SCROLL ABLE Ġto Ġ{ Ġnode Element . is Scroll able Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . SELECTED Ġto Ġ{ Ġnode Element . isSelected Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . CHECK ED Ġto Ġ{ Ġnode Element . isChecked Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . VIEW _ TAG Ġto Ġ{ Ġnode Element . view Tag Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . CONTENT _ DESC Ġto Ġ{ Ġnode Element . content Description Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . BOUN DS Ġto Ġ{ Ġnode Element . bounds . to Short String () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . TEXT Ġto Ġ{ Ġnode Element . text Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . PASSWORD Ġto Ġ{ Ġnode Element . is Password Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAttributes Enum . RESOURCE _ ID Ġto Ġ{ Ġnode Element . resourceId Ġ}, ĊĠĠĠĠĠĠĠ Ġ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Attribute ( it . key , Ġit . value ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( depth Ġ< ĠMAX _ TRA VERSAL _ DEPTH ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠVisit Ġthe Ġchildren Ġand Ġbuild Ġthem Ġtoo ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( index Ġin Ġ 0 Ġuntil Ġsemantics Node . children . count ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserialize Compose Node ( semantics Node . children [ index ], Ġdepth Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAndroid Logger . warn ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Skipping Ġtraversal Ġof Ġ${ semantics Node . java Class . name }' s Ġchildren , Ġsince Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" the Ġcurrent Ġdepth Ġhas Ġreached Ġits Ġmaximum Ġallowed Ġvalue Ġof Ġ$ depth " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġserializer ?. end Tag ( NAMESPACE , ĠtagName ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġto Stream (): ĠInputStream Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġlast Error : ĠThrowable ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ// ĠTry Ġto Ġserialize Ġthe Ġxml Ġinto Ġthe Ġmemory Ġfirst , Ġsince Ġit Ġis Ġfast ĊĠĠĠĠĠĠĠ Ġ// ĠSwitch Ġto Ġa Ġfile Ġsystem Ġserializer Ġif Ġthe Ġfirst Ġapproach Ġcauses ĠOut Of Memory ĊĠĠĠĠĠĠĠ Ġfor Ġ( stream Type Ġin ĠarrayOf < Class < *> >( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠByteArrayOutputStream :: class . java , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFileOutputStream :: class . java ĊĠĠĠĠĠĠĠ Ġ)) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġserializer Ġ= ĠXml . new Serializer () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġview Map . clear () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠoutputStream Ġ= Ġif Ġ( stream Type Ġ== ĠFileOutputStream :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtmp Xml Name Ġ= Ġ"${ UUID . randomUUID ()}. xml " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget ApplicationContext < Context >(). open File Output ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtmp Xml Name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContext . MODE _ PRIVATE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse ĠByteArrayOutputStream () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserializer ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . setOutput ( output Stream , ĠXML _ ENCODING ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . start Document ( XML _ ENCODING , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . set Feature (" http :// xml pull . org / v 1 / doc / features . html # indent - output ", Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠstartTime Ġ= ĠSystem Clock . uptime Millis () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( context . current Strategy Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDriver Context . Strategy Type . COMP OSE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( root Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserialize Compose Node ( root Ġas ĠSem antics Node , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġroot Nodes Ġ= Ġroot Semantic Nodes () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( root Nodes . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserialize Compose Node ( root Nodes . first (), Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserializer ?. start Tag ( NAMESPACE , ĠDEFAULT _ TAG _ NAME ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġroot Nodes . forEach Ġ{ Ġsemantics Node Ġ-> Ġserialize Compose Node ( semantics Node , Ġ 0 ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserializer ?. end Tag ( NAMESPACE , ĠDEFAULT _ TAG _ NAME ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDriver Context . Strategy Type . ES PRESS O Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġroot View Ġ= Ġroot Ġ?: ĠView Getter (). root View ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserialize View ( root View Ġas ĠView , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . end Document () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAndroid Logger . info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" The Ġsource ĠXML Ġtree Ġhas Ġbeen Ġfetched Ġin Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ System Clock . uptime Millis () Ġ- ĠstartTime } ms Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" using Ġ${ stream Type . simple Name }" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠOut Of Memory Error ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Error Ġ= Ġe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( output Stream Ġis ĠFileOutputStream ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget ApplicationContext < Context >(). open File Input ( tmp Xml Name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠByteArrayInputStream (( output Stream Ġas ĠByteArrayOutputStream ). toByteArray ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Error Ġ= Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( last Error Ġis ĠOut Of Memory Error ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġlast Error ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthrow ĠApp ium Exception ( last Error !! ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġroot Semantic Nodes (): ĠList < Semantics Node > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Esp ress o Server Runner Test . compose Test Rule . on Root ( use Un merged Tree Ġ= Ġtrue ). fetch Semantics Node ()) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠAssertionError ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ ĠIde ally Ġthere Ġshould Ġbe Ġon Ġ` root ` Ġnode Ġbut Ġon Ġsome Ġcases Ġe . g : overlay s Ġscreen , Ġthere Ġcan Ġbe Ġmore Ġthan Ġ 1 Ġroot . Ċ // ĠĠĠĠĠĠĠĠĠĠĠ ĠCompose ĠAPI Ġnot Ġrespect ing Ġsuch Ġcases Ġinstead Ġthrows ĠAssertionError , Ġas Ġa Ġwork Ġaround Ġfetching Ġall Ġroot Ġnodes Ġby Ġrelay ing Ġon Ġinternal ĠAPI . Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġe . g : Ġ" Reason : ĠExpected Ġexactly Ġ' 1 ' Ġnode Ġbut Ġfound Ġ' 2 ' Ġnodes Ġthat Ġsatisfy : Ġ( is Root )" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult : ĠSelection Result Ġ= ĠSem antics Node Interaction :: class . declared Member Functions . find Ġ{ Ġit . name Ġ== Ġ" fetch Semantics Nodes " Ġ} ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . is Accessible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . call ( Esp ress o Server Runner Test . compose Test Rule . on Root ( use Un merged Tree Ġ= Ġtrue ), Ġtrue , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġas ĠSelection Result ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . selected Nodes ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġperform Cleanup () Ġ{ ĊĠĠĠĠĠĠĠ Ġtmp Xml Name ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget ApplicationContext < Context >(). delete File ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtmp Xml Name Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġto XML String (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠRES O URCES _ GU ARD . with Permit ({ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto Stream (). use Ġ{ Ġxml Stream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsb Ġ= ĠStringBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreader Ġ= ĠBufferedReader ( InputStream Reader ( xml Stream , ĠXML _ ENCODING )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġline : ĠString ? Ġ= Ġreader . readLine () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( line Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsb . append ( line ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġline Ġ= Ġreader . readLine () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsb . toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}, Ġ{ Ġperform Cleanup () Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġfind Views By XPath ( xpath Selector : ĠString ): ĠList < View > Ġ= ĊĠĠĠĠĠĠĠ Ġmatching Node Ids ( xpath Selector , ĠVIEW _ INDEX ). map Ġ{ Ġview Map . get ( it ) Ġ} ĊĊĠĠĠ Ġfun Ġmatching Node Ids ( xpath Selector : ĠString , Ġattribute Name : ĠString ): ĠList < Int > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġexpr Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠX PATH . compile ( xpath Selector ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( xe : ĠXPath Expression Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠXPath Lookup Exception ( xpath Selector , Ġx e . message !! ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠRES O URCES _ GU ARD . with Permit ({ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto Stream (). use Ġ{ Ġxml Stream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlist Ġ= Ġexpr . evaluate ( Input Source ( xml Stream ), ĠXPath Constants . NODE SET ) Ġas ĠNode List ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġlist . length ). map Ġ{ Ġindex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist . item ( index ). attributes . getName d Item ( attribute Name ). node Value . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}, Ġ{ Ġperform Cleanup () Ġ}) ĊĠĠĠ Ġ} Ċ } Ċ