package Ġio . sa eid . autom ator . location Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . Build Ċ import Ġandroidx . test . core . app . Application Provider Ċ import Ġandroidx . test . platform . app . Instrumentation Registry Ċ import Ġorg . junit . rules . Test Rule Ċ import Ġorg . junit . runner . Description Ċ import Ġorg . junit . runners . model . Statement Ċ import Ġjava . io . FileInputStream Ċ import Ġjava . io . InputStream Reader Ċ Ċ class ĠMock Location Rule ( ĊĠĠĠ Ġgrant Access F ine Location Permission : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġgrant Access Co arse Location Permission : ĠBoolean Ġ= Ġtrue Ċ ) Ġ: ĠTest Rule Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġpermissions : ĠList < String > ĊĠĠĠĠĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġpermissions Ġ= ĠArrayList < String >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd (" android . permission . ACCESS _ MOCK _ LOCATION ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( grant Access F ine Location Permission ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd (" android . permission . ACCESS _ F INE _ LOCATION ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( grant Access Co arse Location Permission ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd (" android . permission . ACCESS _ CO AR SE _ LOCATION ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġapply ( base : ĠStatement , Ġdescription : ĠDescription ): ĠStatement Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġobject Ġ: ĠStatement () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġevaluate () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġuse Ġthe Ġtest Ġapk Ġcontext ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontext Ġ= ĠApplication Provider . getApplicationContext < Context >() ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbefore ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbase . evaluate () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġafter ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbefore ( context : ĠContext ) Ġ{ ĊĠĠĠĠĠĠĠ Ġgrant Needed Permissions ( context . packageName ) ĊĠĠĠĠĠĠĠ Ġgrant Mock Location Access ( context . packageName ) ĊĠĠĠĠĠĠĠ ĠMock Location Autom ator . start ( context ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġafter ( context : ĠContext ) Ġ{ ĊĠĠĠĠĠĠĠ ĠMock Location Autom ator . stop () ĊĠĠĠĠĠĠĠ Ġre voke Mock Location Access ( context . packageName ) ĊĠĠĠĠĠĠĠ Ġre voke Needed Permissions ( context . packageName ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġgrant Needed Permissions ( packageName : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġpermissions . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecute Command (" pm Ġgrant Ġ$ packageName Ġ$ it ", Ġsync Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġre voke Needed Permissions ( packageName : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġ" pm Ġre voke " Ġwill Ġcause Ġthe Ġinstrument ation Ġtest Ġto Ġcrash ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġgrant Mock Location Access ( packageName : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġexecute Command (" app ops Ġset Ġ$ packageName Ġandroid : mock _ location Ġallow ", Ġsync Ġ= Ġtrue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġre voke Mock Location Access ( packageName : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġexecute Command (" app ops Ġset Ġ$ packageName Ġandroid : mock _ location Ġdeny ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġexecute Command ( command : ĠString , Ġsync : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . M ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠInstrument ation Registry . get Instrumentation (). ui Automation . execute Shell Command ( command ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. use Ġ{ Ġp fd Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sync ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSynchron ize Ġwith Ġexecution Ġof Ġcommand Ġby Ġreading Ġthe Ġwhole Ġstream ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠInputStreamReader ( FileInputStream ( p fd . file Descriptor )). read Lines () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }