stim 1.13.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{activity-DfVKZTEB.mjs → activity-B2-kb7k0.mjs} +281 -41
- package/dist/{android-BHfAu2mf.mjs → android-CYmq0jNi.mjs} +2 -2
- package/dist/{android-CD8pr8Q2.mjs → android-Cu_L4RpL.mjs} +524 -412
- package/dist/{android-qx_31wJo.mjs → android-Db2eEMaf.mjs} +152 -65
- package/dist/android-cas-PnKfAdB2.mjs +167 -0
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{app-install-CDFY2nUL.mjs → app-install-CAAplXAt.mjs} +162 -173
- package/dist/{budget-E5o91NR1.mjs → budget-CMiqghig.mjs} +1048 -77
- package/dist/{build-plan-BTa93o_r.mjs → build-plan-aeGMFX7e.mjs} +193 -650
- package/dist/build-progress-C2Jv1AtA.mjs +872 -0
- package/dist/build-slots-Df1ApSuH.mjs +127 -0
- package/dist/{cache-manifest-DWPF4RKJ.mjs → cache-manifest-DnUHBJaU.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{chrome-B5hWgQJS.mjs → chrome-BrcVWQyD.mjs} +4 -4
- package/dist/cli-0cX5s4NM.mjs +45 -0
- package/dist/cli.mjs +6 -42
- package/dist/client-C2IS36Qf.mjs +1333 -0
- package/dist/collector-run.mjs +8 -7
- package/dist/{command-output-BIL7rlX7.mjs → command-output-CliHHn7a.mjs} +1 -1
- package/dist/{config-0jCcMM0E.mjs → config-D0DbpZtM.mjs} +29 -29
- package/dist/{created-devices-Cd558h31.mjs → created-devices-BwVb3liH.mjs} +2 -2
- package/dist/{dependency-state-DNN0yfx6.mjs → dependency-state-BmsjKZ2H.mjs} +2 -2
- package/dist/{deps-2Wo81np9.mjs → deps-BFlKbOIp.mjs} +3 -3
- package/dist/{detached-entry-DJHoca49.mjs → detached-entry-CiTEgMR1.mjs} +1 -1
- package/dist/dev-client-CjzLoNs0.mjs +80 -0
- package/dist/{device-Cf7vl-so.mjs → device-BZ1IyS5A.mjs} +7 -7
- package/dist/device-capacity-DMuKC7nx.mjs +136 -0
- package/dist/device-host-worker.d.mts +1 -0
- package/dist/device-host-worker.mjs +769 -0
- package/dist/device-ios-DMQBUPus.mjs +381 -0
- package/dist/{device-lease-CL9dZf73.mjs → device-lease-W5Pi1q38.mjs} +43 -36
- package/dist/{device-pool-MuoiyRcu.mjs → device-pool-B2r38YjS.mjs} +4 -4
- package/dist/{device-remote-DT9ngZiD.mjs → device-remote-9ulPsdhY.mjs} +68 -162
- package/dist/{doctor-D2iysNNH.mjs → doctor-BcE5xsBn.mjs} +191 -99
- package/dist/{error-diagnostics-BoiOhck8.mjs → error-diagnostics-Cb0P1WLS.mjs} +12 -11
- package/dist/{exec-DK8KaVHK.mjs → exec-CaErVv7t.mjs} +5 -1
- package/dist/{gc-eA-PRBX8.mjs → gc-BuL1Genr.mjs} +430 -102
- package/dist/{android-cas-B9Kv9aIy.mjs → gradle-CmdOBq1d.mjs} +8 -294
- package/dist/{guide-BfZ0OmiP.mjs → guide-cCSGRFd3.mjs} +2052 -240
- package/dist/{guide-status-BaMYu55M.mjs → guide-status-CIoWK6mG.mjs} +3 -3
- package/dist/hosted-macos-DwowNU7W.mjs +447 -0
- package/dist/idle-shutdown-B5LPaNyY.mjs +122 -0
- package/dist/in-use-CndPMilN.mjs +110 -0
- package/dist/{ios-CmEzZiOj.mjs → ios-3CtCRhwr.mjs} +201 -10
- package/dist/{ios-CcfCeZ19.mjs → ios-Chob8ny7.mjs} +560 -259
- package/dist/{ios-device-BW-t_Lkv.mjs → ios-device-DERmMmk-.mjs} +12 -7
- package/dist/{ios-device-BiOsSVzd.mjs → ios-device-Ee7sDXfp.mjs} +1 -1
- package/dist/{launch-verify-CuJaBpEa.mjs → launch-verify-CLlofxRt.mjs} +42 -11
- package/dist/{logs-DcSRbC2t.mjs → logs-h9h6MUvE.mjs} +95 -13
- package/dist/machine-usage-D_YYMzfR.mjs +283 -0
- package/dist/machines-CYtOCqcj.mjs +259 -0
- package/dist/macos-BwtbUtTN.mjs +468 -0
- package/dist/macos-run.d.mts +5 -0
- package/dist/macos-run.mjs +2 -0
- package/dist/{merge-state-ytFQCeh4.mjs → merge-state-BnxLNQiM.mjs} +22 -12
- package/dist/{metro-BPeY1YMh.mjs → metro-Di8EN2Tb.mjs} +20 -120
- package/dist/{named-ports-n7tnJsI8.mjs → named-ports-Dj_XBNaL.mjs} +8 -64
- package/dist/native-run-DFDoIRbY.mjs +147 -0
- package/dist/{native-runtime-CiiFHt0e.mjs → native-runtime-i6OkVg-w.mjs} +11 -6
- package/dist/offload-worker.d.mts +121 -0
- package/dist/offload-worker.mjs +601 -0
- package/dist/{ownership-Bz2kETAS.mjs → ownership-BkYxUtuj.mjs} +3 -2
- package/dist/{page-BTu7I60K.mjs → page-QF_Ke10s.mjs} +7 -2
- package/dist/{ports-C5UutqpJ.mjs → ports-DddwttKM.mjs} +3 -3
- package/dist/prebuild-BvxDlD6C.mjs +213 -0
- package/dist/process-identity-BmRm1qV0.mjs +12 -0
- package/dist/{project-DGeclhvO.mjs → project-CV3tDFHl.mjs} +9 -18
- package/dist/pull-request-pxnDCQzn.mjs +322 -0
- package/dist/pull-requests.d.mts +120 -0
- package/dist/pull-requests.mjs +2 -0
- package/dist/recordings-GEXp4iBT.mjs +37 -0
- package/dist/{reload-C-cV5yy_.mjs → reload-ChPiwvot.mjs} +70 -22
- package/dist/{remote-cache--aehr4Pr.mjs → remote-cache-CO2elm_b.mjs} +4 -4
- package/dist/run-B-xqRrsg.mjs +119 -0
- package/dist/{server-bare-Bq8BpSIo.mjs → server-bare-X7PUgizL.mjs} +60 -13
- package/dist/{server-expo-DUCg52-K.mjs → server-expo-DhtX6bom.mjs} +6 -10
- package/dist/server-expo-KJeD109I.mjs +2 -0
- package/dist/{settings-xB0Frkg6.mjs → settings-CduVcoxj.mjs} +77 -26
- package/dist/{settings-ssVBToDR.mjs → settings-DbL6uhH8.mjs} +16 -10
- package/dist/settings.schema.json +357 -2
- package/dist/{simslim-Bbg9UWrt.mjs → simslim-Ciluxlq4.mjs} +8 -132
- package/dist/slot-launch-BY0BrOLh.mjs +65 -0
- package/dist/{spawn-claims-PT8aQpCa.mjs → spawn-claims-D0XfSe8u.mjs} +1 -1
- package/dist/spawn-entry-DncpJvWL.mjs +16 -0
- package/dist/stage-CzaiwFsI.mjs +143 -0
- package/dist/start-CPO4wRg7.mjs +2 -0
- package/dist/{start-BZhItkiL.mjs → start-CUD9nasA.mjs} +108 -61
- package/dist/state-B4PQFXMW.d.mts +12 -0
- package/dist/state-BxCgeTQu.mjs +41 -0
- package/dist/{state-DwAU2_-D.mjs → state-CaeaHbDA.mjs} +7 -4
- package/dist/{state-l1pYwOre.mjs → state-DFm77wRn.mjs} +67 -5
- package/dist/stats-DBLLFmKd.mjs +66 -0
- package/dist/{status-TJlL0HWo.mjs → status-DYXxNOT0.mjs} +425 -260
- package/dist/{status-sszP4XKU.mjs → status-l84Gbvp2.mjs} +122 -20
- package/dist/stdout-reader-C8yjre1x.mjs +23 -0
- package/dist/stim-desktop-Cnz8CPnl.mjs +63 -0
- package/dist/stim-footprint.swift +32 -0
- package/dist/{stim-installations-CINXy_su.mjs → stim-installations-QMEI32v1.mjs} +1 -1
- package/dist/{stop-BZ2qMiBP.mjs → stop-Bad61z_2.mjs} +128 -19
- package/dist/stop-Bvf1MflS.mjs +48 -0
- package/dist/{stop-DskDKNTU.mjs → stop-CceYh1yG.mjs} +2 -2
- package/dist/stop-cause-CZ_Mr-v9.mjs +665 -0
- package/dist/supervisor-run.d.mts +44 -12
- package/dist/supervisor-run.mjs +276 -33
- package/dist/support-CDQbDkL5.mjs +315 -0
- package/dist/support-WLOzVKUv.mjs +176 -0
- package/dist/teardown-BYuQafiA.mjs +718 -0
- package/dist/{xcode-LM6A8cNZ.mjs → toolchain-DmeYjXD9.mjs} +363 -13
- package/dist/warm-progress-DVHLN4uC.mjs +463 -0
- package/dist/{idle-DxLi5OkN.mjs → watchman-Bx0wceoF.mjs} +55 -8
- package/dist/{web-sWXd5iek.mjs → web-k6w8-HnE.mjs} +39 -22
- package/dist/web-run.mjs +326 -13
- package/dist/workspace-process-lock-BL7Q0HCO.mjs +57 -0
- package/dist/workspace-state-CL2V2Ons.mjs +371 -0
- package/dist/worktree-BT_uULFx.mjs +2 -0
- package/dist/{worktree-DeBQSVtR.mjs → worktree-C0c5Udwa.mjs} +55 -54
- package/dist/{worktree-D4Do_XiQ.mjs → worktree-qXKzADSC.mjs} +161 -255
- package/package.json +10 -5
- package/shim/bundle-response.cjs +55 -10
- package/shim/bundle-response.d.cts +1 -0
- package/shim/expo-metro-config.cjs +10 -2
- package/dist/build-progress-l7d-X-ZP.mjs +0 -247
- package/dist/in-use-wYEaKQM9.mjs +0 -249
- package/dist/ownership-PUP4Dwai.mjs +0 -1138
- package/dist/server-expo-BeYwP_Xy.mjs +0 -2
- package/dist/slot-launch-BIWEW-wI.mjs +0 -19
- package/dist/start-Rw2GD3nV.mjs +0 -2
- package/dist/stats-CaSwmsSZ.mjs +0 -62
- package/dist/stats-D8rUTPHd.mjs +0 -368
- package/dist/stim-desktop-CXt8-Z3J.mjs +0 -40
- package/dist/worktree-3cBa-bQt.mjs +0 -2
- package/dist/{metro-store-DzeWkfqW.mjs → metro-store-CDDZHtPl.mjs} +1 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { d as getConfigDir } from "./config-D0DbpZtM.mjs";
|
|
2
|
+
import { r as register } from "./cache-manifest-DnUHBJaU.mjs";
|
|
3
|
+
import { E as withDirLock, p as ensureWorkspaceStorage } from "./workspace-state-CL2V2Ons.mjs";
|
|
4
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
5
|
+
import { accessSync, constants, existsSync, mkdirSync, readFileSync, realpathSync, renameSync, statSync, symlinkSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { isJsonObject, readJsonFile } from "@stim-cli/core/state";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
//#region src/engine/android-cas.ts
|
|
10
|
+
const CAS_TOOLCHAIN_FIELDS = [
|
|
11
|
+
"clang",
|
|
12
|
+
"clangxx",
|
|
13
|
+
"lld",
|
|
14
|
+
"ar",
|
|
15
|
+
"ranlib",
|
|
16
|
+
"ndk",
|
|
17
|
+
"resourceDir"
|
|
18
|
+
];
|
|
19
|
+
const CAS_TOOLCHAIN_BINARIES = [
|
|
20
|
+
"clang",
|
|
21
|
+
"clangxx",
|
|
22
|
+
"lld",
|
|
23
|
+
"ar",
|
|
24
|
+
"ranlib"
|
|
25
|
+
];
|
|
26
|
+
function executableFile(path) {
|
|
27
|
+
try {
|
|
28
|
+
accessSync(path, constants.X_OK);
|
|
29
|
+
return statSync(path).isFile();
|
|
30
|
+
} catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function directory(path) {
|
|
35
|
+
try {
|
|
36
|
+
return statSync(path).isDirectory();
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function isAndroidCasToolchain(value) {
|
|
42
|
+
return CAS_TOOLCHAIN_FIELDS.every((field) => typeof value[field] === "string");
|
|
43
|
+
}
|
|
44
|
+
function readAndroidCasToolchain(manifest) {
|
|
45
|
+
const parsed = readJsonFile(manifest);
|
|
46
|
+
const toolchain = isJsonObject(parsed) ? parsed : {};
|
|
47
|
+
if (!isAndroidCasToolchain(toolchain)) {
|
|
48
|
+
const missing = CAS_TOOLCHAIN_FIELDS.filter((field) => typeof toolchain[field] !== "string");
|
|
49
|
+
throw new Error(`${manifest} declares no ${missing.join(", ")}.`);
|
|
50
|
+
}
|
|
51
|
+
const notExecutable = CAS_TOOLCHAIN_BINARIES.filter((field) => !executableFile(toolchain[field]));
|
|
52
|
+
if (notExecutable.length > 0) throw new Error(`${manifest} names no executable ${notExecutable.join(", ")}.`);
|
|
53
|
+
if (!directory(toolchain.resourceDir)) throw new Error(`${manifest} names resourceDir ${toolchain.resourceDir}, which is not a directory.`);
|
|
54
|
+
const ndkProperties = readFileSync(join(toolchain.ndk, "source.properties"), "utf8");
|
|
55
|
+
const ndkVersion = /Pkg.Revision\s*=\s*([^\r\n]+)/.exec(ndkProperties)?.[1]?.trim();
|
|
56
|
+
if (!ndkVersion) throw new Error(`Missing NDK version in ${toolchain.ndk}/source.properties.`);
|
|
57
|
+
return {
|
|
58
|
+
toolchain,
|
|
59
|
+
ndkVersion,
|
|
60
|
+
ndkProperties
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function resolveAndroidCompilerCache({ optimizations, use, env = process.env }) {
|
|
64
|
+
if (optimizations.android.compilerCache !== "cas") return {
|
|
65
|
+
cas: null,
|
|
66
|
+
optimizations
|
|
67
|
+
};
|
|
68
|
+
const manifest = optimizations.android.casToolchain;
|
|
69
|
+
try {
|
|
70
|
+
return {
|
|
71
|
+
cas: use(manifest),
|
|
72
|
+
optimizations
|
|
73
|
+
};
|
|
74
|
+
} catch (error) {
|
|
75
|
+
const fromEnvironment = Boolean(env.STIM_ANDROID_CAS_TOOLCHAIN);
|
|
76
|
+
return {
|
|
77
|
+
cas: null,
|
|
78
|
+
optimizations: {
|
|
79
|
+
...optimizations,
|
|
80
|
+
android: {
|
|
81
|
+
...optimizations.android,
|
|
82
|
+
compilerCache: "ccache",
|
|
83
|
+
compilerCacheFallback: {
|
|
84
|
+
key: fromEnvironment ? "STIM_ANDROID_CAS_TOOLCHAIN" : "optimizations.android.casToolchain",
|
|
85
|
+
reason: `could not be used: ${error.message.replace(/\.$/, "")}`,
|
|
86
|
+
fromEnvironment,
|
|
87
|
+
manifest
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function resolveAndroidCas(root, env = process.env) {
|
|
95
|
+
const manifest = env.STIM_ANDROID_CAS_TOOLCHAIN;
|
|
96
|
+
if (!manifest) return null;
|
|
97
|
+
const { toolchain, ndkVersion, ndkProperties } = readAndroidCasToolchain(manifest);
|
|
98
|
+
const scripts = [
|
|
99
|
+
"shim/android-cas.gradle",
|
|
100
|
+
"shim/android-cas.toolchain.cmake",
|
|
101
|
+
"shim/android-cas-pch.cmake",
|
|
102
|
+
"dist/android-cas-compiler.mjs"
|
|
103
|
+
].map((name) => {
|
|
104
|
+
const path = [`../${name}`, `../../${name}`].map((candidate) => fileURLToPath(new URL(candidate, import.meta.url))).find((candidate) => existsSync(candidate));
|
|
105
|
+
if (!path) throw new Error(`Stim installation is missing ${name}.`);
|
|
106
|
+
return path;
|
|
107
|
+
});
|
|
108
|
+
const hash = createHash("sha256").update(JSON.stringify(toolchain));
|
|
109
|
+
for (const path of [
|
|
110
|
+
...scripts,
|
|
111
|
+
toolchain.clang,
|
|
112
|
+
toolchain.clangxx,
|
|
113
|
+
toolchain.lld,
|
|
114
|
+
toolchain.ar,
|
|
115
|
+
toolchain.ranlib
|
|
116
|
+
]) hash.update(readFileSync(path));
|
|
117
|
+
hash.update(ndkProperties);
|
|
118
|
+
const id = `apple-cas-${hash.digest("hex")}`;
|
|
119
|
+
const dir = join(getConfigDir(), "android-cas", id);
|
|
120
|
+
const state = join(ensureWorkspaceStorage(root), "android-cas", id);
|
|
121
|
+
const context = join(state, "context.json");
|
|
122
|
+
mkdirSync(state, { recursive: true });
|
|
123
|
+
mkdirSync(dir, { recursive: true });
|
|
124
|
+
withDirLock(join(state, "setup.lock"), () => {
|
|
125
|
+
for (const name of ["clang", "clang++"]) {
|
|
126
|
+
const path = join(state, name);
|
|
127
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
128
|
+
symlinkSync(scripts[3], temporary);
|
|
129
|
+
renameSync(temporary, path);
|
|
130
|
+
}
|
|
131
|
+
const temporary = `${context}.${process.pid}.tmp`;
|
|
132
|
+
writeFileSync(temporary, JSON.stringify({
|
|
133
|
+
...toolchain,
|
|
134
|
+
source: realpathSync(root),
|
|
135
|
+
state,
|
|
136
|
+
cache: dir
|
|
137
|
+
}));
|
|
138
|
+
renameSync(temporary, context);
|
|
139
|
+
});
|
|
140
|
+
register({
|
|
141
|
+
dir,
|
|
142
|
+
name: "android-cas",
|
|
143
|
+
prune: "atomic",
|
|
144
|
+
note: "Experimental Android compiler CAS"
|
|
145
|
+
});
|
|
146
|
+
return {
|
|
147
|
+
id,
|
|
148
|
+
dir,
|
|
149
|
+
initScript: scripts[0],
|
|
150
|
+
env: {
|
|
151
|
+
STIM_ANDROID_CAS_CONTEXT: context,
|
|
152
|
+
STIM_ANDROID_CAS_SOURCE_ROOT: realpathSync(root),
|
|
153
|
+
STIM_ANDROID_CAS_STATE: state,
|
|
154
|
+
STIM_ANDROID_CAS_NDK: toolchain.ndk,
|
|
155
|
+
STIM_ANDROID_CAS_NDK_VERSION: ndkVersion,
|
|
156
|
+
STIM_ANDROID_CAS_AR: toolchain.ar,
|
|
157
|
+
STIM_ANDROID_CAS_RANLIB: toolchain.ranlib,
|
|
158
|
+
STIM_ANDROID_CAS_CMAKE_TOOLCHAIN: scripts[1],
|
|
159
|
+
STIM_ANDROID_CAS_CMAKE_PCH: scripts[2],
|
|
160
|
+
CMAKE_C_COMPILER_LAUNCHER: "",
|
|
161
|
+
CMAKE_CXX_COMPILER_LAUNCHER: "",
|
|
162
|
+
CCACHE_DISABLE: "1"
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
//#endregion
|
|
167
|
+
export { resolveAndroidCas as n, resolveAndroidCompilerCache as r, readAndroidCasToolchain as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
+
import { t as getExecutor } from "./exec-CaErVv7t.mjs";
|
|
3
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
3
4
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
4
5
|
import { join } from "node:path";
|
|
5
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
6
6
|
import { once } from "node:events";
|
|
7
7
|
//#region bin/android-cas-compiler.ts
|
|
8
8
|
const context = process.env.STIM_ANDROID_CAS_CONTEXT;
|
|
@@ -1,138 +1,6 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { isAbsolute, join } from "node:path";
|
|
5
|
-
import { createHash } from "node:crypto";
|
|
6
|
-
//#region src/engine/installed-artifact.ts
|
|
7
|
-
const READ_CHUNK_BYTES = 1048576;
|
|
8
|
-
const DEVICE_PATH_TIMEOUT_MS = 3e4;
|
|
9
|
-
const DEVICE_HASH_TIMEOUT_MS = 12e4;
|
|
10
|
-
const SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
11
|
-
function parseInstalledApkPath(text) {
|
|
12
|
-
if (typeof text !== "string") return null;
|
|
13
|
-
const paths = [];
|
|
14
|
-
for (const raw of text.split("\n")) {
|
|
15
|
-
const line = raw.trim();
|
|
16
|
-
if (!line.startsWith("package:")) continue;
|
|
17
|
-
const path = line.slice(8);
|
|
18
|
-
if (path.startsWith("/")) paths.push(path);
|
|
19
|
-
}
|
|
20
|
-
return paths.length === 1 ? paths[0] : null;
|
|
21
|
-
}
|
|
22
|
-
function parseDeviceSha256(text) {
|
|
23
|
-
if (typeof text !== "string") return null;
|
|
24
|
-
const first = text.trim().split(/\s+/)[0] ?? "";
|
|
25
|
-
return SHA256_HEX.test(first) ? first : null;
|
|
26
|
-
}
|
|
27
|
-
function parseAppContainerPath(text) {
|
|
28
|
-
if (typeof text !== "string") return null;
|
|
29
|
-
const lines = text.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
30
|
-
return lines.length === 1 && isAbsolute(lines[0]) ? lines[0] : null;
|
|
31
|
-
}
|
|
32
|
-
function artifactsMatch(local, installed) {
|
|
33
|
-
return Boolean(local) && local === installed;
|
|
34
|
-
}
|
|
35
|
-
function hashFile(file) {
|
|
36
|
-
let fd = null;
|
|
37
|
-
try {
|
|
38
|
-
fd = openSync(file, "r");
|
|
39
|
-
const digest = createHash("sha256");
|
|
40
|
-
const buffer = Buffer.allocUnsafe(READ_CHUNK_BYTES);
|
|
41
|
-
for (;;) {
|
|
42
|
-
const read = readSync(fd, buffer, 0, READ_CHUNK_BYTES, null);
|
|
43
|
-
if (read <= 0) break;
|
|
44
|
-
digest.update(buffer.subarray(0, read));
|
|
45
|
-
}
|
|
46
|
-
return digest.digest("hex");
|
|
47
|
-
} catch {
|
|
48
|
-
return null;
|
|
49
|
-
} finally {
|
|
50
|
-
if (fd !== null) try {
|
|
51
|
-
closeSync(fd);
|
|
52
|
-
} catch {}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
function hashBundle(dir) {
|
|
56
|
-
const digest = createHash("sha256");
|
|
57
|
-
const walk = (abs, rel) => {
|
|
58
|
-
let names;
|
|
59
|
-
try {
|
|
60
|
-
names = readdirSync(abs);
|
|
61
|
-
} catch {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
for (const name of names.toSorted()) {
|
|
65
|
-
const child = join(abs, name);
|
|
66
|
-
const path = rel === "" ? name : `${rel}/${name}`;
|
|
67
|
-
let stat;
|
|
68
|
-
try {
|
|
69
|
-
stat = lstatSync(child);
|
|
70
|
-
} catch {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
if (stat.isDirectory()) {
|
|
74
|
-
if (!walk(child, path)) return false;
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
if (!stat.isFile()) return false;
|
|
78
|
-
const file = hashFile(child);
|
|
79
|
-
if (file === null) return false;
|
|
80
|
-
digest.update(`${path}\0${file}\n`);
|
|
81
|
-
}
|
|
82
|
-
return true;
|
|
83
|
-
};
|
|
84
|
-
return walk(dir, "") ? digest.digest("hex") : null;
|
|
85
|
-
}
|
|
86
|
-
function deviceHoldsApk({ serial, packageName, apkPath }, { exec = null } = {}) {
|
|
87
|
-
const e = exec || getExecutor();
|
|
88
|
-
let path;
|
|
89
|
-
try {
|
|
90
|
-
path = parseInstalledApkPath(e.runFile("adb", [
|
|
91
|
-
"-s",
|
|
92
|
-
serial,
|
|
93
|
-
"shell",
|
|
94
|
-
"pm",
|
|
95
|
-
"path",
|
|
96
|
-
packageName
|
|
97
|
-
], { timeoutMs: DEVICE_PATH_TIMEOUT_MS }));
|
|
98
|
-
} catch {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
if (!path) return false;
|
|
102
|
-
let installed;
|
|
103
|
-
try {
|
|
104
|
-
installed = parseDeviceSha256(e.runFile("adb", [
|
|
105
|
-
"-s",
|
|
106
|
-
serial,
|
|
107
|
-
"shell",
|
|
108
|
-
"sha256sum",
|
|
109
|
-
path
|
|
110
|
-
], { timeoutMs: DEVICE_HASH_TIMEOUT_MS }));
|
|
111
|
-
} catch {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
if (!installed) return false;
|
|
115
|
-
return artifactsMatch(hashFile(apkPath), installed);
|
|
116
|
-
}
|
|
117
|
-
function deviceHoldsBundle({ udid, bundleId, appPath }, { exec = null } = {}) {
|
|
118
|
-
const e = exec || getExecutor();
|
|
119
|
-
let container;
|
|
120
|
-
try {
|
|
121
|
-
container = parseAppContainerPath(e.runFile("xcrun", [
|
|
122
|
-
"simctl",
|
|
123
|
-
"get_app_container",
|
|
124
|
-
udid,
|
|
125
|
-
bundleId
|
|
126
|
-
], { timeoutMs: DEVICE_PATH_TIMEOUT_MS }));
|
|
127
|
-
} catch {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
if (!container) return false;
|
|
131
|
-
const installed = hashBundle(container);
|
|
132
|
-
if (!installed) return false;
|
|
133
|
-
return artifactsMatch(hashBundle(appPath), installed);
|
|
134
|
-
}
|
|
135
|
-
//#endregion
|
|
1
|
+
import { t as getExecutor } from "./exec-CaErVv7t.mjs";
|
|
2
|
+
import { D as uninstallIosApp, M as deviceHoldsApk, N as deviceHoldsBundle, l as iosSimulatorFailureAdvice, m as listUserApps } from "./ios-3CtCRhwr.mjs";
|
|
3
|
+
import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-Ee7sDXfp.mjs";
|
|
136
4
|
//#region src/engine/app-install.ts
|
|
137
5
|
const INSTALL_ERROR = "STIM_INSTALL_FAILED";
|
|
138
6
|
const LAUNCH_ERROR = "STIM_LAUNCH_FAILED";
|
|
@@ -142,12 +10,37 @@ const IOS_SCHEME_APPROVAL_OPENER = "com.apple.CoreSimulator.CoreSimulatorBridge"
|
|
|
142
10
|
const IOS_DEV_MENU_OFF_KEYS = ["EXDevMenuShowsAtLaunch", "EXDevMenuShowFloatingActionButton"];
|
|
143
11
|
const DEV_CLIENT_ONBOARDING_QUERY = "disableOnboarding=1";
|
|
144
12
|
const DEV_CLIENT_DISABLE_FAB_QUERY = "disableFab=1";
|
|
13
|
+
const DEV_CLIENT_DEV_MENU_OFF_QUERY = "disableFab=1&disableAutoLaunch=1";
|
|
14
|
+
const DEV_CLIENT_RESERVED_DEV_MENU_OFF_QUERY = "__expo_disable_fab=1&__expo_disable_auto_launch=1";
|
|
145
15
|
const ANDROID_DISABLE_AUTO_LAUNCH_EXTRA = "EXDevMenuDisableAutoLaunch";
|
|
16
|
+
const IOS_DEV_MENU_OFF_DEFAULTS_PLIST = [
|
|
17
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
|
|
18
|
+
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">",
|
|
19
|
+
"<plist version=\"1.0\">",
|
|
20
|
+
"<dict>",
|
|
21
|
+
...IOS_DEV_MENU_OFF_KEYS.flatMap((key) => [` <key>${key}</key>`, " <false/>"]),
|
|
22
|
+
"</dict>",
|
|
23
|
+
"</plist>",
|
|
24
|
+
""
|
|
25
|
+
].join("\n");
|
|
26
|
+
function writeIosDevMenuOffDefaults(udid, bundleId, exec) {
|
|
27
|
+
for (const key of IOS_DEV_MENU_OFF_KEYS) exec.runFile("xcrun", [
|
|
28
|
+
"simctl",
|
|
29
|
+
"spawn",
|
|
30
|
+
udid,
|
|
31
|
+
"defaults",
|
|
32
|
+
"write",
|
|
33
|
+
bundleId,
|
|
34
|
+
key,
|
|
35
|
+
"-bool",
|
|
36
|
+
"false"
|
|
37
|
+
], { timeoutMs: 6e4 });
|
|
38
|
+
}
|
|
146
39
|
function describeIosSimulatorFailure(error, exec) {
|
|
147
40
|
const detail = describe(error);
|
|
148
41
|
return error?.code === "ETIMEDOUT" ? `${detail}. ${iosSimulatorFailureAdvice(exec)}` : detail;
|
|
149
42
|
}
|
|
150
|
-
function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null, proveInstalled = true }, { exec = null, now = null } = {}) {
|
|
43
|
+
function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null, schemeApprovals = [], proveInstalled = true }, { exec = null, now = null } = {}) {
|
|
151
44
|
const e = exec || getExecutor();
|
|
152
45
|
const artifactStartedAt = now?.();
|
|
153
46
|
const skipped = bundleId && proveInstalled ? deviceHoldsBundle({
|
|
@@ -174,20 +67,13 @@ function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null,
|
|
|
174
67
|
}
|
|
175
68
|
const artifactFinishedAt = now?.();
|
|
176
69
|
const artifactDurationMs = artifactStartedAt !== void 0 && artifactFinishedAt !== void 0 ? artifactFinishedAt - artifactStartedAt : void 0;
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
"write",
|
|
185
|
-
bundleId,
|
|
186
|
-
key,
|
|
187
|
-
"-bool",
|
|
188
|
-
"false"
|
|
189
|
-
], { timeoutMs: 6e4 });
|
|
190
|
-
for (const key of iosSchemeApprovalKeys(bundleId, devClientScheme)) e.runFile("xcrun", [
|
|
70
|
+
const devMenuKeys = bundleId && devClientScheme && !skipped ? IOS_DEV_MENU_OFF_KEYS : [];
|
|
71
|
+
const missingApprovals = (bundleId && devClientScheme ? iosSchemeApprovalKeys(bundleId, devClientScheme) : []).filter((key) => !schemeApprovals.includes(`${key}=${bundleId}`));
|
|
72
|
+
const preparing = bundleId && (devMenuKeys.length > 0 || missingApprovals.length > 0);
|
|
73
|
+
const preparationStartedAt = preparing ? artifactFinishedAt : void 0;
|
|
74
|
+
if (bundleId && preparing) try {
|
|
75
|
+
if (devMenuKeys.length > 0) writeIosDevMenuOffDefaults(udid, bundleId, e);
|
|
76
|
+
for (const key of missingApprovals) e.runFile("xcrun", [
|
|
191
77
|
"simctl",
|
|
192
78
|
"spawn",
|
|
193
79
|
udid,
|
|
@@ -208,7 +94,8 @@ function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null,
|
|
|
208
94
|
const devClientPreparationDurationMs = now && preparationStartedAt !== void 0 ? now() - preparationStartedAt : void 0;
|
|
209
95
|
const timing = {
|
|
210
96
|
...artifactDurationMs === void 0 ? {} : { artifactDurationMs },
|
|
211
|
-
...devClientPreparationDurationMs === void 0 ? {} : { devClientPreparationDurationMs }
|
|
97
|
+
...devClientPreparationDurationMs === void 0 ? {} : { devClientPreparationDurationMs },
|
|
98
|
+
...missingApprovals.length > 0 ? { schemeApprovals: [...schemeApprovals, ...missingApprovals.map((key) => `${key}=${bundleId}`)] } : {}
|
|
212
99
|
};
|
|
213
100
|
return skipped ? {
|
|
214
101
|
ok: true,
|
|
@@ -230,6 +117,7 @@ function clearOtherUserApps({ udid, keep }, { list = listUserApps, uninstall = u
|
|
|
230
117
|
} catch {
|
|
231
118
|
return {
|
|
232
119
|
listed: false,
|
|
120
|
+
kept: false,
|
|
233
121
|
removed,
|
|
234
122
|
failed
|
|
235
123
|
};
|
|
@@ -245,6 +133,7 @@ function clearOtherUserApps({ udid, keep }, { list = listUserApps, uninstall = u
|
|
|
245
133
|
}
|
|
246
134
|
return {
|
|
247
135
|
listed: true,
|
|
136
|
+
kept: keep ? installed.includes(keep) : false,
|
|
248
137
|
removed,
|
|
249
138
|
failed
|
|
250
139
|
};
|
|
@@ -252,16 +141,20 @@ function clearOtherUserApps({ udid, keep }, { list = listUserApps, uninstall = u
|
|
|
252
141
|
function jsLocationValue(metroPort) {
|
|
253
142
|
return `localhost:${metroPort}`;
|
|
254
143
|
}
|
|
255
|
-
function devClientDeepLink(scheme, projectOrigin) {
|
|
256
|
-
const
|
|
257
|
-
|
|
144
|
+
function devClientDeepLink(scheme, projectOrigin, { devMenuParams = false } = {}) {
|
|
145
|
+
const projectQuery = devMenuParams ? `${DEV_CLIENT_ONBOARDING_QUERY}&${DEV_CLIENT_DEV_MENU_OFF_QUERY}&${DEV_CLIENT_RESERVED_DEV_MENU_OFF_QUERY}` : DEV_CLIENT_ONBOARDING_QUERY;
|
|
146
|
+
const projectUrl = `${projectOrigin.replace(/\/+$/, "")}/?${projectQuery}`;
|
|
147
|
+
return `${scheme}://expo-development-client/?url=${encodeURIComponent(projectUrl)}&${devMenuParams ? DEV_CLIENT_DEV_MENU_OFF_QUERY : DEV_CLIENT_DISABLE_FAB_QUERY}`;
|
|
258
148
|
}
|
|
259
|
-
function devClientUrl(scheme, metroPort, host = "localhost") {
|
|
260
|
-
return devClientDeepLink(scheme, `http://${host}:${metroPort}
|
|
149
|
+
function devClientUrl(scheme, metroPort, host = "localhost", options = {}) {
|
|
150
|
+
return devClientDeepLink(scheme, `http://${host}:${metroPort}`, options);
|
|
261
151
|
}
|
|
262
152
|
function iosSchemeApprovalKeys(bundleId, devClientScheme) {
|
|
263
153
|
return [.../* @__PURE__ */ new Set([bundleId, devClientScheme])].map((target) => `${IOS_SCHEME_APPROVAL_OPENER}-->${target}`);
|
|
264
154
|
}
|
|
155
|
+
function restartedAppNote(restartedPid, lead = " ") {
|
|
156
|
+
return restartedPid ? `${lead}restarted running app (was pid ${restartedPid})` : "";
|
|
157
|
+
}
|
|
265
158
|
function parseLaunchedPid(text) {
|
|
266
159
|
if (typeof text !== "string") return null;
|
|
267
160
|
const match = text.trim().match(/:\s*(\d+)\s*$/);
|
|
@@ -296,7 +189,7 @@ function launchedIosAppAfterNoHandle(error, udid, bundleId, exec) {
|
|
|
296
189
|
if (!stderr.includes("domain=NSPOSIXErrorDomain, code=3") || !stderr.includes(`Application launch for '${bundleId}' did not return a process handle nor launch error.`)) return null;
|
|
297
190
|
return iosAppProcess(udid, bundleId, { exec }) ?? null;
|
|
298
191
|
}
|
|
299
|
-
function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, consolePaths }, { exec = null } = {}) {
|
|
192
|
+
function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, devMenuParams = false, consolePaths }, { exec = null } = {}) {
|
|
300
193
|
const e = exec || getExecutor();
|
|
301
194
|
const launchArgs = [
|
|
302
195
|
"simctl",
|
|
@@ -305,6 +198,26 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
305
198
|
udid,
|
|
306
199
|
bundleId
|
|
307
200
|
];
|
|
201
|
+
let runningPid = iosAppProcess(udid, bundleId, { exec: e });
|
|
202
|
+
const restart = {};
|
|
203
|
+
if (runningPid) {
|
|
204
|
+
try {
|
|
205
|
+
e.runFile("xcrun", [
|
|
206
|
+
"simctl",
|
|
207
|
+
"terminate",
|
|
208
|
+
udid,
|
|
209
|
+
bundleId
|
|
210
|
+
], { timeoutMs: 3e4 });
|
|
211
|
+
} catch (err) {
|
|
212
|
+
return {
|
|
213
|
+
failed: true,
|
|
214
|
+
code: LAUNCH_ERROR,
|
|
215
|
+
reason: `simctl terminate ${bundleId} failed, so the running app (pid ${runningPid}) was not restarted: ${describeIosSimulatorFailure(err, e)}`
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
restart.restartedPid = runningPid;
|
|
219
|
+
runningPid = null;
|
|
220
|
+
}
|
|
308
221
|
if (metroPort !== null) {
|
|
309
222
|
try {
|
|
310
223
|
e.runFile("xcrun", [
|
|
@@ -325,23 +238,35 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
325
238
|
};
|
|
326
239
|
}
|
|
327
240
|
if (devClientScheme) {
|
|
328
|
-
const url = devClientUrl(devClientScheme, metroPort);
|
|
241
|
+
const url = devClientUrl(devClientScheme, metroPort, "localhost", { devMenuParams });
|
|
242
|
+
const viaInitialUrl = Boolean(consolePaths) && runningPid === null;
|
|
243
|
+
if (!viaInitialUrl) try {
|
|
244
|
+
writeIosDevMenuOffDefaults(udid, bundleId, e);
|
|
245
|
+
} catch (err) {
|
|
246
|
+
return {
|
|
247
|
+
failed: true,
|
|
248
|
+
code: LAUNCH_ERROR,
|
|
249
|
+
reason: `Could not turn off ${bundleId}'s dev menu before opening it (defaults write): ${describeIosSimulatorFailure(err, e)}`
|
|
250
|
+
};
|
|
251
|
+
}
|
|
329
252
|
let launchedWithInitialUrl = false;
|
|
330
253
|
try {
|
|
331
|
-
if (
|
|
254
|
+
if (viaInitialUrl) {
|
|
332
255
|
const initialUrl = new URL(url).searchParams.get("url");
|
|
333
256
|
launchedWithInitialUrl = true;
|
|
334
257
|
const pid = parseLaunchedPid(e.runFile("xcrun", [
|
|
335
258
|
...launchArgs,
|
|
336
259
|
"--initialUrl",
|
|
337
|
-
initialUrl
|
|
260
|
+
initialUrl,
|
|
261
|
+
...DEV_MENU_LAUNCH_ARGS
|
|
338
262
|
], { timeoutMs: 6e4 }));
|
|
339
263
|
return {
|
|
340
264
|
ok: true,
|
|
341
265
|
mode: "launch",
|
|
342
266
|
url,
|
|
343
267
|
jsLocation: jsLocationValue(metroPort),
|
|
344
|
-
pid
|
|
268
|
+
pid,
|
|
269
|
+
...restart
|
|
345
270
|
};
|
|
346
271
|
}
|
|
347
272
|
e.runFile("xcrun", [
|
|
@@ -354,16 +279,18 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
354
279
|
ok: true,
|
|
355
280
|
mode: "openurl",
|
|
356
281
|
url,
|
|
357
|
-
jsLocation: jsLocationValue(metroPort)
|
|
282
|
+
jsLocation: jsLocationValue(metroPort),
|
|
283
|
+
...restart
|
|
358
284
|
};
|
|
359
285
|
} catch (err) {
|
|
360
286
|
const pid = launchedWithInitialUrl ? launchedIosAppAfterNoHandle(err, udid, bundleId, e) : null;
|
|
361
|
-
if (pid) return {
|
|
287
|
+
if (pid && pid !== restart.restartedPid) return {
|
|
362
288
|
ok: true,
|
|
363
289
|
mode: "launch",
|
|
364
290
|
url,
|
|
365
291
|
jsLocation: jsLocationValue(metroPort),
|
|
366
|
-
pid
|
|
292
|
+
pid,
|
|
293
|
+
...restart
|
|
367
294
|
};
|
|
368
295
|
return {
|
|
369
296
|
failed: true,
|
|
@@ -373,22 +300,23 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
373
300
|
}
|
|
374
301
|
}
|
|
375
302
|
}
|
|
376
|
-
const preLaunchPid = iosAppProcess(udid, bundleId, { exec: e });
|
|
377
303
|
try {
|
|
378
304
|
const result = {
|
|
379
305
|
ok: true,
|
|
380
306
|
mode: "launch",
|
|
381
|
-
pid: parseLaunchedPid(e.runFile("xcrun", launchArgs, { timeoutMs: 6e4 }))
|
|
307
|
+
pid: parseLaunchedPid(e.runFile("xcrun", launchArgs, { timeoutMs: 6e4 })),
|
|
308
|
+
...restart
|
|
382
309
|
};
|
|
383
310
|
if (metroPort !== null) result.jsLocation = jsLocationValue(metroPort);
|
|
384
311
|
return result;
|
|
385
312
|
} catch (err) {
|
|
386
|
-
const pid =
|
|
387
|
-
if (pid) {
|
|
313
|
+
const pid = runningPid === null ? launchedIosAppAfterNoHandle(err, udid, bundleId, e) : null;
|
|
314
|
+
if (pid && pid !== restart.restartedPid) {
|
|
388
315
|
const result = {
|
|
389
316
|
ok: true,
|
|
390
317
|
mode: "launch",
|
|
391
|
-
pid
|
|
318
|
+
pid,
|
|
319
|
+
...restart
|
|
392
320
|
};
|
|
393
321
|
if (metroPort !== null) result.jsLocation = jsLocationValue(metroPort);
|
|
394
322
|
return result;
|
|
@@ -533,6 +461,39 @@ function reverseMetroPorts({ serial, metroPort, devicePorts = null }, { exec = n
|
|
|
533
461
|
reversed: pairs.map(([device, host]) => `tcp:${device}->tcp:${host}`)
|
|
534
462
|
};
|
|
535
463
|
}
|
|
464
|
+
function hasMetroReverse(listing, metroPort) {
|
|
465
|
+
return String(listing ?? "").split("\n").some((line) => {
|
|
466
|
+
const cols = line.trim().split(/\s+/);
|
|
467
|
+
return cols[1] === `tcp:${metroPort}` && cols[2] === `tcp:${metroPort}`;
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
/** Re-applies the launch's `metroPort` reverse when the device no longer has it. */
|
|
471
|
+
function ensureMetroReverse({ serial, metroPort }, { exec = null } = {}) {
|
|
472
|
+
const e = exec || getExecutor();
|
|
473
|
+
let listing;
|
|
474
|
+
try {
|
|
475
|
+
listing = e.runFile("adb", [
|
|
476
|
+
"-s",
|
|
477
|
+
serial,
|
|
478
|
+
"reverse",
|
|
479
|
+
"--list"
|
|
480
|
+
], ADB_SHELL_OPTIONS);
|
|
481
|
+
} catch {
|
|
482
|
+
return {
|
|
483
|
+
failed: true,
|
|
484
|
+
reason: `adb reverse --list failed on ${serial}`
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
if (hasMetroReverse(listing, metroPort)) return { restored: false };
|
|
488
|
+
const reversed = reverseMetroPorts({
|
|
489
|
+
serial,
|
|
490
|
+
metroPort
|
|
491
|
+
}, { exec: e });
|
|
492
|
+
return reversed.failed ? {
|
|
493
|
+
failed: true,
|
|
494
|
+
reason: reversed.reason ?? "adb reverse failed"
|
|
495
|
+
} : { restored: true };
|
|
496
|
+
}
|
|
536
497
|
const EMULATOR_HOST_LOOPBACK = "127.0.0.1";
|
|
537
498
|
const PHYSICAL_HOST_LOOPBACK = "localhost";
|
|
538
499
|
function androidMetroHost(physical) {
|
|
@@ -631,8 +592,31 @@ function openAndroidDevClientUrl({ serial, url, packageName }, { exec = null } =
|
|
|
631
592
|
url
|
|
632
593
|
};
|
|
633
594
|
}
|
|
595
|
+
function stopRunningAndroidApp(serial, packageName, exec) {
|
|
596
|
+
const pid = androidAppProcess(serial, packageName, { exec });
|
|
597
|
+
if (!pid) return {};
|
|
598
|
+
try {
|
|
599
|
+
exec.runFile("adb", [
|
|
600
|
+
"-s",
|
|
601
|
+
serial,
|
|
602
|
+
"shell",
|
|
603
|
+
"am",
|
|
604
|
+
"force-stop",
|
|
605
|
+
packageName
|
|
606
|
+
], ADB_SHELL_OPTIONS);
|
|
607
|
+
} catch (err) {
|
|
608
|
+
return {
|
|
609
|
+
failed: true,
|
|
610
|
+
code: LAUNCH_ERROR,
|
|
611
|
+
reason: `am force-stop ${packageName} failed on ${serial}, so the running app (pid ${pid}) was not restarted: ${describe(err)}`
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
return { restartedPid: pid };
|
|
615
|
+
}
|
|
634
616
|
function launchAndroidApp({ serial, packageName, metroPort, devClientScheme = null, physical = false }, { exec = null } = {}) {
|
|
635
617
|
const e = exec || getExecutor();
|
|
618
|
+
const restart = stopRunningAndroidApp(serial, packageName, e);
|
|
619
|
+
if (restart.failed) return restart;
|
|
636
620
|
const reversed = reverseMetroPorts({
|
|
637
621
|
serial,
|
|
638
622
|
metroPort
|
|
@@ -657,7 +641,8 @@ function launchAndroidApp({ serial, packageName, metroPort, devClientScheme = nu
|
|
|
657
641
|
const wiring = {
|
|
658
642
|
reversed: reversedPairs,
|
|
659
643
|
debugHttpHost: prefs.ok ? prefs.host : null,
|
|
660
|
-
debugHttpHostNote: prefs.ok ? null : prefs.reason
|
|
644
|
+
debugHttpHostNote: prefs.ok ? null : prefs.reason,
|
|
645
|
+
...restart
|
|
661
646
|
};
|
|
662
647
|
let devClientNote = null;
|
|
663
648
|
if (devClientScheme) {
|
|
@@ -725,6 +710,8 @@ function launchAndroidApp({ serial, packageName, metroPort, devClientScheme = nu
|
|
|
725
710
|
}
|
|
726
711
|
function launchAndroidReleaseApp({ serial, packageName }, { exec = null } = {}) {
|
|
727
712
|
const e = exec || getExecutor();
|
|
713
|
+
const restart = stopRunningAndroidApp(serial, packageName, e);
|
|
714
|
+
if (restart.failed) return restart;
|
|
728
715
|
const component = resolveLaunchActivity(serial, packageName, { exec: e });
|
|
729
716
|
if (component) try {
|
|
730
717
|
e.runFile("adb", [
|
|
@@ -739,7 +726,8 @@ function launchAndroidReleaseApp({ serial, packageName }, { exec = null } = {})
|
|
|
739
726
|
return {
|
|
740
727
|
ok: true,
|
|
741
728
|
mode: "am-start",
|
|
742
|
-
component
|
|
729
|
+
component,
|
|
730
|
+
...restart
|
|
743
731
|
};
|
|
744
732
|
} catch (err) {
|
|
745
733
|
return {
|
|
@@ -760,7 +748,8 @@ function launchAndroidReleaseApp({ serial, packageName }, { exec = null } = {})
|
|
|
760
748
|
], ADB_SHELL_OPTIONS);
|
|
761
749
|
return {
|
|
762
750
|
ok: true,
|
|
763
|
-
mode: "monkey"
|
|
751
|
+
mode: "monkey",
|
|
752
|
+
...restart
|
|
764
753
|
};
|
|
765
754
|
} catch (err) {
|
|
766
755
|
return {
|
|
@@ -816,4 +805,4 @@ function androidAppProcess(serial, packageName, { exec = null } = {}) {
|
|
|
816
805
|
}
|
|
817
806
|
}
|
|
818
807
|
//#endregion
|
|
819
|
-
export {
|
|
808
|
+
export { restartedAppNote as S, installIosApp as _, IOS_DEV_MENU_OFF_DEFAULTS_PLIST as a, launchAndroidReleaseApp as b, androidDevClientUrl as c, devClientUrl as d, deviceShellArg as f, installConflictKind as g, installAndroidApp as h, INSTALL_ERROR as i, clearOtherUserApps as l, hasMetroReverse as m, ANDROID_DISABLE_AUTO_LAUNCH_EXTRA as n, LAUNCH_ERROR as o, ensureMetroReverse as p, DEFAULT_METRO_PORT as r, androidAppProcess as s, ADB_INSTALL_TIMEOUT_MS as t, devClientDeepLink as u, iosAppProcess as v, launchIosApp as x, launchAndroidApp as y };
|