stim 1.20.2 → 1.22.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 +141 -8
- package/dist/acquire-artifact-Co2k4f7O.mjs +171 -0
- package/dist/act-DsuqEkiM.mjs +2801 -0
- package/dist/activity-CMLmzp7o.mjs +1397 -0
- package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-DUFaTMdd.mjs} +23 -67
- package/dist/{android-DCKZrNvV.mjs → android-ByRMUoiJ.mjs} +157 -93
- package/dist/{android-Mz_Inn3w.mjs → android-C7sVmyI9.mjs} +299 -116
- package/dist/{android-Dlzxshgp.mjs → android-DGkNqa_c.mjs} +5 -5
- package/dist/{android-HqP1_vB_.mjs → android-DR5lZ2Az.mjs} +2 -2
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-ngferVq2.mjs} +7 -6
- package/dist/android-project-BCAAmMwz.mjs +12 -0
- package/dist/android-project-DVWyCbWU.d.mts +391 -0
- package/dist/api.d.mts +810 -64
- package/dist/api.mjs +782 -1
- package/dist/{artifact-HSwkIWEQ.mjs → artifact-8EY8SAPw.mjs} +240 -213
- package/dist/{artifact-D3czlUvT.mjs → artifact-DJPy518Y.mjs} +203 -164
- package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
- package/dist/{browser-web-CA-F1GQo.mjs → browser-web-Bcv99PBM.mjs} +194 -64
- package/dist/budget-Cvwn54qV.mjs +9285 -0
- package/dist/{build-DYDbfkk5.mjs → build-CabC3G23.mjs} +153 -98
- package/dist/build-cache-Dv7RN200.mjs +602 -0
- package/dist/build-plan-DUC8Ka9y.mjs +248 -0
- package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DSeQjt-Q.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-zdKiYQ3E.mjs → ccache-Btwc36-I.mjs} +10 -9
- package/dist/{cdp-Dq_ypAlJ.mjs → cdp-3fwICjzi.mjs} +18 -5
- package/dist/{chrome-BnzZMqsR.mjs → chrome-Bbw689-6.mjs} +7 -4
- package/dist/{cli-CLP3diBm.mjs → cli-CHZa9Lvk.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/client-OyRoEuSr.mjs +1577 -0
- package/dist/collector-run.d.mts +4 -40
- package/dist/collector-run.mjs +9 -8
- package/dist/{command-output-BTy8hZ0F.mjs → command-output-gwpm28fu.mjs} +1 -1
- package/dist/config-DlrsduwG.mjs +955 -0
- package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-x9rN6bhs.mjs} +14 -4
- package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-1I9KZT1Y.mjs} +20 -5
- package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
- package/dist/{dev-client-DAWVIGBu.mjs → dev-client-BSDR5h3F.mjs} +2 -2
- package/dist/{device-BECOiufl.mjs → device-B-L3Fbxy.mjs} +91 -34
- package/dist/device-DklWZLqb.mjs +1068 -0
- package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-DK5_EwRS.mjs} +42 -13
- package/dist/device-host-worker.mjs +76 -79
- package/dist/{device-ios-COSi6oS1.mjs → device-ios-DoB6KFCO.mjs} +77 -51
- package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-xJPQ_QQG.mjs} +14 -26
- package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-BMkdsefq.mjs} +5 -5
- package/dist/{doctor-kfMBnUw6.mjs → doctor-Bo7BXLux.mjs} +271 -320
- package/dist/{doctor-CB8oZKCk.mjs → doctor-D5_EzwfA.mjs} +186 -91
- package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
- package/dist/doctor-fingerprint.mjs +19 -0
- package/dist/doctor-thjWAV0z.mjs +2 -0
- package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-N2wDotwQ.mjs} +40 -21
- package/dist/{eas-build-JyfqyHfC.mjs → eas-build-CwknaQYj.mjs} +53 -20
- package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-CSgAulr5.mjs} +41 -214
- package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-DlY_serQ.mjs} +230 -11
- package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-DBWO2rxE.mjs} +172 -82
- package/dist/exec-DEoAhcze.mjs +858 -0
- package/dist/exec-DnYc4HGH.d.mts +78 -0
- package/dist/{gc-qWOMdnER.mjs → gc-CXxN-4SE.mjs} +1091 -1029
- package/dist/gc-DnNDQyaP.mjs +3 -0
- package/dist/{guide-G9cAbVAc.mjs → guide-Br0LEfKy.mjs} +1165 -297
- package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-B-9f-jkd.mjs} +10 -8
- package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DZAPrcro.mjs} +34 -19
- package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
- package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-FIRx9X2f.mjs} +77 -43
- package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-_awYSpfv.mjs} +35 -22
- package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-BdzE668-.mjs} +49 -27
- package/dist/idle-C4cZ757K.d.mts +24 -0
- package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DDg3SdvY.mjs} +11 -10
- package/dist/ios-CDvlmUs7.d.mts +24 -0
- package/dist/{ios-BwVCF7oA.mjs → ios-Ds1clbIt.mjs} +8 -8
- package/dist/{ios-device-D7pi2Sca.mjs → ios-device--h_-8ENa.mjs} +51 -26
- package/dist/{ios-device-B5veSDDQ.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
- package/dist/{ios-RkW4pnQf.mjs → ios-hcBpnEGk.mjs} +200 -93
- package/dist/{ios-Ce7bc7br.mjs → ios-pm4nL6By.mjs} +160 -108
- package/dist/{ios-project-K9hY_Jab.mjs → ios-project-CZhKODF3.mjs} +13 -13
- package/dist/ios-signing-BtAffm0A.mjs +489 -0
- package/dist/{ios-state-CBLe1xYw.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
- package/dist/{ios-nOLJGVdy.mjs → ios-xtlRHaeB.mjs} +1 -1
- package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Bwhh4S7V.mjs} +30 -25
- package/dist/{launch-C3qJ6Agb.mjs → launch-BjxemNpK.mjs} +85 -543
- package/dist/{launch-F4sOqAhB.mjs → launch-CCzXlc8r.mjs} +91 -90
- package/dist/logs-BfwwadsZ.mjs +479 -0
- package/dist/logs-jTS_lHSo.mjs +248 -0
- package/dist/{macos-D7uDvO-z.mjs → macos-DVlSSyUg.mjs} +1 -1
- package/dist/macos-NfV2D7dO.mjs +694 -0
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +123 -248
- package/dist/{metro-DnCEjCxs.mjs → metro-DiXtA3Ty.mjs} +107 -30
- package/dist/metro-gateway-CKZqKqx7.mjs +209 -0
- package/dist/{named-ports-4WopRPg-.mjs → named-ports-DkEzOfzO.mjs} +42 -90
- package/dist/native-android-CqgnOgsT.mjs +645 -0
- package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
- package/dist/native-gradle-inputs-Dnh84Zbd.mjs +211 -0
- package/dist/native-inputs-TRTTTRxt.mjs +91 -0
- package/dist/native-run-NwUuxbkg.mjs +276 -0
- package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-B7KIafpM.mjs} +11 -9
- package/dist/native-source-Y0yLhFyQ.mjs +133 -0
- package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-D_VOfFL7.mjs} +26 -18
- package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-BYDOHWLN.mjs} +104 -60
- package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
- package/dist/offload-worker.d.mts +59 -41
- package/dist/offload-worker.mjs +478 -115
- package/dist/operation-exec-BW0em61G.mjs +171 -0
- package/dist/{ownership-DCtw_2IA.mjs → ownership-C5fo5Edb.mjs} +3 -3
- package/dist/{page-DRHy329N.mjs → page-DBL2PiUU.mjs} +12 -5
- package/dist/paths-BsJMoPP2.mjs +12 -0
- package/dist/paths-DQtTgsBf.mjs +42 -0
- package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BnGgJRRZ.mjs} +5 -5
- package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-DIsMtN-d.mjs} +15 -11
- package/dist/{ports-DdSUicVo.mjs → ports-Cy1RkmuQ.mjs} +3 -3
- package/dist/prebuild-D4JoEAEs.mjs +484 -0
- package/dist/{project-_phNIJfs.mjs → project-wM_XFTvE.mjs} +65 -37
- package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-W1IuLXDt.mjs} +102 -20
- package/dist/pull-request-eODyIqZF.d.mts +124 -0
- package/dist/pull-requests.d.mts +2 -120
- package/dist/pull-requests.mjs +2 -2
- package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-6OZ7MSM7.mjs} +121 -72
- package/dist/{gradle-DSrXb6lG.mjs → react-native-build-Dvd8hC21.mjs} +292 -15
- package/dist/react-native-doctor-DsoSF1Y9.mjs +234 -0
- package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-4u1Rn-GR.mjs} +71 -39
- package/dist/{recordings-D0d5aQt0.mjs → recordings-CQmfzAh7.mjs} +12 -9
- package/dist/registration-BcRgF6Ox.mjs +51 -0
- package/dist/{reload-C8JhxjSh.mjs → reload-BzkYabB-.mjs} +94 -47
- package/dist/reload-D7AVlb8N.mjs +2 -0
- package/dist/{remote-BiR6aYjy.mjs → remote-DjGDmlTZ.mjs} +26 -18
- package/dist/result-D2Ykz_iD.mjs +435 -0
- package/dist/{run-BtPgpKks.mjs → run-DidHghD1.mjs} +5 -5
- package/dist/selection-DSMbWEX2.mjs +620 -0
- package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CafzuyFB.mjs} +3 -4
- package/dist/{server-command-CTtCkmcQ.mjs → server-command-C6QjeupS.mjs} +14 -7
- package/dist/{server-expo-DsguMGUF.mjs → server-expo-CrjB29pq.mjs} +54 -11
- package/dist/server-expo-D58c9L0M.mjs +2 -0
- package/dist/{settings-B717odTD.mjs → settings-C7O8A6ZI.mjs} +309 -119
- package/dist/settings-DpR-1Wnn.mjs +114 -0
- package/dist/settings-write-CzD60rOD.mjs +360 -0
- package/dist/settings.schema.json +176 -16
- package/dist/{simslim-CCr3rE-A.mjs → simslim-BNckWpXi.mjs} +14 -12
- package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-CbfmNgM6.mjs} +15 -20
- package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
- package/dist/stage-Bps5oius.mjs +200 -0
- package/dist/{start-TXeMmmO2.mjs → start-Br-oxqMD.mjs} +1 -1
- package/dist/start-EojN4WFz.mjs +1364 -0
- package/dist/{state-D1Icyjlu.mjs → state--smjFSTL.mjs} +55 -13
- package/dist/{state-CG_OFoaA.mjs → state-08I3hw3_.mjs} +3 -2
- package/dist/{stats-BoY5sEPU.mjs → stats-D3GerlFW.mjs} +7 -13
- package/dist/stats-report-BzaPrRm6.mjs +16 -0
- package/dist/{status-BTA7kKiQ.mjs → status-BRROykC8.mjs} +7 -5
- package/dist/status-EvrK72L2.mjs +2 -0
- package/dist/{status-WgFbkRzj.mjs → status-WBDajew2.mjs} +554 -452
- package/dist/{status-watch-C23ILtf9.mjs → status-watch-Bg_u-pwR.mjs} +222 -25
- package/dist/status-worker.d.mts +1 -0
- package/dist/status-worker.mjs +19 -0
- package/dist/stim-desktop-D5OGpYZM.mjs +112 -0
- package/dist/{stop-DR6VoDIk.mjs → stop-DTZ9uTw3.mjs} +2 -2
- package/dist/{stop-DPEhunlw.mjs → stop-Dky10AEJ.mjs} +33 -23
- package/dist/{stop-BNmBMi1F.mjs → stop-Mv6W9FAk.mjs} +137 -98
- package/dist/supervisor-run.d.mts +8 -17
- package/dist/supervisor-run.mjs +56 -28
- package/dist/{support-CwjbFs9H.mjs → support-CNioewsd.mjs} +14 -14
- package/dist/{support-DMTqj3Hm.mjs → support-yUiOjnVY.mjs} +20 -13
- package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
- package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
- package/dist/toolchain-BY8X8HXx.mjs +2 -0
- package/dist/toolchain-DpJMHq0n.mjs +876 -0
- package/dist/{trigger-CigAYjeL.mjs → trigger-Cbyc41d_.mjs} +21 -6
- package/dist/trigger-yb_nFzPF.mjs +2 -0
- package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-CA3TgT3-.mjs} +263 -156
- package/dist/web-CZ07gd77.mjs +2 -0
- package/dist/{web-BDBMxDpx.mjs → web-DKx6yoFA.mjs} +20 -14
- package/dist/web-run.mjs +13 -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-state-DJt_MMvf.mjs → workspace-state-U08dEzhG.mjs} +62 -58
- package/dist/{workspaces-C36s2jb9.mjs → workspaces-CpANmBlq.mjs} +1723 -1286
- package/dist/{worktree-CgvJYJ-Q.mjs → worktree-CHecZ4Oq.mjs} +1097 -547
- package/dist/worktree-ZqZVjD9K.mjs +2 -0
- package/dist/xcode-BXn9-xYx.mjs +896 -0
- package/package.json +7 -5
- package/shim/android-audio/Main.java +24 -0
- package/shim/android-audio/README.md +17 -0
- package/shim/android-audio.jar +0 -0
- 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/macos-Ch5VJmcS.mjs +0 -584
- package/dist/metro-gateway-CX9Xlkq2.mjs +0 -103
- package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
- package/dist/native-android-D5qc3-_v.mjs +0 -226
- package/dist/native-gradle-inputs-BsLRrl7u.mjs +0 -349
- 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/settings-vk3mJGSm.d.mts +0 -13
- package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
- package/dist/stage-KNTQopqv.mjs +0 -157
- package/dist/start-BWqzODpb.mjs +0 -1116
- package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
- package/dist/swiftpm-macos-DRNVJWlb.mjs +0 -119
- 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,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { c as declareSpawnsOn, f as stopDeclaringSpawnsOn, g as process_identity_exports, r as WorkspaceProcessCleanupError, t as getExecutor, x as ownership_claim_exports } from "./exec-DEoAhcze.mjs";
|
|
2
|
+
import { C as saveConfig, D as withConfigLock$1, G as projectDeviceSlots, H as deviceSlotPlatforms, K as removeSlotDevice, O as withConfigLockAsync$1, _ as loadConfig$1, c as ensureConfig, d as getConfigDir, f as getConfigPath$1, z as assignSlotDevice } from "./config-DlrsduwG.mjs";
|
|
3
|
+
import { n as runOperationFileQuiet, t as runOperationFile, u as cancellableSleep } from "./operation-exec-BW0em61G.mjs";
|
|
4
|
+
import { c as androidDataPartitionSizeBytes } from "./settings-C7O8A6ZI.mjs";
|
|
5
|
+
import { c as pidExists, p as signalProcessTreeAsync } from "./metro-DiXtA3Ty.mjs";
|
|
6
|
+
import { i as recordCreatedDevice, r as readCreatedDevices$1, t as forgetCreatedDevice } from "./created-devices-x9rN6bhs.mjs";
|
|
7
|
+
import { i as stimDesktopInstalledAsync, n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-D5OGpYZM.mjs";
|
|
8
|
+
import { isDeepStrictEqual } from "node:util";
|
|
7
9
|
import { join } from "node:path";
|
|
8
|
-
import {
|
|
10
|
+
import { ambientEnv, ambientWrite } from "@stim-cli/core";
|
|
9
11
|
import { ANDROID_EMULATOR_APPS, getParkedMax, isJsonObject, loadConfig, settingDefinition } from "@stim-cli/core/state";
|
|
12
|
+
import { dirname as dirname$1, isAbsolute as isAbsolute$1, join as join$1, resolve as resolve$1 } from "path";
|
|
10
13
|
import { existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
|
|
14
|
+
import { rm } from "node:fs/promises";
|
|
11
15
|
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
16
|
//#region src/devices/sim-pool.ts
|
|
31
17
|
const POOL_SETTING_REMEDY = "Run `stim guide settings` for the device pool bounds and where it can be set.";
|
|
32
18
|
function parkedMaxSetting(platform, options = {}) {
|
|
@@ -140,11 +126,11 @@ function claimParkedOperation(platform, udid) {
|
|
|
140
126
|
if (attempt.pending) (0, ownership_claim_exports.releaseClaim)(attempt.pending);
|
|
141
127
|
return attempt.acquired ?? null;
|
|
142
128
|
}
|
|
143
|
-
function removeParkedAfter(platform, udid, beforeRemove) {
|
|
144
|
-
return settleParkedAfter(platform, udid, beforeRemove, null);
|
|
129
|
+
function removeParkedAfter(platform, udid, beforeRemove, operation) {
|
|
130
|
+
return settleParkedAfter(platform, udid, beforeRemove, null, operation);
|
|
145
131
|
}
|
|
146
|
-
function eraseParkedAfter(platform, udid, erase) {
|
|
147
|
-
return settleParkedAfter(platform, udid, erase, erasedRecord);
|
|
132
|
+
function eraseParkedAfter(platform, udid, erase, operation) {
|
|
133
|
+
return settleParkedAfter(platform, udid, erase, erasedRecord, operation);
|
|
148
134
|
}
|
|
149
135
|
function erasedRecord(record) {
|
|
150
136
|
const erased = { ...record };
|
|
@@ -154,11 +140,14 @@ function erasedRecord(record) {
|
|
|
154
140
|
delete erased.schemeApprovals;
|
|
155
141
|
return erased;
|
|
156
142
|
}
|
|
157
|
-
function settleParkedAfter(platform, udid, action, keep) {
|
|
143
|
+
async function settleParkedAfter(platform, udid, action, keep, operation) {
|
|
144
|
+
operation?.signal.throwIfAborted();
|
|
158
145
|
const claim = claimParkedOperation(platform, udid);
|
|
159
146
|
if (!claim) return null;
|
|
147
|
+
let retained = false;
|
|
148
|
+
if (operation) declareSpawnsOn(operation, claim);
|
|
160
149
|
try {
|
|
161
|
-
const claimed =
|
|
150
|
+
const claimed = await withConfigLockAsync$1(() => {
|
|
162
151
|
const cfg = loadConfig$1();
|
|
163
152
|
if (!cfg) return null;
|
|
164
153
|
const records = readParked(platform, { config: cfg });
|
|
@@ -180,23 +169,30 @@ function settleParkedAfter(platform, udid, action, keep) {
|
|
|
180
169
|
record,
|
|
181
170
|
marked
|
|
182
171
|
};
|
|
183
|
-
});
|
|
172
|
+
}, operation?.signal);
|
|
184
173
|
if (!claimed) return null;
|
|
185
174
|
let completed = false;
|
|
186
175
|
let started = false;
|
|
187
176
|
let settled = null;
|
|
188
177
|
try {
|
|
178
|
+
operation?.signal.throwIfAborted();
|
|
189
179
|
(0, ownership_claim_exports.markClaimChildPending)(claim);
|
|
190
180
|
try {
|
|
191
|
-
action(claimed.record, () => {
|
|
181
|
+
await action(claimed.record, () => {
|
|
192
182
|
started = true;
|
|
193
183
|
});
|
|
184
|
+
} catch (cause) {
|
|
185
|
+
if (cause instanceof WorkspaceProcessCleanupError || cause instanceof Error && "reportCleanup" in cause) {
|
|
186
|
+
retained = true;
|
|
187
|
+
throw Object.assign(new WorkspaceProcessCleanupError([.../* @__PURE__ */ new Set([claim, ...cause instanceof WorkspaceProcessCleanupError ? cause.claims : []])], cause.message, "Verify the parked-device operation and its descendants have stopped."), { reportCleanup: true });
|
|
188
|
+
}
|
|
189
|
+
throw cause;
|
|
194
190
|
} finally {
|
|
195
|
-
(0, ownership_claim_exports.clearClaimChild)(claim);
|
|
191
|
+
if (!retained) (0, ownership_claim_exports.clearClaimChild)(claim);
|
|
196
192
|
}
|
|
197
193
|
completed = true;
|
|
198
194
|
} finally {
|
|
199
|
-
|
|
195
|
+
if (!retained) await withConfigLockAsync$1(() => {
|
|
200
196
|
const cfg = loadConfig$1();
|
|
201
197
|
if (!cfg) return;
|
|
202
198
|
const records = readParked(platform, { config: cfg });
|
|
@@ -210,11 +206,12 @@ function settleParkedAfter(platform, udid, action, keep) {
|
|
|
210
206
|
}
|
|
211
207
|
return settled;
|
|
212
208
|
} finally {
|
|
213
|
-
(
|
|
209
|
+
if (operation) stopDeclaringSpawnsOn(operation, claim);
|
|
210
|
+
if (!retained) (0, ownership_claim_exports.releaseClaim)(claim);
|
|
214
211
|
}
|
|
215
212
|
}
|
|
216
|
-
function dropParked(platform, udid) {
|
|
217
|
-
return removeParkedAfter(platform, udid, () => {}) !== null;
|
|
213
|
+
async function dropParked(platform, udid, operation) {
|
|
214
|
+
return await removeParkedAfter(platform, udid, () => {}, operation) !== null;
|
|
218
215
|
}
|
|
219
216
|
//#endregion
|
|
220
217
|
//#region src/devices/device-ownership.ts
|
|
@@ -246,6 +243,27 @@ function isStimOwnedAvd(name) {
|
|
|
246
243
|
return name.startsWith("stim-") && isStimOwnedDevice("android", name);
|
|
247
244
|
}
|
|
248
245
|
//#endregion
|
|
246
|
+
//#region src/devices/android-emulator-viewer.ts
|
|
247
|
+
async function configuredAndroidEmulatorApp(platform = process.platform, env) {
|
|
248
|
+
let value = loadConfig$1()?.androidEmulatorApp;
|
|
249
|
+
if (value === void 0) {
|
|
250
|
+
const installed = await stimDesktopInstalledAsync(platform, env);
|
|
251
|
+
value = settingDefault(settingDefinition("androidEmulatorApp"), () => installed).value;
|
|
252
|
+
}
|
|
253
|
+
if (ANDROID_EMULATOR_APPS.includes(value)) return value;
|
|
254
|
+
const error = /* @__PURE__ */ new Error("Invalid androidEmulatorApp in machine config. Use \"emulator\" or \"stim-desktop\".");
|
|
255
|
+
Object.assign(error, { code: "STIM_BAD_ARG" });
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
258
|
+
async function openEmulatorInStimDesktop(serial) {
|
|
259
|
+
await getExecutor().runFileQuietAsync("open", [
|
|
260
|
+
"-g",
|
|
261
|
+
"-a",
|
|
262
|
+
"Stim",
|
|
263
|
+
`stim-desktop://open?serial=${serial}`
|
|
264
|
+
], STIM_DESKTOP_OPEN_OPTIONS);
|
|
265
|
+
}
|
|
266
|
+
//#endregion
|
|
249
267
|
//#region src/devices/android.ts
|
|
250
268
|
const ANDROID_ABIS = /* @__PURE__ */ new Set([
|
|
251
269
|
"armeabi-v7a",
|
|
@@ -254,11 +272,13 @@ const ANDROID_ABIS = /* @__PURE__ */ new Set([
|
|
|
254
272
|
"x86_64"
|
|
255
273
|
]);
|
|
256
274
|
const DEFAULT_AVD_DEVICE_PROFILE = String(settingDefinition("android.deviceProfile")?.default);
|
|
257
|
-
function androidHome(env =
|
|
275
|
+
function androidHome(env = ambientEnv()) {
|
|
258
276
|
const configured = env.ANDROID_HOME || env.ANDROID_SDK_ROOT;
|
|
259
277
|
if (configured) return configured;
|
|
260
|
-
|
|
261
|
-
return join$1(
|
|
278
|
+
const home = process.platform === "win32" ? env.USERPROFILE || homedir() : env.HOME || homedir();
|
|
279
|
+
if (process.platform === "win32") return join$1(env.LOCALAPPDATA || join$1(home, "AppData", "Local"), "Android", "Sdk");
|
|
280
|
+
if (process.platform === "linux") return join$1(home, "Android", "Sdk");
|
|
281
|
+
return join$1(home, "Library", "Android", "sdk");
|
|
262
282
|
}
|
|
263
283
|
const SDK_TOOL_LOCATIONS = {
|
|
264
284
|
emulator: ["emulator", "emulator"],
|
|
@@ -282,11 +302,11 @@ const WINDOWS_SDK_TOOL_EXTENSIONS = {
|
|
|
282
302
|
avdmanager: ".bat",
|
|
283
303
|
sdkmanager: ".bat"
|
|
284
304
|
};
|
|
285
|
-
function androidToolPath(tool, platform = process.platform) {
|
|
305
|
+
function androidToolPath(tool, platform = process.platform, env = ambientEnv()) {
|
|
286
306
|
const location = SDK_TOOL_LOCATIONS[tool];
|
|
287
307
|
const bare = location.at(-1);
|
|
288
308
|
const name = platform === "win32" ? `${bare}${WINDOWS_SDK_TOOL_EXTENSIONS[tool]}` : bare;
|
|
289
|
-
const abs = join$1(androidHome(), ...location.slice(0, -1), name);
|
|
309
|
+
const abs = join$1(androidHome(env), ...location.slice(0, -1), name);
|
|
290
310
|
return existsSync(abs) ? abs : bare;
|
|
291
311
|
}
|
|
292
312
|
const WINDOWS_BUILD_TOOL_EXTENSIONS = { apksigner: ".bat" };
|
|
@@ -333,8 +353,8 @@ function findBuildTool(tools, { home = androidHome(), readDir = readdirSync, exi
|
|
|
333
353
|
}
|
|
334
354
|
return null;
|
|
335
355
|
}
|
|
336
|
-
function listInstalledSystemImages(onUnreadable) {
|
|
337
|
-
const root = join$1(androidHome(), "system-images");
|
|
356
|
+
function listInstalledSystemImages(onUnreadable, env = ambientEnv()) {
|
|
357
|
+
const root = join$1(androidHome(env), "system-images");
|
|
338
358
|
const images = [];
|
|
339
359
|
const list = (dir) => {
|
|
340
360
|
try {
|
|
@@ -402,9 +422,9 @@ async function createOwnedAvd(label, { systemImage, deviceProfile = DEFAULT_AVD_
|
|
|
402
422
|
"--device",
|
|
403
423
|
deviceProfile
|
|
404
424
|
];
|
|
405
|
-
let env =
|
|
425
|
+
let env = ambientEnv();
|
|
406
426
|
if (!env.ANDROID_AVD_HOME) {
|
|
407
|
-
const root = avdLookupRoots(env, homedir())[0];
|
|
427
|
+
const root = avdLookupRoots(env, (process.platform === "win32" ? env.USERPROFILE : env.HOME) || homedir())[0];
|
|
408
428
|
mkdirSync(root, { recursive: true });
|
|
409
429
|
env = {
|
|
410
430
|
...env,
|
|
@@ -480,6 +500,16 @@ function listAvdDeviceProfiles() {
|
|
|
480
500
|
"-c"
|
|
481
501
|
], { timeoutMs: AVDMANAGER_LIST_TIMEOUT_MS }));
|
|
482
502
|
}
|
|
503
|
+
async function listAvdDeviceProfilesAsync({ signal } = {}) {
|
|
504
|
+
return parseAvdList(await getExecutor().runFileAsync(androidToolPath("avdmanager"), [
|
|
505
|
+
"list",
|
|
506
|
+
"device",
|
|
507
|
+
"-c"
|
|
508
|
+
], {
|
|
509
|
+
signal,
|
|
510
|
+
timeoutMs: AVDMANAGER_LIST_TIMEOUT_MS
|
|
511
|
+
}));
|
|
512
|
+
}
|
|
483
513
|
function sanitizeAvdLabel(label) {
|
|
484
514
|
return String(label).replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
485
515
|
}
|
|
@@ -496,10 +526,12 @@ function ownedAvdName(label) {
|
|
|
496
526
|
return `stim-${clean.startsWith("stim-") ? clean.slice(5) : clean}`;
|
|
497
527
|
}
|
|
498
528
|
const AVDMANAGER_DELETE_TIMEOUT_MS = 12e4;
|
|
499
|
-
function deleteAvd(avdName) {
|
|
529
|
+
async function deleteAvd(avdName, operation) {
|
|
530
|
+
operation?.signal.throwIfAborted();
|
|
500
531
|
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
|
|
502
|
-
|
|
532
|
+
const env = operation?.env ?? ambientEnv();
|
|
533
|
+
const root = env.ANDROID_AVD_HOME ? void 0 : avdStorageRoots(env).find((candidate) => avdPathExists(join$1(candidate, `${avdName}.ini`)));
|
|
534
|
+
await runOperationFile(operation, getExecutor(), androidToolPath("avdmanager", process.platform, env), [
|
|
503
535
|
"delete",
|
|
504
536
|
"avd",
|
|
505
537
|
"-n",
|
|
@@ -507,6 +539,7 @@ function deleteAvd(avdName) {
|
|
|
507
539
|
], {
|
|
508
540
|
timeoutMs: AVDMANAGER_DELETE_TIMEOUT_MS,
|
|
509
541
|
killSignal: "SIGKILL",
|
|
542
|
+
cwd: operation?.cwd,
|
|
510
543
|
...root ? { env: { ANDROID_AVD_HOME: root } } : {}
|
|
511
544
|
});
|
|
512
545
|
forgetCreatedDevice("android", avdName);
|
|
@@ -559,6 +592,14 @@ function listAvds({ timeoutMs = ANDROID_LISTING_TIMEOUT_MS } = {}) {
|
|
|
559
592
|
killSignal: "SIGKILL"
|
|
560
593
|
}));
|
|
561
594
|
}
|
|
595
|
+
async function listAvdsAsync({ timeoutMs = ANDROID_LISTING_TIMEOUT_MS, signal, operation } = {}) {
|
|
596
|
+
return parseAvdList(await runOperationFile(operation, getExecutor(), androidToolPath("emulator", process.platform, operation?.env), ["-list-avds"], {
|
|
597
|
+
timeoutMs,
|
|
598
|
+
killSignal: "SIGKILL",
|
|
599
|
+
signal,
|
|
600
|
+
cwd: operation?.cwd
|
|
601
|
+
}));
|
|
602
|
+
}
|
|
562
603
|
/**
|
|
563
604
|
* Working directory for the adb client and the emulator Stim starts. Both leave processes behind
|
|
564
605
|
* that inherit it: the adb server is spawned by whichever client finds none running, and the
|
|
@@ -577,6 +618,14 @@ function listAdbDevices({ timeoutMs = ANDROID_LISTING_TIMEOUT_MS, platform = pro
|
|
|
577
618
|
cwd: androidToolCwd(platform)
|
|
578
619
|
}));
|
|
579
620
|
}
|
|
621
|
+
async function listAdbDevicesAsync({ timeoutMs = ANDROID_LISTING_TIMEOUT_MS, platform = process.platform, signal, operation } = {}) {
|
|
622
|
+
return parseAdbDevices(await runOperationFile(operation, getExecutor(), androidToolPath("adb", platform, operation?.env), ["devices"], {
|
|
623
|
+
timeoutMs,
|
|
624
|
+
killSignal: "SIGKILL",
|
|
625
|
+
cwd: androidToolCwd(platform) ?? operation?.cwd,
|
|
626
|
+
signal
|
|
627
|
+
}));
|
|
628
|
+
}
|
|
580
629
|
const ADB_PROP_TIMEOUT_MS = 5e3;
|
|
581
630
|
const EMULATOR_HARDWARE = /* @__PURE__ */ new Set([
|
|
582
631
|
"ranchu",
|
|
@@ -688,7 +737,7 @@ function nextConsolePort(claimedPorts) {
|
|
|
688
737
|
if (claimedPorts.length === 0) return 5554;
|
|
689
738
|
return Math.max(...claimedPorts) + 2;
|
|
690
739
|
}
|
|
691
|
-
function headlessEmulatorArgs(env =
|
|
740
|
+
function headlessEmulatorArgs(env = ambientEnv(), platform = process.platform, app = "emulator") {
|
|
692
741
|
const args = [];
|
|
693
742
|
if (platform === "darwin" && app === "stim-desktop") args.push("-no-window", "-gpu", "host");
|
|
694
743
|
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 +766,15 @@ function avdIniPaths(root, ini) {
|
|
|
717
766
|
const parsed = parseAvdRootIni(ini);
|
|
718
767
|
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
768
|
}
|
|
720
|
-
function avdStorageRoots() {
|
|
721
|
-
const
|
|
769
|
+
function avdStorageRoots(env = ambientEnv()) {
|
|
770
|
+
const home = process.platform === "win32" ? env.USERPROFILE || homedir() : env.HOME || homedir();
|
|
722
771
|
return [...new Set([
|
|
723
772
|
env.ANDROID_AVD_HOME,
|
|
724
773
|
env.ANDROID_EMULATOR_HOME ? join$1(env.ANDROID_EMULATOR_HOME, "avd") : null,
|
|
725
774
|
env.ANDROID_USER_HOME ? join$1(env.ANDROID_USER_HOME, "avd") : null,
|
|
726
775
|
env.ANDROID_SDK_HOME ? join$1(env.ANDROID_SDK_HOME, ".android", "avd") : null,
|
|
727
776
|
env.ANDROID_SDK_HOME ? join$1(env.ANDROID_SDK_HOME, "avd") : null,
|
|
728
|
-
join$1(
|
|
777
|
+
join$1(home, ".android", "avd")
|
|
729
778
|
].filter((value) => Boolean(value)))];
|
|
730
779
|
}
|
|
731
780
|
function avdPathExists(path) {
|
|
@@ -803,7 +852,7 @@ function avdLookupRoots(env, home) {
|
|
|
803
852
|
];
|
|
804
853
|
return [...new Set(roots.filter((value) => Boolean(value)))];
|
|
805
854
|
}
|
|
806
|
-
function ownedAvdDirectory(avdName, { env =
|
|
855
|
+
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
856
|
if (!/^stim-[A-Za-z0-9._-]+$/.test(avdName)) return null;
|
|
808
857
|
for (const root of avdLookupRoots(env, home)) {
|
|
809
858
|
let ini;
|
|
@@ -831,11 +880,14 @@ const AVD_USER_DATA = [
|
|
|
831
880
|
"cache.img.qcow2",
|
|
832
881
|
"snapshots"
|
|
833
882
|
];
|
|
834
|
-
function wipeAvdUserData(directory) {
|
|
835
|
-
for (const name of AVD_USER_DATA)
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
883
|
+
async function wipeAvdUserData(directory, signal) {
|
|
884
|
+
for (const name of AVD_USER_DATA) {
|
|
885
|
+
signal?.throwIfAborted();
|
|
886
|
+
await rm(join$1(directory, name), {
|
|
887
|
+
recursive: true,
|
|
888
|
+
force: true
|
|
889
|
+
});
|
|
890
|
+
}
|
|
839
891
|
}
|
|
840
892
|
function withAvdConfigOverrides(contents, overrides) {
|
|
841
893
|
const newline = contents.includes("\r\n") ? "\r\n" : "\n";
|
|
@@ -911,16 +963,16 @@ async function resetAdoptedAvd(avdName, serial, keepPackage) {
|
|
|
911
963
|
let firstFailure;
|
|
912
964
|
let unavailableTarget = false;
|
|
913
965
|
const commandTimeout = (timeoutMs) => recoveryDeadline === void 0 ? timeoutMs : Math.max(1, Math.min(timeoutMs, recoveryDeadline - Date.now()));
|
|
914
|
-
const assertTarget = () => {
|
|
915
|
-
const resolved =
|
|
966
|
+
const assertTarget = async () => {
|
|
967
|
+
const resolved = await resolveOwnedAvdSerialAsync(avdName, { timeoutMs: commandTimeout(3e4) });
|
|
916
968
|
unavailableTarget = Boolean(resolved.notRunning);
|
|
917
969
|
if (resolved.serial !== serial) throw new Error(`AVD ${avdName} is no longer running on ${serial}.`);
|
|
918
970
|
};
|
|
919
971
|
for (;;) {
|
|
920
972
|
unavailableTarget = false;
|
|
921
973
|
try {
|
|
922
|
-
assertTarget();
|
|
923
|
-
const packages = exec.
|
|
974
|
+
await assertTarget();
|
|
975
|
+
const packages = (await exec.runFileAsync("adb", [
|
|
924
976
|
"-s",
|
|
925
977
|
serial,
|
|
926
978
|
"shell",
|
|
@@ -928,20 +980,20 @@ async function resetAdoptedAvd(avdName, serial, keepPackage) {
|
|
|
928
980
|
"list",
|
|
929
981
|
"packages",
|
|
930
982
|
"-3"
|
|
931
|
-
], { timeoutMs: commandTimeout(3e4) }).split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((line) => {
|
|
983
|
+
], { timeoutMs: commandTimeout(3e4) })).split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((line) => {
|
|
932
984
|
const match = /^package:([A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)+)$/.exec(line);
|
|
933
985
|
if (!match) throw new Error(`Could not read installed apps on ${avdName}: ${line}`);
|
|
934
986
|
return match[1];
|
|
935
987
|
});
|
|
936
988
|
for (const packageName of packages) {
|
|
937
|
-
assertTarget();
|
|
989
|
+
await assertTarget();
|
|
938
990
|
const args = packageName === keepPackage ? [
|
|
939
991
|
"shell",
|
|
940
992
|
"pm",
|
|
941
993
|
"clear",
|
|
942
994
|
packageName
|
|
943
995
|
] : ["uninstall", packageName];
|
|
944
|
-
const result = exec.
|
|
996
|
+
const result = await exec.runFileAsync("adb", [
|
|
945
997
|
"-s",
|
|
946
998
|
serial,
|
|
947
999
|
...args
|
|
@@ -974,8 +1026,8 @@ function parseDfAvailableBytes(text) {
|
|
|
974
1026
|
const available = lines[1].split(/\s+/)[3];
|
|
975
1027
|
return available && /^\d+$/.test(available) ? Number(available) * 1024 : null;
|
|
976
1028
|
}
|
|
977
|
-
function androidDataFreeBytes(serial) {
|
|
978
|
-
return parseDfAvailableBytes(getExecutor().
|
|
1029
|
+
async function androidDataFreeBytes(serial) {
|
|
1030
|
+
return parseDfAvailableBytes(await getExecutor().runFileQuietAsync("adb", [
|
|
979
1031
|
"-s",
|
|
980
1032
|
serial,
|
|
981
1033
|
"shell",
|
|
@@ -984,8 +1036,8 @@ function androidDataFreeBytes(serial) {
|
|
|
984
1036
|
"/data"
|
|
985
1037
|
], { timeoutMs: 3e4 }));
|
|
986
1038
|
}
|
|
987
|
-
function trimAndroidCaches(serial, desiredFreeBytes) {
|
|
988
|
-
getExecutor().
|
|
1039
|
+
async function trimAndroidCaches(serial, desiredFreeBytes) {
|
|
1040
|
+
await getExecutor().runFileAsync("adb", [
|
|
989
1041
|
"-s",
|
|
990
1042
|
serial,
|
|
991
1043
|
"shell",
|
|
@@ -1010,7 +1062,7 @@ const CRASH_REPORT_MODE_EMULATOR_VERSION = 37;
|
|
|
1010
1062
|
* Where the emulator keeps crashpad's database on Windows: `AndroidEmulator\emu-crash-<version>.db`
|
|
1011
1063
|
* under GetTempPath, which reads TMP before TEMP.
|
|
1012
1064
|
*/
|
|
1013
|
-
function emulatorCrashDatabases(env =
|
|
1065
|
+
function emulatorCrashDatabases(env = ambientEnv()) {
|
|
1014
1066
|
const root = join$1(env.TMP || env.TEMP || tmpdir(), "AndroidEmulator");
|
|
1015
1067
|
try {
|
|
1016
1068
|
return readdirSync(root).filter((name) => /^emu-crash-.*\.db$/.test(name)).map((name) => join$1(root, name));
|
|
@@ -1039,9 +1091,9 @@ function suppressEmulatorCrashConsent({ platform = process.platform, version = e
|
|
|
1039
1091
|
} catch {}
|
|
1040
1092
|
return [];
|
|
1041
1093
|
}
|
|
1042
|
-
function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process.platform, openViewer = true } = {}) {
|
|
1094
|
+
async function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process.platform, openViewer = true } = {}) {
|
|
1043
1095
|
const exec = getExecutor();
|
|
1044
|
-
const app = configuredAndroidEmulatorApp(platform);
|
|
1096
|
+
const app = await configuredAndroidEmulatorApp(platform, ambientEnv());
|
|
1045
1097
|
const child = exec.spawn(androidToolPath("emulator"), [
|
|
1046
1098
|
"-avd",
|
|
1047
1099
|
avdName,
|
|
@@ -1050,7 +1102,7 @@ function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process
|
|
|
1050
1102
|
"-grpc",
|
|
1051
1103
|
String(consolePort + 3e3),
|
|
1052
1104
|
"-grpc-use-token",
|
|
1053
|
-
...headlessEmulatorArgs(
|
|
1105
|
+
...headlessEmulatorArgs(ambientEnv(), platform, openViewer ? app : "stim-desktop"),
|
|
1054
1106
|
...suppressEmulatorCrashConsent({ platform })
|
|
1055
1107
|
], {
|
|
1056
1108
|
cwd: androidToolCwd(platform),
|
|
@@ -1059,7 +1111,7 @@ function bootAndroidEmulator(avdName, consolePort, { logFile, platform = process
|
|
|
1059
1111
|
});
|
|
1060
1112
|
child?.unref?.();
|
|
1061
1113
|
const pid = child?.pid ?? null;
|
|
1062
|
-
if (openViewer && pid !== null && platform === "darwin" && app === "stim-desktop") openEmulatorInStimDesktop(`emulator-${consolePort}`);
|
|
1114
|
+
if (openViewer && pid !== null && platform === "darwin" && app === "stim-desktop") await openEmulatorInStimDesktop(`emulator-${consolePort}`);
|
|
1063
1115
|
return pid;
|
|
1064
1116
|
}
|
|
1065
1117
|
function emulatorStdio(logFile) {
|
|
@@ -1114,8 +1166,8 @@ function emulatorDiskSpaceRemedy(lines) {
|
|
|
1114
1166
|
function emulatorFailureRemedy(lines) {
|
|
1115
1167
|
return emulatorDiskSpaceRemedy(lines) ?? "Fix what the emulator reported above, then run `stim android` again.";
|
|
1116
1168
|
}
|
|
1117
|
-
function getprop(exec, serial, prop, timeoutMs) {
|
|
1118
|
-
const out = exec.
|
|
1169
|
+
async function getprop(exec, serial, prop, timeoutMs) {
|
|
1170
|
+
const out = await exec.runFileQuietAsync(androidToolPath("adb"), [
|
|
1119
1171
|
"-s",
|
|
1120
1172
|
serial,
|
|
1121
1173
|
"shell",
|
|
@@ -1130,8 +1182,8 @@ const PACKAGE_MANAGER_PROBE = [
|
|
|
1130
1182
|
"path",
|
|
1131
1183
|
"android"
|
|
1132
1184
|
];
|
|
1133
|
-
function packageManagerReady(exec, serial, timeoutMs) {
|
|
1134
|
-
const out = exec.
|
|
1185
|
+
async function packageManagerReady(exec, serial, timeoutMs) {
|
|
1186
|
+
const out = await exec.runFileQuietAsync(androidToolPath("adb"), [
|
|
1135
1187
|
"-s",
|
|
1136
1188
|
serial,
|
|
1137
1189
|
...PACKAGE_MANAGER_PROBE
|
|
@@ -1144,7 +1196,7 @@ async function waitForBoot(serial, timeoutMs = 6e4, { aborted = () => false, pol
|
|
|
1144
1196
|
let exited = false;
|
|
1145
1197
|
const probeTimeout = () => Math.max(1, Math.min(commandTimeoutMs ?? timeoutMs, timeoutMs - (Date.now() - start)));
|
|
1146
1198
|
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 };
|
|
1199
|
+
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
1200
|
if (aborted()) {
|
|
1149
1201
|
exited = true;
|
|
1150
1202
|
break;
|
|
@@ -1152,39 +1204,39 @@ async function waitForBoot(serial, timeoutMs = 6e4, { aborted = () => false, pol
|
|
|
1152
1204
|
await new Promise((r) => setTimeout(r, commandTimeoutMs === void 0 ? pollMs : Math.min(pollMs, Math.max(0, timeoutMs - (Date.now() - start)))));
|
|
1153
1205
|
}
|
|
1154
1206
|
const diagnosticDeadline = Date.now() + Math.min(commandTimeoutMs ?? 5e3, 5e3);
|
|
1155
|
-
const diagnosticQuery = (args) => {
|
|
1207
|
+
const diagnosticQuery = async (args) => {
|
|
1156
1208
|
const remaining = diagnosticDeadline - Date.now();
|
|
1157
1209
|
if (remaining <= 0) return "";
|
|
1158
|
-
const value = exec.
|
|
1210
|
+
const value = await exec.runFileQuietAsync(androidToolPath("adb"), args, { timeoutMs: remaining });
|
|
1159
1211
|
return typeof value === "string" ? value.trim() : "";
|
|
1160
1212
|
};
|
|
1161
1213
|
return {
|
|
1162
1214
|
ok: false,
|
|
1163
1215
|
...exited ? { exited: true } : {},
|
|
1164
1216
|
diagnostic: {
|
|
1165
|
-
devices: diagnosticQuery(["devices"]),
|
|
1166
|
-
sysBoot: diagnosticQuery([
|
|
1217
|
+
devices: await diagnosticQuery(["devices"]),
|
|
1218
|
+
sysBoot: await diagnosticQuery([
|
|
1167
1219
|
"-s",
|
|
1168
1220
|
serial,
|
|
1169
1221
|
"shell",
|
|
1170
1222
|
"getprop",
|
|
1171
1223
|
"sys.boot_completed"
|
|
1172
1224
|
]),
|
|
1173
|
-
devBoot: diagnosticQuery([
|
|
1225
|
+
devBoot: await diagnosticQuery([
|
|
1174
1226
|
"-s",
|
|
1175
1227
|
serial,
|
|
1176
1228
|
"shell",
|
|
1177
1229
|
"getprop",
|
|
1178
1230
|
"dev.bootcomplete"
|
|
1179
1231
|
]),
|
|
1180
|
-
bootAnim: diagnosticQuery([
|
|
1232
|
+
bootAnim: await diagnosticQuery([
|
|
1181
1233
|
"-s",
|
|
1182
1234
|
serial,
|
|
1183
1235
|
"shell",
|
|
1184
1236
|
"getprop",
|
|
1185
1237
|
"init.svc.bootanim"
|
|
1186
1238
|
]),
|
|
1187
|
-
packageManager: diagnosticQuery([
|
|
1239
|
+
packageManager: await diagnosticQuery([
|
|
1188
1240
|
"-s",
|
|
1189
1241
|
serial,
|
|
1190
1242
|
...PACKAGE_MANAGER_PROBE
|
|
@@ -1194,24 +1246,42 @@ async function waitForBoot(serial, timeoutMs = 6e4, { aborted = () => false, pol
|
|
|
1194
1246
|
}
|
|
1195
1247
|
const ANDROID_EMULATOR_SHUTDOWN_TIMEOUT_MS = 6e4;
|
|
1196
1248
|
const ANDROID_EMULATOR_SHUTDOWN_POLL_MS = 100;
|
|
1197
|
-
function shutdownAndroidEmulator(serial, timeoutMs = ANDROID_EMULATOR_SHUTDOWN_TIMEOUT_MS) {
|
|
1249
|
+
async function shutdownAndroidEmulator(serial, timeoutMs = ANDROID_EMULATOR_SHUTDOWN_TIMEOUT_MS, operation) {
|
|
1198
1250
|
const exec = getExecutor();
|
|
1199
1251
|
const started = Date.now();
|
|
1200
|
-
|
|
1252
|
+
const run = async (args, budget) => {
|
|
1253
|
+
const options = {
|
|
1254
|
+
timeoutMs: budget,
|
|
1255
|
+
killSignal: "SIGKILL"
|
|
1256
|
+
};
|
|
1257
|
+
if (!operation) return exec.runFileQuietAsync(androidToolPath("adb"), args, options);
|
|
1258
|
+
try {
|
|
1259
|
+
return await runOperationFile(operation, exec, androidToolPath("adb", process.platform, operation.env), args, {
|
|
1260
|
+
...options,
|
|
1261
|
+
cwd: operation.cwd
|
|
1262
|
+
});
|
|
1263
|
+
} catch (cause) {
|
|
1264
|
+
if (cause instanceof WorkspaceProcessCleanupError) throw cause;
|
|
1265
|
+
operation.signal.throwIfAborted();
|
|
1266
|
+
return null;
|
|
1267
|
+
}
|
|
1268
|
+
};
|
|
1269
|
+
if (await run([
|
|
1201
1270
|
"-s",
|
|
1202
1271
|
serial,
|
|
1203
1272
|
"shell",
|
|
1204
1273
|
"sync"
|
|
1205
|
-
],
|
|
1206
|
-
|
|
1274
|
+
], Math.min(5e3, timeoutMs)) === null) {
|
|
1275
|
+
const warning = `warning: could not flush ${serial} before shutdown; shutting it down anyway\n`;
|
|
1276
|
+
if (operation) operation.output("stderr", warning);
|
|
1277
|
+
else ambientWrite("stderr", warning);
|
|
1278
|
+
}
|
|
1279
|
+
await run([
|
|
1207
1280
|
"-s",
|
|
1208
1281
|
serial,
|
|
1209
1282
|
"emu",
|
|
1210
1283
|
"kill"
|
|
1211
|
-
],
|
|
1212
|
-
}
|
|
1213
|
-
function sleepSync(ms) {
|
|
1214
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
1284
|
+
], Math.max(1, timeoutMs - (Date.now() - started)));
|
|
1215
1285
|
}
|
|
1216
1286
|
function avdProcessLockPaths(avdDirectory, platform) {
|
|
1217
1287
|
return ["hardware-qemu.ini.lock", "userdata-qemu.img.lock"].map((name) => join$1(avdDirectory, name, ...platform === "win32" ? ["pid"] : []));
|
|
@@ -1263,6 +1333,18 @@ function listAvdEmulatorProcesses(avdName, platform) {
|
|
|
1263
1333
|
], { timeoutMs: 5e3 });
|
|
1264
1334
|
return out === null ? null : parseAvdEmulatorProcesses(out, avdName);
|
|
1265
1335
|
}
|
|
1336
|
+
async function listAvdEmulatorProcessesAsync(avdName, platform, operation) {
|
|
1337
|
+
if (platform === "win32") return [];
|
|
1338
|
+
const out = await runOperationFileQuiet(operation, getExecutor(), "ps", [
|
|
1339
|
+
"-axww",
|
|
1340
|
+
"-o",
|
|
1341
|
+
"pid=,command="
|
|
1342
|
+
], {
|
|
1343
|
+
timeoutMs: 5e3,
|
|
1344
|
+
killSignal: "SIGKILL"
|
|
1345
|
+
});
|
|
1346
|
+
return out === null ? null : parseAvdEmulatorProcesses(out, avdName);
|
|
1347
|
+
}
|
|
1266
1348
|
function scanAvdEmulatorProcesses(avdName, platform, listProcesses) {
|
|
1267
1349
|
const pids = listProcesses(avdName, platform);
|
|
1268
1350
|
if (pids === null) throw new Error(`Could not read the process table to verify that owned AVD ${avdName} stopped.`);
|
|
@@ -1285,19 +1367,44 @@ function assertOwnedAvdStopped(avdName, { processAlive = emulatorProcessRunning,
|
|
|
1285
1367
|
if (processId !== null && processAlive(processId)) live.add(processId);
|
|
1286
1368
|
if (live.size) throw new Error(`Owned AVD ${avdName} still has a live emulator process (${[...live].join(", ")}).`);
|
|
1287
1369
|
}
|
|
1370
|
+
/** Async stopped-emulator verification; cancellation and unresolved probe cleanup propagate. */
|
|
1371
|
+
async function assertOwnedAvdStoppedAsync(avdName, operation, resolveDirectory = ownedAvdDirectory) {
|
|
1372
|
+
operation?.signal.throwIfAborted();
|
|
1373
|
+
const { processId } = resolveAvdProcess(avdName, { resolveDirectory });
|
|
1374
|
+
const processes = await listAvdEmulatorProcessesAsync(avdName, process.platform, operation);
|
|
1375
|
+
if (processes === null) throw new Error(`Could not read the process table to verify that owned AVD ${avdName} stopped.`);
|
|
1376
|
+
const live = new Set(processes);
|
|
1377
|
+
if (processId !== null && pidExists(processId)) {
|
|
1378
|
+
const stat = process.platform === "win32" ? null : await runOperationFileQuiet(operation, getExecutor(), "ps", [
|
|
1379
|
+
"-o",
|
|
1380
|
+
"stat=",
|
|
1381
|
+
"-p",
|
|
1382
|
+
String(processId)
|
|
1383
|
+
], {
|
|
1384
|
+
timeoutMs: 5e3,
|
|
1385
|
+
killSignal: "SIGKILL",
|
|
1386
|
+
cwd: operation?.cwd
|
|
1387
|
+
});
|
|
1388
|
+
if (stat === null || !stat.trim().startsWith("Z")) live.add(processId);
|
|
1389
|
+
}
|
|
1390
|
+
if (live.size) throw new Error(`Owned AVD ${avdName} still has a live emulator process (${[...live].join(", ")}).`);
|
|
1391
|
+
}
|
|
1288
1392
|
const CRASH_HANDLER_EXIT_TIMEOUT_MS = 15e3;
|
|
1289
1393
|
/**
|
|
1290
1394
|
* The crashpad handler qemu forks on Windows. It outlives an emulator that crashes on exit while
|
|
1291
1395
|
* it writes the dump, so a `stop` that returns on qemu's exit leaves it running.
|
|
1292
1396
|
* https://github.com/appandflow/stim/issues/918
|
|
1293
1397
|
*/
|
|
1294
|
-
function emulatorCrashHandlerPids(qemuPid) {
|
|
1295
|
-
const out = getExecutor()
|
|
1398
|
+
async function emulatorCrashHandlerPids(qemuPid, operation) {
|
|
1399
|
+
const out = await runOperationFileQuiet(operation, getExecutor(), "powershell.exe", [
|
|
1296
1400
|
"-NoProfile",
|
|
1297
1401
|
"-NonInteractive",
|
|
1298
1402
|
"-Command",
|
|
1299
1403
|
`Get-CimInstance Win32_Process | Where-Object { $_.Name -eq 'crashpad_handler.exe' -and $_.ParentProcessId -eq ${qemuPid} } | ForEach-Object ProcessId`
|
|
1300
|
-
], {
|
|
1404
|
+
], {
|
|
1405
|
+
timeoutMs: 1e4,
|
|
1406
|
+
killSignal: "SIGKILL"
|
|
1407
|
+
});
|
|
1301
1408
|
return String(out ?? "").split(/\r?\n/).map((line) => Number(line.trim())).filter((pid) => Number.isSafeInteger(pid) && pid > 0);
|
|
1302
1409
|
}
|
|
1303
1410
|
const EMULATOR_SIGNAL_GRACE_MS = 5e3;
|
|
@@ -1308,14 +1415,31 @@ const EMULATOR_SIGNAL_GRACE_MS = 5e3;
|
|
|
1308
1415
|
* grace, but only a process whose command line names this AVD and whose identity, captured before
|
|
1309
1416
|
* shutdown, still matches. Windows has no process-table scan, so there nothing is signalled.
|
|
1310
1417
|
*/
|
|
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 =
|
|
1418
|
+
async function waitForAndroidEmulatorShutdown(avdName, shutdown, { operation, 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 = (name, host) => listAvdEmulatorProcessesAsync(name, host, operation), captureIdentity = process_identity_exports.captureProcessIdentity, inspectIdentity = process_identity_exports.inspectProcessIdentity, signal = (pid, name) => signalProcessTreeAsync(pid, name, {
|
|
1419
|
+
platform,
|
|
1420
|
+
operation
|
|
1421
|
+
}), directoryExists = (path) => statSync(path).isDirectory(), crashHandlerPids = (pid) => emulatorCrashHandlerPids(pid, operation), killCrashHandler = (pid) => signalProcessTreeAsync(pid, "SIGKILL", {
|
|
1422
|
+
platform,
|
|
1423
|
+
operation
|
|
1424
|
+
}), now = Date.now, sleep = (ms) => cancellableSleep(ms, {
|
|
1425
|
+
signal: operation?.signal,
|
|
1426
|
+
what: "emulator shutdown"
|
|
1427
|
+
}) } = {}) {
|
|
1428
|
+
operation?.signal.throwIfAborted();
|
|
1312
1429
|
const { directory, processId } = resolveAvdProcess(avdName, {
|
|
1313
1430
|
platform,
|
|
1314
1431
|
resolveDirectory,
|
|
1315
1432
|
readProcessId
|
|
1316
1433
|
});
|
|
1434
|
+
const scan = async () => {
|
|
1435
|
+
operation?.signal.throwIfAborted();
|
|
1436
|
+
const pids = await listProcesses(avdName, platform);
|
|
1437
|
+
operation?.signal.throwIfAborted();
|
|
1438
|
+
if (pids === null) throw new Error(`Could not read the process table to verify that owned AVD ${avdName} stopped.`);
|
|
1439
|
+
return pids;
|
|
1440
|
+
};
|
|
1317
1441
|
const identities = /* @__PURE__ */ new Map();
|
|
1318
|
-
for (const pid of
|
|
1442
|
+
for (const pid of await scan()) {
|
|
1319
1443
|
const captured = captureIdentity(pid);
|
|
1320
1444
|
identities.set(pid, captured.ok ? {
|
|
1321
1445
|
pid,
|
|
@@ -1337,35 +1461,40 @@ function waitForAndroidEmulatorShutdown(avdName, shutdown, { timeoutMs = ANDROID
|
|
|
1337
1461
|
if (processId !== null && !identities.has(processId) && processAlive(processId)) pids.push(processId);
|
|
1338
1462
|
return pids;
|
|
1339
1463
|
};
|
|
1340
|
-
const waitUntil = (until) => {
|
|
1464
|
+
const waitUntil = async (until) => {
|
|
1341
1465
|
for (;;) {
|
|
1466
|
+
operation?.signal.throwIfAborted();
|
|
1342
1467
|
if (running().length === 0) return true;
|
|
1343
1468
|
const remaining = until - now();
|
|
1344
1469
|
if (remaining <= 0) return false;
|
|
1345
|
-
sleep(Math.min(pollMs, remaining));
|
|
1470
|
+
await sleep(Math.min(pollMs, remaining));
|
|
1346
1471
|
}
|
|
1347
1472
|
};
|
|
1348
1473
|
const started = now();
|
|
1349
1474
|
if (shutdown) {
|
|
1350
1475
|
const deadline = started + timeoutMs;
|
|
1351
1476
|
const shutdownTimeoutMs = deadline - now();
|
|
1352
|
-
if (shutdownTimeoutMs > 0) shutdown(shutdownTimeoutMs);
|
|
1353
|
-
waitUntil(deadline);
|
|
1477
|
+
if (shutdownTimeoutMs > 0) await shutdown(shutdownTimeoutMs);
|
|
1478
|
+
await waitUntil(deadline);
|
|
1354
1479
|
}
|
|
1355
1480
|
for (const name of ["SIGTERM", "SIGKILL"]) {
|
|
1481
|
+
operation?.signal.throwIfAborted();
|
|
1356
1482
|
const verified = running().filter((pid) => {
|
|
1357
1483
|
const record = identities.get(pid);
|
|
1358
1484
|
return record && inspectIdentity(record) === "same";
|
|
1359
1485
|
});
|
|
1360
1486
|
if (verified.length === 0) break;
|
|
1361
|
-
for (const pid of verified)
|
|
1362
|
-
signal(
|
|
1363
|
-
|
|
1487
|
+
for (const pid of verified) {
|
|
1488
|
+
operation?.signal.throwIfAborted();
|
|
1489
|
+
try {
|
|
1490
|
+
await signal(pid, name);
|
|
1491
|
+
} catch {}
|
|
1492
|
+
}
|
|
1364
1493
|
const graceMs = name === "SIGTERM" && !shutdown ? timeoutMs : signalGraceMs;
|
|
1365
|
-
if (waitUntil(now() + graceMs)) break;
|
|
1494
|
+
if (await waitUntil(now() + graceMs)) break;
|
|
1366
1495
|
}
|
|
1367
1496
|
const left = new Set(running());
|
|
1368
|
-
for (const pid of
|
|
1497
|
+
for (const pid of await scan()) {
|
|
1369
1498
|
const record = identities.get(pid);
|
|
1370
1499
|
if (record === void 0 || (record === null ? processAlive(pid) : inspectIdentity(record) !== "gone")) left.add(pid);
|
|
1371
1500
|
}
|
|
@@ -1380,10 +1509,14 @@ function waitForAndroidEmulatorShutdown(avdName, shutdown, { timeoutMs = ANDROID
|
|
|
1380
1509
|
}
|
|
1381
1510
|
if (platform === "win32" && processId !== null) {
|
|
1382
1511
|
const handlerDeadline = now() + CRASH_HANDLER_EXIT_TIMEOUT_MS;
|
|
1383
|
-
for (const handler of crashHandlerPids(processId)) {
|
|
1384
|
-
while (processAlive(handler) && now() < handlerDeadline)
|
|
1512
|
+
for (const handler of await crashHandlerPids(processId)) {
|
|
1513
|
+
while (processAlive(handler) && now() < handlerDeadline) {
|
|
1514
|
+
operation?.signal.throwIfAborted();
|
|
1515
|
+
await sleep(pollMs);
|
|
1516
|
+
}
|
|
1517
|
+
operation?.signal.throwIfAborted();
|
|
1385
1518
|
if (processAlive(handler)) {
|
|
1386
|
-
killCrashHandler(handler);
|
|
1519
|
+
await killCrashHandler(handler);
|
|
1387
1520
|
if (processAlive(handler)) throw new Error(`Crashpad handler ${handler} for owned AVD ${avdName} stayed alive.`);
|
|
1388
1521
|
}
|
|
1389
1522
|
}
|
|
@@ -1405,8 +1538,58 @@ function getAvdNameForSerial(serial, { timeoutMs = EMU_AVD_NAME_TIMEOUT_MS } = {
|
|
|
1405
1538
|
if (!out) return null;
|
|
1406
1539
|
return out.split("\n")[0]?.trim() || null;
|
|
1407
1540
|
}
|
|
1408
|
-
function
|
|
1409
|
-
|
|
1541
|
+
async function getAvdNameForSerialAsync(serial, { timeoutMs = EMU_AVD_NAME_TIMEOUT_MS, signal, operation } = {}) {
|
|
1542
|
+
const tool = androidToolPath("adb", process.platform, operation?.env);
|
|
1543
|
+
const args = [
|
|
1544
|
+
"-s",
|
|
1545
|
+
serial,
|
|
1546
|
+
"emu",
|
|
1547
|
+
"avd",
|
|
1548
|
+
"name"
|
|
1549
|
+
];
|
|
1550
|
+
const options = {
|
|
1551
|
+
timeoutMs: Math.min(timeoutMs, EMU_AVD_NAME_TIMEOUT_MS),
|
|
1552
|
+
killSignal: "SIGKILL",
|
|
1553
|
+
signal,
|
|
1554
|
+
cwd: androidToolCwd() ?? operation?.cwd
|
|
1555
|
+
};
|
|
1556
|
+
const out = await runOperationFileQuiet(operation, getExecutor(), tool, args, options);
|
|
1557
|
+
if (!out) return null;
|
|
1558
|
+
return out.split("\n")[0]?.trim() || null;
|
|
1559
|
+
}
|
|
1560
|
+
/** `resolveOwnedAvdSerial` without blocking the event loop, with the same reads and the same timeout budget. */
|
|
1561
|
+
async function resolveOwnedAvdSerialAsync(avdName, opts = {}) {
|
|
1562
|
+
return ownedAvdSerialResolverAsync(opts)(avdName);
|
|
1563
|
+
}
|
|
1564
|
+
/** Shares bounded asynchronous AVD, adb and emulator-name reads across the requested AVDs. */
|
|
1565
|
+
function ownedAvdSerialResolverAsync({ timeoutMs, signal, operation } = {}) {
|
|
1566
|
+
const started = Date.now();
|
|
1567
|
+
const remaining = () => ({
|
|
1568
|
+
signal,
|
|
1569
|
+
operation,
|
|
1570
|
+
timeoutMs: timeoutMs === void 0 ? void 0 : Math.max(MIN_LOOKUP_TIMEOUT_MS, timeoutMs - (Date.now() - started))
|
|
1571
|
+
});
|
|
1572
|
+
const avds = once(() => listAvdsAsync(remaining()));
|
|
1573
|
+
const adb = once(() => listAdbDevicesAsync(remaining()));
|
|
1574
|
+
const names = /* @__PURE__ */ new Map();
|
|
1575
|
+
const avdNameOf = (serial) => {
|
|
1576
|
+
let name = names.get(serial);
|
|
1577
|
+
if (!name) {
|
|
1578
|
+
name = getAvdNameForSerialAsync(serial, remaining());
|
|
1579
|
+
names.set(serial, name);
|
|
1580
|
+
}
|
|
1581
|
+
return name;
|
|
1582
|
+
};
|
|
1583
|
+
return async (avdName) => {
|
|
1584
|
+
signal?.throwIfAborted();
|
|
1585
|
+
if (!(await avds()).includes(avdName)) return { missing: true };
|
|
1586
|
+
if (!isStimOwnedAvd(avdName)) return { notOwned: true };
|
|
1587
|
+
const devices = await adb();
|
|
1588
|
+
signal?.throwIfAborted();
|
|
1589
|
+
const candidates = [...devices.emulators, ...devices.unhealthy.filter((entry) => entry.kind === "emulator" && entry.consolePort !== void 0)];
|
|
1590
|
+
for (const candidate of candidates) if (await avdNameOf(candidate.serial) === avdName) return { serial: candidate.serial };
|
|
1591
|
+
return { notRunning: true };
|
|
1592
|
+
};
|
|
1410
1593
|
}
|
|
1411
1594
|
function once(read) {
|
|
1412
1595
|
let result;
|
|
@@ -1448,4 +1631,4 @@ function ownedAvdSerialResolver({ timeoutMs } = {}) {
|
|
|
1448
1631
|
};
|
|
1449
1632
|
}
|
|
1450
1633
|
//#endregion
|
|
1451
|
-
export {
|
|
1634
|
+
export { resetAdoptedAvd as $, listAdbDevices as A, ownedAvdDeviceProfile as B, emulatorDiskSpaceRemedy as C, getAvdNameForSerial as D, findBuildTool as E, listAvdsAsync as F, ownedAvdSerialResolverAsync as G, ownedAvdMatchesConfiguration as H, listInstalledSystemImages as I, parseAvdSystemImage as J, ownedAvdSystemImage as K, listOrphanedAvdDirectories as L, listAvdDeviceProfiles as M, listAvdDeviceProfilesAsync as N, getAvdNameForSerialAsync as O, listAvds as P, profileNeedsFoldFeature as Q, memoizeEmulatorProbe as R, deleteAvd as S, extractEmulatorFailure as T, ownedAvdName as U, ownedAvdDirectory as V, ownedAvdSerialResolver as W, pickDefaultSystemImage as X, physicalDeviceModel as Y, probeEmulatorSerial as Z, avdPoolConfiguration as _, parkedMaxSetting as _t, androidDeviceAbi as a, waitForAndroidEmulatorShutdown as at, configureNewOwnedAvd as b, selectParked as bt, androidPoolNoCandidatesRefusal as c, configuredAndroidEmulatorApp as ct, androidToolPath as d, POOL_SETTING_REMEDY as dt, resolveOwnedAvdSerialAsync as et, assertOwnedAvdStopped as f, adoptParked as ft, avdPathExists as g, parkSim as gt, avdNameAbsent as h, isLegacyDeletionClaim as ht, androidDataFreeBytes as i, trimAndroidCaches as it, listAdbDevicesAsync as j, hostSystemImageArch as k, androidSystemImageAbi as l, isStimOwnedAvd as lt, avdIniPaths as m, eraseParkedAfter as mt, OWNED_AVD_CONFIG_DEFAULTS as n, shutdownAndroidEmulator as nt, androidHome as o, waitForBoot as ot, assertOwnedAvdStoppedAsync as p, dropParked as pt, parseAvdDeviceProfile as q, androidBuildToolName as r, systemImageSupportsFold as rt, androidPoolCandidates as s, wipeAvdUserData as st, DEFAULT_AVD_DEVICE_PROFILE as t, resolvePhysicalDevice as tt, androidToolCwd as u, isStimOwnedSim as ut, avdStorageRoots as v, readParked as vt, emulatorFailureRemedy as w, createOwnedAvd as x, bootAndroidEmulator as y, removeParkedAfter as yt, nextConsolePort as z };
|