stim 1.20.2 → 1.21.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 +88 -8
- package/dist/acquire-artifact-CD4lbiWE.mjs +153 -0
- package/dist/act-DHAw2A2S.mjs +2667 -0
- package/dist/activity-BzVfHSrY.mjs +1376 -0
- package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-zh1vhbLp.mjs} +21 -65
- package/dist/{android-HqP1_vB_.mjs → android-BEJ8Jpl7.mjs} +2 -2
- package/dist/{android-DCKZrNvV.mjs → android-BLgbNqox.mjs} +128 -78
- package/dist/{android-Dlzxshgp.mjs → android-CV_GCELZ.mjs} +5 -5
- package/dist/{android-Mz_Inn3w.mjs → android-DUYkNF4u.mjs} +184 -102
- package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-Ct5b1xCK.mjs} +7 -6
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/android-project-BCAAmMwz.mjs +12 -0
- package/dist/api.d.mts +740 -8
- package/dist/api.mjs +585 -1
- package/dist/{artifact-HSwkIWEQ.mjs → artifact-B8T3S5gi.mjs} +223 -201
- package/dist/{artifact-D3czlUvT.mjs → artifact-DAuZ-FNU.mjs} +158 -148
- package/dist/{browser-web-CA-F1GQo.mjs → browser-web-QQzVjz3O.mjs} +26 -24
- package/dist/budget-Bs6SxxzO.mjs +9154 -0
- package/dist/{build-DYDbfkk5.mjs → build-CoPzQRNw.mjs} +144 -96
- package/dist/build-cache-DmyR9Zzc.mjs +602 -0
- package/dist/build-plan-CaFskB7_.mjs +188 -0
- package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DkkqguoK.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-zdKiYQ3E.mjs → ccache-BJRZ9pG3.mjs} +10 -9
- package/dist/{cdp-Dq_ypAlJ.mjs → cdp-CWmIUMbw.mjs} +18 -5
- package/dist/{chrome-BnzZMqsR.mjs → chrome-B6tfCta1.mjs} +7 -4
- package/dist/{cli-CLP3diBm.mjs → cli-0DYf8QhQ.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/client-B7QVOlCr.d.mts +253 -0
- package/dist/client-UXD70ZbM.mjs +1406 -0
- package/dist/collector-run.d.mts +4 -40
- package/dist/collector-run.mjs +9 -8
- package/dist/{command-output-BTy8hZ0F.mjs → command-output-B1UrjZHL.mjs} +1 -1
- package/dist/config-CYcBF478.mjs +949 -0
- package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-CqeBlrEn.mjs} +3 -3
- package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-BbKQW83h.mjs} +20 -5
- package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-DFRyG1_o.mjs} +1 -1
- package/dist/{dev-client-DAWVIGBu.mjs → dev-client-UOeESKm6.mjs} +2 -2
- package/dist/device-DCxH7_By.mjs +1068 -0
- package/dist/{device-BECOiufl.mjs → device-ExJq8Ei7.mjs} +35 -35
- package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-CMlqEcvw.mjs} +43 -13
- package/dist/device-host-worker.mjs +65 -61
- package/dist/{device-ios-COSi6oS1.mjs → device-ios-DRUeKaFV.mjs} +48 -45
- package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-C8raGFoP.mjs} +14 -26
- package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-DMRpVX9a.mjs} +5 -5
- package/dist/doctor-BLHCYxzi.mjs +2 -0
- package/dist/{doctor-kfMBnUw6.mjs → doctor-DTvaDOda.mjs} +281 -317
- package/dist/{doctor-CB8oZKCk.mjs → doctor-Dhqebm0q.mjs} +183 -91
- package/dist/doctor-fingerprint.mjs +19 -0
- package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-Cv1F10Kj.mjs} +40 -21
- package/dist/{eas-build-JyfqyHfC.mjs → eas-build-BomfRnFT.mjs} +53 -20
- package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-DJwZpy0c.mjs} +26 -208
- package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-op6A54yi.mjs} +229 -11
- package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-Bf0rZvG9.mjs} +172 -82
- package/dist/exec-H20xSg2T.d.mts +65 -0
- package/dist/exec-_UbtCQcG.mjs +750 -0
- package/dist/gc-C-WwL0yi.mjs +3 -0
- package/dist/{gc-qWOMdnER.mjs → gc-_-dCXdyL.mjs} +584 -796
- package/dist/git-C3iTsJaZ.mjs +73 -0
- package/dist/{guide-G9cAbVAc.mjs → guide-Yqwt2bd6.mjs} +941 -269
- package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-Bw-honsd.mjs} +8 -6
- package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DB_gBPfY.mjs} +34 -19
- package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CUvOf4Vr.mjs} +1 -1
- package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-DL_P5AdN.mjs} +77 -43
- package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-QI141yKk.mjs} +21 -17
- package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-Ksyjgzq-.mjs} +30 -21
- package/dist/idle-BVeRGroT.d.mts +24 -0
- package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DaKmZi0z.mjs} +11 -10
- package/dist/{ios-BwVCF7oA.mjs → ios-CQ68hG9s.mjs} +8 -8
- package/dist/{ios-RkW4pnQf.mjs → ios-CpByZy12.mjs} +140 -80
- package/dist/{ios-device-B5veSDDQ.mjs → ios-device-CXGP1bsD.mjs} +1 -1
- package/dist/{ios-device-D7pi2Sca.mjs → ios-device-CwFMehUS.mjs} +51 -26
- package/dist/{ios-project-K9hY_Jab.mjs → ios-project-WuwwBdvW.mjs} +13 -13
- package/dist/{ios-nOLJGVdy.mjs → ios-qNJt4dFm.mjs} +1 -1
- package/dist/ios-signing-DTTIChGs.mjs +489 -0
- package/dist/{ios-state-CBLe1xYw.mjs → ios-state-DvFX-K_l.mjs} +1 -1
- package/dist/{ios-Ce7bc7br.mjs → ios-ubFsBzwq.mjs} +129 -86
- package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Cc1dttps.mjs} +53 -26
- package/dist/{launch-F4sOqAhB.mjs → launch-CD1yVc7U.mjs} +91 -90
- package/dist/{launch-C3qJ6Agb.mjs → launch-Zq2mOSDy.mjs} +82 -541
- package/dist/logs-BS00Anxf.mjs +352 -0
- package/dist/logs-CMm05HxN.mjs +255 -0
- package/dist/{macos-D7uDvO-z.mjs → macos-B65--pPd.mjs} +1 -1
- package/dist/{macos-Ch5VJmcS.mjs → macos-C-0qJ6zq.mjs} +225 -212
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +122 -247
- package/dist/{metro-DnCEjCxs.mjs → metro-DEXpIhHC.mjs} +67 -12
- package/dist/{metro-gateway-CX9Xlkq2.mjs → metro-gateway-BMJNlj3E.mjs} +20 -12
- package/dist/{named-ports-4WopRPg-.mjs → named-ports-BWTzt6mu.mjs} +8 -63
- package/dist/native-android-JACyjTZs.mjs +844 -0
- package/dist/{native-gradle-inputs-BsLRrl7u.mjs → native-gradle-inputs-Bep9JcSF.mjs} +128 -140
- package/dist/native-inputs-TRTTTRxt.mjs +91 -0
- package/dist/native-run-DY_RLx3C.mjs +277 -0
- package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-Dg1Q7tfF.mjs} +9 -8
- package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-CB2iQeWq.mjs} +27 -18
- package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-CXX39F7o.mjs} +96 -47
- package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
- package/dist/offload-worker.d.mts +1 -46
- package/dist/offload-worker.mjs +197 -66
- package/dist/{ownership-DCtw_2IA.mjs → ownership-DEmM5vhh.mjs} +3 -3
- package/dist/{page-DRHy329N.mjs → page-CPaHeYqj.mjs} +7 -4
- package/dist/paths-BsJMoPP2.mjs +12 -0
- package/dist/paths-DQtTgsBf.mjs +42 -0
- package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BqGbTa61.mjs} +5 -5
- package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-Bwj-IjY1.mjs} +6 -6
- package/dist/{ports-DdSUicVo.mjs → ports-D-MmCTdv.mjs} +3 -3
- package/dist/prebuild-uD_ipCxF.mjs +449 -0
- package/dist/{project-_phNIJfs.mjs → project-BZNjmW_8.mjs} +65 -37
- package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-Lfetn8Kr.mjs} +2 -2
- package/dist/pull-request-zjCSAryH.d.mts +120 -0
- package/dist/pull-requests.d.mts +1 -119
- package/dist/pull-requests.mjs +1 -1
- package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-DuzH0cn3.mjs} +74 -48
- package/dist/{gradle-DSrXb6lG.mjs → react-native-build-rhk4smwQ.mjs} +292 -15
- package/dist/react-native-doctor-CQpuIMso.mjs +234 -0
- package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-Bhq1rJeV.mjs} +46 -28
- package/dist/{recordings-D0d5aQt0.mjs → recordings-DYteQSu4.mjs} +12 -9
- package/dist/{reload-C8JhxjSh.mjs → reload-CmTRFJaX.mjs} +93 -47
- package/dist/reload-DzjSl5P_.mjs +2 -0
- package/dist/{remote-BiR6aYjy.mjs → remote-ByYkXdGD.mjs} +15 -10
- package/dist/result-DNiS-tTP.mjs +434 -0
- package/dist/{run-BtPgpKks.mjs → run-D23HmJMs.mjs} +4 -5
- package/dist/selection-CSl9i5qU.mjs +619 -0
- package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CxTrvDg8.mjs} +3 -4
- package/dist/{server-command-CTtCkmcQ.mjs → server-command-CtzloH3v.mjs} +14 -7
- package/dist/server-expo-C-90EhcG.mjs +2 -0
- package/dist/{server-expo-DsguMGUF.mjs → server-expo-DT_F_uVI.mjs} +50 -9
- package/dist/{settings-B717odTD.mjs → settings-CsJDEXgK.mjs} +234 -24
- package/dist/{settings-vk3mJGSm.d.mts → settings-DkdmlelE.d.mts} +6 -4
- package/dist/settings-T1gtc3bf.mjs +114 -0
- package/dist/settings-write-HyVZ8eQ8.mjs +359 -0
- package/dist/settings.schema.json +163 -16
- package/dist/{simslim-CCr3rE-A.mjs → simslim-Cgk17SXV.mjs} +14 -12
- package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-DF8VfT64.mjs} +15 -20
- package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
- package/dist/stage-BIS0ydsV.mjs +183 -0
- package/dist/{start-BWqzODpb.mjs → start-7lpH7hmN.mjs} +63 -44
- package/dist/{start-TXeMmmO2.mjs → start-RChynRDp.mjs} +1 -1
- package/dist/{state-D1Icyjlu.mjs → state-C4ZtUisW.mjs} +40 -13
- package/dist/{state-CG_OFoaA.mjs → state-XMziexv2.mjs} +3 -2
- package/dist/{stats-BoY5sEPU.mjs → stats-53T7OTb9.mjs} +7 -13
- package/dist/stats-report-BFfMpWWF.mjs +16 -0
- package/dist/{status-WgFbkRzj.mjs → status-BL7jVyAB.mjs} +535 -447
- package/dist/status-CSi6tlRq.mjs +2 -0
- package/dist/{status-BTA7kKiQ.mjs → status-DqEUSSxs.mjs} +6 -4
- package/dist/{status-watch-C23ILtf9.mjs → status-watch-GDCfqpTE.mjs} +187 -22
- package/dist/status-worker.d.mts +1 -0
- package/dist/status-worker.mjs +19 -0
- package/dist/stim-desktop-C12we7lz.mjs +112 -0
- package/dist/{stop-DR6VoDIk.mjs → stop-Bk_1qiV6.mjs} +2 -2
- package/dist/{stop-BNmBMi1F.mjs → stop-CPzlM1L-.mjs} +138 -98
- package/dist/{stop-DPEhunlw.mjs → stop-D7h6jAXQ.mjs} +11 -10
- package/dist/supervisor-run.d.mts +8 -17
- package/dist/supervisor-run.mjs +63 -27
- package/dist/{support-DMTqj3Hm.mjs → support-67vraa1Q.mjs} +18 -11
- package/dist/{support-CwjbFs9H.mjs → support-Dlu37g6H.mjs} +12 -12
- package/dist/{swiftpm-macos-DRNVJWlb.mjs → swiftpm-macos-p8WZbxKU.mjs} +35 -24
- package/dist/toolchain-DhKwp9iI.mjs +2 -0
- package/dist/toolchain-Hp9sCpK4.mjs +873 -0
- package/dist/{trigger-CigAYjeL.mjs → trigger-BAahxUPq.mjs} +20 -5
- package/dist/trigger-Bf3uDcpv.mjs +2 -0
- package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-BHX5r0Ei.mjs} +250 -156
- package/dist/{web-BDBMxDpx.mjs → web-CJmIj6AI.mjs} +18 -13
- package/dist/web-DknQETPs.mjs +2 -0
- package/dist/web-run.mjs +11 -12
- package/dist/windows-report.d.mts +1 -0
- package/dist/windows-report.mjs +18 -0
- package/dist/windows-report.ps1 +43 -0
- package/dist/workspace-process-lock-1_1OoVW5.mjs +57 -0
- package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-Cjuigeeu.mjs} +62 -58
- package/dist/{workspaces-C36s2jb9.mjs → workspaces-BccMFmGQ.mjs} +1188 -1079
- package/dist/worktree-CK2MpJW5.mjs +2 -0
- package/dist/{worktree-CgvJYJ-Q.mjs → worktree-DQ6Zi2Mv.mjs} +304 -53
- package/dist/xcode-Zlx3qjEs.mjs +896 -0
- package/package.json +7 -5
- package/shim/android-optimizations.gradle +7 -5
- package/dist/activity-BSV745Kz.mjs +0 -629
- package/dist/api-qvOzWyfO.mjs +0 -154
- package/dist/api-run.mjs +0 -294
- package/dist/app-install-BIKtMfPq.mjs +0 -896
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
- package/dist/budget-f7516Zk0.mjs +0 -4106
- package/dist/build-facts-DcLv2HSd.d.mts +0 -111
- package/dist/cancellation-C_22VQTH.mjs +0 -24
- package/dist/client-qQAaXSUs.mjs +0 -1771
- package/dist/config-BYDxlMY3.mjs +0 -562
- package/dist/device-DuiPJQSn.mjs +0 -290
- package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
- package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
- package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
- package/dist/exec-DqKo9GKJ.mjs +0 -268
- package/dist/git-DDfFzkMm.mjs +0 -45
- package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
- package/dist/logs-BGrEUaEs.mjs +0 -383
- package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
- package/dist/native-android-D5qc3-_v.mjs +0 -226
- package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
- package/dist/plan-C4TjdPsR.mjs +0 -260
- package/dist/prebuild-DYbucPXy.mjs +0 -212
- package/dist/preview-78a9kR_-.mjs +0 -1011
- package/dist/react-native-build-CtCccJtb.mjs +0 -239
- package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
- package/dist/remote-cache-OyOyVIS3.mjs +0 -526
- package/dist/result-CaJg5Iat.mjs +0 -186
- package/dist/server-expo-Bigriskl.mjs +0 -2
- package/dist/settings-BORNaaCO.mjs +0 -402
- package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
- package/dist/stage-KNTQopqv.mjs +0 -157
- package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
- package/dist/tailnet-Dh-qiYzG.mjs +0 -265
- package/dist/toolchain-BFkAcstd.mjs +0 -2
- package/dist/toolchain-DxSsNssu.mjs +0 -1657
- package/dist/trigger-9_USgmxz.mjs +0 -2
- package/dist/web-Dq-i3wzJ.mjs +0 -2
- package/dist/worktree-DpLdCHga.mjs +0 -2
- package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
- package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
|
@@ -1,32 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { c as androidDataPartitionSizeBytes } from "./settings-
|
|
4
|
-
import {
|
|
5
|
-
import { n as readCreatedDevices$1, r as recordCreatedDevice, t as forgetCreatedDevice } from "./created-devices-
|
|
6
|
-
import {
|
|
1
|
+
import { f as ownership_claim_exports, p as process_identity_exports, t as getExecutor } from "./exec-_UbtCQcG.mjs";
|
|
2
|
+
import { B as assignSlotDevice, C as saveConfig, D as withConfigLock$1, K as projectDeviceSlots, O as withConfigLockAsync$1, U as deviceSlotPlatforms, _ as loadConfig$1, c as ensureConfig, d as getConfigDir, f as getConfigPath$1, q as removeSlotDevice } from "./config-CYcBF478.mjs";
|
|
3
|
+
import { c as androidDataPartitionSizeBytes } from "./settings-CsJDEXgK.mjs";
|
|
4
|
+
import { l as pidExists, m as signalProcessTreeAsync } from "./metro-DEXpIhHC.mjs";
|
|
5
|
+
import { n as readCreatedDevices$1, r as recordCreatedDevice, t as forgetCreatedDevice } from "./created-devices-CqeBlrEn.mjs";
|
|
6
|
+
import { i as stimDesktopInstalledAsync, n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-C12we7lz.mjs";
|
|
7
|
+
import { isDeepStrictEqual } from "node:util";
|
|
7
8
|
import { join } from "node:path";
|
|
8
|
-
import {
|
|
9
|
+
import { ambientEnv, ambientWrite } from "@stim-cli/core";
|
|
9
10
|
import { ANDROID_EMULATOR_APPS, getParkedMax, isJsonObject, loadConfig, settingDefinition } from "@stim-cli/core/state";
|
|
11
|
+
import { dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, resolve as resolve$1 } from "path";
|
|
10
12
|
import { existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
|
|
11
13
|
import { homedir, tmpdir } from "os";
|
|
12
|
-
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
|
-
//#endregion
|
|
30
14
|
//#region src/devices/sim-pool.ts
|
|
31
15
|
const POOL_SETTING_REMEDY = "Run `stim guide settings` for the device pool bounds and where it can be set.";
|
|
32
16
|
function parkedMaxSetting(platform, options = {}) {
|
|
@@ -154,11 +138,11 @@ function erasedRecord(record) {
|
|
|
154
138
|
delete erased.schemeApprovals;
|
|
155
139
|
return erased;
|
|
156
140
|
}
|
|
157
|
-
function settleParkedAfter(platform, udid, action, keep) {
|
|
141
|
+
async function settleParkedAfter(platform, udid, action, keep) {
|
|
158
142
|
const claim = claimParkedOperation(platform, udid);
|
|
159
143
|
if (!claim) return null;
|
|
160
144
|
try {
|
|
161
|
-
const claimed =
|
|
145
|
+
const claimed = await withConfigLockAsync$1(() => {
|
|
162
146
|
const cfg = loadConfig$1();
|
|
163
147
|
if (!cfg) return null;
|
|
164
148
|
const records = readParked(platform, { config: cfg });
|
|
@@ -188,7 +172,7 @@ function settleParkedAfter(platform, udid, action, keep) {
|
|
|
188
172
|
try {
|
|
189
173
|
(0, ownership_claim_exports.markClaimChildPending)(claim);
|
|
190
174
|
try {
|
|
191
|
-
action(claimed.record, () => {
|
|
175
|
+
await action(claimed.record, () => {
|
|
192
176
|
started = true;
|
|
193
177
|
});
|
|
194
178
|
} finally {
|
|
@@ -196,7 +180,7 @@ function settleParkedAfter(platform, udid, action, keep) {
|
|
|
196
180
|
}
|
|
197
181
|
completed = true;
|
|
198
182
|
} finally {
|
|
199
|
-
|
|
183
|
+
await withConfigLockAsync$1(() => {
|
|
200
184
|
const cfg = loadConfig$1();
|
|
201
185
|
if (!cfg) return;
|
|
202
186
|
const records = readParked(platform, { config: cfg });
|
|
@@ -213,8 +197,8 @@ function settleParkedAfter(platform, udid, action, keep) {
|
|
|
213
197
|
(0, ownership_claim_exports.releaseClaim)(claim);
|
|
214
198
|
}
|
|
215
199
|
}
|
|
216
|
-
function dropParked(platform, udid) {
|
|
217
|
-
return removeParkedAfter(platform, udid, () => {}) !== null;
|
|
200
|
+
async function dropParked(platform, udid) {
|
|
201
|
+
return await removeParkedAfter(platform, udid, () => {}) !== null;
|
|
218
202
|
}
|
|
219
203
|
//#endregion
|
|
220
204
|
//#region src/devices/device-ownership.ts
|
|
@@ -246,6 +230,27 @@ function isStimOwnedAvd(name) {
|
|
|
246
230
|
return name.startsWith("stim-") && isStimOwnedDevice("android", name);
|
|
247
231
|
}
|
|
248
232
|
//#endregion
|
|
233
|
+
//#region src/devices/android-emulator-viewer.ts
|
|
234
|
+
async function configuredAndroidEmulatorApp(platform = process.platform, env) {
|
|
235
|
+
let value = loadConfig$1()?.androidEmulatorApp;
|
|
236
|
+
if (value === void 0) {
|
|
237
|
+
const installed = await stimDesktopInstalledAsync(platform, env);
|
|
238
|
+
value = settingDefault(settingDefinition("androidEmulatorApp"), () => installed).value;
|
|
239
|
+
}
|
|
240
|
+
if (ANDROID_EMULATOR_APPS.includes(value)) return value;
|
|
241
|
+
const error = /* @__PURE__ */ new Error("Invalid androidEmulatorApp in machine config. Use \"emulator\" or \"stim-desktop\".");
|
|
242
|
+
Object.assign(error, { code: "STIM_BAD_ARG" });
|
|
243
|
+
throw error;
|
|
244
|
+
}
|
|
245
|
+
async function openEmulatorInStimDesktop(serial) {
|
|
246
|
+
await getExecutor().runFileQuietAsync("open", [
|
|
247
|
+
"-g",
|
|
248
|
+
"-a",
|
|
249
|
+
"Stim",
|
|
250
|
+
`stim-desktop://open?serial=${serial}`
|
|
251
|
+
], STIM_DESKTOP_OPEN_OPTIONS);
|
|
252
|
+
}
|
|
253
|
+
//#endregion
|
|
249
254
|
//#region src/devices/android.ts
|
|
250
255
|
const ANDROID_ABIS = /* @__PURE__ */ new Set([
|
|
251
256
|
"armeabi-v7a",
|
|
@@ -254,11 +259,13 @@ const ANDROID_ABIS = /* @__PURE__ */ new Set([
|
|
|
254
259
|
"x86_64"
|
|
255
260
|
]);
|
|
256
261
|
const DEFAULT_AVD_DEVICE_PROFILE = String(settingDefinition("android.deviceProfile")?.default);
|
|
257
|
-
function androidHome(env =
|
|
262
|
+
function androidHome(env = ambientEnv()) {
|
|
258
263
|
const configured = env.ANDROID_HOME || env.ANDROID_SDK_ROOT;
|
|
259
264
|
if (configured) return configured;
|
|
260
|
-
|
|
261
|
-
return join$1(
|
|
265
|
+
const home = process.platform === "win32" ? env.USERPROFILE || homedir() : env.HOME || homedir();
|
|
266
|
+
if (process.platform === "win32") return join$1(env.LOCALAPPDATA || join$1(home, "AppData", "Local"), "Android", "Sdk");
|
|
267
|
+
if (process.platform === "linux") return join$1(home, "Android", "Sdk");
|
|
268
|
+
return join$1(home, "Library", "Android", "sdk");
|
|
262
269
|
}
|
|
263
270
|
const SDK_TOOL_LOCATIONS = {
|
|
264
271
|
emulator: ["emulator", "emulator"],
|
|
@@ -282,11 +289,11 @@ const WINDOWS_SDK_TOOL_EXTENSIONS = {
|
|
|
282
289
|
avdmanager: ".bat",
|
|
283
290
|
sdkmanager: ".bat"
|
|
284
291
|
};
|
|
285
|
-
function androidToolPath(tool, platform = process.platform) {
|
|
292
|
+
function androidToolPath(tool, platform = process.platform, env = ambientEnv()) {
|
|
286
293
|
const location = SDK_TOOL_LOCATIONS[tool];
|
|
287
294
|
const bare = location.at(-1);
|
|
288
295
|
const name = platform === "win32" ? `${bare}${WINDOWS_SDK_TOOL_EXTENSIONS[tool]}` : bare;
|
|
289
|
-
const abs = join$1(androidHome(), ...location.slice(0, -1), name);
|
|
296
|
+
const abs = join$1(androidHome(env), ...location.slice(0, -1), name);
|
|
290
297
|
return existsSync(abs) ? abs : bare;
|
|
291
298
|
}
|
|
292
299
|
const WINDOWS_BUILD_TOOL_EXTENSIONS = { apksigner: ".bat" };
|
|
@@ -333,8 +340,8 @@ function findBuildTool(tools, { home = androidHome(), readDir = readdirSync, exi
|
|
|
333
340
|
}
|
|
334
341
|
return null;
|
|
335
342
|
}
|
|
336
|
-
function listInstalledSystemImages(onUnreadable) {
|
|
337
|
-
const root = join$1(androidHome(), "system-images");
|
|
343
|
+
function listInstalledSystemImages(onUnreadable, env = ambientEnv()) {
|
|
344
|
+
const root = join$1(androidHome(env), "system-images");
|
|
338
345
|
const images = [];
|
|
339
346
|
const list = (dir) => {
|
|
340
347
|
try {
|
|
@@ -402,9 +409,9 @@ async function createOwnedAvd(label, { systemImage, deviceProfile = DEFAULT_AVD_
|
|
|
402
409
|
"--device",
|
|
403
410
|
deviceProfile
|
|
404
411
|
];
|
|
405
|
-
let env =
|
|
412
|
+
let env = ambientEnv();
|
|
406
413
|
if (!env.ANDROID_AVD_HOME) {
|
|
407
|
-
const root = avdLookupRoots(env, homedir())[0];
|
|
414
|
+
const root = avdLookupRoots(env, (process.platform === "win32" ? env.USERPROFILE : env.HOME) || homedir())[0];
|
|
408
415
|
mkdirSync(root, { recursive: true });
|
|
409
416
|
env = {
|
|
410
417
|
...env,
|
|
@@ -496,10 +503,10 @@ function ownedAvdName(label) {
|
|
|
496
503
|
return `stim-${clean.startsWith("stim-") ? clean.slice(5) : clean}`;
|
|
497
504
|
}
|
|
498
505
|
const AVDMANAGER_DELETE_TIMEOUT_MS = 12e4;
|
|
499
|
-
function deleteAvd(avdName) {
|
|
506
|
+
async function deleteAvd(avdName) {
|
|
500
507
|
if (!isStimOwnedAvd(avdName)) throw new Error(`Refusing to delete AVD "${avdName}": not a Stim-owned AVD; Stim has no record of creating it.`);
|
|
501
|
-
const root =
|
|
502
|
-
getExecutor().
|
|
508
|
+
const root = ambientEnv().ANDROID_AVD_HOME ? void 0 : avdStorageRoots().find((candidate) => avdPathExists(join$1(candidate, `${avdName}.ini`)));
|
|
509
|
+
await getExecutor().runFileAsync(androidToolPath("avdmanager"), [
|
|
503
510
|
"delete",
|
|
504
511
|
"avd",
|
|
505
512
|
"-n",
|
|
@@ -559,6 +566,12 @@ function listAvds({ timeoutMs = ANDROID_LISTING_TIMEOUT_MS } = {}) {
|
|
|
559
566
|
killSignal: "SIGKILL"
|
|
560
567
|
}));
|
|
561
568
|
}
|
|
569
|
+
async function listAvdsAsync({ timeoutMs = ANDROID_LISTING_TIMEOUT_MS } = {}) {
|
|
570
|
+
return parseAvdList(await getExecutor().runFileAsync(androidToolPath("emulator"), ["-list-avds"], {
|
|
571
|
+
timeoutMs,
|
|
572
|
+
killSignal: "SIGKILL"
|
|
573
|
+
}));
|
|
574
|
+
}
|
|
562
575
|
/**
|
|
563
576
|
* Working directory for the adb client and the emulator Stim starts. Both leave processes behind
|
|
564
577
|
* that inherit it: the adb server is spawned by whichever client finds none running, and the
|
|
@@ -577,6 +590,13 @@ function listAdbDevices({ timeoutMs = ANDROID_LISTING_TIMEOUT_MS, platform = pro
|
|
|
577
590
|
cwd: androidToolCwd(platform)
|
|
578
591
|
}));
|
|
579
592
|
}
|
|
593
|
+
async function listAdbDevicesAsync({ timeoutMs = ANDROID_LISTING_TIMEOUT_MS, platform = process.platform } = {}) {
|
|
594
|
+
return parseAdbDevices(await getExecutor().runFileAsync(androidToolPath("adb"), ["devices"], {
|
|
595
|
+
timeoutMs,
|
|
596
|
+
killSignal: "SIGKILL",
|
|
597
|
+
cwd: androidToolCwd(platform)
|
|
598
|
+
}));
|
|
599
|
+
}
|
|
580
600
|
const ADB_PROP_TIMEOUT_MS = 5e3;
|
|
581
601
|
const EMULATOR_HARDWARE = /* @__PURE__ */ new Set([
|
|
582
602
|
"ranchu",
|
|
@@ -688,7 +708,7 @@ function nextConsolePort(claimedPorts) {
|
|
|
688
708
|
if (claimedPorts.length === 0) return 5554;
|
|
689
709
|
return Math.max(...claimedPorts) + 2;
|
|
690
710
|
}
|
|
691
|
-
function headlessEmulatorArgs(env =
|
|
711
|
+
function headlessEmulatorArgs(env = ambientEnv(), platform = process.platform, app = "emulator") {
|
|
692
712
|
const args = [];
|
|
693
713
|
if (platform === "darwin" && app === "stim-desktop") args.push("-no-window", "-gpu", "host");
|
|
694
714
|
if (platform === "linux" && !env.DISPLAY && !env.WAYLAND_DISPLAY) args.push("-no-window", "-noaudio", "-no-boot-anim", "-gpu", "swiftshader_indirect", "-no-snapshot-save", "-no-snapshot-load");
|
|
@@ -717,15 +737,15 @@ function avdIniPaths(root, ini) {
|
|
|
717
737
|
const parsed = parseAvdRootIni(ini);
|
|
718
738
|
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);
|
|
719
739
|
}
|
|
720
|
-
function avdStorageRoots() {
|
|
721
|
-
const
|
|
740
|
+
function avdStorageRoots(env = ambientEnv()) {
|
|
741
|
+
const home = process.platform === "win32" ? env.USERPROFILE || homedir() : env.HOME || homedir();
|
|
722
742
|
return [...new Set([
|
|
723
743
|
env.ANDROID_AVD_HOME,
|
|
724
744
|
env.ANDROID_EMULATOR_HOME ? join$1(env.ANDROID_EMULATOR_HOME, "avd") : null,
|
|
725
745
|
env.ANDROID_USER_HOME ? join$1(env.ANDROID_USER_HOME, "avd") : null,
|
|
726
746
|
env.ANDROID_SDK_HOME ? join$1(env.ANDROID_SDK_HOME, ".android", "avd") : null,
|
|
727
747
|
env.ANDROID_SDK_HOME ? join$1(env.ANDROID_SDK_HOME, "avd") : null,
|
|
728
|
-
join$1(
|
|
748
|
+
join$1(home, ".android", "avd")
|
|
729
749
|
].filter((value) => Boolean(value)))];
|
|
730
750
|
}
|
|
731
751
|
function avdPathExists(path) {
|
|
@@ -803,7 +823,7 @@ function avdLookupRoots(env, home) {
|
|
|
803
823
|
];
|
|
804
824
|
return [...new Set(roots.filter((value) => Boolean(value)))];
|
|
805
825
|
}
|
|
806
|
-
function ownedAvdDirectory(avdName, { env =
|
|
826
|
+
function ownedAvdDirectory(avdName, { env = ambientEnv(), home = (process.platform === "win32" ? env.USERPROFILE : env.HOME) || homedir(), readFile = (path) => readFileSync(path, "utf8"), realpath = realpathSync, isDirectory = (path) => statSync(path).isDirectory() } = {}) {
|
|
807
827
|
if (!/^stim-[A-Za-z0-9._-]+$/.test(avdName)) return null;
|
|
808
828
|
for (const root of avdLookupRoots(env, home)) {
|
|
809
829
|
let ini;
|
|
@@ -911,16 +931,16 @@ async function resetAdoptedAvd(avdName, serial, keepPackage) {
|
|
|
911
931
|
let firstFailure;
|
|
912
932
|
let unavailableTarget = false;
|
|
913
933
|
const commandTimeout = (timeoutMs) => recoveryDeadline === void 0 ? timeoutMs : Math.max(1, Math.min(timeoutMs, recoveryDeadline - Date.now()));
|
|
914
|
-
const assertTarget = () => {
|
|
915
|
-
const resolved =
|
|
934
|
+
const assertTarget = async () => {
|
|
935
|
+
const resolved = await resolveOwnedAvdSerialAsync(avdName, { timeoutMs: commandTimeout(3e4) });
|
|
916
936
|
unavailableTarget = Boolean(resolved.notRunning);
|
|
917
937
|
if (resolved.serial !== serial) throw new Error(`AVD ${avdName} is no longer running on ${serial}.`);
|
|
918
938
|
};
|
|
919
939
|
for (;;) {
|
|
920
940
|
unavailableTarget = false;
|
|
921
941
|
try {
|
|
922
|
-
assertTarget();
|
|
923
|
-
const packages = exec.
|
|
942
|
+
await assertTarget();
|
|
943
|
+
const packages = (await exec.runFileAsync("adb", [
|
|
924
944
|
"-s",
|
|
925
945
|
serial,
|
|
926
946
|
"shell",
|
|
@@ -928,20 +948,20 @@ async function resetAdoptedAvd(avdName, serial, keepPackage) {
|
|
|
928
948
|
"list",
|
|
929
949
|
"packages",
|
|
930
950
|
"-3"
|
|
931
|
-
], { timeoutMs: commandTimeout(3e4) }).split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((line) => {
|
|
951
|
+
], { timeoutMs: commandTimeout(3e4) })).split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((line) => {
|
|
932
952
|
const match = /^package:([A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)+)$/.exec(line);
|
|
933
953
|
if (!match) throw new Error(`Could not read installed apps on ${avdName}: ${line}`);
|
|
934
954
|
return match[1];
|
|
935
955
|
});
|
|
936
956
|
for (const packageName of packages) {
|
|
937
|
-
assertTarget();
|
|
957
|
+
await assertTarget();
|
|
938
958
|
const args = packageName === keepPackage ? [
|
|
939
959
|
"shell",
|
|
940
960
|
"pm",
|
|
941
961
|
"clear",
|
|
942
962
|
packageName
|
|
943
963
|
] : ["uninstall", packageName];
|
|
944
|
-
const result = exec.
|
|
964
|
+
const result = await exec.runFileAsync("adb", [
|
|
945
965
|
"-s",
|
|
946
966
|
serial,
|
|
947
967
|
...args
|
|
@@ -974,8 +994,8 @@ function parseDfAvailableBytes(text) {
|
|
|
974
994
|
const available = lines[1].split(/\s+/)[3];
|
|
975
995
|
return available && /^\d+$/.test(available) ? Number(available) * 1024 : null;
|
|
976
996
|
}
|
|
977
|
-
function androidDataFreeBytes(serial) {
|
|
978
|
-
return parseDfAvailableBytes(getExecutor().
|
|
997
|
+
async function androidDataFreeBytes(serial) {
|
|
998
|
+
return parseDfAvailableBytes(await getExecutor().runFileQuietAsync("adb", [
|
|
979
999
|
"-s",
|
|
980
1000
|
serial,
|
|
981
1001
|
"shell",
|
|
@@ -984,8 +1004,8 @@ function androidDataFreeBytes(serial) {
|
|
|
984
1004
|
"/data"
|
|
985
1005
|
], { timeoutMs: 3e4 }));
|
|
986
1006
|
}
|
|
987
|
-
function trimAndroidCaches(serial, desiredFreeBytes) {
|
|
988
|
-
getExecutor().
|
|
1007
|
+
async function trimAndroidCaches(serial, desiredFreeBytes) {
|
|
1008
|
+
await getExecutor().runFileAsync("adb", [
|
|
989
1009
|
"-s",
|
|
990
1010
|
serial,
|
|
991
1011
|
"shell",
|
|
@@ -1010,7 +1030,7 @@ const CRASH_REPORT_MODE_EMULATOR_VERSION = 37;
|
|
|
1010
1030
|
* Where the emulator keeps crashpad's database on Windows: `AndroidEmulator\emu-crash-<version>.db`
|
|
1011
1031
|
* under GetTempPath, which reads TMP before TEMP.
|
|
1012
1032
|
*/
|
|
1013
|
-
function emulatorCrashDatabases(env =
|
|
1033
|
+
function emulatorCrashDatabases(env = ambientEnv()) {
|
|
1014
1034
|
const root = join$1(env.TMP || env.TEMP || tmpdir(), "AndroidEmulator");
|
|
1015
1035
|
try {
|
|
1016
1036
|
return readdirSync(root).filter((name) => /^emu-crash-.*\.db$/.test(name)).map((name) => join$1(root, name));
|
|
@@ -1039,9 +1059,9 @@ function suppressEmulatorCrashConsent({ platform = process.platform, version = e
|
|
|
1039
1059
|
} catch {}
|
|
1040
1060
|
return [];
|
|
1041
1061
|
}
|
|
1042
|
-
function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process.platform, openViewer = true } = {}) {
|
|
1062
|
+
async function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process.platform, openViewer = true } = {}) {
|
|
1043
1063
|
const exec = getExecutor();
|
|
1044
|
-
const app = configuredAndroidEmulatorApp(platform);
|
|
1064
|
+
const app = await configuredAndroidEmulatorApp(platform, ambientEnv());
|
|
1045
1065
|
const child = exec.spawn(androidToolPath("emulator"), [
|
|
1046
1066
|
"-avd",
|
|
1047
1067
|
avdName,
|
|
@@ -1050,7 +1070,7 @@ function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process
|
|
|
1050
1070
|
"-grpc",
|
|
1051
1071
|
String(consolePort + 3e3),
|
|
1052
1072
|
"-grpc-use-token",
|
|
1053
|
-
...headlessEmulatorArgs(
|
|
1073
|
+
...headlessEmulatorArgs(ambientEnv(), platform, openViewer ? app : "stim-desktop"),
|
|
1054
1074
|
...suppressEmulatorCrashConsent({ platform })
|
|
1055
1075
|
], {
|
|
1056
1076
|
cwd: androidToolCwd(platform),
|
|
@@ -1059,7 +1079,7 @@ function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process
|
|
|
1059
1079
|
});
|
|
1060
1080
|
child?.unref?.();
|
|
1061
1081
|
const pid = child?.pid ?? null;
|
|
1062
|
-
if (openViewer && pid !== null && platform === "darwin" && app === "stim-desktop") openEmulatorInStimDesktop(`emulator-${consolePort}`);
|
|
1082
|
+
if (openViewer && pid !== null && platform === "darwin" && app === "stim-desktop") await openEmulatorInStimDesktop(`emulator-${consolePort}`);
|
|
1063
1083
|
return pid;
|
|
1064
1084
|
}
|
|
1065
1085
|
function emulatorStdio(logFile) {
|
|
@@ -1114,8 +1134,8 @@ function emulatorDiskSpaceRemedy(lines) {
|
|
|
1114
1134
|
function emulatorFailureRemedy(lines) {
|
|
1115
1135
|
return emulatorDiskSpaceRemedy(lines) ?? "Fix what the emulator reported above, then run `stim android` again.";
|
|
1116
1136
|
}
|
|
1117
|
-
function getprop(exec, serial, prop, timeoutMs) {
|
|
1118
|
-
const out = exec.
|
|
1137
|
+
async function getprop(exec, serial, prop, timeoutMs) {
|
|
1138
|
+
const out = await exec.runFileQuietAsync(androidToolPath("adb"), [
|
|
1119
1139
|
"-s",
|
|
1120
1140
|
serial,
|
|
1121
1141
|
"shell",
|
|
@@ -1130,8 +1150,8 @@ const PACKAGE_MANAGER_PROBE = [
|
|
|
1130
1150
|
"path",
|
|
1131
1151
|
"android"
|
|
1132
1152
|
];
|
|
1133
|
-
function packageManagerReady(exec, serial, timeoutMs) {
|
|
1134
|
-
const out = exec.
|
|
1153
|
+
async function packageManagerReady(exec, serial, timeoutMs) {
|
|
1154
|
+
const out = await exec.runFileQuietAsync(androidToolPath("adb"), [
|
|
1135
1155
|
"-s",
|
|
1136
1156
|
serial,
|
|
1137
1157
|
...PACKAGE_MANAGER_PROBE
|
|
@@ -1144,7 +1164,7 @@ async function waitForBoot(serial, timeoutMs = 6e4, { aborted = () => false, pol
|
|
|
1144
1164
|
let exited = false;
|
|
1145
1165
|
const probeTimeout = () => Math.max(1, Math.min(commandTimeoutMs ?? timeoutMs, timeoutMs - (Date.now() - start)));
|
|
1146
1166
|
while (Date.now() - start < timeoutMs) {
|
|
1147
|
-
if ((getprop(exec, serial, "sys.boot_completed", probeTimeout()) === "1" || getprop(exec, serial, "dev.bootcomplete", probeTimeout()) === "1") && packageManagerReady(exec, serial, probeTimeout())) return { ok: true };
|
|
1167
|
+
if ((await getprop(exec, serial, "sys.boot_completed", probeTimeout()) === "1" || await getprop(exec, serial, "dev.bootcomplete", probeTimeout()) === "1") && await packageManagerReady(exec, serial, probeTimeout())) return { ok: true };
|
|
1148
1168
|
if (aborted()) {
|
|
1149
1169
|
exited = true;
|
|
1150
1170
|
break;
|
|
@@ -1152,39 +1172,39 @@ async function waitForBoot(serial, timeoutMs = 6e4, { aborted = () => false, pol
|
|
|
1152
1172
|
await new Promise((r) => setTimeout(r, commandTimeoutMs === void 0 ? pollMs : Math.min(pollMs, Math.max(0, timeoutMs - (Date.now() - start)))));
|
|
1153
1173
|
}
|
|
1154
1174
|
const diagnosticDeadline = Date.now() + Math.min(commandTimeoutMs ?? 5e3, 5e3);
|
|
1155
|
-
const diagnosticQuery = (args) => {
|
|
1175
|
+
const diagnosticQuery = async (args) => {
|
|
1156
1176
|
const remaining = diagnosticDeadline - Date.now();
|
|
1157
1177
|
if (remaining <= 0) return "";
|
|
1158
|
-
const value = exec.
|
|
1178
|
+
const value = await exec.runFileQuietAsync(androidToolPath("adb"), args, { timeoutMs: remaining });
|
|
1159
1179
|
return typeof value === "string" ? value.trim() : "";
|
|
1160
1180
|
};
|
|
1161
1181
|
return {
|
|
1162
1182
|
ok: false,
|
|
1163
1183
|
...exited ? { exited: true } : {},
|
|
1164
1184
|
diagnostic: {
|
|
1165
|
-
devices: diagnosticQuery(["devices"]),
|
|
1166
|
-
sysBoot: diagnosticQuery([
|
|
1185
|
+
devices: await diagnosticQuery(["devices"]),
|
|
1186
|
+
sysBoot: await diagnosticQuery([
|
|
1167
1187
|
"-s",
|
|
1168
1188
|
serial,
|
|
1169
1189
|
"shell",
|
|
1170
1190
|
"getprop",
|
|
1171
1191
|
"sys.boot_completed"
|
|
1172
1192
|
]),
|
|
1173
|
-
devBoot: diagnosticQuery([
|
|
1193
|
+
devBoot: await diagnosticQuery([
|
|
1174
1194
|
"-s",
|
|
1175
1195
|
serial,
|
|
1176
1196
|
"shell",
|
|
1177
1197
|
"getprop",
|
|
1178
1198
|
"dev.bootcomplete"
|
|
1179
1199
|
]),
|
|
1180
|
-
bootAnim: diagnosticQuery([
|
|
1200
|
+
bootAnim: await diagnosticQuery([
|
|
1181
1201
|
"-s",
|
|
1182
1202
|
serial,
|
|
1183
1203
|
"shell",
|
|
1184
1204
|
"getprop",
|
|
1185
1205
|
"init.svc.bootanim"
|
|
1186
1206
|
]),
|
|
1187
|
-
packageManager: diagnosticQuery([
|
|
1207
|
+
packageManager: await diagnosticQuery([
|
|
1188
1208
|
"-s",
|
|
1189
1209
|
serial,
|
|
1190
1210
|
...PACKAGE_MANAGER_PROBE
|
|
@@ -1194,24 +1214,27 @@ async function waitForBoot(serial, timeoutMs = 6e4, { aborted = () => false, pol
|
|
|
1194
1214
|
}
|
|
1195
1215
|
const ANDROID_EMULATOR_SHUTDOWN_TIMEOUT_MS = 6e4;
|
|
1196
1216
|
const ANDROID_EMULATOR_SHUTDOWN_POLL_MS = 100;
|
|
1197
|
-
function shutdownAndroidEmulator(serial, timeoutMs = ANDROID_EMULATOR_SHUTDOWN_TIMEOUT_MS) {
|
|
1217
|
+
async function shutdownAndroidEmulator(serial, timeoutMs = ANDROID_EMULATOR_SHUTDOWN_TIMEOUT_MS) {
|
|
1198
1218
|
const exec = getExecutor();
|
|
1199
1219
|
const started = Date.now();
|
|
1200
|
-
if (exec.
|
|
1220
|
+
if (await exec.runFileQuietAsync(androidToolPath("adb"), [
|
|
1201
1221
|
"-s",
|
|
1202
1222
|
serial,
|
|
1203
1223
|
"shell",
|
|
1204
1224
|
"sync"
|
|
1205
|
-
], {
|
|
1206
|
-
|
|
1225
|
+
], {
|
|
1226
|
+
timeoutMs: Math.min(5e3, timeoutMs),
|
|
1227
|
+
killSignal: "SIGKILL"
|
|
1228
|
+
}) === null) ambientWrite("stderr", `warning: could not flush ${serial} before shutdown; shutting it down anyway\n`);
|
|
1229
|
+
await exec.runFileQuietAsync(androidToolPath("adb"), [
|
|
1207
1230
|
"-s",
|
|
1208
1231
|
serial,
|
|
1209
1232
|
"emu",
|
|
1210
1233
|
"kill"
|
|
1211
|
-
], {
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1234
|
+
], {
|
|
1235
|
+
timeoutMs: Math.max(1, timeoutMs - (Date.now() - started)),
|
|
1236
|
+
killSignal: "SIGKILL"
|
|
1237
|
+
});
|
|
1215
1238
|
}
|
|
1216
1239
|
function avdProcessLockPaths(avdDirectory, platform) {
|
|
1217
1240
|
return ["hardware-qemu.ini.lock", "userdata-qemu.img.lock"].map((name) => join$1(avdDirectory, name, ...platform === "win32" ? ["pid"] : []));
|
|
@@ -1263,6 +1286,18 @@ function listAvdEmulatorProcesses(avdName, platform) {
|
|
|
1263
1286
|
], { timeoutMs: 5e3 });
|
|
1264
1287
|
return out === null ? null : parseAvdEmulatorProcesses(out, avdName);
|
|
1265
1288
|
}
|
|
1289
|
+
async function listAvdEmulatorProcessesAsync(avdName, platform) {
|
|
1290
|
+
if (platform === "win32") return [];
|
|
1291
|
+
const out = await getExecutor().runFileQuietAsync("ps", [
|
|
1292
|
+
"-axww",
|
|
1293
|
+
"-o",
|
|
1294
|
+
"pid=,command="
|
|
1295
|
+
], {
|
|
1296
|
+
timeoutMs: 5e3,
|
|
1297
|
+
killSignal: "SIGKILL"
|
|
1298
|
+
});
|
|
1299
|
+
return out === null ? null : parseAvdEmulatorProcesses(out, avdName);
|
|
1300
|
+
}
|
|
1266
1301
|
function scanAvdEmulatorProcesses(avdName, platform, listProcesses) {
|
|
1267
1302
|
const pids = listProcesses(avdName, platform);
|
|
1268
1303
|
if (pids === null) throw new Error(`Could not read the process table to verify that owned AVD ${avdName} stopped.`);
|
|
@@ -1291,13 +1326,16 @@ const CRASH_HANDLER_EXIT_TIMEOUT_MS = 15e3;
|
|
|
1291
1326
|
* it writes the dump, so a `stop` that returns on qemu's exit leaves it running.
|
|
1292
1327
|
* https://github.com/appandflow/stim/issues/918
|
|
1293
1328
|
*/
|
|
1294
|
-
function emulatorCrashHandlerPids(qemuPid) {
|
|
1295
|
-
const out = getExecutor().
|
|
1329
|
+
async function emulatorCrashHandlerPids(qemuPid) {
|
|
1330
|
+
const out = await getExecutor().runFileQuietAsync("powershell.exe", [
|
|
1296
1331
|
"-NoProfile",
|
|
1297
1332
|
"-NonInteractive",
|
|
1298
1333
|
"-Command",
|
|
1299
1334
|
`Get-CimInstance Win32_Process | Where-Object { $_.Name -eq 'crashpad_handler.exe' -and $_.ParentProcessId -eq ${qemuPid} } | ForEach-Object ProcessId`
|
|
1300
|
-
], {
|
|
1335
|
+
], {
|
|
1336
|
+
timeoutMs: 1e4,
|
|
1337
|
+
killSignal: "SIGKILL"
|
|
1338
|
+
});
|
|
1301
1339
|
return String(out ?? "").split(/\r?\n/).map((line) => Number(line.trim())).filter((pid) => Number.isSafeInteger(pid) && pid > 0);
|
|
1302
1340
|
}
|
|
1303
1341
|
const EMULATOR_SIGNAL_GRACE_MS = 5e3;
|
|
@@ -1308,14 +1346,19 @@ const EMULATOR_SIGNAL_GRACE_MS = 5e3;
|
|
|
1308
1346
|
* grace, but only a process whose command line names this AVD and whose identity, captured before
|
|
1309
1347
|
* shutdown, still matches. Windows has no process-table scan, so there nothing is signalled.
|
|
1310
1348
|
*/
|
|
1311
|
-
function waitForAndroidEmulatorShutdown(avdName, shutdown, { timeoutMs = ANDROID_EMULATOR_SHUTDOWN_TIMEOUT_MS, pollMs = ANDROID_EMULATOR_SHUTDOWN_POLL_MS, signalGraceMs = EMULATOR_SIGNAL_GRACE_MS, platform = process.platform, resolveDirectory = ownedAvdDirectory, readProcessId = readAvdProcessId, processAlive = pidExists, listProcesses =
|
|
1349
|
+
async function waitForAndroidEmulatorShutdown(avdName, shutdown, { timeoutMs = ANDROID_EMULATOR_SHUTDOWN_TIMEOUT_MS, pollMs = ANDROID_EMULATOR_SHUTDOWN_POLL_MS, signalGraceMs = EMULATOR_SIGNAL_GRACE_MS, platform = process.platform, resolveDirectory = ownedAvdDirectory, readProcessId = readAvdProcessId, processAlive = pidExists, listProcesses = listAvdEmulatorProcessesAsync, captureIdentity = process_identity_exports.captureProcessIdentity, inspectIdentity = process_identity_exports.inspectProcessIdentity, signal = (pid, name) => signalProcessTreeAsync(pid, name, { platform }), directoryExists = (path) => statSync(path).isDirectory(), crashHandlerPids = emulatorCrashHandlerPids, killCrashHandler = (pid) => signalProcessTreeAsync(pid, "SIGKILL", { platform }), now = Date.now, sleep = (ms) => new Promise((done) => setTimeout(done, ms)) } = {}) {
|
|
1312
1350
|
const { directory, processId } = resolveAvdProcess(avdName, {
|
|
1313
1351
|
platform,
|
|
1314
1352
|
resolveDirectory,
|
|
1315
1353
|
readProcessId
|
|
1316
1354
|
});
|
|
1355
|
+
const scan = async () => {
|
|
1356
|
+
const pids = await listProcesses(avdName, platform);
|
|
1357
|
+
if (pids === null) throw new Error(`Could not read the process table to verify that owned AVD ${avdName} stopped.`);
|
|
1358
|
+
return pids;
|
|
1359
|
+
};
|
|
1317
1360
|
const identities = /* @__PURE__ */ new Map();
|
|
1318
|
-
for (const pid of
|
|
1361
|
+
for (const pid of await scan()) {
|
|
1319
1362
|
const captured = captureIdentity(pid);
|
|
1320
1363
|
identities.set(pid, captured.ok ? {
|
|
1321
1364
|
pid,
|
|
@@ -1337,20 +1380,20 @@ function waitForAndroidEmulatorShutdown(avdName, shutdown, { timeoutMs = ANDROID
|
|
|
1337
1380
|
if (processId !== null && !identities.has(processId) && processAlive(processId)) pids.push(processId);
|
|
1338
1381
|
return pids;
|
|
1339
1382
|
};
|
|
1340
|
-
const waitUntil = (until) => {
|
|
1383
|
+
const waitUntil = async (until) => {
|
|
1341
1384
|
for (;;) {
|
|
1342
1385
|
if (running().length === 0) return true;
|
|
1343
1386
|
const remaining = until - now();
|
|
1344
1387
|
if (remaining <= 0) return false;
|
|
1345
|
-
sleep(Math.min(pollMs, remaining));
|
|
1388
|
+
await sleep(Math.min(pollMs, remaining));
|
|
1346
1389
|
}
|
|
1347
1390
|
};
|
|
1348
1391
|
const started = now();
|
|
1349
1392
|
if (shutdown) {
|
|
1350
1393
|
const deadline = started + timeoutMs;
|
|
1351
1394
|
const shutdownTimeoutMs = deadline - now();
|
|
1352
|
-
if (shutdownTimeoutMs > 0) shutdown(shutdownTimeoutMs);
|
|
1353
|
-
waitUntil(deadline);
|
|
1395
|
+
if (shutdownTimeoutMs > 0) await shutdown(shutdownTimeoutMs);
|
|
1396
|
+
await waitUntil(deadline);
|
|
1354
1397
|
}
|
|
1355
1398
|
for (const name of ["SIGTERM", "SIGKILL"]) {
|
|
1356
1399
|
const verified = running().filter((pid) => {
|
|
@@ -1359,13 +1402,13 @@ function waitForAndroidEmulatorShutdown(avdName, shutdown, { timeoutMs = ANDROID
|
|
|
1359
1402
|
});
|
|
1360
1403
|
if (verified.length === 0) break;
|
|
1361
1404
|
for (const pid of verified) try {
|
|
1362
|
-
signal(pid, name);
|
|
1405
|
+
await signal(pid, name);
|
|
1363
1406
|
} catch {}
|
|
1364
1407
|
const graceMs = name === "SIGTERM" && !shutdown ? timeoutMs : signalGraceMs;
|
|
1365
|
-
if (waitUntil(now() + graceMs)) break;
|
|
1408
|
+
if (await waitUntil(now() + graceMs)) break;
|
|
1366
1409
|
}
|
|
1367
1410
|
const left = new Set(running());
|
|
1368
|
-
for (const pid of
|
|
1411
|
+
for (const pid of await scan()) {
|
|
1369
1412
|
const record = identities.get(pid);
|
|
1370
1413
|
if (record === void 0 || (record === null ? processAlive(pid) : inspectIdentity(record) !== "gone")) left.add(pid);
|
|
1371
1414
|
}
|
|
@@ -1380,10 +1423,10 @@ function waitForAndroidEmulatorShutdown(avdName, shutdown, { timeoutMs = ANDROID
|
|
|
1380
1423
|
}
|
|
1381
1424
|
if (platform === "win32" && processId !== null) {
|
|
1382
1425
|
const handlerDeadline = now() + CRASH_HANDLER_EXIT_TIMEOUT_MS;
|
|
1383
|
-
for (const handler of crashHandlerPids(processId)) {
|
|
1384
|
-
while (processAlive(handler) && now() < handlerDeadline) sleep(pollMs);
|
|
1426
|
+
for (const handler of await crashHandlerPids(processId)) {
|
|
1427
|
+
while (processAlive(handler) && now() < handlerDeadline) await sleep(pollMs);
|
|
1385
1428
|
if (processAlive(handler)) {
|
|
1386
|
-
killCrashHandler(handler);
|
|
1429
|
+
await killCrashHandler(handler);
|
|
1387
1430
|
if (processAlive(handler)) throw new Error(`Crashpad handler ${handler} for owned AVD ${avdName} stayed alive.`);
|
|
1388
1431
|
}
|
|
1389
1432
|
}
|
|
@@ -1405,8 +1448,47 @@ function getAvdNameForSerial(serial, { timeoutMs = EMU_AVD_NAME_TIMEOUT_MS } = {
|
|
|
1405
1448
|
if (!out) return null;
|
|
1406
1449
|
return out.split("\n")[0]?.trim() || null;
|
|
1407
1450
|
}
|
|
1408
|
-
function
|
|
1409
|
-
|
|
1451
|
+
async function getAvdNameForSerialAsync(serial, { timeoutMs = EMU_AVD_NAME_TIMEOUT_MS } = {}) {
|
|
1452
|
+
const out = await getExecutor().runFileQuietAsync(androidToolPath("adb"), [
|
|
1453
|
+
"-s",
|
|
1454
|
+
serial,
|
|
1455
|
+
"emu",
|
|
1456
|
+
"avd",
|
|
1457
|
+
"name"
|
|
1458
|
+
], {
|
|
1459
|
+
timeoutMs: Math.min(timeoutMs, EMU_AVD_NAME_TIMEOUT_MS),
|
|
1460
|
+
killSignal: "SIGKILL"
|
|
1461
|
+
});
|
|
1462
|
+
if (!out) return null;
|
|
1463
|
+
return out.split("\n")[0]?.trim() || null;
|
|
1464
|
+
}
|
|
1465
|
+
/** `resolveOwnedAvdSerial` without blocking the event loop, with the same reads and the same timeout budget. */
|
|
1466
|
+
async function resolveOwnedAvdSerialAsync(avdName, opts = {}) {
|
|
1467
|
+
return ownedAvdSerialResolverAsync(opts)(avdName);
|
|
1468
|
+
}
|
|
1469
|
+
/** Shares bounded asynchronous AVD, adb and emulator-name reads across the requested AVDs. */
|
|
1470
|
+
function ownedAvdSerialResolverAsync({ timeoutMs } = {}) {
|
|
1471
|
+
const started = Date.now();
|
|
1472
|
+
const remaining = () => ({ timeoutMs: timeoutMs === void 0 ? void 0 : Math.max(MIN_LOOKUP_TIMEOUT_MS, timeoutMs - (Date.now() - started)) });
|
|
1473
|
+
const avds = once(() => listAvdsAsync(remaining()));
|
|
1474
|
+
const adb = once(() => listAdbDevicesAsync(remaining()));
|
|
1475
|
+
const names = /* @__PURE__ */ new Map();
|
|
1476
|
+
const avdNameOf = (serial) => {
|
|
1477
|
+
let name = names.get(serial);
|
|
1478
|
+
if (!name) {
|
|
1479
|
+
name = getAvdNameForSerialAsync(serial, remaining());
|
|
1480
|
+
names.set(serial, name);
|
|
1481
|
+
}
|
|
1482
|
+
return name;
|
|
1483
|
+
};
|
|
1484
|
+
return async (avdName) => {
|
|
1485
|
+
if (!(await avds()).includes(avdName)) return { missing: true };
|
|
1486
|
+
if (!isStimOwnedAvd(avdName)) return { notOwned: true };
|
|
1487
|
+
const devices = await adb();
|
|
1488
|
+
const candidates = [...devices.emulators, ...devices.unhealthy.filter((entry) => entry.kind === "emulator" && entry.consolePort !== void 0)];
|
|
1489
|
+
for (const candidate of candidates) if (await avdNameOf(candidate.serial) === avdName) return { serial: candidate.serial };
|
|
1490
|
+
return { notRunning: true };
|
|
1491
|
+
};
|
|
1410
1492
|
}
|
|
1411
1493
|
function once(read) {
|
|
1412
1494
|
let result;
|
|
@@ -1448,4 +1530,4 @@ function ownedAvdSerialResolver({ timeoutMs } = {}) {
|
|
|
1448
1530
|
};
|
|
1449
1531
|
}
|
|
1450
1532
|
//#endregion
|
|
1451
|
-
export {
|
|
1533
|
+
export { resolvePhysicalDevice as $, listAdbDevicesAsync as A, ownedAvdMatchesConfiguration as B, emulatorFailureRemedy as C, getAvdNameForSerialAsync as D, getAvdNameForSerial as E, listOrphanedAvdDirectories as F, parseAvdDeviceProfile as G, ownedAvdSerialResolver as H, memoizeEmulatorProbe as I, pickDefaultSystemImage as J, parseAvdSystemImage as K, nextConsolePort as L, listAvds as M, listAvdsAsync as N, hostSystemImageArch as O, listInstalledSystemImages as P, resolveOwnedAvdSerialAsync as Q, ownedAvdDeviceProfile as R, emulatorDiskSpaceRemedy as S, findBuildTool as T, ownedAvdSerialResolverAsync as U, ownedAvdName as V, ownedAvdSystemImage as W, profileNeedsFoldFeature as X, probeEmulatorSerial as Y, resetAdoptedAvd as Z, avdStorageRoots as _, removeParkedAfter as _t, androidDeviceAbi as a, wipeAvdUserData as at, createOwnedAvd as b, androidPoolNoCandidatesRefusal as c, isStimOwnedSim as ct, androidToolPath as d, dropParked as dt, shutdownAndroidEmulator as et, assertOwnedAvdStopped as f, eraseParkedAfter as ft, avdPoolConfiguration as g, readParked as gt, avdPathExists as h, parkedMaxSetting as ht, androidDataFreeBytes as i, waitForBoot as it, listAvdDeviceProfiles as j, listAdbDevices as k, androidSystemImageAbi as l, POOL_SETTING_REMEDY as lt, avdNameAbsent as m, parkSim as mt, OWNED_AVD_CONFIG_DEFAULTS as n, trimAndroidCaches as nt, androidHome as o, configuredAndroidEmulatorApp as ot, avdIniPaths as p, isLegacyDeletionClaim as pt, physicalDeviceModel as q, androidBuildToolName as r, waitForAndroidEmulatorShutdown as rt, androidPoolCandidates as s, isStimOwnedAvd as st, DEFAULT_AVD_DEVICE_PROFILE as t, systemImageSupportsFold as tt, androidToolCwd as u, adoptParked as ut, bootAndroidEmulator as v, selectParked as vt, extractEmulatorFailure as w, deleteAvd as x, configureNewOwnedAvd as y, ownedAvdDirectory as z };
|