@react-native-harness/platform-android 1.1.0-rc.2 → 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.
- package/README.md +9 -2
- package/dist/__tests__/adb.test.js +283 -10
- package/dist/__tests__/avd-config.test.d.ts +2 -0
- package/dist/__tests__/avd-config.test.d.ts.map +1 -0
- package/dist/__tests__/avd-config.test.js +174 -0
- package/dist/__tests__/ci-action.test.d.ts +2 -0
- package/dist/__tests__/ci-action.test.d.ts.map +1 -0
- package/dist/__tests__/ci-action.test.js +46 -0
- package/dist/__tests__/emulator-startup.test.d.ts +2 -0
- package/dist/__tests__/emulator-startup.test.d.ts.map +1 -0
- package/dist/__tests__/emulator-startup.test.js +19 -0
- package/dist/__tests__/environment.test.d.ts +2 -0
- package/dist/__tests__/environment.test.d.ts.map +1 -0
- package/dist/__tests__/environment.test.js +117 -0
- package/dist/__tests__/instance.test.d.ts +2 -0
- package/dist/__tests__/instance.test.d.ts.map +1 -0
- package/dist/__tests__/instance.test.js +423 -0
- package/dist/__tests__/targets.test.d.ts +2 -0
- package/dist/__tests__/targets.test.d.ts.map +1 -0
- package/dist/__tests__/targets.test.js +49 -0
- package/dist/adb.d.ts +23 -0
- package/dist/adb.d.ts.map +1 -1
- package/dist/adb.js +259 -16
- package/dist/app-monitor.d.ts.map +1 -1
- package/dist/app-monitor.js +27 -7
- package/dist/assertions.d.ts +5 -0
- package/dist/assertions.d.ts.map +1 -0
- package/dist/assertions.js +6 -0
- package/dist/avd-config.d.ts +41 -0
- package/dist/avd-config.d.ts.map +1 -0
- package/dist/avd-config.js +173 -0
- package/dist/config.d.ts +77 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -0
- package/dist/emulator-startup.d.ts +3 -0
- package/dist/emulator-startup.d.ts.map +1 -0
- package/dist/emulator-startup.js +17 -0
- package/dist/emulator.d.ts +6 -0
- package/dist/emulator.d.ts.map +1 -0
- package/dist/emulator.js +27 -0
- package/dist/environment.d.ts +31 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +317 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +14 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/instance.d.ts +6 -0
- package/dist/instance.d.ts.map +1 -0
- package/dist/instance.js +232 -0
- package/dist/reader.d.ts +6 -0
- package/dist/reader.d.ts.map +1 -0
- package/dist/reader.js +57 -0
- package/dist/runner.d.ts +2 -2
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +9 -52
- package/dist/targets.d.ts +1 -1
- package/dist/targets.d.ts.map +1 -1
- package/dist/targets.js +4 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/types.d.ts +381 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +107 -0
- package/package.json +4 -4
- package/src/__tests__/adb.test.ts +419 -15
- package/src/__tests__/avd-config.test.ts +206 -0
- package/src/__tests__/ci-action.test.ts +81 -0
- package/src/__tests__/emulator-startup.test.ts +32 -0
- package/src/__tests__/environment.test.ts +212 -0
- package/src/__tests__/instance.test.ts +610 -0
- package/src/__tests__/targets.test.ts +53 -0
- package/src/adb.ts +430 -28
- package/src/app-monitor.ts +56 -18
- package/src/avd-config.ts +290 -0
- package/src/config.ts +8 -0
- package/src/emulator-startup.ts +28 -0
- package/src/environment.ts +554 -0
- package/src/errors.ts +19 -0
- package/src/factory.ts +4 -0
- package/src/index.ts +7 -1
- package/src/instance.ts +380 -0
- package/src/runner.ts +19 -70
- package/src/targets.ts +18 -8
package/dist/config.d.ts
CHANGED
|
@@ -11,16 +11,29 @@ export declare const AndroidEmulatorAVDConfigSchema: z.ZodObject<{
|
|
|
11
11
|
profile: z.ZodString;
|
|
12
12
|
diskSize: z.ZodDefault<z.ZodString>;
|
|
13
13
|
heapSize: z.ZodDefault<z.ZodString>;
|
|
14
|
+
snapshot: z.ZodOptional<z.ZodObject<{
|
|
15
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
16
|
+
}, "strip", z.ZodTypeAny, {
|
|
17
|
+
enabled?: boolean | undefined;
|
|
18
|
+
}, {
|
|
19
|
+
enabled?: boolean | undefined;
|
|
20
|
+
}>>;
|
|
14
21
|
}, "strip", z.ZodTypeAny, {
|
|
15
22
|
apiLevel: number;
|
|
16
23
|
profile: string;
|
|
17
24
|
diskSize: string;
|
|
18
25
|
heapSize: string;
|
|
26
|
+
snapshot?: {
|
|
27
|
+
enabled?: boolean | undefined;
|
|
28
|
+
} | undefined;
|
|
19
29
|
}, {
|
|
20
30
|
apiLevel: number;
|
|
21
31
|
profile: string;
|
|
22
32
|
diskSize?: string | undefined;
|
|
23
33
|
heapSize?: string | undefined;
|
|
34
|
+
snapshot?: {
|
|
35
|
+
enabled?: boolean | undefined;
|
|
36
|
+
} | undefined;
|
|
24
37
|
}>;
|
|
25
38
|
export declare const AndroidEmulatorSchema: z.ZodObject<{
|
|
26
39
|
type: z.ZodLiteral<"emulator">;
|
|
@@ -30,16 +43,29 @@ export declare const AndroidEmulatorSchema: z.ZodObject<{
|
|
|
30
43
|
profile: z.ZodString;
|
|
31
44
|
diskSize: z.ZodDefault<z.ZodString>;
|
|
32
45
|
heapSize: z.ZodDefault<z.ZodString>;
|
|
46
|
+
snapshot: z.ZodOptional<z.ZodObject<{
|
|
47
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
48
|
+
}, "strip", z.ZodTypeAny, {
|
|
49
|
+
enabled?: boolean | undefined;
|
|
50
|
+
}, {
|
|
51
|
+
enabled?: boolean | undefined;
|
|
52
|
+
}>>;
|
|
33
53
|
}, "strip", z.ZodTypeAny, {
|
|
34
54
|
apiLevel: number;
|
|
35
55
|
profile: string;
|
|
36
56
|
diskSize: string;
|
|
37
57
|
heapSize: string;
|
|
58
|
+
snapshot?: {
|
|
59
|
+
enabled?: boolean | undefined;
|
|
60
|
+
} | undefined;
|
|
38
61
|
}, {
|
|
39
62
|
apiLevel: number;
|
|
40
63
|
profile: string;
|
|
41
64
|
diskSize?: string | undefined;
|
|
42
65
|
heapSize?: string | undefined;
|
|
66
|
+
snapshot?: {
|
|
67
|
+
enabled?: boolean | undefined;
|
|
68
|
+
} | undefined;
|
|
43
69
|
}>>;
|
|
44
70
|
}, "strip", z.ZodTypeAny, {
|
|
45
71
|
name: string;
|
|
@@ -49,6 +75,9 @@ export declare const AndroidEmulatorSchema: z.ZodObject<{
|
|
|
49
75
|
profile: string;
|
|
50
76
|
diskSize: string;
|
|
51
77
|
heapSize: string;
|
|
78
|
+
snapshot?: {
|
|
79
|
+
enabled?: boolean | undefined;
|
|
80
|
+
} | undefined;
|
|
52
81
|
} | undefined;
|
|
53
82
|
}, {
|
|
54
83
|
name: string;
|
|
@@ -58,6 +87,9 @@ export declare const AndroidEmulatorSchema: z.ZodObject<{
|
|
|
58
87
|
profile: string;
|
|
59
88
|
diskSize?: string | undefined;
|
|
60
89
|
heapSize?: string | undefined;
|
|
90
|
+
snapshot?: {
|
|
91
|
+
enabled?: boolean | undefined;
|
|
92
|
+
} | undefined;
|
|
61
93
|
} | undefined;
|
|
62
94
|
}>;
|
|
63
95
|
export declare const PhysicalAndroidDeviceSchema: z.ZodObject<{
|
|
@@ -81,16 +113,29 @@ export declare const AndroidDeviceSchema: z.ZodDiscriminatedUnion<"type", [z.Zod
|
|
|
81
113
|
profile: z.ZodString;
|
|
82
114
|
diskSize: z.ZodDefault<z.ZodString>;
|
|
83
115
|
heapSize: z.ZodDefault<z.ZodString>;
|
|
116
|
+
snapshot: z.ZodOptional<z.ZodObject<{
|
|
117
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
118
|
+
}, "strip", z.ZodTypeAny, {
|
|
119
|
+
enabled?: boolean | undefined;
|
|
120
|
+
}, {
|
|
121
|
+
enabled?: boolean | undefined;
|
|
122
|
+
}>>;
|
|
84
123
|
}, "strip", z.ZodTypeAny, {
|
|
85
124
|
apiLevel: number;
|
|
86
125
|
profile: string;
|
|
87
126
|
diskSize: string;
|
|
88
127
|
heapSize: string;
|
|
128
|
+
snapshot?: {
|
|
129
|
+
enabled?: boolean | undefined;
|
|
130
|
+
} | undefined;
|
|
89
131
|
}, {
|
|
90
132
|
apiLevel: number;
|
|
91
133
|
profile: string;
|
|
92
134
|
diskSize?: string | undefined;
|
|
93
135
|
heapSize?: string | undefined;
|
|
136
|
+
snapshot?: {
|
|
137
|
+
enabled?: boolean | undefined;
|
|
138
|
+
} | undefined;
|
|
94
139
|
}>>;
|
|
95
140
|
}, "strip", z.ZodTypeAny, {
|
|
96
141
|
name: string;
|
|
@@ -100,6 +145,9 @@ export declare const AndroidDeviceSchema: z.ZodDiscriminatedUnion<"type", [z.Zod
|
|
|
100
145
|
profile: string;
|
|
101
146
|
diskSize: string;
|
|
102
147
|
heapSize: string;
|
|
148
|
+
snapshot?: {
|
|
149
|
+
enabled?: boolean | undefined;
|
|
150
|
+
} | undefined;
|
|
103
151
|
} | undefined;
|
|
104
152
|
}, {
|
|
105
153
|
name: string;
|
|
@@ -109,6 +157,9 @@ export declare const AndroidDeviceSchema: z.ZodDiscriminatedUnion<"type", [z.Zod
|
|
|
109
157
|
profile: string;
|
|
110
158
|
diskSize?: string | undefined;
|
|
111
159
|
heapSize?: string | undefined;
|
|
160
|
+
snapshot?: {
|
|
161
|
+
enabled?: boolean | undefined;
|
|
162
|
+
} | undefined;
|
|
112
163
|
} | undefined;
|
|
113
164
|
}>, z.ZodObject<{
|
|
114
165
|
type: z.ZodLiteral<"physical">;
|
|
@@ -133,16 +184,29 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
133
184
|
profile: z.ZodString;
|
|
134
185
|
diskSize: z.ZodDefault<z.ZodString>;
|
|
135
186
|
heapSize: z.ZodDefault<z.ZodString>;
|
|
187
|
+
snapshot: z.ZodOptional<z.ZodObject<{
|
|
188
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
189
|
+
}, "strip", z.ZodTypeAny, {
|
|
190
|
+
enabled?: boolean | undefined;
|
|
191
|
+
}, {
|
|
192
|
+
enabled?: boolean | undefined;
|
|
193
|
+
}>>;
|
|
136
194
|
}, "strip", z.ZodTypeAny, {
|
|
137
195
|
apiLevel: number;
|
|
138
196
|
profile: string;
|
|
139
197
|
diskSize: string;
|
|
140
198
|
heapSize: string;
|
|
199
|
+
snapshot?: {
|
|
200
|
+
enabled?: boolean | undefined;
|
|
201
|
+
} | undefined;
|
|
141
202
|
}, {
|
|
142
203
|
apiLevel: number;
|
|
143
204
|
profile: string;
|
|
144
205
|
diskSize?: string | undefined;
|
|
145
206
|
heapSize?: string | undefined;
|
|
207
|
+
snapshot?: {
|
|
208
|
+
enabled?: boolean | undefined;
|
|
209
|
+
} | undefined;
|
|
146
210
|
}>>;
|
|
147
211
|
}, "strip", z.ZodTypeAny, {
|
|
148
212
|
name: string;
|
|
@@ -152,6 +216,9 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
152
216
|
profile: string;
|
|
153
217
|
diskSize: string;
|
|
154
218
|
heapSize: string;
|
|
219
|
+
snapshot?: {
|
|
220
|
+
enabled?: boolean | undefined;
|
|
221
|
+
} | undefined;
|
|
155
222
|
} | undefined;
|
|
156
223
|
}, {
|
|
157
224
|
name: string;
|
|
@@ -161,6 +228,9 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
161
228
|
profile: string;
|
|
162
229
|
diskSize?: string | undefined;
|
|
163
230
|
heapSize?: string | undefined;
|
|
231
|
+
snapshot?: {
|
|
232
|
+
enabled?: boolean | undefined;
|
|
233
|
+
} | undefined;
|
|
164
234
|
} | undefined;
|
|
165
235
|
}>, z.ZodObject<{
|
|
166
236
|
type: z.ZodLiteral<"physical">;
|
|
@@ -194,6 +264,9 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
194
264
|
profile: string;
|
|
195
265
|
diskSize: string;
|
|
196
266
|
heapSize: string;
|
|
267
|
+
snapshot?: {
|
|
268
|
+
enabled?: boolean | undefined;
|
|
269
|
+
} | undefined;
|
|
197
270
|
} | undefined;
|
|
198
271
|
} | {
|
|
199
272
|
manufacturer: string;
|
|
@@ -215,6 +288,9 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
215
288
|
profile: string;
|
|
216
289
|
diskSize?: string | undefined;
|
|
217
290
|
heapSize?: string | undefined;
|
|
291
|
+
snapshot?: {
|
|
292
|
+
enabled?: boolean | undefined;
|
|
293
|
+
} | undefined;
|
|
218
294
|
} | undefined;
|
|
219
295
|
} | {
|
|
220
296
|
manufacturer: string;
|
|
@@ -233,6 +309,7 @@ export type AndroidDevice = z.infer<typeof AndroidDeviceSchema>;
|
|
|
233
309
|
export type AndroidPlatformConfig = z.infer<typeof AndroidPlatformConfigSchema>;
|
|
234
310
|
export type AndroidAppLaunchOptions = z.infer<typeof AndroidAppLaunchOptionsSchema>;
|
|
235
311
|
export type AndroidEmulatorAVDConfig = z.infer<typeof AndroidEmulatorAVDConfigSchema>;
|
|
312
|
+
export type AndroidEmulatorAVDSnapshotConfig = NonNullable<AndroidEmulatorAVDConfig['snapshot']>;
|
|
236
313
|
export declare const isAndroidDeviceEmulator: (device: AndroidDevice) => device is AndroidEmulator;
|
|
237
314
|
export declare const isAndroidDevicePhysical: (device: AndroidDevice) => device is PhysicalAndroidDevice;
|
|
238
315
|
export declare function assertAndroidDeviceEmulator(device: AndroidDevice): asserts device is AndroidEmulator;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,6BAA6B;;;;;;EAIxC,CAAC;AAEH,eAAO,MAAM,8BAA8B
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,6BAA6B;;;;;;EAIxC,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUzC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIhC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;EAItC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAG9B,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAStC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACpE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AACF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAC5C,OAAO,8BAA8B,CACtC,CAAC;AACF,MAAM,MAAM,gCAAgC,GAAG,WAAW,CACxD,wBAAwB,CAAC,UAAU,CAAC,CACrC,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,QAAQ,aAAa,KACpB,MAAM,IAAI,eAEZ,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,QAAQ,aAAa,KACpB,MAAM,IAAI,qBAEZ,CAAC;AAEF,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,IAAI,eAAe,CAInC;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,IAAI,qBAAqB,CAIzC"}
|
package/dist/config.js
CHANGED
|
@@ -9,6 +9,11 @@ export const AndroidEmulatorAVDConfigSchema = z.object({
|
|
|
9
9
|
profile: z.string().min(1, 'Profile is required'),
|
|
10
10
|
diskSize: z.string().min(1, 'Disk size is required').default('1G'),
|
|
11
11
|
heapSize: z.string().min(1, 'Heap size is required').default('1G'),
|
|
12
|
+
snapshot: z
|
|
13
|
+
.object({
|
|
14
|
+
enabled: z.boolean().optional(),
|
|
15
|
+
})
|
|
16
|
+
.optional(),
|
|
12
17
|
});
|
|
13
18
|
export const AndroidEmulatorSchema = z.object({
|
|
14
19
|
type: z.literal('emulator'),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emulator-startup.d.ts","sourceRoot":"","sources":["../src/emulator-startup.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GACxB,cAAc,GACd,2BAA2B,GAC3B,gBAAgB,CAAC;AAYrB,eAAO,MAAM,sBAAsB,GACjC,MAAM,MAAM,EACZ,MAAM,gBAAgB,KACrB,MAAM,EASR,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const COMMON_EMULATOR_ARGS = [
|
|
2
|
+
'-no-window',
|
|
3
|
+
'-gpu',
|
|
4
|
+
'swiftshader_indirect',
|
|
5
|
+
'-noaudio',
|
|
6
|
+
'-no-boot-anim',
|
|
7
|
+
'-camera-back',
|
|
8
|
+
'none',
|
|
9
|
+
];
|
|
10
|
+
export const getEmulatorStartupArgs = (name, mode) => {
|
|
11
|
+
const modeArgs = mode === 'clean-snapshot-generation'
|
|
12
|
+
? ['-no-snapshot-load']
|
|
13
|
+
: mode === 'snapshot-reuse'
|
|
14
|
+
? ['-no-snapshot-save']
|
|
15
|
+
: ['-no-snapshot-load', '-no-snapshot-save'];
|
|
16
|
+
return [`@${name}`, ...modeArgs, ...COMMON_EMULATOR_ARGS];
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emulator.d.ts","sourceRoot":"","sources":["../src/emulator.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,KACd,OAAO,CAAC,eAAe,CA8BzB,CAAC"}
|
package/dist/emulator.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { spawn } from '@react-native-harness/tools';
|
|
2
|
+
import * as adb from './adb.js';
|
|
3
|
+
export const runEmulator = async (avdName) => {
|
|
4
|
+
const process = spawn('emulator', ['-avd', avdName]);
|
|
5
|
+
await process.nodeChildProcess;
|
|
6
|
+
const adbId = await adb.getEmulatorName(avdName);
|
|
7
|
+
if (!adbId) {
|
|
8
|
+
throw new Error('Emulator not found');
|
|
9
|
+
}
|
|
10
|
+
// Poll for emulator status until it's fully running
|
|
11
|
+
const checkStatus = async () => {
|
|
12
|
+
const status = await adb.isBootCompleted(adbId);
|
|
13
|
+
if (!status) {
|
|
14
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
15
|
+
await checkStatus();
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
// Start checking status after a brief delay to allow emulator to start
|
|
19
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
20
|
+
await checkStatus();
|
|
21
|
+
return {
|
|
22
|
+
adbId,
|
|
23
|
+
stop: async () => {
|
|
24
|
+
await adb.stopEmulator(adbId);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type AndroidSystemImageArch = 'x86_64' | 'arm64-v8a' | 'armeabi-v7a';
|
|
2
|
+
type AndroidSdkRootOptions = {
|
|
3
|
+
env?: NodeJS.ProcessEnv;
|
|
4
|
+
platform?: NodeJS.Platform;
|
|
5
|
+
homeDirectory?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const getDefaultUnixAndroidSdkRoot: ({ platform, homeDirectory, }?: Omit<AndroidSdkRootOptions, "env">) => string | null;
|
|
8
|
+
export declare const getAndroidSdkRoot: (env?: NodeJS.ProcessEnv, options?: Omit<AndroidSdkRootOptions, "env">) => string | null;
|
|
9
|
+
export declare const getHostAndroidSystemImageArch: (architecture?: string) => AndroidSystemImageArch;
|
|
10
|
+
export declare const getAndroidPlatformPackage: (apiLevel: number) => string;
|
|
11
|
+
export declare const getAndroidSystemImagePackage: (apiLevel: number, architecture?: AndroidSystemImageArch) => string;
|
|
12
|
+
export declare const getRequiredAndroidSdkPackages: ({ apiLevel, includeEmulator, architecture, }?: {
|
|
13
|
+
apiLevel?: number;
|
|
14
|
+
includeEmulator?: boolean;
|
|
15
|
+
architecture?: AndroidSystemImageArch;
|
|
16
|
+
}) => string[];
|
|
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>;
|
|
21
|
+
export declare const ensureAndroidDiscoveryEnvironment: () => Promise<string>;
|
|
22
|
+
export declare const ensureAndroidPhysicalDeviceEnvironment: () => Promise<string>;
|
|
23
|
+
export declare const ensureAndroidEmulatorEnvironment: (apiLevel: number) => Promise<string>;
|
|
24
|
+
export declare const getAndroidProcessEnv: (env?: NodeJS.ProcessEnv) => NodeJS.ProcessEnv;
|
|
25
|
+
export declare const initializeAndroidProcessEnv: () => void;
|
|
26
|
+
export declare const getAdbBinaryPath: (sdkRoot?: string) => string;
|
|
27
|
+
export declare const getEmulatorBinaryPath: (sdkRoot?: string) => string;
|
|
28
|
+
export declare const getSdkManagerBinaryPath: (sdkRoot?: string) => string;
|
|
29
|
+
export declare const getAvdManagerBinaryPath: (sdkRoot?: string) => string;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -0,0 +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;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"}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { spawn } from '@react-native-harness/tools';
|
|
2
|
+
import { logger } from '@react-native-harness/tools';
|
|
3
|
+
import { createWriteStream } from 'node:fs';
|
|
4
|
+
import { access, cp, mkdir, mkdtemp, rm } from 'node:fs/promises';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { pipeline } from 'node:stream/promises';
|
|
8
|
+
import https from 'node:https';
|
|
9
|
+
const CMDLINE_TOOLS_PATH_SEGMENTS = ['cmdline-tools', 'latest'];
|
|
10
|
+
const ANDROID_REPOSITORY_INDEX_URL = 'https://dl.google.com/android/repository/repository2-1.xml';
|
|
11
|
+
const androidEnvironmentLogger = logger.child('android-environment');
|
|
12
|
+
const getConfiguredAndroidSdkRoot = (env = process.env) => {
|
|
13
|
+
return env.ANDROID_HOME ?? env.ANDROID_SDK_ROOT ?? null;
|
|
14
|
+
};
|
|
15
|
+
export const getDefaultUnixAndroidSdkRoot = ({ platform = process.platform, homeDirectory = os.homedir(), } = {}) => {
|
|
16
|
+
if (platform === 'darwin') {
|
|
17
|
+
return path.join(homeDirectory, 'Library', 'Android', 'sdk');
|
|
18
|
+
}
|
|
19
|
+
if (platform === 'linux') {
|
|
20
|
+
return path.join(homeDirectory, 'Android', 'Sdk');
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
};
|
|
24
|
+
const canBootstrapAndroidSdk = (platform = process.platform) => {
|
|
25
|
+
return platform === 'darwin' || platform === 'linux';
|
|
26
|
+
};
|
|
27
|
+
const pathExists = async (filePath) => {
|
|
28
|
+
try {
|
|
29
|
+
await access(filePath);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const quoteShell = (value) => {
|
|
37
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
38
|
+
};
|
|
39
|
+
const downloadText = async (url) => {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
const request = https.get(url, (response) => {
|
|
42
|
+
const { statusCode = 0, headers } = response;
|
|
43
|
+
if (statusCode >= 300 &&
|
|
44
|
+
statusCode < 400 &&
|
|
45
|
+
typeof headers.location === 'string') {
|
|
46
|
+
response.resume();
|
|
47
|
+
resolve(downloadText(headers.location));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (statusCode !== 200) {
|
|
51
|
+
response.resume();
|
|
52
|
+
reject(new Error(`Failed to download Android repository index from ${url} (status ${statusCode}).`));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
response.setEncoding('utf8');
|
|
56
|
+
let body = '';
|
|
57
|
+
response.on('data', (chunk) => {
|
|
58
|
+
body += chunk;
|
|
59
|
+
});
|
|
60
|
+
response.once('end', () => {
|
|
61
|
+
resolve(body);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
request.once('error', reject);
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
const downloadFile = async (url, destinationPath) => {
|
|
68
|
+
await new Promise((resolve, reject) => {
|
|
69
|
+
const request = https.get(url, (response) => {
|
|
70
|
+
const { statusCode = 0, headers } = response;
|
|
71
|
+
if (statusCode >= 300 &&
|
|
72
|
+
statusCode < 400 &&
|
|
73
|
+
typeof headers.location === 'string') {
|
|
74
|
+
response.resume();
|
|
75
|
+
resolve(downloadFile(headers.location, destinationPath));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (statusCode !== 200) {
|
|
79
|
+
response.resume();
|
|
80
|
+
reject(new Error(`Failed to download Android command-line tools from ${url} (status ${statusCode}).`));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const output = createWriteStream(destinationPath);
|
|
84
|
+
pipeline(response, output).then(resolve).catch(reject);
|
|
85
|
+
});
|
|
86
|
+
request.once('error', reject);
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
const getCommandLineToolsArchiveUrl = async (platform = process.platform) => {
|
|
90
|
+
const archivePlatform = platform === 'darwin' ? 'mac' : platform === 'linux' ? 'linux' : null;
|
|
91
|
+
if (!archivePlatform) {
|
|
92
|
+
throw new Error('Automatic Android SDK bootstrap is only supported on macOS and Linux.');
|
|
93
|
+
}
|
|
94
|
+
const repositoryIndex = await downloadText(ANDROID_REPOSITORY_INDEX_URL);
|
|
95
|
+
const archivePattern = new RegExp(`commandlinetools-${archivePlatform}-(\\d+)_latest\\.zip`, 'g');
|
|
96
|
+
const matches = [...repositoryIndex.matchAll(archivePattern)];
|
|
97
|
+
if (matches.length === 0) {
|
|
98
|
+
throw new Error(`Failed to resolve Android command-line tools archive for ${archivePlatform}.`);
|
|
99
|
+
}
|
|
100
|
+
const newestArchive = matches
|
|
101
|
+
.map((match) => ({
|
|
102
|
+
fileName: match[0],
|
|
103
|
+
revision: Number(match[1]),
|
|
104
|
+
}))
|
|
105
|
+
.sort((left, right) => right.revision - left.revision)[0];
|
|
106
|
+
return `https://dl.google.com/android/repository/${newestArchive.fileName}`;
|
|
107
|
+
};
|
|
108
|
+
const ensureAndroidCommandLineTools = async (sdkRoot, platform = process.platform) => {
|
|
109
|
+
if ((await pathExists(getSdkManagerBinaryPath(sdkRoot))) &&
|
|
110
|
+
(await pathExists(getAvdManagerBinaryPath(sdkRoot)))) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (!canBootstrapAndroidSdk(platform)) {
|
|
114
|
+
throw new Error('Android command-line tools are missing. Set ANDROID_HOME or ANDROID_SDK_ROOT to an initialized SDK.');
|
|
115
|
+
}
|
|
116
|
+
androidEnvironmentLogger.info('Bootstrapping Android command-line tools in %s', sdkRoot);
|
|
117
|
+
await mkdir(sdkRoot, { recursive: true });
|
|
118
|
+
const temporaryDirectory = await mkdtemp(path.join(os.tmpdir(), 'android-cmdline-tools-'));
|
|
119
|
+
const archivePath = path.join(temporaryDirectory, 'cmdline-tools.zip');
|
|
120
|
+
const extractedPath = path.join(temporaryDirectory, 'extracted');
|
|
121
|
+
const sourceDirectory = path.join(extractedPath, 'cmdline-tools');
|
|
122
|
+
const targetDirectory = path.join(sdkRoot, ...CMDLINE_TOOLS_PATH_SEGMENTS);
|
|
123
|
+
try {
|
|
124
|
+
await downloadFile(await getCommandLineToolsArchiveUrl(platform), archivePath);
|
|
125
|
+
await spawn('unzip', ['-q', archivePath, '-d', extractedPath]);
|
|
126
|
+
await rm(targetDirectory, { force: true, recursive: true });
|
|
127
|
+
await mkdir(path.dirname(targetDirectory), { recursive: true });
|
|
128
|
+
await cp(sourceDirectory, targetDirectory, { recursive: true });
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
await rm(temporaryDirectory, { force: true, recursive: true });
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const acceptAndroidLicenses = async (sdkRoot) => {
|
|
135
|
+
const sdkManagerBinaryPath = getSdkManagerBinaryPath(sdkRoot);
|
|
136
|
+
await spawn('bash', [
|
|
137
|
+
'-lc',
|
|
138
|
+
`yes | ${quoteShell(sdkManagerBinaryPath)} --sdk_root=${quoteShell(sdkRoot)} --licenses >/dev/null`,
|
|
139
|
+
], {
|
|
140
|
+
env: getAndroidProcessEnv({
|
|
141
|
+
...process.env,
|
|
142
|
+
ANDROID_HOME: sdkRoot,
|
|
143
|
+
ANDROID_SDK_ROOT: sdkRoot,
|
|
144
|
+
}),
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
const getPackageVerificationPath = (sdkRoot, packageName) => {
|
|
148
|
+
if (packageName === 'platform-tools') {
|
|
149
|
+
return getAdbBinaryPath(sdkRoot);
|
|
150
|
+
}
|
|
151
|
+
if (packageName === 'emulator') {
|
|
152
|
+
return getEmulatorBinaryPath(sdkRoot);
|
|
153
|
+
}
|
|
154
|
+
if (packageName.startsWith('platforms;android-')) {
|
|
155
|
+
return path.join(sdkRoot, packageName.replace(';', '/'));
|
|
156
|
+
}
|
|
157
|
+
if (packageName.startsWith('system-images;android-')) {
|
|
158
|
+
return path.join(sdkRoot, packageName.replaceAll(';', path.sep));
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
};
|
|
162
|
+
const getMissingAndroidSdkPackages = async (sdkRoot, packages) => {
|
|
163
|
+
const missingPackages = [];
|
|
164
|
+
for (const packageName of packages) {
|
|
165
|
+
const verificationPath = getPackageVerificationPath(sdkRoot, packageName);
|
|
166
|
+
if (!verificationPath) {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (!(await pathExists(verificationPath))) {
|
|
170
|
+
missingPackages.push(packageName);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return missingPackages;
|
|
174
|
+
};
|
|
175
|
+
const installAndroidSdkPackages = async (sdkRoot, packages) => {
|
|
176
|
+
if (packages.length === 0) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const sdkManagerBinaryPath = getSdkManagerBinaryPath(sdkRoot);
|
|
180
|
+
const packageArgs = packages
|
|
181
|
+
.map((packageName) => quoteShell(packageName))
|
|
182
|
+
.join(' ');
|
|
183
|
+
androidEnvironmentLogger.info('Installing missing Android SDK packages: %s', packages.join(', '));
|
|
184
|
+
await acceptAndroidLicenses(sdkRoot);
|
|
185
|
+
await spawn('bash', [
|
|
186
|
+
'-lc',
|
|
187
|
+
`yes | ${quoteShell(sdkManagerBinaryPath)} --sdk_root=${quoteShell(sdkRoot)} ${packageArgs}`,
|
|
188
|
+
], {
|
|
189
|
+
env: getAndroidProcessEnv({
|
|
190
|
+
...process.env,
|
|
191
|
+
ANDROID_HOME: sdkRoot,
|
|
192
|
+
ANDROID_SDK_ROOT: sdkRoot,
|
|
193
|
+
}),
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
export const getAndroidSdkRoot = (env = process.env, options = {}) => {
|
|
197
|
+
return (getConfiguredAndroidSdkRoot(env) ?? getDefaultUnixAndroidSdkRoot(options));
|
|
198
|
+
};
|
|
199
|
+
const getRequiredAndroidSdkRoot = (env = process.env, options = {}) => {
|
|
200
|
+
const sdkRoot = getAndroidSdkRoot(env, options);
|
|
201
|
+
if (!sdkRoot) {
|
|
202
|
+
throw new Error('Android SDK root is not configured. Set ANDROID_HOME or ANDROID_SDK_ROOT.');
|
|
203
|
+
}
|
|
204
|
+
return sdkRoot;
|
|
205
|
+
};
|
|
206
|
+
export const getHostAndroidSystemImageArch = (architecture = process.arch) => {
|
|
207
|
+
switch (architecture) {
|
|
208
|
+
case 'arm64':
|
|
209
|
+
return 'arm64-v8a';
|
|
210
|
+
case 'arm':
|
|
211
|
+
return 'armeabi-v7a';
|
|
212
|
+
case 'x64':
|
|
213
|
+
default:
|
|
214
|
+
return 'x86_64';
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
export const getAndroidPlatformPackage = (apiLevel) => {
|
|
218
|
+
return `platforms;android-${apiLevel}`;
|
|
219
|
+
};
|
|
220
|
+
export const getAndroidSystemImagePackage = (apiLevel, architecture = getHostAndroidSystemImageArch()) => {
|
|
221
|
+
return `system-images;android-${apiLevel};default;${architecture}`;
|
|
222
|
+
};
|
|
223
|
+
export const getRequiredAndroidSdkPackages = ({ apiLevel, includeEmulator = false, architecture = getHostAndroidSystemImageArch(), } = {}) => {
|
|
224
|
+
const packages = ['platform-tools'];
|
|
225
|
+
if (!includeEmulator) {
|
|
226
|
+
return packages;
|
|
227
|
+
}
|
|
228
|
+
packages.push('emulator');
|
|
229
|
+
if (typeof apiLevel === 'number') {
|
|
230
|
+
packages.push(getAndroidPlatformPackage(apiLevel));
|
|
231
|
+
packages.push(getAndroidSystemImagePackage(apiLevel, architecture));
|
|
232
|
+
}
|
|
233
|
+
return packages;
|
|
234
|
+
};
|
|
235
|
+
const getMissingAndroidSdkPackagesForEnvironment = async (packages, { env = process.env, platform = process.platform, homeDirectory = os.homedir(), } = {}) => {
|
|
236
|
+
const sdkRoot = getRequiredAndroidSdkRoot(env, { platform, homeDirectory });
|
|
237
|
+
await mkdir(sdkRoot, { recursive: true });
|
|
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;
|
|
251
|
+
}
|
|
252
|
+
await ensureAndroidCommandLineTools(sdkRoot, platform);
|
|
253
|
+
await installAndroidSdkPackages(sdkRoot, missingPackages);
|
|
254
|
+
const unresolvedPackages = await getMissingAndroidSdkPackages(sdkRoot, packages);
|
|
255
|
+
if (unresolvedPackages.length > 0) {
|
|
256
|
+
throw new Error(`Android SDK packages are still missing after installation: ${unresolvedPackages.join(', ')}`);
|
|
257
|
+
}
|
|
258
|
+
return sdkRoot;
|
|
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
|
+
};
|
|
272
|
+
export const ensureAndroidDiscoveryEnvironment = async () => {
|
|
273
|
+
initializeAndroidProcessEnv();
|
|
274
|
+
return ensureAndroidAdbAvailable();
|
|
275
|
+
};
|
|
276
|
+
export const ensureAndroidPhysicalDeviceEnvironment = async () => {
|
|
277
|
+
initializeAndroidProcessEnv();
|
|
278
|
+
return ensureAndroidAdbAvailable();
|
|
279
|
+
};
|
|
280
|
+
export const ensureAndroidEmulatorEnvironment = async (apiLevel) => {
|
|
281
|
+
initializeAndroidProcessEnv();
|
|
282
|
+
await ensureAndroidAdbAvailable();
|
|
283
|
+
await ensureAndroidEmulatorAvailable();
|
|
284
|
+
return ensureAndroidAvdProvisioningAvailable(apiLevel);
|
|
285
|
+
};
|
|
286
|
+
export const getAndroidProcessEnv = (env = process.env) => {
|
|
287
|
+
const sdkRoot = getAndroidSdkRoot(env);
|
|
288
|
+
if (!sdkRoot) {
|
|
289
|
+
return env;
|
|
290
|
+
}
|
|
291
|
+
const platformToolsPath = path.join(sdkRoot, 'platform-tools');
|
|
292
|
+
const emulatorPath = path.join(sdkRoot, 'emulator');
|
|
293
|
+
const cmdlineToolsPath = path.join(sdkRoot, ...CMDLINE_TOOLS_PATH_SEGMENTS);
|
|
294
|
+
const cmdlineToolsBinPath = path.join(cmdlineToolsPath, 'bin');
|
|
295
|
+
const currentPath = env.PATH ?? '';
|
|
296
|
+
const pathEntries = [
|
|
297
|
+
platformToolsPath,
|
|
298
|
+
emulatorPath,
|
|
299
|
+
cmdlineToolsPath,
|
|
300
|
+
cmdlineToolsBinPath,
|
|
301
|
+
currentPath,
|
|
302
|
+
].filter((entry) => entry !== '');
|
|
303
|
+
return {
|
|
304
|
+
...env,
|
|
305
|
+
ANDROID_HOME: sdkRoot,
|
|
306
|
+
ANDROID_SDK_ROOT: sdkRoot,
|
|
307
|
+
ANDROID_AVD_HOME: path.join(os.homedir(), '.android', 'avd'),
|
|
308
|
+
PATH: pathEntries.join(path.delimiter),
|
|
309
|
+
};
|
|
310
|
+
};
|
|
311
|
+
export const initializeAndroidProcessEnv = () => {
|
|
312
|
+
Object.assign(process.env, getAndroidProcessEnv());
|
|
313
|
+
};
|
|
314
|
+
export const getAdbBinaryPath = (sdkRoot = getRequiredAndroidSdkRoot()) => path.join(sdkRoot, 'platform-tools', 'adb');
|
|
315
|
+
export const getEmulatorBinaryPath = (sdkRoot = getRequiredAndroidSdkRoot()) => path.join(sdkRoot, 'emulator', 'emulator');
|
|
316
|
+
export const getSdkManagerBinaryPath = (sdkRoot = getRequiredAndroidSdkRoot()) => path.join(sdkRoot, ...CMDLINE_TOOLS_PATH_SEGMENTS, 'bin', 'sdkmanager');
|
|
317
|
+
export const getAvdManagerBinaryPath = (sdkRoot = getRequiredAndroidSdkRoot()) => path.join(sdkRoot, ...CMDLINE_TOOLS_PATH_SEGMENTS, 'bin', 'avdmanager');
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare class HarnessAppPathError extends Error {
|
|
2
|
+
constructor(reason: 'missing' | 'invalid', appPath?: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class HarnessEmulatorConfigError extends Error {
|
|
5
|
+
constructor(deviceName: string);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM;CAQ5D;AAED,qBAAa,0BAA2B,SAAQ,KAAK;gBACvC,UAAU,EAAE,MAAM;CAM/B"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export class HarnessAppPathError extends Error {
|
|
2
|
+
constructor(reason, appPath) {
|
|
3
|
+
super(reason === 'missing'
|
|
4
|
+
? 'App is not installed on the emulator and HARNESS_APP_PATH is not set.'
|
|
5
|
+
: `HARNESS_APP_PATH points to a missing APK: ${appPath ?? '<unknown>'}`);
|
|
6
|
+
this.name = 'HarnessAppPathError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class HarnessEmulatorConfigError extends Error {
|
|
10
|
+
constructor(deviceName) {
|
|
11
|
+
super(`Android emulator "${deviceName}" is not running and no AVD config was provided. Add the "avd" property to this runner config so Harness can create and boot the emulator.`);
|
|
12
|
+
this.name = 'HarnessEmulatorConfigError';
|
|
13
|
+
}
|
|
14
|
+
}
|