stim 1.20.2 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -8
- package/dist/acquire-artifact-CD4lbiWE.mjs +153 -0
- package/dist/act-DHAw2A2S.mjs +2667 -0
- package/dist/activity-BzVfHSrY.mjs +1376 -0
- package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-zh1vhbLp.mjs} +21 -65
- package/dist/{android-HqP1_vB_.mjs → android-BEJ8Jpl7.mjs} +2 -2
- package/dist/{android-DCKZrNvV.mjs → android-BLgbNqox.mjs} +128 -78
- package/dist/{android-Dlzxshgp.mjs → android-CV_GCELZ.mjs} +5 -5
- package/dist/{android-Mz_Inn3w.mjs → android-DUYkNF4u.mjs} +184 -102
- package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-Ct5b1xCK.mjs} +7 -6
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/android-project-BCAAmMwz.mjs +12 -0
- package/dist/api.d.mts +740 -8
- package/dist/api.mjs +585 -1
- package/dist/{artifact-HSwkIWEQ.mjs → artifact-B8T3S5gi.mjs} +223 -201
- package/dist/{artifact-D3czlUvT.mjs → artifact-DAuZ-FNU.mjs} +158 -148
- package/dist/{browser-web-CA-F1GQo.mjs → browser-web-QQzVjz3O.mjs} +26 -24
- package/dist/budget-Bs6SxxzO.mjs +9154 -0
- package/dist/{build-DYDbfkk5.mjs → build-CoPzQRNw.mjs} +144 -96
- package/dist/build-cache-DmyR9Zzc.mjs +602 -0
- package/dist/build-plan-CaFskB7_.mjs +188 -0
- package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DkkqguoK.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-zdKiYQ3E.mjs → ccache-BJRZ9pG3.mjs} +10 -9
- package/dist/{cdp-Dq_ypAlJ.mjs → cdp-CWmIUMbw.mjs} +18 -5
- package/dist/{chrome-BnzZMqsR.mjs → chrome-B6tfCta1.mjs} +7 -4
- package/dist/{cli-CLP3diBm.mjs → cli-0DYf8QhQ.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/client-B7QVOlCr.d.mts +253 -0
- package/dist/client-UXD70ZbM.mjs +1406 -0
- package/dist/collector-run.d.mts +4 -40
- package/dist/collector-run.mjs +9 -8
- package/dist/{command-output-BTy8hZ0F.mjs → command-output-B1UrjZHL.mjs} +1 -1
- package/dist/config-CYcBF478.mjs +949 -0
- package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-CqeBlrEn.mjs} +3 -3
- package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-BbKQW83h.mjs} +20 -5
- package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-DFRyG1_o.mjs} +1 -1
- package/dist/{dev-client-DAWVIGBu.mjs → dev-client-UOeESKm6.mjs} +2 -2
- package/dist/device-DCxH7_By.mjs +1068 -0
- package/dist/{device-BECOiufl.mjs → device-ExJq8Ei7.mjs} +35 -35
- package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-CMlqEcvw.mjs} +43 -13
- package/dist/device-host-worker.mjs +65 -61
- package/dist/{device-ios-COSi6oS1.mjs → device-ios-DRUeKaFV.mjs} +48 -45
- package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-C8raGFoP.mjs} +14 -26
- package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-DMRpVX9a.mjs} +5 -5
- package/dist/doctor-BLHCYxzi.mjs +2 -0
- package/dist/{doctor-kfMBnUw6.mjs → doctor-DTvaDOda.mjs} +281 -317
- package/dist/{doctor-CB8oZKCk.mjs → doctor-Dhqebm0q.mjs} +183 -91
- package/dist/doctor-fingerprint.mjs +19 -0
- package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-Cv1F10Kj.mjs} +40 -21
- package/dist/{eas-build-JyfqyHfC.mjs → eas-build-BomfRnFT.mjs} +53 -20
- package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-DJwZpy0c.mjs} +26 -208
- package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-op6A54yi.mjs} +229 -11
- package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-Bf0rZvG9.mjs} +172 -82
- package/dist/exec-H20xSg2T.d.mts +65 -0
- package/dist/exec-_UbtCQcG.mjs +750 -0
- package/dist/gc-C-WwL0yi.mjs +3 -0
- package/dist/{gc-qWOMdnER.mjs → gc-_-dCXdyL.mjs} +584 -796
- package/dist/git-C3iTsJaZ.mjs +73 -0
- package/dist/{guide-G9cAbVAc.mjs → guide-Yqwt2bd6.mjs} +941 -269
- package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-Bw-honsd.mjs} +8 -6
- package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DB_gBPfY.mjs} +34 -19
- package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CUvOf4Vr.mjs} +1 -1
- package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-DL_P5AdN.mjs} +77 -43
- package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-QI141yKk.mjs} +21 -17
- package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-Ksyjgzq-.mjs} +30 -21
- package/dist/idle-BVeRGroT.d.mts +24 -0
- package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DaKmZi0z.mjs} +11 -10
- package/dist/{ios-BwVCF7oA.mjs → ios-CQ68hG9s.mjs} +8 -8
- package/dist/{ios-RkW4pnQf.mjs → ios-CpByZy12.mjs} +140 -80
- package/dist/{ios-device-B5veSDDQ.mjs → ios-device-CXGP1bsD.mjs} +1 -1
- package/dist/{ios-device-D7pi2Sca.mjs → ios-device-CwFMehUS.mjs} +51 -26
- package/dist/{ios-project-K9hY_Jab.mjs → ios-project-WuwwBdvW.mjs} +13 -13
- package/dist/{ios-nOLJGVdy.mjs → ios-qNJt4dFm.mjs} +1 -1
- package/dist/ios-signing-DTTIChGs.mjs +489 -0
- package/dist/{ios-state-CBLe1xYw.mjs → ios-state-DvFX-K_l.mjs} +1 -1
- package/dist/{ios-Ce7bc7br.mjs → ios-ubFsBzwq.mjs} +129 -86
- package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Cc1dttps.mjs} +53 -26
- package/dist/{launch-F4sOqAhB.mjs → launch-CD1yVc7U.mjs} +91 -90
- package/dist/{launch-C3qJ6Agb.mjs → launch-Zq2mOSDy.mjs} +82 -541
- package/dist/logs-BS00Anxf.mjs +352 -0
- package/dist/logs-CMm05HxN.mjs +255 -0
- package/dist/{macos-D7uDvO-z.mjs → macos-B65--pPd.mjs} +1 -1
- package/dist/{macos-Ch5VJmcS.mjs → macos-C-0qJ6zq.mjs} +225 -212
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +122 -247
- package/dist/{metro-DnCEjCxs.mjs → metro-DEXpIhHC.mjs} +67 -12
- package/dist/{metro-gateway-CX9Xlkq2.mjs → metro-gateway-BMJNlj3E.mjs} +20 -12
- package/dist/{named-ports-4WopRPg-.mjs → named-ports-BWTzt6mu.mjs} +8 -63
- package/dist/native-android-JACyjTZs.mjs +844 -0
- package/dist/{native-gradle-inputs-BsLRrl7u.mjs → native-gradle-inputs-Bep9JcSF.mjs} +128 -140
- package/dist/native-inputs-TRTTTRxt.mjs +91 -0
- package/dist/native-run-DY_RLx3C.mjs +277 -0
- package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-Dg1Q7tfF.mjs} +9 -8
- package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-CB2iQeWq.mjs} +27 -18
- package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-CXX39F7o.mjs} +96 -47
- package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
- package/dist/offload-worker.d.mts +1 -46
- package/dist/offload-worker.mjs +197 -66
- package/dist/{ownership-DCtw_2IA.mjs → ownership-DEmM5vhh.mjs} +3 -3
- package/dist/{page-DRHy329N.mjs → page-CPaHeYqj.mjs} +7 -4
- package/dist/paths-BsJMoPP2.mjs +12 -0
- package/dist/paths-DQtTgsBf.mjs +42 -0
- package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BqGbTa61.mjs} +5 -5
- package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-Bwj-IjY1.mjs} +6 -6
- package/dist/{ports-DdSUicVo.mjs → ports-D-MmCTdv.mjs} +3 -3
- package/dist/prebuild-uD_ipCxF.mjs +449 -0
- package/dist/{project-_phNIJfs.mjs → project-BZNjmW_8.mjs} +65 -37
- package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-Lfetn8Kr.mjs} +2 -2
- package/dist/pull-request-zjCSAryH.d.mts +120 -0
- package/dist/pull-requests.d.mts +1 -119
- package/dist/pull-requests.mjs +1 -1
- package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-DuzH0cn3.mjs} +74 -48
- package/dist/{gradle-DSrXb6lG.mjs → react-native-build-rhk4smwQ.mjs} +292 -15
- package/dist/react-native-doctor-CQpuIMso.mjs +234 -0
- package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-Bhq1rJeV.mjs} +46 -28
- package/dist/{recordings-D0d5aQt0.mjs → recordings-DYteQSu4.mjs} +12 -9
- package/dist/{reload-C8JhxjSh.mjs → reload-CmTRFJaX.mjs} +93 -47
- package/dist/reload-DzjSl5P_.mjs +2 -0
- package/dist/{remote-BiR6aYjy.mjs → remote-ByYkXdGD.mjs} +15 -10
- package/dist/result-DNiS-tTP.mjs +434 -0
- package/dist/{run-BtPgpKks.mjs → run-D23HmJMs.mjs} +4 -5
- package/dist/selection-CSl9i5qU.mjs +619 -0
- package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CxTrvDg8.mjs} +3 -4
- package/dist/{server-command-CTtCkmcQ.mjs → server-command-CtzloH3v.mjs} +14 -7
- package/dist/server-expo-C-90EhcG.mjs +2 -0
- package/dist/{server-expo-DsguMGUF.mjs → server-expo-DT_F_uVI.mjs} +50 -9
- package/dist/{settings-B717odTD.mjs → settings-CsJDEXgK.mjs} +234 -24
- package/dist/{settings-vk3mJGSm.d.mts → settings-DkdmlelE.d.mts} +6 -4
- package/dist/settings-T1gtc3bf.mjs +114 -0
- package/dist/settings-write-HyVZ8eQ8.mjs +359 -0
- package/dist/settings.schema.json +163 -16
- package/dist/{simslim-CCr3rE-A.mjs → simslim-Cgk17SXV.mjs} +14 -12
- package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-DF8VfT64.mjs} +15 -20
- package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
- package/dist/stage-BIS0ydsV.mjs +183 -0
- package/dist/{start-BWqzODpb.mjs → start-7lpH7hmN.mjs} +63 -44
- package/dist/{start-TXeMmmO2.mjs → start-RChynRDp.mjs} +1 -1
- package/dist/{state-D1Icyjlu.mjs → state-C4ZtUisW.mjs} +40 -13
- package/dist/{state-CG_OFoaA.mjs → state-XMziexv2.mjs} +3 -2
- package/dist/{stats-BoY5sEPU.mjs → stats-53T7OTb9.mjs} +7 -13
- package/dist/stats-report-BFfMpWWF.mjs +16 -0
- package/dist/{status-WgFbkRzj.mjs → status-BL7jVyAB.mjs} +535 -447
- package/dist/status-CSi6tlRq.mjs +2 -0
- package/dist/{status-BTA7kKiQ.mjs → status-DqEUSSxs.mjs} +6 -4
- package/dist/{status-watch-C23ILtf9.mjs → status-watch-GDCfqpTE.mjs} +187 -22
- package/dist/status-worker.d.mts +1 -0
- package/dist/status-worker.mjs +19 -0
- package/dist/stim-desktop-C12we7lz.mjs +112 -0
- package/dist/{stop-DR6VoDIk.mjs → stop-Bk_1qiV6.mjs} +2 -2
- package/dist/{stop-BNmBMi1F.mjs → stop-CPzlM1L-.mjs} +138 -98
- package/dist/{stop-DPEhunlw.mjs → stop-D7h6jAXQ.mjs} +11 -10
- package/dist/supervisor-run.d.mts +8 -17
- package/dist/supervisor-run.mjs +63 -27
- package/dist/{support-DMTqj3Hm.mjs → support-67vraa1Q.mjs} +18 -11
- package/dist/{support-CwjbFs9H.mjs → support-Dlu37g6H.mjs} +12 -12
- package/dist/{swiftpm-macos-DRNVJWlb.mjs → swiftpm-macos-p8WZbxKU.mjs} +35 -24
- package/dist/toolchain-DhKwp9iI.mjs +2 -0
- package/dist/toolchain-Hp9sCpK4.mjs +873 -0
- package/dist/{trigger-CigAYjeL.mjs → trigger-BAahxUPq.mjs} +20 -5
- package/dist/trigger-Bf3uDcpv.mjs +2 -0
- package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-BHX5r0Ei.mjs} +250 -156
- package/dist/{web-BDBMxDpx.mjs → web-CJmIj6AI.mjs} +18 -13
- package/dist/web-DknQETPs.mjs +2 -0
- package/dist/web-run.mjs +11 -12
- package/dist/windows-report.d.mts +1 -0
- package/dist/windows-report.mjs +18 -0
- package/dist/windows-report.ps1 +43 -0
- package/dist/workspace-process-lock-1_1OoVW5.mjs +57 -0
- package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-Cjuigeeu.mjs} +62 -58
- package/dist/{workspaces-C36s2jb9.mjs → workspaces-BccMFmGQ.mjs} +1188 -1079
- package/dist/worktree-CK2MpJW5.mjs +2 -0
- package/dist/{worktree-CgvJYJ-Q.mjs → worktree-DQ6Zi2Mv.mjs} +304 -53
- package/dist/xcode-Zlx3qjEs.mjs +896 -0
- package/package.json +7 -5
- package/shim/android-optimizations.gradle +7 -5
- package/dist/activity-BSV745Kz.mjs +0 -629
- package/dist/api-qvOzWyfO.mjs +0 -154
- package/dist/api-run.mjs +0 -294
- package/dist/app-install-BIKtMfPq.mjs +0 -896
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
- package/dist/budget-f7516Zk0.mjs +0 -4106
- package/dist/build-facts-DcLv2HSd.d.mts +0 -111
- package/dist/cancellation-C_22VQTH.mjs +0 -24
- package/dist/client-qQAaXSUs.mjs +0 -1771
- package/dist/config-BYDxlMY3.mjs +0 -562
- package/dist/device-DuiPJQSn.mjs +0 -290
- package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
- package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
- package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
- package/dist/exec-DqKo9GKJ.mjs +0 -268
- package/dist/git-DDfFzkMm.mjs +0 -45
- package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
- package/dist/logs-BGrEUaEs.mjs +0 -383
- package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
- package/dist/native-android-D5qc3-_v.mjs +0 -226
- package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
- package/dist/plan-C4TjdPsR.mjs +0 -260
- package/dist/prebuild-DYbucPXy.mjs +0 -212
- package/dist/preview-78a9kR_-.mjs +0 -1011
- package/dist/react-native-build-CtCccJtb.mjs +0 -239
- package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
- package/dist/remote-cache-OyOyVIS3.mjs +0 -526
- package/dist/result-CaJg5Iat.mjs +0 -186
- package/dist/server-expo-Bigriskl.mjs +0 -2
- package/dist/settings-BORNaaCO.mjs +0 -402
- package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
- package/dist/stage-KNTQopqv.mjs +0 -157
- package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
- package/dist/tailnet-Dh-qiYzG.mjs +0 -265
- package/dist/toolchain-BFkAcstd.mjs +0 -2
- package/dist/toolchain-DxSsNssu.mjs +0 -1657
- package/dist/trigger-9_USgmxz.mjs +0 -2
- package/dist/web-Dq-i3wzJ.mjs +0 -2
- package/dist/worktree-DpLdCHga.mjs +0 -2
- package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
- package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
|
@@ -1,896 +0,0 @@
|
|
|
1
|
-
import { r as debugLog, t as getExecutor } from "./exec-DqKo9GKJ.mjs";
|
|
2
|
-
import { R as deviceHoldsApk, g as listUserApps, k as uninstallIosApp, u as iosSimulatorFailureAdvice, z as deviceHoldsBundle } from "./ios-RkW4pnQf.mjs";
|
|
3
|
-
import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-B5veSDDQ.mjs";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
//#region src/engine/app-schemes.ts
|
|
6
|
-
function schemesFromInfoPlist(plist) {
|
|
7
|
-
const types = plist?.CFBundleURLTypes;
|
|
8
|
-
if (!Array.isArray(types)) return [];
|
|
9
|
-
const out = [];
|
|
10
|
-
for (const type of types) {
|
|
11
|
-
const schemes = type?.CFBundleURLSchemes;
|
|
12
|
-
if (Array.isArray(schemes)) out.push(...schemes.filter((s) => typeof s === "string" && s.trim() !== ""));
|
|
13
|
-
}
|
|
14
|
-
return out;
|
|
15
|
-
}
|
|
16
|
-
function readBundleSchemes(appPath, { exec = null } = {}) {
|
|
17
|
-
if (typeof appPath !== "string" || appPath.trim() === "") return [];
|
|
18
|
-
const e = exec || getExecutor();
|
|
19
|
-
let out;
|
|
20
|
-
try {
|
|
21
|
-
out = e.runFile("plutil", [
|
|
22
|
-
"-convert",
|
|
23
|
-
"json",
|
|
24
|
-
"-o",
|
|
25
|
-
"-",
|
|
26
|
-
join(appPath, "Info.plist")
|
|
27
|
-
], { timeoutMs: 1e4 });
|
|
28
|
-
} catch {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
try {
|
|
32
|
-
return schemesFromInfoPlist(JSON.parse(String(out)));
|
|
33
|
-
} catch {
|
|
34
|
-
return [];
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
const THIRD_PARTY_SCHEME = /^(?:fb\d+|com\.googleusercontent\.apps\.|msauth\.|msauthv2|twitterkit-|db-[a-z0-9]+$|spotify|snapchat|com\.facebook)/i;
|
|
38
|
-
function approvableSchemes(schemes) {
|
|
39
|
-
return (Array.isArray(schemes) ? schemes : []).filter((s) => typeof s === "string" && s.trim() !== "").map((s) => s.trim()).filter((s) => !/^(?:https?|mailto|tel|sms|itms(?:-apps)?)$/i.test(s) && !THIRD_PARTY_SCHEME.test(s));
|
|
40
|
-
}
|
|
41
|
-
function pickDevClientScheme(schemes) {
|
|
42
|
-
const all = approvableSchemes(schemes);
|
|
43
|
-
const expo = all.filter((s) => s.startsWith("exp+"));
|
|
44
|
-
return (expo.length ? expo : all).toSorted((a, b) => b.length - a.length)[0] ?? null;
|
|
45
|
-
}
|
|
46
|
-
//#endregion
|
|
47
|
-
//#region src/engine/app-install.ts
|
|
48
|
-
const INSTALL_ERROR = "STIM_INSTALL_FAILED";
|
|
49
|
-
const LAUNCH_ERROR = "STIM_LAUNCH_FAILED";
|
|
50
|
-
const DEFAULT_METRO_PORT = 8081;
|
|
51
|
-
const IOS_SCHEME_APPROVAL_DOMAIN = "com.apple.launchservices.schemeapproval";
|
|
52
|
-
const IOS_SCHEME_APPROVAL_OPENER = "com.apple.CoreSimulator.CoreSimulatorBridge";
|
|
53
|
-
const IOS_DEV_MENU_OFF_KEYS = ["EXDevMenuShowsAtLaunch", "EXDevMenuShowFloatingActionButton"];
|
|
54
|
-
const DEV_CLIENT_ONBOARDING_QUERY = "disableOnboarding=1";
|
|
55
|
-
const DEV_CLIENT_DISABLE_FAB_QUERY = "disableFab=1";
|
|
56
|
-
const DEV_CLIENT_DEV_MENU_OFF_QUERY = "disableFab=1&disableAutoLaunch=1";
|
|
57
|
-
const DEV_CLIENT_RESERVED_DEV_MENU_OFF_QUERY = "__expo_disable_fab=1&__expo_disable_auto_launch=1";
|
|
58
|
-
const ANDROID_DISABLE_AUTO_LAUNCH_EXTRA = "EXDevMenuDisableAutoLaunch";
|
|
59
|
-
const IOS_DEV_MENU_OFF_DEFAULTS_PLIST = [
|
|
60
|
-
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
|
|
61
|
-
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">",
|
|
62
|
-
"<plist version=\"1.0\">",
|
|
63
|
-
"<dict>",
|
|
64
|
-
...IOS_DEV_MENU_OFF_KEYS.flatMap((key) => [` <key>${key}</key>`, " <false/>"]),
|
|
65
|
-
"</dict>",
|
|
66
|
-
"</plist>",
|
|
67
|
-
""
|
|
68
|
-
].join("\n");
|
|
69
|
-
function writeIosDevMenuOffDefaults(udid, bundleId, exec) {
|
|
70
|
-
for (const key of IOS_DEV_MENU_OFF_KEYS) exec.runFile("xcrun", [
|
|
71
|
-
"simctl",
|
|
72
|
-
"spawn",
|
|
73
|
-
udid,
|
|
74
|
-
"defaults",
|
|
75
|
-
"write",
|
|
76
|
-
bundleId,
|
|
77
|
-
key,
|
|
78
|
-
"-bool",
|
|
79
|
-
"false"
|
|
80
|
-
], { timeoutMs: 6e4 });
|
|
81
|
-
}
|
|
82
|
-
function describeIosSimulatorFailure(error, exec) {
|
|
83
|
-
const detail = describe(error);
|
|
84
|
-
return error?.code === "ETIMEDOUT" ? `${detail}. ${iosSimulatorFailureAdvice(exec)}` : detail;
|
|
85
|
-
}
|
|
86
|
-
function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null, schemeApprovals = [], proveInstalled = true }, { exec = null, now = null } = {}) {
|
|
87
|
-
const e = exec || getExecutor();
|
|
88
|
-
const artifactStartedAt = now?.();
|
|
89
|
-
const skipped = bundleId && proveInstalled ? deviceHoldsBundle({
|
|
90
|
-
udid,
|
|
91
|
-
bundleId,
|
|
92
|
-
appPath
|
|
93
|
-
}, { exec: e }) : false;
|
|
94
|
-
if (!skipped) try {
|
|
95
|
-
e.runFile("xcrun", [
|
|
96
|
-
"simctl",
|
|
97
|
-
"install",
|
|
98
|
-
udid,
|
|
99
|
-
appPath
|
|
100
|
-
], {
|
|
101
|
-
timeoutMs: 3e5,
|
|
102
|
-
killSignal: "SIGKILL"
|
|
103
|
-
});
|
|
104
|
-
} catch (err) {
|
|
105
|
-
return {
|
|
106
|
-
failed: true,
|
|
107
|
-
code: INSTALL_ERROR,
|
|
108
|
-
reason: `simctl install failed for ${appPath}: ${describeIosSimulatorFailure(err, e)}`
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
const artifactFinishedAt = now?.();
|
|
112
|
-
const artifactDurationMs = artifactStartedAt !== void 0 && artifactFinishedAt !== void 0 ? artifactFinishedAt - artifactStartedAt : void 0;
|
|
113
|
-
const devMenuKeys = bundleId && devClientScheme && !skipped ? IOS_DEV_MENU_OFF_KEYS : [];
|
|
114
|
-
const missingApprovals = (bundleId ? iosSchemeApprovalKeys(bundleId, [...approvableSchemes(readBundleSchemes(appPath, { exec: e })), ...devClientScheme ? [devClientScheme] : []]) : []).filter((key) => !schemeApprovals.includes(`${key}=${bundleId}`));
|
|
115
|
-
const preparing = bundleId && (devMenuKeys.length > 0 || missingApprovals.length > 0);
|
|
116
|
-
const preparationStartedAt = preparing ? artifactFinishedAt : void 0;
|
|
117
|
-
if (bundleId && preparing) try {
|
|
118
|
-
if (devMenuKeys.length > 0) writeIosDevMenuOffDefaults(udid, bundleId, e);
|
|
119
|
-
for (const key of missingApprovals) e.runFile("xcrun", [
|
|
120
|
-
"simctl",
|
|
121
|
-
"spawn",
|
|
122
|
-
udid,
|
|
123
|
-
"defaults",
|
|
124
|
-
"write",
|
|
125
|
-
IOS_SCHEME_APPROVAL_DOMAIN,
|
|
126
|
-
key,
|
|
127
|
-
"-string",
|
|
128
|
-
bundleId
|
|
129
|
-
], { timeoutMs: 6e4 });
|
|
130
|
-
} catch (err) {
|
|
131
|
-
return {
|
|
132
|
-
failed: true,
|
|
133
|
-
code: INSTALL_ERROR,
|
|
134
|
-
reason: `Installed ${bundleId}, but could not prepare the dev client: ${describeIosSimulatorFailure(err, e)}`
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
const devClientPreparationDurationMs = now && preparationStartedAt !== void 0 ? now() - preparationStartedAt : void 0;
|
|
138
|
-
const timing = {
|
|
139
|
-
...artifactDurationMs === void 0 ? {} : { artifactDurationMs },
|
|
140
|
-
...devClientPreparationDurationMs === void 0 ? {} : { devClientPreparationDurationMs },
|
|
141
|
-
...missingApprovals.length > 0 ? { schemeApprovals: [...schemeApprovals, ...missingApprovals.map((key) => `${key}=${bundleId}`)] } : {}
|
|
142
|
-
};
|
|
143
|
-
return skipped ? {
|
|
144
|
-
ok: true,
|
|
145
|
-
appPath,
|
|
146
|
-
skipped: true,
|
|
147
|
-
...timing
|
|
148
|
-
} : {
|
|
149
|
-
ok: true,
|
|
150
|
-
appPath,
|
|
151
|
-
...timing
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
function clearOtherUserApps({ udid, keep }, { list = listUserApps, uninstall = uninstallIosApp } = {}) {
|
|
155
|
-
const removed = [];
|
|
156
|
-
const failed = [];
|
|
157
|
-
let installed;
|
|
158
|
-
try {
|
|
159
|
-
installed = list(udid);
|
|
160
|
-
} catch {
|
|
161
|
-
return {
|
|
162
|
-
listed: false,
|
|
163
|
-
kept: false,
|
|
164
|
-
removed,
|
|
165
|
-
failed
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
for (const bundleId of installed) {
|
|
169
|
-
if (bundleId === keep) continue;
|
|
170
|
-
try {
|
|
171
|
-
uninstall(udid, bundleId);
|
|
172
|
-
removed.push(bundleId);
|
|
173
|
-
} catch {
|
|
174
|
-
failed.push(bundleId);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return {
|
|
178
|
-
listed: true,
|
|
179
|
-
kept: keep ? installed.includes(keep) : false,
|
|
180
|
-
removed,
|
|
181
|
-
failed
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
function jsLocationValue(metroPort) {
|
|
185
|
-
return `localhost:${metroPort}`;
|
|
186
|
-
}
|
|
187
|
-
function devClientDeepLink(scheme, projectOrigin, { devMenuParams = false } = {}) {
|
|
188
|
-
const projectQuery = devMenuParams ? `${DEV_CLIENT_ONBOARDING_QUERY}&${DEV_CLIENT_DEV_MENU_OFF_QUERY}&${DEV_CLIENT_RESERVED_DEV_MENU_OFF_QUERY}` : DEV_CLIENT_ONBOARDING_QUERY;
|
|
189
|
-
const projectUrl = `${projectOrigin.replace(/\/+$/, "")}/?${projectQuery}`;
|
|
190
|
-
return `${scheme}://expo-development-client/?url=${encodeURIComponent(projectUrl)}&${devMenuParams ? DEV_CLIENT_DEV_MENU_OFF_QUERY : DEV_CLIENT_DISABLE_FAB_QUERY}`;
|
|
191
|
-
}
|
|
192
|
-
function devClientUrl(scheme, metroPort, host = "localhost", options = {}) {
|
|
193
|
-
return devClientDeepLink(scheme, `http://${host}:${metroPort}`, options);
|
|
194
|
-
}
|
|
195
|
-
function iosSchemeApprovalKeys(bundleId, schemes) {
|
|
196
|
-
return [.../* @__PURE__ */ new Set([bundleId, ...schemes])].map((target) => `${IOS_SCHEME_APPROVAL_OPENER}-->${target}`);
|
|
197
|
-
}
|
|
198
|
-
function restartedAppNote(restartedPid, lead = " ") {
|
|
199
|
-
return restartedPid ? `${lead}restarted running app (was pid ${restartedPid})` : "";
|
|
200
|
-
}
|
|
201
|
-
function parseLaunchedPid(text) {
|
|
202
|
-
if (typeof text !== "string") return null;
|
|
203
|
-
const match = text.trim().match(/:\s*(\d+)\s*$/);
|
|
204
|
-
if (!match) return null;
|
|
205
|
-
const pid = Number(match[1]);
|
|
206
|
-
return Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
207
|
-
}
|
|
208
|
-
function appProcessFromPid(pid) {
|
|
209
|
-
return pid === null ? { state: "stopped" } : {
|
|
210
|
-
state: "running",
|
|
211
|
-
pid
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
function iosAppProcess(udid, bundleId, { exec = null } = {}) {
|
|
215
|
-
const e = exec || getExecutor();
|
|
216
|
-
const started = performance.now();
|
|
217
|
-
let probe = { state: "unknown" };
|
|
218
|
-
let failure = {};
|
|
219
|
-
try {
|
|
220
|
-
const out = e.runFile("xcrun", [
|
|
221
|
-
"simctl",
|
|
222
|
-
"spawn",
|
|
223
|
-
udid,
|
|
224
|
-
"launchctl",
|
|
225
|
-
"list"
|
|
226
|
-
], { timeoutMs: 2e3 });
|
|
227
|
-
const label = `UIKitApplication:${bundleId}[`;
|
|
228
|
-
probe = { state: "stopped" };
|
|
229
|
-
for (const line of out.split("\n")) {
|
|
230
|
-
if (!line.includes(label)) continue;
|
|
231
|
-
const candidate = Number(line.trim().split(/\s+/)[0]);
|
|
232
|
-
if (Number.isInteger(candidate) && candidate > 0) {
|
|
233
|
-
probe = {
|
|
234
|
-
state: "running",
|
|
235
|
-
pid: candidate
|
|
236
|
-
};
|
|
237
|
-
break;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return probe;
|
|
241
|
-
} catch (error) {
|
|
242
|
-
const { code, status } = error ?? {};
|
|
243
|
-
failure = {
|
|
244
|
-
...typeof code === "string" ? { code } : {},
|
|
245
|
-
...typeof status === "number" ? { exit: status } : {}
|
|
246
|
-
};
|
|
247
|
-
return probe;
|
|
248
|
-
} finally {
|
|
249
|
-
debugLog.log("ios.app-process", {
|
|
250
|
-
deviceId: udid,
|
|
251
|
-
bundleId,
|
|
252
|
-
state: probe.state === "stopped" ? "absent" : probe.state,
|
|
253
|
-
...probe.state === "running" ? { appPid: probe.pid } : {},
|
|
254
|
-
ms: Math.round(performance.now() - started),
|
|
255
|
-
...failure
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
function launchedIosAppAfterNoHandle(error, udid, bundleId, exec) {
|
|
260
|
-
const stderr = String(error?.stderr ?? "");
|
|
261
|
-
if (!stderr.includes("domain=NSPOSIXErrorDomain, code=3") || !stderr.includes(`Application launch for '${bundleId}' did not return a process handle nor launch error.`)) return null;
|
|
262
|
-
const probe = iosAppProcess(udid, bundleId, { exec });
|
|
263
|
-
return probe.state === "running" ? probe.pid : null;
|
|
264
|
-
}
|
|
265
|
-
function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, devMenuParams = false, consolePaths }, { exec = null } = {}) {
|
|
266
|
-
const e = exec || getExecutor();
|
|
267
|
-
const running = iosAppProcess(udid, bundleId, { exec: e });
|
|
268
|
-
const stateUnknown = running.state === "unknown";
|
|
269
|
-
const launchArgs = [
|
|
270
|
-
"simctl",
|
|
271
|
-
"launch",
|
|
272
|
-
...consolePaths ? [`--stdout=${consolePaths.stdout}`, `--stderr=${consolePaths.stderr}`] : [],
|
|
273
|
-
...stateUnknown ? ["--terminate-running-process"] : [],
|
|
274
|
-
udid,
|
|
275
|
-
bundleId
|
|
276
|
-
];
|
|
277
|
-
const restart = {};
|
|
278
|
-
if (running.state === "running") {
|
|
279
|
-
try {
|
|
280
|
-
e.runFile("xcrun", [
|
|
281
|
-
"simctl",
|
|
282
|
-
"terminate",
|
|
283
|
-
udid,
|
|
284
|
-
bundleId
|
|
285
|
-
], { timeoutMs: 3e4 });
|
|
286
|
-
} catch (err) {
|
|
287
|
-
return {
|
|
288
|
-
failed: true,
|
|
289
|
-
code: LAUNCH_ERROR,
|
|
290
|
-
reason: `simctl terminate ${bundleId} failed, so the running app (pid ${running.pid}) was not restarted: ${describeIosSimulatorFailure(err, e)}`
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
restart.restartedPid = running.pid;
|
|
294
|
-
}
|
|
295
|
-
if (metroPort !== null) {
|
|
296
|
-
try {
|
|
297
|
-
e.runFile("xcrun", [
|
|
298
|
-
"simctl",
|
|
299
|
-
"spawn",
|
|
300
|
-
udid,
|
|
301
|
-
"defaults",
|
|
302
|
-
"write",
|
|
303
|
-
bundleId,
|
|
304
|
-
"RCT_jsLocation",
|
|
305
|
-
jsLocationValue(metroPort)
|
|
306
|
-
], { timeoutMs: 6e4 });
|
|
307
|
-
} catch (err) {
|
|
308
|
-
return {
|
|
309
|
-
failed: true,
|
|
310
|
-
code: LAUNCH_ERROR,
|
|
311
|
-
reason: `Could not point ${bundleId} at Metro port ${metroPort} (defaults write RCT_jsLocation): ${describeIosSimulatorFailure(err, e)}`
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
if (devClientScheme) {
|
|
315
|
-
const url = devClientUrl(devClientScheme, metroPort, "localhost", { devMenuParams });
|
|
316
|
-
const viaInitialUrl = Boolean(consolePaths) || stateUnknown;
|
|
317
|
-
if (!viaInitialUrl) try {
|
|
318
|
-
writeIosDevMenuOffDefaults(udid, bundleId, e);
|
|
319
|
-
} catch (err) {
|
|
320
|
-
return {
|
|
321
|
-
failed: true,
|
|
322
|
-
code: LAUNCH_ERROR,
|
|
323
|
-
reason: `Could not turn off ${bundleId}'s dev menu before opening it (defaults write): ${describeIosSimulatorFailure(err, e)}`
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
let launchedWithInitialUrl = false;
|
|
327
|
-
try {
|
|
328
|
-
if (viaInitialUrl) {
|
|
329
|
-
const initialUrl = new URL(url).searchParams.get("url");
|
|
330
|
-
launchedWithInitialUrl = true;
|
|
331
|
-
const pid = parseLaunchedPid(e.runFile("xcrun", [
|
|
332
|
-
...launchArgs,
|
|
333
|
-
"--initialUrl",
|
|
334
|
-
initialUrl,
|
|
335
|
-
...DEV_MENU_LAUNCH_ARGS
|
|
336
|
-
], { timeoutMs: 6e4 }));
|
|
337
|
-
return {
|
|
338
|
-
ok: true,
|
|
339
|
-
mode: "launch",
|
|
340
|
-
url,
|
|
341
|
-
jsLocation: jsLocationValue(metroPort),
|
|
342
|
-
pid,
|
|
343
|
-
...restart
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
e.runFile("xcrun", [
|
|
347
|
-
"simctl",
|
|
348
|
-
"openurl",
|
|
349
|
-
udid,
|
|
350
|
-
url
|
|
351
|
-
], { timeoutMs: 6e4 });
|
|
352
|
-
return {
|
|
353
|
-
ok: true,
|
|
354
|
-
mode: "openurl",
|
|
355
|
-
url,
|
|
356
|
-
jsLocation: jsLocationValue(metroPort),
|
|
357
|
-
...restart
|
|
358
|
-
};
|
|
359
|
-
} catch (err) {
|
|
360
|
-
const pid = launchedWithInitialUrl && !stateUnknown ? launchedIosAppAfterNoHandle(err, udid, bundleId, e) : null;
|
|
361
|
-
if (pid && pid !== restart.restartedPid) return {
|
|
362
|
-
ok: true,
|
|
363
|
-
mode: "launch",
|
|
364
|
-
url,
|
|
365
|
-
jsLocation: jsLocationValue(metroPort),
|
|
366
|
-
pid,
|
|
367
|
-
...restart
|
|
368
|
-
};
|
|
369
|
-
return {
|
|
370
|
-
failed: true,
|
|
371
|
-
code: LAUNCH_ERROR,
|
|
372
|
-
reason: `simctl ${launchedWithInitialUrl ? `launch ${bundleId}` : `openurl ${url}`} failed: ${describeIosSimulatorFailure(err, e)}`
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
try {
|
|
378
|
-
const result = {
|
|
379
|
-
ok: true,
|
|
380
|
-
mode: "launch",
|
|
381
|
-
pid: parseLaunchedPid(e.runFile("xcrun", launchArgs, { timeoutMs: 6e4 })),
|
|
382
|
-
...restart
|
|
383
|
-
};
|
|
384
|
-
if (metroPort !== null) result.jsLocation = jsLocationValue(metroPort);
|
|
385
|
-
return result;
|
|
386
|
-
} catch (err) {
|
|
387
|
-
const pid = stateUnknown ? null : launchedIosAppAfterNoHandle(err, udid, bundleId, e);
|
|
388
|
-
if (pid && pid !== restart.restartedPid) {
|
|
389
|
-
const result = {
|
|
390
|
-
ok: true,
|
|
391
|
-
mode: "launch",
|
|
392
|
-
pid,
|
|
393
|
-
...restart
|
|
394
|
-
};
|
|
395
|
-
if (metroPort !== null) result.jsLocation = jsLocationValue(metroPort);
|
|
396
|
-
return result;
|
|
397
|
-
}
|
|
398
|
-
return {
|
|
399
|
-
failed: true,
|
|
400
|
-
code: LAUNCH_ERROR,
|
|
401
|
-
reason: `simctl launch ${bundleId} failed: ${describeIosSimulatorFailure(err, e)}`
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
function installConflictKind(text) {
|
|
406
|
-
const out = String(text ?? "");
|
|
407
|
-
if (/INSTALL_FAILED_UPDATE_INCOMPATIBLE|INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES|signatures do not match/i.test(out)) return "signature";
|
|
408
|
-
if (/INSTALL_FAILED_VERSION_DOWNGRADE/i.test(out)) return "downgrade";
|
|
409
|
-
return null;
|
|
410
|
-
}
|
|
411
|
-
const ADB_INSTALL_TIMEOUT_MS = 3e5;
|
|
412
|
-
const ADB_UNINSTALL_TIMEOUT_MS = 12e4;
|
|
413
|
-
const ADB_SHELL_OPTIONS = {
|
|
414
|
-
timeoutMs: 3e4,
|
|
415
|
-
killSignal: "SIGKILL"
|
|
416
|
-
};
|
|
417
|
-
function installAndroidApp({ serial, apkPath, packageName = null, allowUninstall = false }, { exec = null } = {}) {
|
|
418
|
-
const e = exec || getExecutor();
|
|
419
|
-
if (packageName && deviceHoldsApk({
|
|
420
|
-
serial,
|
|
421
|
-
packageName,
|
|
422
|
-
apkPath
|
|
423
|
-
}, { exec: e })) return {
|
|
424
|
-
ok: true,
|
|
425
|
-
apkPath,
|
|
426
|
-
skipped: true
|
|
427
|
-
};
|
|
428
|
-
const install = () => {
|
|
429
|
-
e.runFile("adb", [
|
|
430
|
-
"-s",
|
|
431
|
-
serial,
|
|
432
|
-
"install",
|
|
433
|
-
"-r",
|
|
434
|
-
apkPath
|
|
435
|
-
], { timeoutMs: ADB_INSTALL_TIMEOUT_MS });
|
|
436
|
-
};
|
|
437
|
-
try {
|
|
438
|
-
install();
|
|
439
|
-
return {
|
|
440
|
-
ok: true,
|
|
441
|
-
apkPath
|
|
442
|
-
};
|
|
443
|
-
} catch (err) {
|
|
444
|
-
const conflict = installConflictKind(describe(err));
|
|
445
|
-
if (!conflict || !allowUninstall || !packageName) return {
|
|
446
|
-
failed: true,
|
|
447
|
-
code: INSTALL_ERROR,
|
|
448
|
-
reason: `adb install failed for ${apkPath}: ${describe(err)}`
|
|
449
|
-
};
|
|
450
|
-
try {
|
|
451
|
-
e.runFile("adb", [
|
|
452
|
-
"-s",
|
|
453
|
-
serial,
|
|
454
|
-
"uninstall",
|
|
455
|
-
packageName
|
|
456
|
-
], {
|
|
457
|
-
timeoutMs: ADB_UNINSTALL_TIMEOUT_MS,
|
|
458
|
-
killSignal: "SIGKILL"
|
|
459
|
-
});
|
|
460
|
-
} catch (uninstallErr) {
|
|
461
|
-
return {
|
|
462
|
-
failed: true,
|
|
463
|
-
code: INSTALL_ERROR,
|
|
464
|
-
reason: `adb install failed for ${apkPath} (${conflict}) and ${packageName} could not be uninstalled: ` + describe(uninstallErr)
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
try {
|
|
468
|
-
install();
|
|
469
|
-
} catch (retryErr) {
|
|
470
|
-
return {
|
|
471
|
-
failed: true,
|
|
472
|
-
code: INSTALL_ERROR,
|
|
473
|
-
reason: `adb install failed for ${apkPath} even after uninstalling ${packageName}: ${describe(retryErr)}`
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
return {
|
|
477
|
-
ok: true,
|
|
478
|
-
apkPath,
|
|
479
|
-
uninstalled: true,
|
|
480
|
-
note: conflict === "signature" ? `${packageName} was already installed with a different signer, so it was uninstalled (its data went with it) before this APK could be installed` : `${packageName} was already installed at a higher versionCode, so it was uninstalled (its data went with it) before this APK could be installed`
|
|
481
|
-
};
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
function parseResolvedActivity(text) {
|
|
485
|
-
if (typeof text !== "string") return null;
|
|
486
|
-
for (const raw of text.split("\n")) {
|
|
487
|
-
const line = raw.trim();
|
|
488
|
-
if (!line) continue;
|
|
489
|
-
if (/^No activity found/i.test(line)) return null;
|
|
490
|
-
if (line.includes("=")) continue;
|
|
491
|
-
if (!line.includes("/")) continue;
|
|
492
|
-
return line;
|
|
493
|
-
}
|
|
494
|
-
return null;
|
|
495
|
-
}
|
|
496
|
-
function resolveLaunchActivity(serial, packageName, { exec = null } = {}) {
|
|
497
|
-
const e = exec || getExecutor();
|
|
498
|
-
try {
|
|
499
|
-
return parseResolvedActivity(e.runFile("adb", [
|
|
500
|
-
"-s",
|
|
501
|
-
serial,
|
|
502
|
-
"shell",
|
|
503
|
-
"cmd",
|
|
504
|
-
"package",
|
|
505
|
-
"resolve-activity",
|
|
506
|
-
"--brief",
|
|
507
|
-
"-c",
|
|
508
|
-
"android.intent.category.LAUNCHER",
|
|
509
|
-
packageName
|
|
510
|
-
], ADB_SHELL_OPTIONS));
|
|
511
|
-
} catch {
|
|
512
|
-
return null;
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
function reverseMetroPorts({ serial, metroPort, devicePorts = null }, { exec = null } = {}) {
|
|
516
|
-
const e = exec || getExecutor();
|
|
517
|
-
const pairs = (devicePorts ?? [metroPort]).map((device) => [device, metroPort]);
|
|
518
|
-
for (const [device, host] of pairs) try {
|
|
519
|
-
e.runFile("adb", [
|
|
520
|
-
"-s",
|
|
521
|
-
serial,
|
|
522
|
-
"reverse",
|
|
523
|
-
`tcp:${device}`,
|
|
524
|
-
`tcp:${host}`
|
|
525
|
-
], ADB_SHELL_OPTIONS);
|
|
526
|
-
} catch (err) {
|
|
527
|
-
return {
|
|
528
|
-
failed: true,
|
|
529
|
-
code: LAUNCH_ERROR,
|
|
530
|
-
reason: `adb reverse tcp:${device} tcp:${host} failed on ${serial}: ${describe(err)}`
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
return {
|
|
534
|
-
ok: true,
|
|
535
|
-
reversed: pairs.map(([device, host]) => `tcp:${device}->tcp:${host}`)
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
function hasMetroReverse(listing, metroPort) {
|
|
539
|
-
return String(listing ?? "").split("\n").some((line) => {
|
|
540
|
-
const cols = line.trim().split(/\s+/);
|
|
541
|
-
return cols[1] === `tcp:${metroPort}` && cols[2] === `tcp:${metroPort}`;
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
/** Re-applies the launch's `metroPort` reverse when the device no longer has it. */
|
|
545
|
-
function ensureMetroReverse({ serial, metroPort }, { exec = null } = {}) {
|
|
546
|
-
const e = exec || getExecutor();
|
|
547
|
-
let listing;
|
|
548
|
-
try {
|
|
549
|
-
listing = e.runFile("adb", [
|
|
550
|
-
"-s",
|
|
551
|
-
serial,
|
|
552
|
-
"reverse",
|
|
553
|
-
"--list"
|
|
554
|
-
], ADB_SHELL_OPTIONS);
|
|
555
|
-
} catch {
|
|
556
|
-
return {
|
|
557
|
-
failed: true,
|
|
558
|
-
reason: `adb reverse --list failed on ${serial}`
|
|
559
|
-
};
|
|
560
|
-
}
|
|
561
|
-
if (hasMetroReverse(listing, metroPort)) return { restored: false };
|
|
562
|
-
const reversed = reverseMetroPorts({
|
|
563
|
-
serial,
|
|
564
|
-
metroPort
|
|
565
|
-
}, { exec: e });
|
|
566
|
-
return reversed.failed ? {
|
|
567
|
-
failed: true,
|
|
568
|
-
reason: reversed.reason ?? "adb reverse failed"
|
|
569
|
-
} : { restored: true };
|
|
570
|
-
}
|
|
571
|
-
const EMULATOR_HOST_LOOPBACK = "127.0.0.1";
|
|
572
|
-
const PHYSICAL_HOST_LOOPBACK = "localhost";
|
|
573
|
-
function androidMetroHost(physical) {
|
|
574
|
-
return physical ? PHYSICAL_HOST_LOOPBACK : EMULATOR_HOST_LOOPBACK;
|
|
575
|
-
}
|
|
576
|
-
function deviceShellArg(text) {
|
|
577
|
-
return `'${String(text).replace(/'/g, "'\\''")}'`;
|
|
578
|
-
}
|
|
579
|
-
function debugHttpHostScript({ packageName, host, dataDir = null }) {
|
|
580
|
-
const dir = dataDir || `/data/data/${packageName}`;
|
|
581
|
-
const prefs = `shared_prefs/${packageName}_preferences.xml`;
|
|
582
|
-
const tmp = `${prefs}.stim.tmp`;
|
|
583
|
-
return [
|
|
584
|
-
`cd ${dir} || exit 1`,
|
|
585
|
-
"mkdir -p shared_prefs || exit 1",
|
|
586
|
-
`printf '%s\\n' '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>' '<map>' > ${tmp} || exit 1`,
|
|
587
|
-
`if [ -f ${prefs} ]; then grep -v 'debug_http_host' ${prefs} | grep -v '<?xml' | grep -v '<map' | grep -v '</map>' >> ${tmp}; fi`,
|
|
588
|
-
`printf '%s\\n' ' <string name="debug_http_host">${host}</string>' '</map>' >> ${tmp} || exit 1`,
|
|
589
|
-
`mv ${tmp} ${prefs} || exit 1`,
|
|
590
|
-
`grep -q '>${host}<' ${prefs} || exit 1`
|
|
591
|
-
].join("\n");
|
|
592
|
-
}
|
|
593
|
-
function writeDebugHttpHost({ serial, packageName, metroPort, physical = false }, { exec = null } = {}) {
|
|
594
|
-
const e = exec || getExecutor();
|
|
595
|
-
const host = `${androidMetroHost(physical)}:${metroPort}`;
|
|
596
|
-
const script = debugHttpHostScript({
|
|
597
|
-
packageName,
|
|
598
|
-
host
|
|
599
|
-
});
|
|
600
|
-
try {
|
|
601
|
-
e.runFile("adb", [
|
|
602
|
-
"-s",
|
|
603
|
-
serial,
|
|
604
|
-
"shell",
|
|
605
|
-
"run-as",
|
|
606
|
-
packageName,
|
|
607
|
-
"sh",
|
|
608
|
-
"-c",
|
|
609
|
-
deviceShellArg(script)
|
|
610
|
-
], ADB_SHELL_OPTIONS);
|
|
611
|
-
return {
|
|
612
|
-
ok: true,
|
|
613
|
-
host
|
|
614
|
-
};
|
|
615
|
-
} catch (err) {
|
|
616
|
-
return {
|
|
617
|
-
ok: false,
|
|
618
|
-
reason: `debug_http_host not written (${describe(err)}); relying on adb reverse`
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
function androidDevClientUrl(scheme, metroPort, physical = false) {
|
|
623
|
-
return devClientUrl(scheme, metroPort, androidMetroHost(physical));
|
|
624
|
-
}
|
|
625
|
-
function amStartError(text) {
|
|
626
|
-
const out = String(text ?? "");
|
|
627
|
-
for (const raw of out.split("\n")) {
|
|
628
|
-
const line = raw.trim();
|
|
629
|
-
if (/^Error:/i.test(line)) return line;
|
|
630
|
-
}
|
|
631
|
-
return null;
|
|
632
|
-
}
|
|
633
|
-
function openAndroidDevClientUrl({ serial, url, packageName, stopOnStart = false }, { exec = null } = {}) {
|
|
634
|
-
const e = exec || getExecutor();
|
|
635
|
-
let out;
|
|
636
|
-
try {
|
|
637
|
-
const args = [
|
|
638
|
-
"-s",
|
|
639
|
-
serial,
|
|
640
|
-
"shell",
|
|
641
|
-
"am",
|
|
642
|
-
"start",
|
|
643
|
-
...stopOnStart ? ["-S"] : [],
|
|
644
|
-
"-a",
|
|
645
|
-
"android.intent.action.VIEW",
|
|
646
|
-
"-d",
|
|
647
|
-
deviceShellArg(url),
|
|
648
|
-
...packageName ? ["-p", packageName] : [],
|
|
649
|
-
"--ez",
|
|
650
|
-
ANDROID_DISABLE_AUTO_LAUNCH_EXTRA,
|
|
651
|
-
"true"
|
|
652
|
-
];
|
|
653
|
-
out = e.runFile("adb", args, ADB_SHELL_OPTIONS);
|
|
654
|
-
} catch (err) {
|
|
655
|
-
return {
|
|
656
|
-
failed: true,
|
|
657
|
-
reason: `am start -d ${url} failed on ${serial}: ${describe(err)}`
|
|
658
|
-
};
|
|
659
|
-
}
|
|
660
|
-
const error = amStartError(out);
|
|
661
|
-
if (error) return {
|
|
662
|
-
failed: true,
|
|
663
|
-
reason: `am start -d ${url} did not start anything on ${serial}: ${error}`
|
|
664
|
-
};
|
|
665
|
-
return {
|
|
666
|
-
ok: true,
|
|
667
|
-
url
|
|
668
|
-
};
|
|
669
|
-
}
|
|
670
|
-
function stopRunningAndroidApp(serial, packageName, exec) {
|
|
671
|
-
const running = androidAppProcess(serial, packageName, { exec });
|
|
672
|
-
if (running.state === "stopped") return {};
|
|
673
|
-
if (running.state !== "running") return { stopOnStart: true };
|
|
674
|
-
try {
|
|
675
|
-
exec.runFile("adb", [
|
|
676
|
-
"-s",
|
|
677
|
-
serial,
|
|
678
|
-
"shell",
|
|
679
|
-
"am",
|
|
680
|
-
"force-stop",
|
|
681
|
-
packageName
|
|
682
|
-
], ADB_SHELL_OPTIONS);
|
|
683
|
-
} catch (err) {
|
|
684
|
-
return {
|
|
685
|
-
failed: true,
|
|
686
|
-
code: LAUNCH_ERROR,
|
|
687
|
-
reason: `am force-stop ${packageName} failed on ${serial}, so the running app (pid ${running.pid}) was not restarted: ${describe(err)}`
|
|
688
|
-
};
|
|
689
|
-
}
|
|
690
|
-
return { restartedPid: running.pid };
|
|
691
|
-
}
|
|
692
|
-
function launchAndroidWithMonkey(serial, packageName, stopOnStart, exec) {
|
|
693
|
-
if (stopOnStart) try {
|
|
694
|
-
exec.runFile("adb", [
|
|
695
|
-
"-s",
|
|
696
|
-
serial,
|
|
697
|
-
"shell",
|
|
698
|
-
"am",
|
|
699
|
-
"force-stop",
|
|
700
|
-
packageName
|
|
701
|
-
], ADB_SHELL_OPTIONS);
|
|
702
|
-
} catch {}
|
|
703
|
-
exec.runFile("adb", [
|
|
704
|
-
"-s",
|
|
705
|
-
serial,
|
|
706
|
-
"shell",
|
|
707
|
-
"monkey",
|
|
708
|
-
"-p",
|
|
709
|
-
packageName,
|
|
710
|
-
"1"
|
|
711
|
-
], ADB_SHELL_OPTIONS);
|
|
712
|
-
}
|
|
713
|
-
function launchAndroidApp({ serial, packageName, metroPort, devClientScheme = null, physical = false, bridgePort }, { exec = null } = {}) {
|
|
714
|
-
const e = exec || getExecutor();
|
|
715
|
-
const { stopOnStart = false, ...restart } = stopRunningAndroidApp(serial, packageName, e);
|
|
716
|
-
if (restart.failed) return restart;
|
|
717
|
-
const reversed = reverseMetroPorts({
|
|
718
|
-
serial,
|
|
719
|
-
metroPort: bridgePort ?? metroPort,
|
|
720
|
-
devicePorts: [metroPort]
|
|
721
|
-
}, { exec: e });
|
|
722
|
-
if (reversed.failed) return reversed;
|
|
723
|
-
const prefs = writeDebugHttpHost({
|
|
724
|
-
serial,
|
|
725
|
-
packageName,
|
|
726
|
-
metroPort,
|
|
727
|
-
physical
|
|
728
|
-
}, { exec: e });
|
|
729
|
-
let reversedPairs = reversed.reversed ?? [];
|
|
730
|
-
if (!prefs.ok && Number(metroPort) !== 8081) {
|
|
731
|
-
const fallback = reverseMetroPorts({
|
|
732
|
-
serial,
|
|
733
|
-
metroPort: bridgePort ?? metroPort,
|
|
734
|
-
devicePorts: [DEFAULT_METRO_PORT]
|
|
735
|
-
}, { exec: e });
|
|
736
|
-
if (fallback.failed) return fallback;
|
|
737
|
-
reversedPairs = [...reversedPairs, ...fallback.reversed ?? []];
|
|
738
|
-
}
|
|
739
|
-
const wiring = {
|
|
740
|
-
reversed: reversedPairs,
|
|
741
|
-
debugHttpHost: prefs.ok ? prefs.host : null,
|
|
742
|
-
debugHttpHostNote: prefs.ok ? null : prefs.reason,
|
|
743
|
-
...restart
|
|
744
|
-
};
|
|
745
|
-
let devClientNote = null;
|
|
746
|
-
if (devClientScheme) {
|
|
747
|
-
const url = androidDevClientUrl(devClientScheme, metroPort, physical);
|
|
748
|
-
const opened = openAndroidDevClientUrl({
|
|
749
|
-
serial,
|
|
750
|
-
url,
|
|
751
|
-
stopOnStart
|
|
752
|
-
}, { exec: e });
|
|
753
|
-
if (opened.ok) return {
|
|
754
|
-
ok: true,
|
|
755
|
-
mode: "deep-link",
|
|
756
|
-
devClientUrl: url,
|
|
757
|
-
...wiring
|
|
758
|
-
};
|
|
759
|
-
devClientNote = `${opened.reason}; fell back to the launcher activity`;
|
|
760
|
-
}
|
|
761
|
-
const component = resolveLaunchActivity(serial, packageName, { exec: e });
|
|
762
|
-
if (component) try {
|
|
763
|
-
e.runFile("adb", [
|
|
764
|
-
"-s",
|
|
765
|
-
serial,
|
|
766
|
-
"shell",
|
|
767
|
-
"am",
|
|
768
|
-
"start",
|
|
769
|
-
...stopOnStart ? ["-S"] : [],
|
|
770
|
-
"-n",
|
|
771
|
-
component
|
|
772
|
-
], ADB_SHELL_OPTIONS);
|
|
773
|
-
return {
|
|
774
|
-
ok: true,
|
|
775
|
-
mode: "am-start",
|
|
776
|
-
component,
|
|
777
|
-
devClientNote,
|
|
778
|
-
...wiring
|
|
779
|
-
};
|
|
780
|
-
} catch (err) {
|
|
781
|
-
return {
|
|
782
|
-
failed: true,
|
|
783
|
-
code: LAUNCH_ERROR,
|
|
784
|
-
reason: `am start -n ${component} failed on ${serial}: ${describe(err)}`
|
|
785
|
-
};
|
|
786
|
-
}
|
|
787
|
-
try {
|
|
788
|
-
launchAndroidWithMonkey(serial, packageName, stopOnStart, e);
|
|
789
|
-
return {
|
|
790
|
-
ok: true,
|
|
791
|
-
mode: "monkey",
|
|
792
|
-
devClientNote,
|
|
793
|
-
...wiring
|
|
794
|
-
};
|
|
795
|
-
} catch (err) {
|
|
796
|
-
return {
|
|
797
|
-
failed: true,
|
|
798
|
-
code: LAUNCH_ERROR,
|
|
799
|
-
reason: `Could not launch ${packageName} on ${serial}: no launcher activity resolved and monkey failed: ${describe(err)}`
|
|
800
|
-
};
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
function launchAndroidReleaseApp({ serial, packageName }, { exec = null } = {}) {
|
|
804
|
-
const e = exec || getExecutor();
|
|
805
|
-
const { stopOnStart = false, ...restart } = stopRunningAndroidApp(serial, packageName, e);
|
|
806
|
-
if (restart.failed) return restart;
|
|
807
|
-
const component = resolveLaunchActivity(serial, packageName, { exec: e });
|
|
808
|
-
if (component) try {
|
|
809
|
-
e.runFile("adb", [
|
|
810
|
-
"-s",
|
|
811
|
-
serial,
|
|
812
|
-
"shell",
|
|
813
|
-
"am",
|
|
814
|
-
"start",
|
|
815
|
-
...stopOnStart ? ["-S"] : [],
|
|
816
|
-
"-n",
|
|
817
|
-
component
|
|
818
|
-
], ADB_SHELL_OPTIONS);
|
|
819
|
-
return {
|
|
820
|
-
ok: true,
|
|
821
|
-
mode: "am-start",
|
|
822
|
-
component,
|
|
823
|
-
...restart
|
|
824
|
-
};
|
|
825
|
-
} catch (err) {
|
|
826
|
-
return {
|
|
827
|
-
failed: true,
|
|
828
|
-
code: LAUNCH_ERROR,
|
|
829
|
-
reason: `am start -n ${component} failed on ${serial}: ${describe(err)}`
|
|
830
|
-
};
|
|
831
|
-
}
|
|
832
|
-
try {
|
|
833
|
-
launchAndroidWithMonkey(serial, packageName, stopOnStart, e);
|
|
834
|
-
return {
|
|
835
|
-
ok: true,
|
|
836
|
-
mode: "monkey",
|
|
837
|
-
...restart
|
|
838
|
-
};
|
|
839
|
-
} catch (err) {
|
|
840
|
-
return {
|
|
841
|
-
failed: true,
|
|
842
|
-
code: LAUNCH_ERROR,
|
|
843
|
-
reason: `Could not launch ${packageName} on ${serial}: no launcher activity resolved and monkey failed: ${describe(err)}`
|
|
844
|
-
};
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
function describe(err) {
|
|
848
|
-
const e = err;
|
|
849
|
-
const stderr = e?.stderr ? String(e.stderr).trim() : "";
|
|
850
|
-
const message = e?.message ? String(e.message).trim() : String(err);
|
|
851
|
-
return stderr ? `${message}: ${stderr}` : message;
|
|
852
|
-
}
|
|
853
|
-
function parsePidof(text) {
|
|
854
|
-
const first = String(text ?? "").trim().split(/\s+/)[0];
|
|
855
|
-
const pid = Number(first);
|
|
856
|
-
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
857
|
-
}
|
|
858
|
-
function parsePsPid(text, packageName) {
|
|
859
|
-
for (const raw of String(text ?? "").split("\n")) {
|
|
860
|
-
const cols = raw.trim().split(/\s+/);
|
|
861
|
-
if (cols.length < 2) continue;
|
|
862
|
-
if (cols[cols.length - 1] !== packageName) continue;
|
|
863
|
-
const pid = Number(cols[1]);
|
|
864
|
-
if (Number.isFinite(pid) && pid > 0) return pid;
|
|
865
|
-
}
|
|
866
|
-
return null;
|
|
867
|
-
}
|
|
868
|
-
function androidAppProcess(serial, packageName, { exec = null } = {}) {
|
|
869
|
-
const e = exec || getExecutor();
|
|
870
|
-
try {
|
|
871
|
-
const pid = parsePidof(e.runFile("adb", [
|
|
872
|
-
"-s",
|
|
873
|
-
serial,
|
|
874
|
-
"shell",
|
|
875
|
-
"pidof",
|
|
876
|
-
packageName
|
|
877
|
-
], ADB_SHELL_OPTIONS));
|
|
878
|
-
if (pid !== null) return {
|
|
879
|
-
state: "running",
|
|
880
|
-
pid
|
|
881
|
-
};
|
|
882
|
-
} catch {}
|
|
883
|
-
try {
|
|
884
|
-
return appProcessFromPid(parsePsPid(e.runFile("adb", [
|
|
885
|
-
"-s",
|
|
886
|
-
serial,
|
|
887
|
-
"shell",
|
|
888
|
-
"ps",
|
|
889
|
-
"-A"
|
|
890
|
-
], ADB_SHELL_OPTIONS), packageName));
|
|
891
|
-
} catch {
|
|
892
|
-
return { state: "unknown" };
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
//#endregion
|
|
896
|
-
export { restartedAppNote as C, readBundleSchemes as D, pickDevClientScheme as E, schemesFromInfoPlist as O, launchIosApp as S, writeDebugHttpHost as T, installConflictKind as _, IOS_DEV_MENU_OFF_DEFAULTS_PLIST as a, launchAndroidApp as b, androidDevClientUrl as c, devClientDeepLink as d, devClientUrl as f, installAndroidApp as g, hasMetroReverse as h, INSTALL_ERROR as i, appProcessFromPid as l, ensureMetroReverse as m, ANDROID_DISABLE_AUTO_LAUNCH_EXTRA as n, LAUNCH_ERROR as o, deviceShellArg as p, DEFAULT_METRO_PORT as r, androidAppProcess as s, ADB_INSTALL_TIMEOUT_MS as t, clearOtherUserApps as u, installIosApp as v, reverseMetroPorts as w, launchAndroidReleaseApp as x, iosAppProcess as y };
|