stim 1.14.0 → 1.16.0
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 +2 -0
- package/dist/activity-BxwdD81S.mjs +609 -0
- package/dist/agent-device-usage-output-Dpih1Tfa.mjs +411 -0
- package/dist/{android-d6rGq1pA.mjs → android-B_NumVyQ.mjs} +169 -81
- package/dist/{android-LbPFRWVL.mjs → android-Ift4kVvt.mjs} +517 -413
- package/dist/android-cas-8U4DPqeR.mjs +167 -0
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{android-XpvCrV7q.mjs → android-r2rBL8kV.mjs} +2 -2
- package/dist/{app-install-BpgSgkJj.mjs → app-install-CKWdbXIX.mjs} +128 -151
- package/dist/attempt-Bk2ouQVL.mjs +39 -0
- package/dist/budget-DjrURfQn.mjs +2700 -0
- package/dist/{build-plan-Dcr-3ie0.mjs → build-plan-DjeSb2Xl.mjs} +192 -653
- package/dist/build-slots-rUk77xqh.mjs +132 -0
- package/dist/{cache-manifest-C68QQ0ua.mjs → cache-manifest-DnUHBJaU.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{chrome-BPCiC3ZX.mjs → chrome-BrcVWQyD.mjs} +1 -1
- package/dist/cli-BkYZ_6hy.mjs +51 -0
- package/dist/cli.mjs +6 -42
- package/dist/client-BTY686R6.mjs +1368 -0
- package/dist/collector-run.mjs +9 -195
- package/dist/{command-output-DVcpw6eE.mjs → command-output-DnJMdEY-.mjs} +1 -1
- package/dist/{config-lvc7d3C2.mjs → config-D0DbpZtM.mjs} +28 -29
- package/dist/{created-devices-CllH_8eb.mjs → created-devices-D5owjN4C.mjs} +2 -2
- package/dist/{dependency-state-DsT7aKeo.mjs → dependency-state-B6cMXZab.mjs} +2 -2
- package/dist/{deps-D9IcKqXS.mjs → deps-urbmfXig.mjs} +3 -3
- package/dist/{detached-entry-DJHoca49.mjs → detached-entry-CiTEgMR1.mjs} +1 -1
- package/dist/dev-client-CroAIjjj.mjs +43 -0
- package/dist/{device-CjuuAJjQ.mjs → device-DZQjF7H5.mjs} +8 -7
- package/dist/device-capacity-BHwxNBlu.mjs +136 -0
- package/dist/device-host-worker.d.mts +1 -0
- package/dist/device-host-worker.mjs +964 -0
- package/dist/device-ios-BadmeL2V.mjs +381 -0
- package/dist/{device-lease-5c3WrVRm.mjs → device-lease-D-hLqx1b.mjs} +43 -36
- package/dist/{device-pool-BiyDyPP-.mjs → device-lease-run-CqjShqWW.mjs} +6 -126
- package/dist/device-pool-CUaEWMMm.mjs +125 -0
- package/dist/{device-remote-D87zEzaq.mjs → device-remote-D5WVWqOq.mjs} +69 -163
- package/dist/{doctor-x9pnU9fq.mjs → doctor-Cimf-gGB.mjs} +241 -103
- package/dist/{error-diagnostics-C5HzcwCW.mjs → error-diagnostics-B9L4Ae0x.mjs} +15 -18
- package/dist/{exec-DK8KaVHK.mjs → exec-CaErVv7t.mjs} +5 -1
- package/dist/{gc-ko6mUAYD.mjs → gc-Bqy4bjEu.mjs} +599 -108
- package/dist/{android-cas-iZK3DOCr.mjs → gradle-BsO1MdsH.mjs} +8 -294
- package/dist/{guide-6R0VNFqI.mjs → guide-B_uyKTxW.mjs} +2511 -239
- package/dist/{guide-status-BZrFPIA_.mjs → guide-status-CjEZMAD4.mjs} +3 -3
- package/dist/hosted-client-a-WmqE2L.mjs +197 -0
- package/dist/hosted-ios-CIWelIqf.mjs +220 -0
- package/dist/hosted-logs-D5g041Q3.mjs +187 -0
- package/dist/hosted-macos-BSZyIb3y.mjs +135 -0
- package/dist/idle-DYVymG92.mjs +1099 -0
- package/dist/idle-shutdown-CTsDnAde.mjs +122 -0
- package/dist/in-use-DvBw0Kxo.mjs +130 -0
- package/dist/{ios-BwDPrnYQ.mjs → ios-BaInn3sW.mjs} +201 -10
- package/dist/ios-Cr1h5gnO.mjs +189 -0
- package/dist/{ios-P1f5nm2n.mjs → ios-aq3QoGI3.mjs} +1159 -633
- package/dist/{ios-device-BiOsSVzd.mjs → ios-device-Ee7sDXfp.mjs} +1 -1
- package/dist/{ios-device-DGglU3E_.mjs → ios-device-FfCN_C8p.mjs} +12 -7
- package/dist/ios-state-DS5UpYTH.mjs +48 -0
- package/dist/{launch-verify-Deg4tB3Z.mjs → launch-verify-2DBRizjo.mjs} +5 -5
- package/dist/logs-CHEVK8zD.mjs +371 -0
- package/dist/machines-BIBUdhpj.mjs +265 -0
- package/dist/macos-CSYEAFmF.mjs +473 -0
- package/dist/macos-run.d.mts +5 -0
- package/dist/macos-run.mjs +2 -0
- package/dist/maintenance-run.d.mts +4 -0
- package/dist/maintenance-run.mjs +254 -0
- package/dist/{metro-CcEo8Fl8.mjs → metro-BeK1ZPz1.mjs} +20 -120
- package/dist/metro-gateway-BJ-rxQAB.mjs +84 -0
- package/dist/{named-ports-Blg8IxOh.mjs → named-ports-Bk_YXEmE.mjs} +6 -59
- package/dist/native-run-NaBrRFtQ.mjs +147 -0
- package/dist/{native-runtime-DjBHRg5m.mjs → native-runtime-DBzRnEKS.mjs} +9 -5
- package/dist/{ndjson-CDY9IkVC.mjs → ndjson-PclOIwVY.mjs} +2 -2
- package/dist/offload-worker.d.mts +122 -0
- package/dist/offload-worker.mjs +606 -0
- package/dist/{ownership-DyYDF5ww.mjs → ownership-DiA16AsN.mjs} +3 -2
- package/dist/ownership-hCkPzGmr.mjs +571 -0
- package/dist/{page-BHUzTDFt.mjs → page-QF_Ke10s.mjs} +7 -2
- package/dist/{ports-BguS83ex.mjs → ports-R2k4Knz3.mjs} +3 -3
- package/dist/prebuild-D2fsca_Z.mjs +213 -0
- package/dist/preview-DhVbvPAZ.mjs +318 -0
- package/dist/process-identity-BmRm1qV0.mjs +12 -0
- package/dist/{project-CWlvEaeN.mjs → project-Du91Ilvc.mjs} +74 -19
- package/dist/pull-request-pxnDCQzn.mjs +322 -0
- package/dist/pull-requests.d.mts +120 -0
- package/dist/pull-requests.mjs +2 -0
- package/dist/recordings-BIXOzVnr.mjs +37 -0
- package/dist/{reload-BiniwsSZ.mjs → reload-rM9jV1fz.mjs} +109 -24
- package/dist/{remote-cache-CcR6o6lI.mjs → remote-cache-C8-V13XN.mjs} +5 -5
- package/dist/run-f4vI6EnK.mjs +119 -0
- package/dist/{server-bare-DGfgyJ5J.mjs → server-bare-CpPGmnmO.mjs} +33 -15
- package/dist/server-expo-CVqO2c35.mjs +2 -0
- package/dist/{server-expo-BVuwQ65v.mjs → server-expo-MC0rHlOC.mjs} +8 -12
- package/dist/settings-BBpMcDbD.mjs +25 -0
- package/dist/{settings-B-fsC-Om.mjs → settings-ZkDzkzvB.mjs} +22 -10
- package/dist/settings-oTSkkNrM.mjs +1439 -0
- package/dist/settings.schema.json +845 -97
- package/dist/{simslim-DrDN4WuV.mjs → simslim-B8-7AoTI.mjs} +8 -132
- package/dist/{slot-launch-D5t8EiMf.mjs → slot-launch-B8VrHxn1.mjs} +11 -8
- package/dist/{spawn-claims-Drw_o-Fb.mjs → spawn-claims-D0XfSe8u.mjs} +1 -1
- package/dist/spawn-entry-jw19m8Nl.mjs +17 -0
- package/dist/stage-CzaiwFsI.mjs +143 -0
- package/dist/start-CX8Ig-U2.mjs +2 -0
- package/dist/{start-s4RXp1wy.mjs → start-ClDfwXa4.mjs} +116 -65
- package/dist/state-3DwSQIBK.mjs +41 -0
- package/dist/state-B4PQFXMW.d.mts +12 -0
- package/dist/{state-Dk9RVXI7.mjs → state-C1jB7Q8q.mjs} +70 -8
- package/dist/{state-DHqvsbqC.mjs → state-DcW6vOd_.mjs} +7 -4
- package/dist/stats-CEZ_i5je.mjs +77 -0
- package/dist/{status-BgAuxESg.mjs → status-BuvBFeII.mjs} +118 -20
- package/dist/{status-BsPAnfOI.mjs → status-Cs7VLg9D.mjs} +542 -283
- package/dist/status-DlKvVJBE.mjs +49 -0
- package/dist/stdout-reader-C8yjre1x.mjs +23 -0
- package/dist/stim-desktop-Cnz8CPnl.mjs +63 -0
- package/dist/stim-footprint.swift +32 -0
- package/dist/{stim-installations-CINXy_su.mjs → stim-installations-QMEI32v1.mjs} +1 -1
- package/dist/stop-B0Yxtmiy.mjs +48 -0
- package/dist/{stop-BzreOWJp.mjs → stop-Bffozsac.mjs} +83 -16
- package/dist/{stop-BWIF_6BK.mjs → stop-Dt_dM16A.mjs} +2 -2
- package/dist/stop-cause-CidxIqup.mjs +97 -0
- package/dist/supervisor-run.d.mts +43 -11
- package/dist/supervisor-run.mjs +363 -24
- package/dist/support-CAP8qDUF.mjs +316 -0
- package/dist/support-D4aYJniO.mjs +201 -0
- package/dist/teardown-CL6vDs2Y.mjs +727 -0
- package/dist/{xcode-Cp5KvK9x.mjs → toolchain-DkUflduf.mjs} +364 -14
- package/dist/trigger-Bemu8ytw.mjs +65 -0
- package/dist/trigger-CXts6qt1.mjs +2 -0
- package/dist/warm-progress-CpGv3Wb6.mjs +732 -0
- package/dist/{web-BsQs1WlO.mjs → web-DWUaMp8P.mjs} +37 -21
- package/dist/web-run.mjs +310 -13
- package/dist/workspace-process-lock-BL7Q0HCO.mjs +57 -0
- package/dist/workspace-state-B8-aJ1_5.mjs +371 -0
- package/dist/workspaces-BV4pdHFz.mjs +306 -0
- package/dist/{worktree-UrQWXSeb.mjs → worktree-K-xj9Db0.mjs} +625 -256
- package/dist/worktree-jnG8Iph5.mjs +2 -0
- package/package.json +10 -5
- package/shim/bundle-response.cjs +28 -12
- package/dist/activity-CYVDcrt3.mjs +0 -356
- package/dist/budget-CGDkhvv_.mjs +0 -1745
- package/dist/build-progress-DxKpwnaS.mjs +0 -247
- package/dist/idle-DXtx3RbX.mjs +0 -191
- package/dist/in-use-DlqBDKqY.mjs +0 -249
- package/dist/logs-Civ4gbBH.mjs +0 -486
- package/dist/merge-state-ytFQCeh4.mjs +0 -262
- package/dist/server-expo-DIHDhvGg.mjs +0 -2
- package/dist/settings-D61iNOsB.mjs +0 -629
- package/dist/start-Cetfvy8l.mjs +0 -2
- package/dist/stats-CFpFGlJV.mjs +0 -62
- package/dist/stats-CX1Z8Tca.mjs +0 -368
- package/dist/stim-desktop-CXt8-Z3J.mjs +0 -40
- package/dist/stop-cause-hjGBOZTG.mjs +0 -1231
- package/dist/worktree-BVrHsYZG.mjs +0 -752
- package/dist/worktree-CHWWvm5v.mjs +0 -2
- package/dist/{metro-store-DzeWkfqW.mjs → metro-store-CDDZHtPl.mjs} +1 -1
|
@@ -1,31 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { t as getExecutor } from "./exec-CaErVv7t.mjs";
|
|
2
|
+
import { C as saveConfig, D as withConfigLock$1, H as projectDeviceSlots, I as assignSlotDevice, U as removeSlotDevice, _ as loadConfig$1, c as ensureConfig, d as getConfigDir, f as getConfigPath$1, z as deviceSlotPlatforms } from "./config-D0DbpZtM.mjs";
|
|
3
|
+
import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-BmRm1qV0.mjs";
|
|
4
|
+
import { c as androidDataPartitionSizeBytes } from "./settings-oTSkkNrM.mjs";
|
|
5
|
+
import { o as pidExists, u as signalProcessTree } from "./metro-BeK1ZPz1.mjs";
|
|
6
|
+
import { n as readCreatedDevices$1, r as recordCreatedDevice, t as forgetCreatedDevice } from "./created-devices-D5owjN4C.mjs";
|
|
7
|
+
import { n as settingDefault, r as stimDesktopInstalled, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-Cnz8CPnl.mjs";
|
|
8
|
+
import { join } from "node:path";
|
|
7
9
|
import { existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
|
|
8
|
-
import { dirname, isAbsolute, join, resolve } from "path";
|
|
9
|
-
import { ANDROID_EMULATOR_APPS, loadConfig, settingDefinition } from "@stim-cli/core/state";
|
|
10
|
-
import { join as join$1 } from "node:path";
|
|
11
10
|
import { homedir, tmpdir } from "os";
|
|
11
|
+
import { dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, resolve as resolve$1 } from "path";
|
|
12
|
+
import { ANDROID_EMULATOR_APPS, loadConfig, settingDefinition } from "@stim-cli/core/state";
|
|
12
13
|
import { isDeepStrictEqual } from "node:util";
|
|
13
|
-
//#region src/devices/android-emulator-viewer.ts
|
|
14
|
-
function configuredAndroidEmulatorApp(platform = process.platform) {
|
|
15
|
-
const value = loadConfig$1()?.androidEmulatorApp ?? settingDefault(settingDefinition("androidEmulatorApp"), () => stimDesktopInstalled(platform)).value;
|
|
16
|
-
if (ANDROID_EMULATOR_APPS.includes(value)) return value;
|
|
17
|
-
const error = /* @__PURE__ */ new Error("Invalid androidEmulatorApp in machine config. Use \"emulator\" or \"stim-desktop\".");
|
|
18
|
-
Object.assign(error, { code: "STIM_BAD_ARG" });
|
|
19
|
-
throw error;
|
|
20
|
-
}
|
|
21
|
-
function openEmulatorInStimDesktop(serial) {
|
|
22
|
-
getExecutor().runFileQuiet("open", [
|
|
23
|
-
"-g",
|
|
24
|
-
"-a",
|
|
25
|
-
"Stim",
|
|
26
|
-
`stim-desktop://open?serial=${serial}`
|
|
27
|
-
], STIM_DESKTOP_OPEN_OPTIONS);
|
|
28
|
-
}
|
|
29
14
|
const POOL_SETTING_REMEDY = "Run `stim guide settings` for the device pool bounds and where it can be set.";
|
|
30
15
|
const MAX_SETTING = {
|
|
31
16
|
ios: {
|
|
@@ -70,7 +55,7 @@ function parkedMaxSetting(platform, { config, env = process.env } = {}) {
|
|
|
70
55
|
function isParkedRecord(value, platform) {
|
|
71
56
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
72
57
|
const record = value;
|
|
73
|
-
return typeof record.udid === "string" && typeof record.name === "string" && record.name.startsWith("stim-") && typeof record.parkedAt === "string" && (platform === "android" ? record.udid === record.name && /^stim-[A-Za-z0-9._-]+$/.test(record.name) && typeof record.systemImage === "string" && typeof record.configuration === "string" : typeof record.deviceTypeIdentifier === "string" && typeof record.runtimeIdentifier === "string" && typeof record.simslimManaged === "boolean" && (record.bundleId === void 0 || typeof record.bundleId === "string") && (record.cacheKey === void 0 || typeof record.cacheKey === "string"));
|
|
58
|
+
return typeof record.udid === "string" && typeof record.name === "string" && record.name.startsWith("stim-") && typeof record.parkedAt === "string" && (platform === "android" ? record.udid === record.name && /^stim-[A-Za-z0-9._-]+$/.test(record.name) && typeof record.systemImage === "string" && typeof record.configuration === "string" && (record.packageName === void 0 || typeof record.packageName === "string") && (record.cacheKey === void 0 || typeof record.cacheKey === "string") : typeof record.deviceTypeIdentifier === "string" && typeof record.runtimeIdentifier === "string" && typeof record.simslimManaged === "boolean" && (record.bundleId === void 0 || typeof record.bundleId === "string") && (record.cacheKey === void 0 || typeof record.cacheKey === "string") && (record.schemeApprovals === void 0 || Array.isArray(record.schemeApprovals) && record.schemeApprovals.every((v) => typeof v === "string")));
|
|
74
59
|
}
|
|
75
60
|
function poolBlock(config) {
|
|
76
61
|
const raw = config?.parked;
|
|
@@ -124,7 +109,13 @@ function parkSim({ platform, projectPath, slot = "default", record, max }) {
|
|
|
124
109
|
const current = deviceSlotPlatforms(cfg.projects[projectPath], slot)?.[platform];
|
|
125
110
|
const currentId = platform === "ios" ? current?.deviceUdid : current?.avdName;
|
|
126
111
|
if (!current?.owned || currentId !== record.udid) throw new Error(`The ${platform === "ios" ? "simulator" : "emulator"} assignment changed before parking.`);
|
|
127
|
-
const
|
|
112
|
+
const currentApprovals = platform === "ios" ? current.schemeApprovals : void 0;
|
|
113
|
+
const schemeApprovals = Array.isArray(currentApprovals) && currentApprovals.every((v) => typeof v === "string") ? currentApprovals : void 0;
|
|
114
|
+
const carried = schemeApprovals && schemeApprovals.length > 0 ? {
|
|
115
|
+
...record,
|
|
116
|
+
schemeApprovals
|
|
117
|
+
} : record;
|
|
118
|
+
const { keep, evicted } = evictOverflow([...readParked(platform, { config: cfg }).filter((r) => r.udid !== record.udid), carried], max);
|
|
128
119
|
writeParked(cfg, platform, [...keep, ...evicted]);
|
|
129
120
|
const project = cfg.projects[projectPath];
|
|
130
121
|
if (project) removeSlotDevice(project, platform, slot);
|
|
@@ -145,10 +136,15 @@ function adoptParked({ platform, projectPath, slot = "default", udid, device })
|
|
|
145
136
|
writeParked(cfg, platform, records.filter((r) => r.udid !== udid));
|
|
146
137
|
const project = cfg.projects[projectPath];
|
|
147
138
|
if (!project) throw new Error(`Project not registered: ${projectPath}`);
|
|
148
|
-
|
|
149
|
-
saveConfig(cfg);
|
|
150
|
-
const adopted = { ...taken };
|
|
139
|
+
const adopted = taken.deletionClaim === void 0 ? { ...taken } : erasedRecord(taken);
|
|
151
140
|
delete adopted.deletionClaim;
|
|
141
|
+
const takenApprovals = platform === "ios" ? adopted.schemeApprovals : void 0;
|
|
142
|
+
const assigned = takenApprovals && takenApprovals.length > 0 ? {
|
|
143
|
+
...device,
|
|
144
|
+
schemeApprovals: takenApprovals
|
|
145
|
+
} : device;
|
|
146
|
+
assignSlotDevice(project, platform, assigned, slot);
|
|
147
|
+
saveConfig(cfg);
|
|
152
148
|
return adopted;
|
|
153
149
|
});
|
|
154
150
|
} finally {
|
|
@@ -157,7 +153,7 @@ function adoptParked({ platform, projectPath, slot = "default", udid, device })
|
|
|
157
153
|
}
|
|
158
154
|
function claimParkedOperation(platform, udid) {
|
|
159
155
|
const attempt = (0, ownership_claim_exports.tryAcquireClaim)({
|
|
160
|
-
root: join
|
|
156
|
+
root: join(getConfigDir(), "pool-locks", platform, `${encodeURIComponent(udid.toLowerCase())}.lock`),
|
|
161
157
|
mode: "exclusive",
|
|
162
158
|
label: `parked ${platform} device ${udid}`
|
|
163
159
|
});
|
|
@@ -165,6 +161,20 @@ function claimParkedOperation(platform, udid) {
|
|
|
165
161
|
return attempt.acquired ?? null;
|
|
166
162
|
}
|
|
167
163
|
function removeParkedAfter(platform, udid, beforeRemove) {
|
|
164
|
+
return settleParkedAfter(platform, udid, beforeRemove, null);
|
|
165
|
+
}
|
|
166
|
+
function eraseParkedAfter(platform, udid, erase) {
|
|
167
|
+
return settleParkedAfter(platform, udid, erase, erasedRecord);
|
|
168
|
+
}
|
|
169
|
+
function erasedRecord(record) {
|
|
170
|
+
const erased = { ...record };
|
|
171
|
+
delete erased.bundleId;
|
|
172
|
+
delete erased.packageName;
|
|
173
|
+
delete erased.cacheKey;
|
|
174
|
+
delete erased.schemeApprovals;
|
|
175
|
+
return erased;
|
|
176
|
+
}
|
|
177
|
+
function settleParkedAfter(platform, udid, action, keep) {
|
|
168
178
|
const claim = claimParkedOperation(platform, udid);
|
|
169
179
|
if (!claim) return null;
|
|
170
180
|
try {
|
|
@@ -193,11 +203,14 @@ function removeParkedAfter(platform, udid, beforeRemove) {
|
|
|
193
203
|
});
|
|
194
204
|
if (!claimed) return null;
|
|
195
205
|
let completed = false;
|
|
196
|
-
let
|
|
206
|
+
let started = false;
|
|
207
|
+
let settled = null;
|
|
197
208
|
try {
|
|
198
209
|
(0, ownership_claim_exports.markClaimChildPending)(claim);
|
|
199
210
|
try {
|
|
200
|
-
|
|
211
|
+
action(claimed.record, () => {
|
|
212
|
+
started = true;
|
|
213
|
+
});
|
|
201
214
|
} finally {
|
|
202
215
|
(0, ownership_claim_exports.clearClaimChild)(claim);
|
|
203
216
|
}
|
|
@@ -209,12 +222,13 @@ function removeParkedAfter(platform, udid, beforeRemove) {
|
|
|
209
222
|
const records = readParked(platform, { config: cfg });
|
|
210
223
|
const current = records.find((candidate) => candidate.udid === udid);
|
|
211
224
|
if (!isDeepStrictEqual(current, claimed.marked)) return;
|
|
212
|
-
|
|
225
|
+
const after = (completed || started) && keep ? keep(claimed.record) : claimed.record;
|
|
226
|
+
writeParked(cfg, platform, completed && !keep ? records.filter((candidate) => candidate.udid !== udid) : records.map((candidate) => candidate.udid === udid ? after : candidate));
|
|
213
227
|
saveConfig(cfg);
|
|
214
|
-
if (completed)
|
|
228
|
+
if (completed) settled = claimed.record;
|
|
215
229
|
});
|
|
216
230
|
}
|
|
217
|
-
return
|
|
231
|
+
return settled;
|
|
218
232
|
} finally {
|
|
219
233
|
(0, ownership_claim_exports.releaseClaim)(claim);
|
|
220
234
|
}
|
|
@@ -252,6 +266,23 @@ function isStimOwnedAvd(name) {
|
|
|
252
266
|
return name.startsWith("stim-") && isStimOwnedDevice("android", name);
|
|
253
267
|
}
|
|
254
268
|
//#endregion
|
|
269
|
+
//#region src/devices/android-emulator-viewer.ts
|
|
270
|
+
function configuredAndroidEmulatorApp(platform = process.platform) {
|
|
271
|
+
const value = loadConfig$1()?.androidEmulatorApp ?? settingDefault(settingDefinition("androidEmulatorApp"), () => stimDesktopInstalled(platform)).value;
|
|
272
|
+
if (ANDROID_EMULATOR_APPS.includes(value)) return value;
|
|
273
|
+
const error = /* @__PURE__ */ new Error("Invalid androidEmulatorApp in machine config. Use \"emulator\" or \"stim-desktop\".");
|
|
274
|
+
Object.assign(error, { code: "STIM_BAD_ARG" });
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
function openEmulatorInStimDesktop(serial) {
|
|
278
|
+
getExecutor().runFileQuiet("open", [
|
|
279
|
+
"-g",
|
|
280
|
+
"-a",
|
|
281
|
+
"Stim",
|
|
282
|
+
`stim-desktop://open?serial=${serial}`
|
|
283
|
+
], STIM_DESKTOP_OPEN_OPTIONS);
|
|
284
|
+
}
|
|
285
|
+
//#endregion
|
|
255
286
|
//#region src/devices/android.ts
|
|
256
287
|
const ANDROID_ABIS = /* @__PURE__ */ new Set([
|
|
257
288
|
"armeabi-v7a",
|
|
@@ -263,8 +294,8 @@ const DEFAULT_AVD_DEVICE_PROFILE = String(settingDefinition("android.deviceProfi
|
|
|
263
294
|
function androidHome(env = process.env) {
|
|
264
295
|
const configured = env.ANDROID_HOME || env.ANDROID_SDK_ROOT;
|
|
265
296
|
if (configured) return configured;
|
|
266
|
-
if (process.platform === "win32") return join(env.LOCALAPPDATA || join(homedir(), "AppData", "Local"), "Android", "Sdk");
|
|
267
|
-
return join(homedir(), "Library", "Android", "sdk");
|
|
297
|
+
if (process.platform === "win32") return join$1(env.LOCALAPPDATA || join$1(homedir(), "AppData", "Local"), "Android", "Sdk");
|
|
298
|
+
return join$1(homedir(), "Library", "Android", "sdk");
|
|
268
299
|
}
|
|
269
300
|
const SDK_TOOL_LOCATIONS = {
|
|
270
301
|
emulator: ["emulator", "emulator"],
|
|
@@ -292,7 +323,7 @@ function androidToolPath(tool, platform = process.platform) {
|
|
|
292
323
|
const location = SDK_TOOL_LOCATIONS[tool];
|
|
293
324
|
const bare = location.at(-1);
|
|
294
325
|
const name = platform === "win32" ? `${bare}${WINDOWS_SDK_TOOL_EXTENSIONS[tool]}` : bare;
|
|
295
|
-
const abs = join(androidHome(), ...location.slice(0, -1), name);
|
|
326
|
+
const abs = join$1(androidHome(), ...location.slice(0, -1), name);
|
|
296
327
|
return existsSync(abs) ? abs : bare;
|
|
297
328
|
}
|
|
298
329
|
const WINDOWS_BUILD_TOOL_EXTENSIONS = { apksigner: ".bat" };
|
|
@@ -316,7 +347,7 @@ function buildToolsMajor(version) {
|
|
|
316
347
|
return Number.isFinite(major) ? major : 0;
|
|
317
348
|
}
|
|
318
349
|
function findBuildTool(tools, { home = androidHome(), readDir = readdirSync, exists = existsSync, platform = process.platform } = {}) {
|
|
319
|
-
const root = join(home, "build-tools");
|
|
350
|
+
const root = join$1(home, "build-tools");
|
|
320
351
|
let versions = [];
|
|
321
352
|
try {
|
|
322
353
|
versions = readDir(root);
|
|
@@ -327,7 +358,7 @@ function findBuildTool(tools, { home = androidHome(), readDir = readdirSync, exi
|
|
|
327
358
|
const version = newestBuildTools(versions);
|
|
328
359
|
if (!version) return null;
|
|
329
360
|
for (const tool of tools) {
|
|
330
|
-
const path = join(root, version, androidBuildToolName(tool, platform));
|
|
361
|
+
const path = join$1(root, version, androidBuildToolName(tool, platform));
|
|
331
362
|
if (exists(path)) return {
|
|
332
363
|
path,
|
|
333
364
|
tool,
|
|
@@ -344,7 +375,7 @@ function androidTool(tool) {
|
|
|
344
375
|
return resolved === tool ? tool : `"${resolved}"`;
|
|
345
376
|
}
|
|
346
377
|
function listInstalledSystemImages(onUnreadable) {
|
|
347
|
-
const root = join(androidHome(), "system-images");
|
|
378
|
+
const root = join$1(androidHome(), "system-images");
|
|
348
379
|
const images = [];
|
|
349
380
|
const list = (dir) => {
|
|
350
381
|
try {
|
|
@@ -358,8 +389,8 @@ function listInstalledSystemImages(onUnreadable) {
|
|
|
358
389
|
for (const apiDir of list(root)) {
|
|
359
390
|
const m = apiDir.match(/^android-(\d+)$/);
|
|
360
391
|
if (!m) continue;
|
|
361
|
-
const apiPath = join(root, apiDir);
|
|
362
|
-
for (const tag of list(apiPath)) for (const arch of list(join(apiPath, tag))) images.push({
|
|
392
|
+
const apiPath = join$1(root, apiDir);
|
|
393
|
+
for (const tag of list(apiPath)) for (const arch of list(join$1(apiPath, tag))) images.push({
|
|
363
394
|
api: Number(m[1]),
|
|
364
395
|
tag,
|
|
365
396
|
arch,
|
|
@@ -387,7 +418,7 @@ function profileNeedsFoldFeature(profile) {
|
|
|
387
418
|
}
|
|
388
419
|
function systemImageSupportsFold(pkg, home = androidHome()) {
|
|
389
420
|
try {
|
|
390
|
-
const ini = readFileSync(join(home, ...pkg.split(";"), "advancedFeatures.ini"), "utf8");
|
|
421
|
+
const ini = readFileSync(join$1(home, ...pkg.split(";"), "advancedFeatures.ini"), "utf8");
|
|
391
422
|
return /^\s*SupportPixelFold\s*=\s*on\s*$/im.test(ini);
|
|
392
423
|
} catch {
|
|
393
424
|
return false;
|
|
@@ -412,13 +443,23 @@ async function createOwnedAvd(label, { systemImage, deviceProfile = DEFAULT_AVD_
|
|
|
412
443
|
"--device",
|
|
413
444
|
deviceProfile
|
|
414
445
|
];
|
|
446
|
+
let env = process.env;
|
|
447
|
+
if (!env.ANDROID_AVD_HOME) {
|
|
448
|
+
const root = avdLookupRoots(env, homedir())[0];
|
|
449
|
+
mkdirSync(root, { recursive: true });
|
|
450
|
+
env = {
|
|
451
|
+
...env,
|
|
452
|
+
ANDROID_AVD_HOME: root
|
|
453
|
+
};
|
|
454
|
+
}
|
|
415
455
|
const child = spawn(tool, args, {
|
|
416
456
|
detached: true,
|
|
417
457
|
stdio: [
|
|
418
458
|
"pipe",
|
|
419
459
|
"pipe",
|
|
420
460
|
"pipe"
|
|
421
|
-
]
|
|
461
|
+
],
|
|
462
|
+
env
|
|
422
463
|
});
|
|
423
464
|
let stderr = "";
|
|
424
465
|
child.stdout?.on("data", () => {});
|
|
@@ -463,7 +504,7 @@ function ownedAvdSystemImage(avdName, { avdDirectory = ownedAvdDirectory, readFi
|
|
|
463
504
|
const directory = avdDirectory(avdName);
|
|
464
505
|
if (!directory) return null;
|
|
465
506
|
try {
|
|
466
|
-
return parseAvdSystemImage(readFile(join(directory, "config.ini")));
|
|
507
|
+
return parseAvdSystemImage(readFile(join$1(directory, "config.ini")));
|
|
467
508
|
} catch {
|
|
468
509
|
return null;
|
|
469
510
|
}
|
|
@@ -486,7 +527,7 @@ function sanitizeAvdLabel(label) {
|
|
|
486
527
|
function avdConfigIni(avdName, directory = ownedAvdDirectory(avdName)) {
|
|
487
528
|
if (!directory) return null;
|
|
488
529
|
try {
|
|
489
|
-
return readFileSync(join(directory, "config.ini"), "utf8");
|
|
530
|
+
return readFileSync(join$1(directory, "config.ini"), "utf8");
|
|
490
531
|
} catch {
|
|
491
532
|
return null;
|
|
492
533
|
}
|
|
@@ -498,9 +539,11 @@ function ownedAvdName(label) {
|
|
|
498
539
|
const AVDMANAGER_DELETE_TIMEOUT_MS = 12e4;
|
|
499
540
|
function deleteAvd(avdName) {
|
|
500
541
|
if (!isStimOwnedAvd(avdName)) throw new Error(`Refusing to delete AVD "${avdName}": not a Stim-owned AVD; Stim has no record of creating it.`);
|
|
542
|
+
const root = process.env.ANDROID_AVD_HOME ? void 0 : avdStorageRoots().find((candidate) => avdPathExists(join$1(candidate, `${avdName}.ini`)));
|
|
501
543
|
getExecutor().run(`${androidTool("avdmanager")} delete avd -n "${avdName}"`, {
|
|
502
544
|
timeoutMs: AVDMANAGER_DELETE_TIMEOUT_MS,
|
|
503
|
-
killSignal: "SIGKILL"
|
|
545
|
+
killSignal: "SIGKILL",
|
|
546
|
+
...root ? { env: { ANDROID_AVD_HOME: root } } : {}
|
|
504
547
|
});
|
|
505
548
|
forgetCreatedDevice("android", avdName);
|
|
506
549
|
}
|
|
@@ -703,17 +746,17 @@ function parseAvdRootIni(contents) {
|
|
|
703
746
|
}
|
|
704
747
|
function avdIniPaths(root, ini) {
|
|
705
748
|
const parsed = parseAvdRootIni(ini);
|
|
706
|
-
return [parsed.relativePath && !isAbsolute(parsed.relativePath) ? resolve(dirname(root), parsed.relativePath) : null, parsed.path && isAbsolute(parsed.path) ? parsed.path : null].filter((candidate) => candidate !== null);
|
|
749
|
+
return [parsed.relativePath && !isAbsolute$1(parsed.relativePath) ? resolve$1(dirname$1(root), parsed.relativePath) : null, parsed.path && isAbsolute$1(parsed.path) ? parsed.path : null].filter((candidate) => candidate !== null);
|
|
707
750
|
}
|
|
708
751
|
function avdStorageRoots() {
|
|
709
752
|
const env = process.env;
|
|
710
753
|
return [...new Set([
|
|
711
754
|
env.ANDROID_AVD_HOME,
|
|
712
|
-
env.ANDROID_EMULATOR_HOME ? join(env.ANDROID_EMULATOR_HOME, "avd") : null,
|
|
713
|
-
env.ANDROID_USER_HOME ? join(env.ANDROID_USER_HOME, "avd") : null,
|
|
714
|
-
env.ANDROID_SDK_HOME ? join(env.ANDROID_SDK_HOME, ".android", "avd") : null,
|
|
715
|
-
env.ANDROID_SDK_HOME ? join(env.ANDROID_SDK_HOME, "avd") : null,
|
|
716
|
-
join(homedir(), ".android", "avd")
|
|
755
|
+
env.ANDROID_EMULATOR_HOME ? join$1(env.ANDROID_EMULATOR_HOME, "avd") : null,
|
|
756
|
+
env.ANDROID_USER_HOME ? join$1(env.ANDROID_USER_HOME, "avd") : null,
|
|
757
|
+
env.ANDROID_SDK_HOME ? join$1(env.ANDROID_SDK_HOME, ".android", "avd") : null,
|
|
758
|
+
env.ANDROID_SDK_HOME ? join$1(env.ANDROID_SDK_HOME, "avd") : null,
|
|
759
|
+
join$1(homedir(), ".android", "avd")
|
|
717
760
|
].filter((value) => Boolean(value)))];
|
|
718
761
|
}
|
|
719
762
|
function avdPathExists(path) {
|
|
@@ -732,7 +775,7 @@ function avdPathExists(path) {
|
|
|
732
775
|
*/
|
|
733
776
|
function avdNameAbsent(avdName, roots = avdStorageRoots()) {
|
|
734
777
|
if (!roots[0] || !isDirectoryPath(roots[0])) return false;
|
|
735
|
-
return roots.every((root) => !avdPathExists(join(root, `${avdName}.ini`)) && !avdPathExists(join(root, `${avdName}.avd`)));
|
|
778
|
+
return roots.every((root) => !avdPathExists(join$1(root, `${avdName}.ini`)) && !avdPathExists(join$1(root, `${avdName}.avd`)));
|
|
736
779
|
}
|
|
737
780
|
function isDirectoryPath(path) {
|
|
738
781
|
try {
|
|
@@ -751,7 +794,7 @@ function listOrphanedAvdDirectories(avdName) {
|
|
|
751
794
|
}));
|
|
752
795
|
const registered = /* @__PURE__ */ new Set();
|
|
753
796
|
for (const { root, canonicalRoot, names } of stores) for (const name of names.filter((entry) => entry.endsWith(".ini"))) {
|
|
754
|
-
const path = join(root, name);
|
|
797
|
+
const path = join$1(root, name);
|
|
755
798
|
const ini = readFileSync(path, "utf8");
|
|
756
799
|
const targets = /* @__PURE__ */ new Set([...avdIniPaths(root, ini), ...avdIniPaths(canonicalRoot, ini)]);
|
|
757
800
|
if (!targets.size) throw new Error(`Cannot verify AVD registration at ${path}; its data was kept.`);
|
|
@@ -768,8 +811,8 @@ function listOrphanedAvdDirectories(avdName) {
|
|
|
768
811
|
for (const entry of names) {
|
|
769
812
|
if (!/^stim-[A-Za-z0-9._-]+\.avd$/.test(entry)) continue;
|
|
770
813
|
const name = entry.slice(0, -4);
|
|
771
|
-
if (roots.some((candidate) => avdPathExists(join(candidate, `${name}.ini`)))) continue;
|
|
772
|
-
const directory = join(canonicalRoot, entry);
|
|
814
|
+
if (roots.some((candidate) => avdPathExists(join$1(candidate, `${name}.ini`)))) continue;
|
|
815
|
+
const directory = join$1(canonicalRoot, entry);
|
|
773
816
|
if (registered.has(directory) || !avdPathExists(directory)) continue;
|
|
774
817
|
const stat = lstatSync(directory);
|
|
775
818
|
if (!stat.isDirectory() || stat.isSymbolicLink() || realpathSync(directory) !== directory) throw new Error(`Cannot verify AVD data at ${directory}; it was kept.`);
|
|
@@ -783,17 +826,20 @@ function listOrphanedAvdDirectories(avdName) {
|
|
|
783
826
|
}
|
|
784
827
|
return orphaned;
|
|
785
828
|
}
|
|
786
|
-
function
|
|
787
|
-
if (!/^stim-[A-Za-z0-9._-]+$/.test(avdName)) return null;
|
|
829
|
+
function avdLookupRoots(env, home) {
|
|
788
830
|
const roots = [
|
|
789
831
|
env.ANDROID_AVD_HOME,
|
|
790
|
-
env.ANDROID_SDK_HOME ? join(env.ANDROID_SDK_HOME, "avd") : null,
|
|
791
|
-
join(home, ".android", "avd")
|
|
832
|
+
env.ANDROID_SDK_HOME ? join$1(env.ANDROID_SDK_HOME, "avd") : null,
|
|
833
|
+
join$1(home, ".android", "avd")
|
|
792
834
|
];
|
|
793
|
-
|
|
835
|
+
return [...new Set(roots.filter((value) => Boolean(value)))];
|
|
836
|
+
}
|
|
837
|
+
function ownedAvdDirectory(avdName, { env = process.env, home = homedir(), readFile = (path) => readFileSync(path, "utf8"), realpath = realpathSync, isDirectory = (path) => statSync(path).isDirectory() } = {}) {
|
|
838
|
+
if (!/^stim-[A-Za-z0-9._-]+$/.test(avdName)) return null;
|
|
839
|
+
for (const root of avdLookupRoots(env, home)) {
|
|
794
840
|
let ini;
|
|
795
841
|
try {
|
|
796
|
-
ini = readFile(join(root, `${avdName}.ini`));
|
|
842
|
+
ini = readFile(join$1(root, `${avdName}.ini`));
|
|
797
843
|
} catch (error) {
|
|
798
844
|
const code = error.code;
|
|
799
845
|
if (code === "ENOENT" || code === "ENOTDIR") continue;
|
|
@@ -817,7 +863,7 @@ const AVD_USER_DATA = [
|
|
|
817
863
|
"snapshots"
|
|
818
864
|
];
|
|
819
865
|
function wipeAvdUserData(directory) {
|
|
820
|
-
for (const name of AVD_USER_DATA) rmSync(join(directory, name), {
|
|
866
|
+
for (const name of AVD_USER_DATA) rmSync(join$1(directory, name), {
|
|
821
867
|
recursive: true,
|
|
822
868
|
force: true
|
|
823
869
|
});
|
|
@@ -850,14 +896,14 @@ function configureNewOwnedAvd(avdName, { dataPartitionSizeGb, avdConfig = {} },
|
|
|
850
896
|
const sizeBytes = androidDataPartitionSizeBytes(dataPartitionSizeGb);
|
|
851
897
|
const directory = avdDirectory(avdName);
|
|
852
898
|
if (!directory) throw new Error(`Could not resolve the content directory for newly created AVD ${avdName}.`);
|
|
853
|
-
const configPath = join(directory, "config.ini");
|
|
899
|
+
const configPath = join$1(directory, "config.ini");
|
|
854
900
|
const original = readFile(configPath);
|
|
855
901
|
const expected = {
|
|
856
902
|
...avdConfig,
|
|
857
903
|
"disk.dataPartition.size": String(sizeBytes)
|
|
858
904
|
};
|
|
859
905
|
const updated = withAvdConfigOverrides(original, expected);
|
|
860
|
-
const tempPath = join(directory, `.config.ini.stim-${process.pid}-${++avdConfigWriteSequence}.tmp`);
|
|
906
|
+
const tempPath = join$1(directory, `.config.ini.stim-${process.pid}-${++avdConfigWriteSequence}.tmp`);
|
|
861
907
|
try {
|
|
862
908
|
writeFile(tempPath, updated);
|
|
863
909
|
rename(tempPath, configPath);
|
|
@@ -886,7 +932,7 @@ function avdPoolConfiguration(dataPartitionSizeGb, avdConfig, deviceProfile = DE
|
|
|
886
932
|
function ownedAvdMatchesConfiguration(avdName, configuration) {
|
|
887
933
|
const directory = ownedAvdDirectory(avdName);
|
|
888
934
|
if (!directory) return false;
|
|
889
|
-
const contents = readFileSync(join(directory, "config.ini"), "utf8");
|
|
935
|
+
const contents = readFileSync(join$1(directory, "config.ini"), "utf8");
|
|
890
936
|
const expected = JSON.parse(configuration);
|
|
891
937
|
return Array.isArray(expected) && expected.length > 0 && expected.every((entry) => Array.isArray(entry) && entry.length === 2 && entry.every((value) => typeof value === "string") && contents.split(/\r?\n/).some((line) => line.trim() === `${entry[0]}=${entry[1]}`));
|
|
892
938
|
}
|
|
@@ -953,6 +999,35 @@ async function resetAdoptedAvd(avdName, serial, keepPackage) {
|
|
|
953
999
|
}
|
|
954
1000
|
}
|
|
955
1001
|
}
|
|
1002
|
+
function parseDfAvailableBytes(text) {
|
|
1003
|
+
const lines = String(text ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
1004
|
+
if (lines.length !== 2 || !/^Filesystem\s/.test(lines[0])) return null;
|
|
1005
|
+
const available = lines[1].split(/\s+/)[3];
|
|
1006
|
+
return available && /^\d+$/.test(available) ? Number(available) * 1024 : null;
|
|
1007
|
+
}
|
|
1008
|
+
function androidDataFreeBytes(serial) {
|
|
1009
|
+
return parseDfAvailableBytes(getExecutor().runFileQuiet("adb", [
|
|
1010
|
+
"-s",
|
|
1011
|
+
serial,
|
|
1012
|
+
"shell",
|
|
1013
|
+
"df",
|
|
1014
|
+
"-k",
|
|
1015
|
+
"/data"
|
|
1016
|
+
], { timeoutMs: 3e4 }));
|
|
1017
|
+
}
|
|
1018
|
+
function trimAndroidCaches(serial, desiredFreeBytes) {
|
|
1019
|
+
getExecutor().runFile("adb", [
|
|
1020
|
+
"-s",
|
|
1021
|
+
serial,
|
|
1022
|
+
"shell",
|
|
1023
|
+
"pm",
|
|
1024
|
+
"trim-caches",
|
|
1025
|
+
String(desiredFreeBytes)
|
|
1026
|
+
], {
|
|
1027
|
+
timeoutMs: 12e4,
|
|
1028
|
+
killSignal: "SIGKILL"
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
956
1031
|
function parseEmulatorVersion(text) {
|
|
957
1032
|
const match = /Android emulator version (\d+)\./.exec(String(text ?? ""));
|
|
958
1033
|
return match ? Number(match[1]) : null;
|
|
@@ -967,9 +1042,9 @@ const CRASH_REPORT_MODE_EMULATOR_VERSION = 37;
|
|
|
967
1042
|
* under GetTempPath, which reads TMP before TEMP.
|
|
968
1043
|
*/
|
|
969
1044
|
function emulatorCrashDatabases(env = process.env) {
|
|
970
|
-
const root = join(env.TMP || env.TEMP || tmpdir(), "AndroidEmulator");
|
|
1045
|
+
const root = join$1(env.TMP || env.TEMP || tmpdir(), "AndroidEmulator");
|
|
971
1046
|
try {
|
|
972
|
-
return readdirSync(root).filter((name) => /^emu-crash-.*\.db$/.test(name)).map((name) => join(root, name));
|
|
1047
|
+
return readdirSync(root).filter((name) => /^emu-crash-.*\.db$/.test(name)).map((name) => join$1(root, name));
|
|
973
1048
|
} catch {
|
|
974
1049
|
return [];
|
|
975
1050
|
}
|
|
@@ -995,7 +1070,7 @@ function suppressEmulatorCrashConsent({ platform = process.platform, version = e
|
|
|
995
1070
|
} catch {}
|
|
996
1071
|
return [];
|
|
997
1072
|
}
|
|
998
|
-
function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process.platform } = {}) {
|
|
1073
|
+
function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process.platform, openViewer = true } = {}) {
|
|
999
1074
|
const exec = getExecutor();
|
|
1000
1075
|
const app = configuredAndroidEmulatorApp(platform);
|
|
1001
1076
|
const child = exec.spawn(androidToolPath("emulator"), [
|
|
@@ -1006,7 +1081,7 @@ function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process
|
|
|
1006
1081
|
"-grpc",
|
|
1007
1082
|
String(consolePort + 3e3),
|
|
1008
1083
|
"-grpc-use-token",
|
|
1009
|
-
...headlessEmulatorArgs(process.env, platform, app),
|
|
1084
|
+
...headlessEmulatorArgs(process.env, platform, openViewer ? app : "stim-desktop"),
|
|
1010
1085
|
...suppressEmulatorCrashConsent({ platform })
|
|
1011
1086
|
], {
|
|
1012
1087
|
cwd: androidToolCwd(platform),
|
|
@@ -1015,13 +1090,13 @@ function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process
|
|
|
1015
1090
|
});
|
|
1016
1091
|
child?.unref?.();
|
|
1017
1092
|
const pid = child?.pid ?? null;
|
|
1018
|
-
if (pid !== null && platform === "darwin" && app === "stim-desktop") openEmulatorInStimDesktop(`emulator-${consolePort}`);
|
|
1093
|
+
if (openViewer && pid !== null && platform === "darwin" && app === "stim-desktop") openEmulatorInStimDesktop(`emulator-${consolePort}`);
|
|
1019
1094
|
return pid;
|
|
1020
1095
|
}
|
|
1021
1096
|
function emulatorStdio(logFile) {
|
|
1022
1097
|
if (!logFile) return "ignore";
|
|
1023
1098
|
try {
|
|
1024
|
-
mkdirSync(dirname(logFile), { recursive: true });
|
|
1099
|
+
mkdirSync(dirname$1(logFile), { recursive: true });
|
|
1025
1100
|
const fd = openSync(logFile, "w");
|
|
1026
1101
|
return [
|
|
1027
1102
|
"ignore",
|
|
@@ -1123,7 +1198,7 @@ function sleepSync(ms) {
|
|
|
1123
1198
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
1124
1199
|
}
|
|
1125
1200
|
function avdProcessLockPaths(avdDirectory, platform) {
|
|
1126
|
-
return ["hardware-qemu.ini.lock", "userdata-qemu.img.lock"].map((name) => join(avdDirectory, name, ...platform === "win32" ? ["pid"] : []));
|
|
1201
|
+
return ["hardware-qemu.ini.lock", "userdata-qemu.img.lock"].map((name) => join$1(avdDirectory, name, ...platform === "win32" ? ["pid"] : []));
|
|
1127
1202
|
}
|
|
1128
1203
|
function readAvdProcessId(path) {
|
|
1129
1204
|
try {
|
|
@@ -1177,7 +1252,18 @@ function scanAvdEmulatorProcesses(avdName, platform, listProcesses) {
|
|
|
1177
1252
|
if (pids === null) throw new Error(`Could not read the process table to verify that owned AVD ${avdName} stopped.`);
|
|
1178
1253
|
return pids;
|
|
1179
1254
|
}
|
|
1180
|
-
function
|
|
1255
|
+
function emulatorProcessRunning(pid) {
|
|
1256
|
+
if (!pidExists(pid)) return false;
|
|
1257
|
+
if (process.platform === "win32") return true;
|
|
1258
|
+
const stat = getExecutor().runFileQuiet("ps", [
|
|
1259
|
+
"-o",
|
|
1260
|
+
"stat=",
|
|
1261
|
+
"-p",
|
|
1262
|
+
String(pid)
|
|
1263
|
+
], { timeoutMs: 5e3 });
|
|
1264
|
+
return stat === null || !stat.trim().startsWith("Z");
|
|
1265
|
+
}
|
|
1266
|
+
function assertOwnedAvdStopped(avdName, { processAlive = emulatorProcessRunning, listProcesses = listAvdEmulatorProcesses, ...resolveOptions } = {}) {
|
|
1181
1267
|
const { processId } = resolveAvdProcess(avdName, resolveOptions);
|
|
1182
1268
|
const live = new Set(scanAvdEmulatorProcesses(avdName, resolveOptions.platform ?? process.platform, listProcesses));
|
|
1183
1269
|
if (processId !== null && processAlive(processId)) live.add(processId);
|
|
@@ -1312,20 +1398,22 @@ function once(read) {
|
|
|
1312
1398
|
return result.value;
|
|
1313
1399
|
};
|
|
1314
1400
|
}
|
|
1401
|
+
/** Floor for a single `listAvds`, `adb devices`, or `emu avd name` call in {@link ownedAvdSerialResolver}. */
|
|
1402
|
+
const MIN_LOOKUP_TIMEOUT_MS = 1e3;
|
|
1315
1403
|
/**
|
|
1316
1404
|
* `resolveOwnedAvdSerial` for several AVDs against one reading of the AVD list, `adb devices`, and
|
|
1317
1405
|
* each emulator's AVD name. The timeout budget starts when the resolver is created.
|
|
1318
1406
|
*/
|
|
1319
1407
|
function ownedAvdSerialResolver({ timeoutMs } = {}) {
|
|
1320
1408
|
const started = Date.now();
|
|
1321
|
-
const remaining = () => ({ timeoutMs: timeoutMs === void 0 ? void 0 : Math.max(
|
|
1409
|
+
const remaining = () => ({ timeoutMs: timeoutMs === void 0 ? void 0 : Math.max(MIN_LOOKUP_TIMEOUT_MS, timeoutMs - (Date.now() - started)) });
|
|
1322
1410
|
const avds = once(() => listAvds(remaining()));
|
|
1323
1411
|
const adb = once(() => listAdbDevices(remaining()));
|
|
1324
1412
|
const names = /* @__PURE__ */ new Map();
|
|
1325
1413
|
const avdNameOf = (serial) => {
|
|
1326
|
-
if (names.has(serial)) return names.get(serial);
|
|
1414
|
+
if (names.has(serial)) return names.get(serial) ?? null;
|
|
1327
1415
|
const name = getAvdNameForSerial(serial, remaining());
|
|
1328
|
-
|
|
1416
|
+
names.set(serial, name);
|
|
1329
1417
|
return name;
|
|
1330
1418
|
};
|
|
1331
1419
|
return (avdName) => {
|
|
@@ -1338,4 +1426,4 @@ function ownedAvdSerialResolver({ timeoutMs } = {}) {
|
|
|
1338
1426
|
};
|
|
1339
1427
|
}
|
|
1340
1428
|
//#endregion
|
|
1341
|
-
export {
|
|
1429
|
+
export { trimAndroidCaches as $, listAvds as A, ownedAvdSystemImage as B, emulatorFailureRemedy as C, hostSystemImageArch as D, getAvdNameForSerial as E, ownedAvdDeviceProfile as F, probeEmulatorSerial as G, parseAvdSystemImage as H, ownedAvdDirectory as I, resolveOwnedAvdSerial as J, profileNeedsFoldFeature as K, ownedAvdMatchesConfiguration as L, listOrphanedAvdDirectories as M, memoizeEmulatorProbe as N, listAdbDevices as O, nextConsolePort as P, systemImageSupportsFold as Q, ownedAvdName as R, emulatorDiskSpaceRemedy as S, findBuildTool as T, physicalDeviceModel as U, parseAvdDeviceProfile as V, pickDefaultSystemImage as W, shutdownAndroidEmulator as X, resolvePhysicalDevice as Y, sleepSync as Z, avdStorageRoots as _, androidDeviceAbi as a, isStimOwnedSim as at, createOwnedAvd as b, androidPoolNoCandidatesRefusal as c, dropParked as ct, androidToolPath as d, parkSim as dt, waitForAndroidEmulatorShutdown as et, assertOwnedAvdStopped as f, parkedMaxSetting as ft, avdPoolConfiguration as g, avdPathExists as h, selectParked as ht, androidDataFreeBytes as i, isStimOwnedAvd as it, listInstalledSystemImages as j, listAvdDeviceProfiles as k, androidSystemImageAbi as l, eraseParkedAfter as lt, avdNameAbsent as m, removeParkedAfter as mt, OWNED_AVD_CONFIG_DEFAULTS as n, wipeAvdUserData as nt, androidHome as o, POOL_SETTING_REMEDY as ot, avdIniPaths as p, readParked as pt, resetAdoptedAvd as q, androidBuildToolName as r, configuredAndroidEmulatorApp as rt, androidPoolCandidates as s, adoptParked as st, DEFAULT_AVD_DEVICE_PROFILE as t, waitForBoot as tt, androidToolCwd as u, isLegacyDeletionClaim as ut, bootAndroidEmulator as v, extractEmulatorFailure as w, deleteAvd as x, configureNewOwnedAvd as y, ownedAvdSerialResolver as z };
|