package Ġsa ar land . cis pa . frontmatter ĊĊ Ċ import Ġorg . assertj . core . api . Assertions . assertThat Ċ import Ġorg . junit . Ignore Ċ import Ġorg . junit . jupiter . api . BeforeEach Ċ import Ġorg . junit . jupiter . api . Test Ċ import Ġsa ar land . cis pa . frontmatter . analy ses . App Platform Ċ import Ġsa ar land . cis pa . frontmatter . analy ses . Front matter Metadata Ċ import Ġsa ar land . cis pa . frontmatter . cg . Call graph Assembler Ċ import Ġsa ar land . cis pa . frontmatter . cg . Inter pro ced ural CFG Wrapper Ċ import Ġsa ar land . cis pa . frontmatter . resolvers . Transition Resolver Ċ import Ġsa ar land . cis pa . frontmatter . resolvers . Value Resolver Ċ import Ġsa ar land . cis pa . frontmatter . resolvers . View Resolver Ċ import Ġso ot . Scene Ċ import Ġso ot . j imple . info flow . android . manifest . Process Manifest Ċ import Ġjava . nio . file . Paths ĊĊ Ċ class ĠUni App Test Ġ{ ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġapp Model : ĠApp Model ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġres Parser : ĠResource Parser ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġscene V : ĠScene ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġapk Info : ĠA pk Info ĊĠĠĠ Ġprivate Ġvar Ġapk File Ġ= ĠPaths . get ("/ Users / ku z net so v / work / workspace / apk _ samples / uni - app - android / android - app / build / outputs / apk / debug / android - app - debug . apk ") ĊĊĠĠĠ Ġ// ĠĠĠ Ġprivate Ġvar Ġapk File : ĠString Ġ= Ġ"/ Users / ku z net so v / work / workspace / apk _ samples / back stage _ test _ apps / Button _ xml / app / build / outputs / apk / debug / app - debug . apk " ĊĠĠĠ Ġprivate Ġval Ġmeta Ġ= ĠFront matter Metadata ("", Ġ"", Ġ 0 , Ġ 0 , Ġ"", ĠApp Platform . NORMAL , Ġ"") ĊĠĠĠ Ġprivate Ġvar Ġandroid Jar Ġ= ĠPaths . get ( System . getenv (" ANDROID _ HOME "), Ġ" platforms ") ĊĊĠĠĠ Ġ@ BeforeEach ĊĠĠĠ Ġfun Ġinit () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmanifest Ġ= ĠProcess Manifest ( apk File . to File ()) ĊĠĠĠĠĠĠĠ Ġscene V Ġ= ĠUtils . initialize S oot ( android Jar , Ġapk File , Ġmanifest . packageName ) ĊĠĠĠĠĠĠĠ Ġapk Info Ġ= ĠA pk Info ( scene V , Ġapk File , Ġmanifest ) ĊĠĠĠĠĠĠĠ Ġres Parser Ġ= Ġapk Info . resource Parser ĊĠĠĠĠĠĠĠ Ġapp Model Ġ= ĠApp Model ( apk Info . declared Activities , Ġmeta ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġcall Graph Size Test () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlayout Analysis Ġ= ĠXml Layout Analysis ( scene V , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġval Ġcallback Analysis Ġ= ĠCallback Analysis ( scene V , Ġlayout Analysis ) ĊĠĠĠĠĠĠĠ Ġval Ġcall graph Assembler Ġ= ĠCall graph Assembler ( scene V , Ġcallback Analysis . possible Callbacks , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġval Ġcall Graph Ġ= Ġcall graph Assembler . call graph ĊĠĠĠĠĠĠĠ ĠassertThat ( call Graph ). has Size ( 7 5 2 3 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun ĠsetContentView Test () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlayout Analysis Ġ= ĠXml Layout Analysis ( scene V , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġval Ġcallback Analysis Ġ= ĠCallback Analysis ( scene V , Ġlayout Analysis ) ĊĠĠĠĠĠĠĠ Ġval Ġcall graph Assembler Ġ= ĠCall graph Assembler ( scene V , Ġcallback Analysis . possible Callbacks , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġval Ġic fg Ġ= ĠInter pro ced ural CFG Wrapper ( scene V , Ġcall graph Assembler . call graph ) ĊĠĠĠĠĠĠĠ Ġval Ġvalue Resolver Ġ= ĠValue Resolver ( scene V , Ġic fg ) ĊĠĠĠĠĠĠĠ Ġval Ġactivity Holder Ġ= ĠApp Model ( apk Info . declared Activities , Ġmeta ) ĊĠĠĠĠĠĠĠ Ġval Ġlm Ġ= ĠActivity Layout Resolver ( scene V , Ġactivity Holder , Ġvalue Resolver , Ġapk Info . resource Parser , Ġlayout Analysis ) ĊĠĠĠĠĠĠĠ Ġval Ġah Ġ= Ġlm . resolve () ĊĠĠĠĠĠĠĠ Ġval Ġlayout Mapping Ġ= Ġah . activity Layouts ĊĠĠĠĠĠĠĠ Ġval Ġactual Activity Names Ġ= Ġlayout Mapping . keySet (). map Ġ{ Ġit . name Ġ}. toSet () ĊĠĠĠĠĠĠĠ Ġprint ( actual Activity Names ) ĊĠĠĠĠĠĠĠ Ġval Ġexpected Activity Names Ġ= Ġset Of ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . staff . SearchResult Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . bus . Bus Detail Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . about . About Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . camp us . Camp us Search Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . camp us . Camp us Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . rss Views . RSS Detail Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . bus . Bus Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . MainActivity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . staff . Search Staff Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . staff . SearchResult Item Detail Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . staff . Person Detail Web Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . rss Views . RSS Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . restaurant . Opening Hours Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . restaurant . Restaurant Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . restaurant . ui helper . Mens a Show Ing redients Activity ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" de . un isa ar land . uni App . settings . Settings Activity " ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertThat ( actual Activity Names ). contains Exactly In Any Order (* expected Activity Names . to Typed Array ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġ@ Ignore (" deprecated ") ĊĠĠĠ Ġfun Ġset Callback Test () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlayout Analysis Ġ= ĠXml Layout Analysis ( scene V , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġval Ġcallback Analysis Ġ= ĠCallback Analysis ( scene V , Ġlayout Analysis ) ĊĠĠĠĠĠĠĠ Ġval Ġcall graph Assembler Ġ= ĠCall graph Assembler ( scene V , Ġcallback Analysis . possible Callbacks , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġval Ġic fg Ġ= ĠInter pro ced ural CFG Wrapper ( scene V , Ġcall graph Assembler . call graph ) ĊĠĠĠĠĠĠĠ Ġval Ġvalue Resolver Ġ= ĠValue Resolver ( scene V , Ġic fg ) ĊĠĠĠĠĠĠĠ Ġval Ġview Resolver Ġ= ĠView Resolver ( scene V . getS oot Class ( D UMMY _ ACTIVITY _ NAME ), Ġapp Model , Ġscene V , Ġvalue Resolver , Ġapk Info . resource Parser , Ġlayout Analysis ) ĊĠĠĠĠĠĠĠ Ġval Ġcf Ġ= ĠCallback Finder ( scene V , Ġvalue Resolver , Ġview Resolver ) ĊĠĠĠĠĠĠĠ Ġval Ġcallbacks Ġ= Ġcf . resolve () ĊĠĠĠĠĠĠĠ Ġprintln ( callbacks . size ) ĊĠĠĠĠĠĠĠ Ġcallbacks . on Each Ġ{ Ġprintln ( it ) Ġ} ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . MainActivity " Ġ}). has Size ( 6 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . about . About Activity " Ġ}). has Size ( 2 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . bus . Bus Detail Activity " Ġ}). has Size ( 2 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . bus . Bus Activity " Ġ}). has Size ( 2 ) Ġ// Bus St ations Adapter Ġ& ĠSearch Station Adapter ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . camp us . Camp us Activity " Ġ}). has Size ( 4 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . camp us . Camp us Search Activity " Ġ}). has Size ( 1 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . camp us . Camp us Search Activity \$ Camp us Categories Adapter " Ġ}). has Size ( 3 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . camp us . ui helper . Search Adapter " Ġ}). has Size ( 1 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . staff . Person Detail Web Activity " Ġ}). has Size ( 2 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . staff . SearchResult Item Detail Activity " Ġ}). has Size ( 4 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . staff . Search Staff Activity " Ġ}). has Size ( 3 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . staff . SearchResult Activity " Ġ}). has Size ( 1 ) ĊĠĠĠĠĠĠĠ ĠassertThat ( callbacks . filter Ġ{ Ġit . third ?. name Ġ== Ġ" de . un isa ar land . uni App . rss Views . RSS Adapter " Ġ}). has Size ( 1 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġcall Chain Test () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlayout Analysis Ġ= ĠXml Layout Analysis ( scene V , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġval Ġcallback Analysis Ġ= ĠCallback Analysis ( scene V , Ġlayout Analysis ) ĊĠĠĠĠĠĠĠ Ġval Ġcall graph Assembler Ġ= ĠCall graph Assembler ( scene V , Ġcallback Analysis . possible Callbacks , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġval Ġic fg Ġ= ĠInter pro ced ural CFG Wrapper ( scene V , Ġcall graph Assembler . call graph ) ĊĠĠĠĠĠĠĠ Ġval Ġcw Ġ= ĠCall chain Walker ( scene V , Ġapp Model , ĠValue Resolver ( scene V , Ġic fg )) ĊĠĠĠĠĠĠĠ Ġval Ġids Ġ= Ġcw . trace To View Id ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscene V . getMethod ("< com . example . av di i enko . button _ xml . One Listener Multiple Buttons $ 2 : Ġvoid ĠonClick ( android . view . View )> "), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscene V . getMethod ("< android . tele phony . Tele phony Manager : Ġjava . lang . String Ġget DeviceId ()> ") ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertThat ( ids ). contains Exactly ( 2 1 3 1 1 6 5 2 5 0 ) Ċ // ĠĠĠĠĠĠĠ Ġval Ġresolve From Callback Ġ= Ġcw . bind Callback To Views ( scene V . getMethod ("< com . example . av di i enko . button _ xml . One Listener Multiple Buttons $ 2 : Ġvoid ĠonClick ( android . view . View )> ")) Ċ // ĠĠĠĠĠĠĠ Ġval Ġresolve From Callback 2 Ġ= Ġcw . resolve Callback Units ById ( scene V . getMethod ("< com . example . av di i enko . button _ xml . One Listener Multiple Buttons $ 2 : Ġvoid ĠonClick ( android . view . View )> "), Ġ 2 1 3 1 2 3 0 7 3 0 ) ĊĠĠĠ Ġ} Ċ // ĠĠĠĠ Ġ@ Test Ċ // ĠĠĠĠ Ġpublic Ġvoid Ġsave Results Test () Ġ{ Ċ // ĠĠĠĠĠĠĠĠ ĠXml Layout Analysis Ġlayout Analysis Ġ= Ġnew ĠXml Layout Analysis ( scene V , Ġapk Manifest Info ); Ċ // ĠĠĠĠĠĠĠĠ ĠCallback Analysis Ġcallback Analysis Ġ= Ġnew ĠCallback Analysis ( scene V , Ġlayout Analysis ); Ċ // ĠĠĠĠĠĠĠĠ ĠCall graph Assembler Ġcall graph Assembler Ġ= Ġnew ĠCall graph Assembler ( scene V , Ġcallback Analysis . get Possible Callbacks (), Ġapk Manifest Info ); Ċ // ĠĠĠĠĠĠĠĠ ĠI Info flow CFG Ġic fg Ġ= Ġnew ĠInter pro ced ural CFG Wrapper ( scene V , Ġcall graph Assembler . get Call graph ()); Ċ // ĠĠĠĠĠĠĠĠ ĠValue Resolver Ġvalue Resolver Ġ= Ġnew ĠValue Resolver ( scene V , Ġic fg ); Ċ // ĠĠĠĠĠĠĠĠ ĠLayout Mapper Ġlm Ġ= Ġnew ĠLayout Mapper ( scene V , Ġic fg , Ġvalue Resolver ); Ċ // ĠĠĠĠĠĠĠĠ ĠMulti Map < S oot Class , ĠValue > Ġlayout Mapping Ġ= Ġlm . resolve Layout Mapping (); Ċ // ĠĠĠĠĠĠĠĠ ĠString Ġpkg Ġ= ĠPaths . get ( apk File ). get FileName (). toString (); Ċ // ĠĠĠĠĠĠĠĠ ĠString Ġres FilePath Ġ= Ġ" layouts _" Ġ+ Ġpkg Ġ+ Ġ". json "; Ċ // ĠĠĠĠĠĠĠĠ ĠResults Handler . save Activities Content ( layout Analysis . get Layout sWith Id (), Ġlayout Mapping , ĠPaths . get ( res FilePath )); Ċ // ĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġsimple Layouts Test () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlayout Analysis Ġ= ĠXml Layout Analysis ( scene V , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġval Ġuser Controls Ġ= Ġlayout Analysis . flat Layouts ĊĠĠĠĠĠĠĠ ĠassertThat ( user Controls . keySet ()). has Size ( 7 3 )// 4 5 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun ĠstartActivity Test () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlayout Analysis Ġ= ĠXml Layout Analysis ( scene V , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġprintln (" === ${ apk Info . manifest . target Sdk Version () }") ĊĠĠĠĠĠĠĠ Ġval Ġcallback Analysis Ġ= ĠCallback Analysis ( scene V , Ġlayout Analysis ) ĊĠĠĠĠĠĠĠ Ġval Ġcall graph Assembler Ġ= ĠCall graph Assembler ( scene V , Ġcallback Analysis . possible Callbacks , Ġapk Info ) ĊĠĠĠĠĠĠĠ Ġval Ġic fg Ġ= ĠInter pro ced ural CFG Wrapper ( scene V , Ġcall graph Assembler . call graph ) ĊĠĠĠĠĠĠĠ Ġval Ġvalue Resolver Ġ= ĠValue Resolver ( scene V , Ġic fg ) ĊĠĠĠĠĠĠĠ Ġval Ġat f Ġ= ĠTransition Resolver ( scene V , Ġapp Model , Ġic fg , Ġvalue Resolver , Ġapk Info . resource Parser , Ġapk Info . intent Filters ) ĊĠĠĠĠĠĠĠ Ġat f . resolve () ĊĠĠĠĠĠĠĠ Ġval Ġactivity Transitions Ġ= Ġapp Model . transitions ĊĠĠĠĠĠĠĠ Ġfor Ġ( activity Transition Ġin Ġactivity Transitions ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . out . println ( activity Transition ) ĊĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ ĠassertThat ( activity Transitions [ scene V . getS oot Class (" de . un isa ar land . uni App . MainActivity ")] ). has Size ( 7 ) Ċ // ĠĠĠĠĠĠĠ ĠassertThat ( activity Transitions [ scene V . getS oot Class (" de . un isa ar land . uni App . camp us . Camp us Activity ")] ). has Size ( 3 ) Ċ // ĠĠĠĠĠĠĠ ĠassertThat ( activity Transitions [ scene V . getS oot Class (" de . un isa ar land . uni App . restaurant . Restaurant Activity ")] ). has Size ( 2 ) Ċ // ĠĠĠĠĠĠĠ ĠassertThat ( activity Transitions [ scene V . getS oot Class (" de . un isa ar land . uni App . staff . SearchResult Item Detail Activity ")] ). has Size ( 2 ) Ċ // ĠĠĠĠĠĠĠ ĠassertThat ( activity Transitions [ scene V . getS oot Class (" de . un isa ar land . uni App . staff . Search Staff Activity ")] ). has Size ( 1 ) Ċ // ĠĠĠĠĠĠĠ ĠassertThat ( activity Transitions [ scene V . getS oot Class (" de . un isa ar land . uni App . staff . SearchResult Activity ")] ). has Size ( 1 ) Ċ // Ċ // ĠĠĠĠĠĠĠ ĠassertThat ( activity Transitions [ scene V . getS oot Class (" de . un isa ar land . uni App . about . About Activity ")] ). isEmpty () ĊĠĠĠĠĠĠĠ ĠassertThat ( activity Transitions ). has Size ( 1 8 ) ĊĠĠĠĠĠĠĠ Ġ// TODO : Ġcomplete ĊĠĠĠ Ġ} Ċ } Ċ