@react-native-harness/platform-android 1.1.0-rc.3 → 1.1.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,76 @@
1
1
  import { beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { getAndroidSdkRoot, getAndroidSystemImagePackage, getDefaultUnixAndroidSdkRoot, getHostAndroidSystemImageArch, getRequiredAndroidSdkPackages, } from '../environment.js';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { ensureAndroidAdbAvailable, ensureAndroidEmulatorAvailable, getAndroidSdkRoot, getAndroidSystemImagePackage, getDefaultUnixAndroidSdkRoot, getHostAndroidSystemImageArch, getRequiredAndroidSdkPackages, } from '../environment.js';
6
+ import * as tools from '@react-native-harness/tools';
3
7
  describe('Android environment', () => {
4
8
  beforeEach(() => {
5
9
  vi.restoreAllMocks();
6
10
  vi.unstubAllEnvs();
7
11
  });
12
+ it('skips bootstrapping command-line tools when adb is already installed', async () => {
13
+ const sdkRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'android-sdk-'));
14
+ const adbPath = path.join(sdkRoot, 'platform-tools', 'adb');
15
+ fs.mkdirSync(path.dirname(adbPath), { recursive: true });
16
+ fs.writeFileSync(adbPath, '');
17
+ const spawnSpy = vi.spyOn(tools, 'spawn');
18
+ await expect(ensureAndroidAdbAvailable({
19
+ env: { ANDROID_HOME: sdkRoot },
20
+ })).resolves.toBe(sdkRoot);
21
+ expect(spawnSpy).not.toHaveBeenCalled();
22
+ fs.rmSync(sdkRoot, { force: true, recursive: true });
23
+ });
24
+ it('installs only platform-tools when adb is missing', async () => {
25
+ const sdkRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'android-sdk-'));
26
+ const sdkManagerDirectory = path.join(sdkRoot, 'cmdline-tools', 'latest', 'bin');
27
+ fs.mkdirSync(sdkManagerDirectory, { recursive: true });
28
+ fs.writeFileSync(path.join(sdkManagerDirectory, 'sdkmanager'), '');
29
+ fs.writeFileSync(path.join(sdkManagerDirectory, 'avdmanager'), '');
30
+ const spawnSpy = vi.spyOn(tools, 'spawn').mockImplementation((async (command, args) => {
31
+ if (command === 'bash' && typeof args?.[1] === 'string') {
32
+ const commandString = args[1];
33
+ if (commandString.includes('platform-tools')) {
34
+ const adbPath = path.join(sdkRoot, 'platform-tools', 'adb');
35
+ fs.mkdirSync(path.dirname(adbPath), { recursive: true });
36
+ fs.writeFileSync(adbPath, '');
37
+ }
38
+ }
39
+ return {};
40
+ }));
41
+ await expect(ensureAndroidAdbAvailable({
42
+ env: { ANDROID_HOME: sdkRoot },
43
+ })).resolves.toBe(sdkRoot);
44
+ expect(spawnSpy).toHaveBeenCalledWith('bash', ['-lc', expect.stringContaining('platform-tools')], expect.any(Object));
45
+ expect(spawnSpy.mock.calls.some(([command, args]) => command === 'bash' &&
46
+ typeof args?.[1] === 'string' &&
47
+ args[1].includes('platform-tools') &&
48
+ args[1].includes('emulator'))).toBe(false);
49
+ fs.rmSync(sdkRoot, { force: true, recursive: true });
50
+ });
51
+ it('installs emulator only when emulator is missing', async () => {
52
+ const sdkRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'android-sdk-'));
53
+ const sdkManagerDirectory = path.join(sdkRoot, 'cmdline-tools', 'latest', 'bin');
54
+ fs.mkdirSync(sdkManagerDirectory, { recursive: true });
55
+ fs.writeFileSync(path.join(sdkManagerDirectory, 'sdkmanager'), '');
56
+ fs.writeFileSync(path.join(sdkManagerDirectory, 'avdmanager'), '');
57
+ const spawnSpy = vi.spyOn(tools, 'spawn').mockImplementation((async (command, args) => {
58
+ if (command === 'bash' && typeof args?.[1] === 'string') {
59
+ const commandString = args[1];
60
+ if (commandString.includes('emulator')) {
61
+ const emulatorPath = path.join(sdkRoot, 'emulator', 'emulator');
62
+ fs.mkdirSync(path.dirname(emulatorPath), { recursive: true });
63
+ fs.writeFileSync(emulatorPath, '');
64
+ }
65
+ }
66
+ return {};
67
+ }));
68
+ await expect(ensureAndroidEmulatorAvailable({
69
+ env: { ANDROID_HOME: sdkRoot },
70
+ })).resolves.toBe(sdkRoot);
71
+ expect(spawnSpy).toHaveBeenCalledWith('bash', ['-lc', expect.stringContaining('emulator')], expect.any(Object));
72
+ fs.rmSync(sdkRoot, { force: true, recursive: true });
73
+ });
8
74
  it('uses the default Unix SDK root when env vars are missing', () => {
9
75
  expect(getDefaultUnixAndroidSdkRoot({
10
76
  platform: 'darwin',
@@ -54,7 +54,7 @@ describe('Android platform instance', () => {
54
54
  activityName: '.MainActivity',
55
55
  }, harnessConfig, init);
56
56
  await instance.dispose();
57
- expect(ensureAndroidEmulatorEnvironment).toHaveBeenCalledWith(35);
57
+ expect(ensureAndroidEmulatorEnvironment).not.toHaveBeenCalled();
58
58
  expect(stopEmulator).not.toHaveBeenCalled();
59
59
  });
60
60
  it('creates and boots an emulator when missing and shuts it down on dispose', async () => {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=targets.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targets.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/targets.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { getRunTargets } from '../targets.js';
3
+ import * as adb from '../adb.js';
4
+ import * as environment from '../environment.js';
5
+ describe('Android target discovery', () => {
6
+ beforeEach(() => {
7
+ vi.restoreAllMocks();
8
+ vi.unstubAllEnvs();
9
+ });
10
+ it('installs adb and emulator only for discovery', async () => {
11
+ const ensureAndroidAdbAvailable = vi
12
+ .spyOn(environment, 'ensureAndroidAdbAvailable')
13
+ .mockResolvedValue('/tmp/android-sdk');
14
+ const ensureAndroidEmulatorAvailable = vi
15
+ .spyOn(environment, 'ensureAndroidEmulatorAvailable')
16
+ .mockResolvedValue('/tmp/android-sdk');
17
+ vi.spyOn(adb, 'getAvds').mockResolvedValue(['Pixel_8_API_35']);
18
+ vi.spyOn(adb, 'getConnectedDevices').mockResolvedValue([
19
+ {
20
+ id: 'device-1',
21
+ manufacturer: 'Google',
22
+ model: 'Pixel 8',
23
+ },
24
+ ]);
25
+ await expect(getRunTargets()).resolves.toEqual([
26
+ {
27
+ type: 'emulator',
28
+ name: 'Pixel_8_API_35',
29
+ platform: 'android',
30
+ description: 'Android emulator',
31
+ device: {
32
+ name: 'Pixel_8_API_35',
33
+ },
34
+ },
35
+ {
36
+ type: 'physical',
37
+ name: 'Google Pixel 8',
38
+ platform: 'android',
39
+ description: 'Physical device (device-1)',
40
+ device: {
41
+ manufacturer: 'Google',
42
+ model: 'Pixel 8',
43
+ },
44
+ },
45
+ ]);
46
+ expect(ensureAndroidAdbAvailable).toHaveBeenCalledTimes(1);
47
+ expect(ensureAndroidEmulatorAvailable).toHaveBeenCalledTimes(1);
48
+ });
49
+ });
package/dist/adb.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"adb.d.ts","sourceRoot":"","sources":["../src/adb.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adb.d.ts","sourceRoot":"","sources":["../src/adb.ts"],"names":[],"mappings":"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"}
package/dist/adb.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { spawn, SubprocessError } from '@react-native-harness/tools';
2
2
  import { spawn as nodeSpawn } from 'node:child_process';
3
3
  import { access, rm } from 'node:fs/promises';
4
- import { ensureAndroidSdkPackages, getAdbBinaryPath, getAndroidSystemImagePackage, getAvdManagerBinaryPath, getEmulatorBinaryPath, getHostAndroidSystemImageArch, getRequiredAndroidSdkPackages, getSdkManagerBinaryPath, } from './environment.js';
4
+ import { ensureAndroidEmulatorAvailable, ensureAndroidSdkPackages, getAdbBinaryPath, getAndroidSystemImagePackage, getAvdManagerBinaryPath, getEmulatorBinaryPath, getHostAndroidSystemImageArch, getRequiredAndroidSdkPackages, } from './environment.js';
5
5
  import { getEmulatorStartupArgs, } from './emulator-startup.js';
6
6
  const wait = async (ms) => {
7
7
  await new Promise((resolve) => {
@@ -64,16 +64,10 @@ const formatEmulatorStartupError = ({ name, stdout, stderr, exitCode, signal, er
64
64
  });
65
65
  };
66
66
  const ensureEmulatorInstalled = async () => {
67
+ await ensureAndroidEmulatorAvailable();
67
68
  const emulatorBinaryPath = getEmulatorBinaryPath();
68
- try {
69
- await access(emulatorBinaryPath);
70
- return emulatorBinaryPath;
71
- }
72
- catch {
73
- await spawn(getSdkManagerBinaryPath(), ['emulator']);
74
- await access(emulatorBinaryPath);
75
- return emulatorBinaryPath;
76
- }
69
+ await access(emulatorBinaryPath);
70
+ return emulatorBinaryPath;
77
71
  };
78
72
  export const getRequiredEmulatorPackages = (apiLevel) => {
79
73
  return getRequiredAndroidSdkPackages({
@@ -15,6 +15,9 @@ export declare const getRequiredAndroidSdkPackages: ({ apiLevel, includeEmulator
15
15
  architecture?: AndroidSystemImageArch;
16
16
  }) => string[];
17
17
  export declare const ensureAndroidSdkPackages: (packages: readonly string[], { env, platform, homeDirectory, }?: AndroidSdkRootOptions) => Promise<string>;
18
+ export declare const ensureAndroidAdbAvailable: (options?: AndroidSdkRootOptions) => Promise<string>;
19
+ export declare const ensureAndroidEmulatorAvailable: (options?: AndroidSdkRootOptions) => Promise<string>;
20
+ export declare const ensureAndroidAvdProvisioningAvailable: (apiLevel: number, architecture?: AndroidSystemImageArch, options?: AndroidSdkRootOptions) => Promise<string>;
18
21
  export declare const ensureAndroidDiscoveryEnvironment: () => Promise<string>;
19
22
  export declare const ensureAndroidPhysicalDeviceEnvironment: () => Promise<string>;
20
23
  export declare const ensureAndroidEmulatorEnvironment: (apiLevel: number) => Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,CAAC;AAE5E,KAAK,qBAAqB,GAAG;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAQF,eAAO,MAAM,4BAA4B,GAAI,+BAG1C,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAM,KAAG,MAAM,GAAG,IAUrD,CAAC;AAwRF,eAAO,MAAM,iBAAiB,GAC5B,MAAK,MAAM,CAAC,UAAwB,EACpC,UAAS,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAM,KAC/C,MAAM,GAAG,IAIX,CAAC;AAiBF,eAAO,MAAM,6BAA6B,GACxC,eAAc,MAAqB,KAClC,sBAUF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,UAAU,MAAM,KAAG,MAE5D,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,UAAU,MAAM,EAChB,eAAc,sBAAwD,KACrE,MAEF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAI,+CAI3C;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,sBAAsB,CAAC;CAClC,KAAG,MAAM,EAed,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,UAAU,SAAS,MAAM,EAAE,EAC3B,oCAIG,qBAA0B,KAC5B,OAAO,CAAC,MAAM,CA0BhB,CAAC;AAEF,eAAO,MAAM,iCAAiC,QAAa,OAAO,CAAC,MAAM,CAMxE,CAAC;AAEF,eAAO,MAAM,sCAAsC,QACvC,OAAO,CAAC,MAAM,CAIvB,CAAC;AAEJ,eAAO,MAAM,gCAAgC,GAC3C,UAAU,MAAM,KACf,OAAO,CAAC,MAAM,CAShB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,MAAK,MAAM,CAAC,UAAwB,KACnC,MAAM,CAAC,UA2BT,CAAC;AAEF,eAAO,MAAM,2BAA2B,QAAO,IAE9C,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAS,MAAoC,KAC5C,MAAqD,CAAC;AAEzD,eAAO,MAAM,qBAAqB,GAChC,UAAS,MAAoC,KAC5C,MAAoD,CAAC;AAExD,eAAO,MAAM,uBAAuB,GAClC,UAAS,MAAoC,KAC5C,MACsE,CAAC;AAE1E,eAAO,MAAM,uBAAuB,GAClC,UAAS,MAAoC,KAC5C,MACsE,CAAC"}
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,CAAC;AAE5E,KAAK,qBAAqB,GAAG;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAQF,eAAO,MAAM,4BAA4B,GAAI,+BAG1C,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAM,KAAG,MAAM,GAAG,IAUrD,CAAC;AAwRF,eAAO,MAAM,iBAAiB,GAC5B,MAAK,MAAM,CAAC,UAAwB,EACpC,UAAS,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAM,KAC/C,MAAM,GAAG,IAIX,CAAC;AAiBF,eAAO,MAAM,6BAA6B,GACxC,eAAc,MAAqB,KAClC,sBAUF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,UAAU,MAAM,KAAG,MAE5D,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,UAAU,MAAM,EAChB,eAAc,sBAAwD,KACrE,MAEF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAI,+CAI3C;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,sBAAsB,CAAC;CAClC,KAAG,MAAM,EAed,CAAC;AAoBF,eAAO,MAAM,wBAAwB,GACnC,UAAU,SAAS,MAAM,EAAE,EAC3B,oCAIG,qBAA0B,KAC5B,OAAO,CAAC,MAAM,CA8BhB,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,UAAS,qBAA0B,KAClC,OAAO,CAAC,MAAM,CAEhB,CAAC;AAEF,eAAO,MAAM,8BAA8B,GACzC,UAAS,qBAA0B,KAClC,OAAO,CAAC,MAAM,CAEhB,CAAC;AAEF,eAAO,MAAM,qCAAqC,GAChD,UAAU,MAAM,EAChB,eAAc,sBAAwD,EACtE,UAAS,qBAA0B,KAClC,OAAO,CAAC,MAAM,CAQhB,CAAC;AAEF,eAAO,MAAM,iCAAiC,QAAa,OAAO,CAAC,MAAM,CAIxE,CAAC;AAEF,eAAO,MAAM,sCAAsC,QACvC,OAAO,CAAC,MAAM,CAIvB,CAAC;AAEJ,eAAO,MAAM,gCAAgC,GAC3C,UAAU,MAAM,KACf,OAAO,CAAC,MAAM,CAOhB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,MAAK,MAAM,CAAC,UAAwB,KACnC,MAAM,CAAC,UA2BT,CAAC;AAEF,eAAO,MAAM,2BAA2B,QAAO,IAE9C,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAS,MAAoC,KAC5C,MAAqD,CAAC;AAEzD,eAAO,MAAM,qBAAqB,GAChC,UAAS,MAAoC,KAC5C,MAAoD,CAAC;AAExD,eAAO,MAAM,uBAAuB,GAClC,UAAS,MAAoC,KAC5C,MACsE,CAAC;AAE1E,eAAO,MAAM,uBAAuB,GAClC,UAAS,MAAoC,KAC5C,MACsE,CAAC"}
@@ -232,34 +232,56 @@ export const getRequiredAndroidSdkPackages = ({ apiLevel, includeEmulator = fals
232
232
  }
233
233
  return packages;
234
234
  };
235
- export const ensureAndroidSdkPackages = async (packages, { env = process.env, platform = process.platform, homeDirectory = os.homedir(), } = {}) => {
235
+ const getMissingAndroidSdkPackagesForEnvironment = async (packages, { env = process.env, platform = process.platform, homeDirectory = os.homedir(), } = {}) => {
236
236
  const sdkRoot = getRequiredAndroidSdkRoot(env, { platform, homeDirectory });
237
237
  await mkdir(sdkRoot, { recursive: true });
238
- await ensureAndroidCommandLineTools(sdkRoot, platform);
239
- const missingPackages = await getMissingAndroidSdkPackages(sdkRoot, packages);
240
- if (missingPackages.length > 0) {
241
- await installAndroidSdkPackages(sdkRoot, missingPackages);
238
+ return {
239
+ sdkRoot,
240
+ missingPackages: await getMissingAndroidSdkPackages(sdkRoot, packages),
241
+ };
242
+ };
243
+ export const ensureAndroidSdkPackages = async (packages, { env = process.env, platform = process.platform, homeDirectory = os.homedir(), } = {}) => {
244
+ const { sdkRoot, missingPackages } = await getMissingAndroidSdkPackagesForEnvironment(packages, {
245
+ env,
246
+ platform,
247
+ homeDirectory,
248
+ });
249
+ if (missingPackages.length === 0) {
250
+ return sdkRoot;
242
251
  }
252
+ await ensureAndroidCommandLineTools(sdkRoot, platform);
253
+ await installAndroidSdkPackages(sdkRoot, missingPackages);
243
254
  const unresolvedPackages = await getMissingAndroidSdkPackages(sdkRoot, packages);
244
255
  if (unresolvedPackages.length > 0) {
245
256
  throw new Error(`Android SDK packages are still missing after installation: ${unresolvedPackages.join(', ')}`);
246
257
  }
247
258
  return sdkRoot;
248
259
  };
260
+ export const ensureAndroidAdbAvailable = async (options = {}) => {
261
+ return ensureAndroidSdkPackages(['platform-tools'], options);
262
+ };
263
+ export const ensureAndroidEmulatorAvailable = async (options = {}) => {
264
+ return ensureAndroidSdkPackages(['emulator'], options);
265
+ };
266
+ export const ensureAndroidAvdProvisioningAvailable = async (apiLevel, architecture = getHostAndroidSystemImageArch(), options = {}) => {
267
+ return ensureAndroidSdkPackages([
268
+ getAndroidPlatformPackage(apiLevel),
269
+ getAndroidSystemImagePackage(apiLevel, architecture),
270
+ ], options);
271
+ };
249
272
  export const ensureAndroidDiscoveryEnvironment = async () => {
250
273
  initializeAndroidProcessEnv();
251
- return ensureAndroidSdkPackages(getRequiredAndroidSdkPackages({ includeEmulator: true }));
274
+ return ensureAndroidAdbAvailable();
252
275
  };
253
276
  export const ensureAndroidPhysicalDeviceEnvironment = async () => {
254
277
  initializeAndroidProcessEnv();
255
- return ensureAndroidSdkPackages(getRequiredAndroidSdkPackages());
278
+ return ensureAndroidAdbAvailable();
256
279
  };
257
280
  export const ensureAndroidEmulatorEnvironment = async (apiLevel) => {
258
281
  initializeAndroidProcessEnv();
259
- return ensureAndroidSdkPackages(getRequiredAndroidSdkPackages({
260
- apiLevel,
261
- includeEmulator: true,
262
- }));
282
+ await ensureAndroidAdbAvailable();
283
+ await ensureAndroidEmulatorAvailable();
284
+ return ensureAndroidAvdProvisioningAvailable(apiLevel);
263
285
  };
264
286
  export const getAndroidProcessEnv = (env = process.env) => {
265
287
  const sdkRoot = getAndroidSdkRoot(env);
@@ -1 +1 @@
1
- {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../src/instance.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,0BAA0B,EAC/B,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE5E,OAAO,EACL,qBAAqB,EAGtB,MAAM,aAAa,CAAC;AAgKrB,eAAO,MAAM,kCAAkC,GAC7C,QAAQ,qBAAqB,EAC7B,eAAe,aAAa,EAC5B,MAAM,0BAA0B,KAC/B,OAAO,CAAC,qBAAqB,CAoI/B,CAAC;AAEF,eAAO,MAAM,wCAAwC,GACnD,QAAQ,qBAAqB,EAC7B,eAAe,aAAa,KAC3B,OAAO,CAAC,qBAAqB,CAiE/B,CAAC"}
1
+ {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../src/instance.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,0BAA0B,EAC/B,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE5E,OAAO,EACL,qBAAqB,EAGtB,MAAM,aAAa,CAAC;AAkKrB,eAAO,MAAM,kCAAkC,GAC7C,QAAQ,qBAAqB,EAC7B,eAAe,aAAa,EAC5B,MAAM,0BAA0B,KAC/B,OAAO,CAAC,qBAAqB,CAkI/B,CAAC;AAEF,eAAO,MAAM,wCAAwC,GACnD,QAAQ,qBAAqB,EAC7B,eAAe,aAAa,KAC3B,OAAO,CAAC,qBAAqB,CAiE/B,CAAC"}
package/dist/instance.js CHANGED
@@ -8,7 +8,7 @@ import { applyHarnessDebugHttpHost, clearHarnessDebugHttpHost, } from './shared-
8
8
  import { getDeviceName } from './utils.js';
9
9
  import { createAndroidAppMonitor } from './app-monitor.js';
10
10
  import { HarnessAppPathError, HarnessEmulatorConfigError } from './errors.js';
11
- import { ensureAndroidEmulatorEnvironment, getHostAndroidSystemImageArch, } from './environment.js';
11
+ import { ensureAndroidEmulatorAvailable, ensureAndroidEmulatorEnvironment, getHostAndroidSystemImageArch, } from './environment.js';
12
12
  import { isInteractive } from '@react-native-harness/tools';
13
13
  import fs from 'node:fs';
14
14
  const androidInstanceLogger = logger.child('android-instance');
@@ -40,6 +40,7 @@ const configureAndroidRuntime = async (adbId, config, harnessConfig) => {
40
40
  return adb.getAppUid(adbId, config.bundleId);
41
41
  };
42
42
  const startAndWaitForBoot = async ({ emulatorName, signal, mode, }) => {
43
+ await ensureAndroidEmulatorAvailable();
43
44
  await adb.startEmulator(emulatorName, mode);
44
45
  return adb.waitForBoot(emulatorName, signal);
45
46
  };
@@ -135,9 +136,6 @@ export const getAndroidEmulatorPlatformInstance = async (config, harnessConfig,
135
136
  startedByHarness = true;
136
137
  androidInstanceLogger.debug('Android emulator %s connected as %s', emulatorConfig.name, adbId);
137
138
  }
138
- else if (emulatorConfig.avd) {
139
- await ensureAndroidEmulatorEnvironment(emulatorConfig.avd.apiLevel);
140
- }
141
139
  if (!adbId) {
142
140
  throw new DeviceNotFoundError(getDeviceName(emulatorConfig));
143
141
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,EAChC,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAEL,KAAK,qBAAqB,EAE3B,MAAM,aAAa,CAAC;AAWrB,QAAA,MAAM,gBAAgB,GACpB,QAAQ,qBAAqB,EAC7B,eAAe,aAAa,EAC5B,MAAM,0BAA0B,KAC/B,OAAO,CAAC,qBAAqB,CAoB/B,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,EAChC,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAEL,KAAK,qBAAqB,EAE3B,MAAM,aAAa,CAAC;AAUrB,QAAA,MAAM,gBAAgB,GACpB,QAAQ,qBAAqB,EAC7B,eAAe,aAAa,EAC5B,MAAM,0BAA0B,KAC/B,OAAO,CAAC,qBAAqB,CAgB/B,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
package/dist/runner.js CHANGED
@@ -1,16 +1,13 @@
1
1
  import { AndroidPlatformConfigSchema, isAndroidDeviceEmulator, } from './config.js';
2
2
  import { getAndroidEmulatorPlatformInstance, getAndroidPhysicalDevicePlatformInstance, } from './instance.js';
3
- import { ensureAndroidEmulatorEnvironment, ensureAndroidPhysicalDeviceEnvironment, initializeAndroidProcessEnv, } from './environment.js';
3
+ import { ensureAndroidAdbAvailable, initializeAndroidProcessEnv, } from './environment.js';
4
4
  const getAndroidRunner = async (config, harnessConfig, init) => {
5
5
  const parsedConfig = AndroidPlatformConfigSchema.parse(config);
6
6
  initializeAndroidProcessEnv();
7
+ await ensureAndroidAdbAvailable();
7
8
  if (isAndroidDeviceEmulator(parsedConfig.device)) {
8
- if (parsedConfig.device.avd) {
9
- await ensureAndroidEmulatorEnvironment(parsedConfig.device.avd.apiLevel);
10
- }
11
9
  return getAndroidEmulatorPlatformInstance(parsedConfig, harnessConfig, init);
12
10
  }
13
- await ensureAndroidPhysicalDeviceEnvironment();
14
11
  return getAndroidPhysicalDevicePlatformInstance(parsedConfig, harnessConfig);
15
12
  };
16
13
  export default getAndroidRunner;
@@ -1 +1 @@
1
- {"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../src/targets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAI5D,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,SAAS,EAAE,CAoCzD,CAAC"}
1
+ {"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../src/targets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAQ5D,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,SAAS,EAAE,CAuCzD,CAAC"}
package/dist/targets.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import * as adb from './adb.js';
2
- import { ensureAndroidDiscoveryEnvironment } from './environment.js';
2
+ import { ensureAndroidAdbAvailable, ensureAndroidEmulatorAvailable, initializeAndroidProcessEnv, } from './environment.js';
3
3
  export const getRunTargets = async () => {
4
- await ensureAndroidDiscoveryEnvironment();
4
+ initializeAndroidProcessEnv();
5
+ await ensureAndroidAdbAvailable();
6
+ await ensureAndroidEmulatorAvailable();
5
7
  const [avds, connectedDevices] = await Promise.all([
6
8
  adb.getAvds(),
7
9
  adb.getConnectedDevices(),