11import { type AndroidAppLaunchOptions } from '@react-native-harness/platforms' ;
22import { spawn , SubprocessError } from '@react-native-harness/tools' ;
3+ import {
4+ getAdbBinaryPath ,
5+ getAvdManagerBinaryPath ,
6+ getEmulatorBinaryPath ,
7+ getSdkManagerBinaryPath ,
8+ } from './environment.js' ;
39
410const wait = async ( ms : number ) : Promise < void > => {
511 await new Promise ( ( resolve ) => {
@@ -11,6 +17,11 @@ const getSystemImagePackage = (apiLevel: number): string => {
1117 return `system-images;android-${ apiLevel } ;default;x86_64` ;
1218} ;
1319
20+ const getAvdConfigPath = ( name : string ) : string =>
21+ `${
22+ process . env . ANDROID_AVD_HOME ?? `${ process . env . HOME } /.android/avd`
23+ } /${ name } .avd/config.ini`;
24+
1425export type CreateAvdOptions = {
1526 name : string ;
1627 apiLevel : number ;
@@ -65,7 +76,7 @@ export const isAppInstalled = async (
6576 adbId : string ,
6677 bundleId : string
6778) : Promise < boolean > => {
68- const { stdout } = await spawn ( 'adb' , [
79+ const { stdout } = await spawn ( getAdbBinaryPath ( ) , [
6980 '-s' ,
7081 adbId ,
7182 'shell' ,
@@ -82,7 +93,7 @@ export const reversePort = async (
8293 port : number ,
8394 hostPort : number = port
8495) : Promise < void > => {
85- await spawn ( 'adb' , [
96+ await spawn ( getAdbBinaryPath ( ) , [
8697 '-s' ,
8798 adbId ,
8899 'reverse' ,
@@ -95,7 +106,14 @@ export const stopApp = async (
95106 adbId : string ,
96107 bundleId : string
97108) : Promise < void > => {
98- await spawn ( 'adb' , [ '-s' , adbId , 'shell' , 'am' , 'force-stop' , bundleId ] ) ;
109+ await spawn ( getAdbBinaryPath ( ) , [
110+ '-s' ,
111+ adbId ,
112+ 'shell' ,
113+ 'am' ,
114+ 'force-stop' ,
115+ bundleId ,
116+ ] ) ;
99117} ;
100118
101119export const startApp = async (
@@ -104,15 +122,15 @@ export const startApp = async (
104122 activityName : string ,
105123 options ?: AndroidAppLaunchOptions
106124) : Promise < void > => {
107- await spawn ( 'adb' , [
125+ await spawn ( getAdbBinaryPath ( ) , [
108126 '-s' ,
109127 adbId ,
110128 ...getStartAppArgs ( bundleId , activityName , options ) ,
111129 ] ) ;
112130} ;
113131
114132export const getDeviceIds = async ( ) : Promise < string [ ] > => {
115- const { stdout } = await spawn ( 'adb' , [ 'devices' ] ) ;
133+ const { stdout } = await spawn ( getAdbBinaryPath ( ) , [ 'devices' ] ) ;
116134 return stdout
117135 . split ( '\n' )
118136 . slice ( 1 ) // Skip header
@@ -123,15 +141,21 @@ export const getDeviceIds = async (): Promise<string[]> => {
123141export const getEmulatorName = async (
124142 adbId : string
125143) : Promise < string | null > => {
126- const { stdout } = await spawn ( 'adb' , [ '-s' , adbId , 'emu' , 'avd' , 'name' ] ) ;
144+ const { stdout } = await spawn ( getAdbBinaryPath ( ) , [
145+ '-s' ,
146+ adbId ,
147+ 'emu' ,
148+ 'avd' ,
149+ 'name' ,
150+ ] ) ;
127151 return stdout . split ( '\n' ) [ 0 ] . trim ( ) || null ;
128152} ;
129153
130154export const getShellProperty = async (
131155 adbId : string ,
132156 property : string
133157) : Promise < string | null > => {
134- const { stdout } = await spawn ( 'adb' , [
158+ const { stdout } = await spawn ( getAdbBinaryPath ( ) , [
135159 '-s' ,
136160 adbId ,
137161 'shell' ,
@@ -160,14 +184,14 @@ export const isBootCompleted = async (adbId: string): Promise<boolean> => {
160184} ;
161185
162186export const stopEmulator = async ( adbId : string ) : Promise < void > => {
163- await spawn ( 'adb' , [ '-s' , adbId , 'emu' , 'kill' ] ) ;
187+ await spawn ( getAdbBinaryPath ( ) , [ '-s' , adbId , 'emu' , 'kill' ] ) ;
164188} ;
165189
166190export const installApp = async (
167191 adbId : string ,
168192 appPath : string
169193) : Promise < void > => {
170- await spawn ( 'adb' , [ '-s' , adbId , 'install' , '-r' , appPath ] ) ;
194+ await spawn ( getAdbBinaryPath ( ) , [ '-s' , adbId , 'install' , '-r' , appPath ] ) ;
171195} ;
172196
173197export const hasAvd = async ( name : string ) : Promise < boolean > => {
@@ -184,20 +208,22 @@ export const createAvd = async ({
184208} : CreateAvdOptions ) : Promise < void > => {
185209 const systemImagePackage = getSystemImagePackage ( apiLevel ) ;
186210
187- await spawn ( 'sdkmanager' , [ systemImagePackage ] ) ;
211+ await spawn ( getSdkManagerBinaryPath ( ) , [ systemImagePackage ] ) ;
188212 await spawn ( 'bash' , [
189213 '-lc' ,
190- `printf 'no\n' | avdmanager create avd --force --name "${ name } " --package "${ systemImagePackage } " --device "${ profile } "` ,
214+ `printf 'no\n' | " ${ getAvdManagerBinaryPath ( ) } " create avd --force --name "${ name } " --package "${ systemImagePackage } " --device "${ profile } "` ,
191215 ] ) ;
192216 await spawn ( 'bash' , [
193217 '-lc' ,
194- `printf '%s\n%s\n' 'disk.dataPartition.size=${ diskSize } ' 'vm.heapSize=${ heapSize } ' >> "$HOME/.android/avd/${ name } .avd/config.ini"` ,
218+ `printf '%s\n%s\n' 'disk.dataPartition.size=${ diskSize } ' 'vm.heapSize=${ heapSize } ' >> "${ getAvdConfigPath (
219+ name
220+ ) } "`,
195221 ] ) ;
196222} ;
197223
198224export const startEmulator = async ( name : string ) : Promise < void > => {
199225 void spawn (
200- 'emulator' ,
226+ getEmulatorBinaryPath ( ) ,
201227 [
202228 `@${ name } ` ,
203229 '-no-snapshot-save' ,
@@ -266,7 +292,7 @@ export const isAppRunning = async (
266292 bundleId : string
267293) : Promise < boolean > => {
268294 try {
269- const { stdout } = await spawn ( 'adb' , [
295+ const { stdout } = await spawn ( getAdbBinaryPath ( ) , [
270296 '-s' ,
271297 adbId ,
272298 'shell' ,
@@ -287,7 +313,7 @@ export const getAppUid = async (
287313 adbId : string ,
288314 bundleId : string
289315) : Promise < number > => {
290- const { stdout } = await spawn ( 'adb' , [
316+ const { stdout } = await spawn ( getAdbBinaryPath ( ) , [
291317 '-s' ,
292318 adbId ,
293319 'shell' ,
@@ -312,7 +338,7 @@ export const setHideErrorDialogs = async (
312338 adbId : string ,
313339 hide : boolean
314340) : Promise < void > => {
315- await spawn ( 'adb' , [
341+ await spawn ( getAdbBinaryPath ( ) , [
316342 '-s' ,
317343 adbId ,
318344 'shell' ,
@@ -325,7 +351,7 @@ export const setHideErrorDialogs = async (
325351} ;
326352
327353export const getLogcatTimestamp = async ( adbId : string ) : Promise < string > => {
328- const { stdout } = await spawn ( 'adb' , [
354+ const { stdout } = await spawn ( getAdbBinaryPath ( ) , [
329355 '-s' ,
330356 adbId ,
331357 'shell' ,
@@ -338,7 +364,7 @@ export const getLogcatTimestamp = async (adbId: string): Promise<string> => {
338364
339365export const getAvds = async ( ) : Promise < string [ ] > => {
340366 try {
341- const { stdout } = await spawn ( 'emulator' , [ '-list-avds' ] ) ;
367+ const { stdout } = await spawn ( getEmulatorBinaryPath ( ) , [ '-list-avds' ] ) ;
342368 return stdout
343369 . split ( '\n' )
344370 . map ( ( line ) => line . trim ( ) )
@@ -355,7 +381,7 @@ export type AdbDevice = {
355381} ;
356382
357383export const getConnectedDevices = async ( ) : Promise < AdbDevice [ ] > => {
358- const { stdout } = await spawn ( 'adb' , [ 'devices' , '-l' ] ) ;
384+ const { stdout } = await spawn ( getAdbBinaryPath ( ) , [ 'devices' , '-l' ] ) ;
359385 const lines = stdout . split ( '\n' ) . slice ( 1 ) ;
360386 const devices : AdbDevice [ ] = [ ] ;
361387
0 commit comments