@expo/cli 0.1.0 → 0.1.1
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/build/bin/cli +38 -11
- package/build/bin/cli.map +1 -1
- package/build/src/config/index.js +7 -17
- package/build/src/config/index.js.map +1 -1
- package/build/src/export/createBundles.js +62 -0
- package/build/src/export/createBundles.js.map +1 -0
- package/build/src/export/createMetadataJson.js +36 -0
- package/build/src/export/createMetadataJson.js.map +1 -0
- package/build/src/export/exportApp.js +102 -0
- package/build/src/export/exportApp.js.map +1 -0
- package/build/src/export/exportAssets.js +106 -0
- package/build/src/export/exportAssets.js.map +1 -0
- package/build/src/export/exportAsync.js +49 -0
- package/build/src/export/exportAsync.js.map +1 -0
- package/build/src/export/fork-bundleAsync.js +138 -0
- package/build/src/export/fork-bundleAsync.js.map +1 -0
- package/build/src/export/getPublicExpoManifest.js +28 -0
- package/build/src/export/getPublicExpoManifest.js.map +1 -0
- package/build/src/export/getResolvedLocales.js +35 -0
- package/build/src/export/getResolvedLocales.js.map +1 -0
- package/build/src/export/index.js +77 -0
- package/build/src/export/index.js.map +1 -0
- package/build/src/export/printBundleSizes.js +122 -0
- package/build/src/export/printBundleSizes.js.map +1 -0
- package/build/src/export/resolveOptions.js +24 -0
- package/build/src/export/resolveOptions.js.map +1 -0
- package/build/src/export/saveAssets.js +65 -0
- package/build/src/export/saveAssets.js.map +1 -0
- package/build/src/export/writeContents.js +108 -0
- package/build/src/export/writeContents.js.map +1 -0
- package/build/src/install/index.js +13 -40
- package/build/src/install/index.js.map +1 -1
- package/build/src/login/index.js +6 -20
- package/build/src/login/index.js.map +1 -1
- package/build/src/logout/index.js +2 -17
- package/build/src/logout/index.js.map +1 -1
- package/build/src/prebuild/index.js +10 -21
- package/build/src/prebuild/index.js.map +1 -1
- package/build/src/prebuild/prebuildAsync.js +1 -1
- package/build/src/prebuild/prebuildAsync.js.map +1 -1
- package/build/src/register/index.js +2 -17
- package/build/src/register/index.js.map +1 -1
- package/build/src/run/android/index.js +97 -0
- package/build/src/run/android/index.js.map +1 -0
- package/build/src/run/android/resolveDevice.js +23 -0
- package/build/src/run/android/resolveDevice.js.map +1 -0
- package/build/src/run/android/resolveGradleProps.js +37 -0
- package/build/src/run/android/resolveGradleProps.js.map +1 -0
- package/build/src/run/android/resolveInstallApkName.js +72 -0
- package/build/src/run/android/resolveInstallApkName.js.map +1 -0
- package/build/src/run/android/resolveLaunchProps.js +32 -0
- package/build/src/run/android/resolveLaunchProps.js.map +1 -0
- package/build/src/run/android/resolveOptions.js +25 -0
- package/build/src/run/android/resolveOptions.js.map +1 -0
- package/build/src/run/android/runAndroidAsync.js +74 -0
- package/build/src/run/android/runAndroidAsync.js.map +1 -0
- package/build/src/run/ensureNativeProject.js +33 -0
- package/build/src/run/ensureNativeProject.js.map +1 -0
- package/build/src/run/hints.js +22 -0
- package/build/src/run/hints.js.map +1 -0
- package/build/src/run/resolveBundlerProps.js +31 -0
- package/build/src/run/resolveBundlerProps.js.map +1 -0
- package/build/src/run/startBundler.js +76 -0
- package/build/src/run/startBundler.js.map +1 -0
- package/build/src/start/index.js +29 -39
- package/build/src/start/index.js.map +1 -1
- package/build/src/start/platforms/ExpoGoInstaller.js +4 -1
- package/build/src/start/platforms/ExpoGoInstaller.js.map +1 -1
- package/build/src/start/platforms/PlatformManager.js +25 -0
- package/build/src/start/platforms/PlatformManager.js.map +1 -1
- package/build/src/start/platforms/android/ADBServer.js +3 -1
- package/build/src/start/platforms/android/ADBServer.js.map +1 -1
- package/build/src/start/platforms/android/AndroidDeviceManager.js +13 -1
- package/build/src/start/platforms/android/AndroidDeviceManager.js.map +1 -1
- package/build/src/start/platforms/android/activateWindow.js +2 -0
- package/build/src/start/platforms/android/activateWindow.js.map +1 -1
- package/build/src/start/platforms/android/adb.js +37 -4
- package/build/src/start/platforms/android/adb.js.map +1 -1
- package/build/src/start/platforms/android/gradle.js +86 -0
- package/build/src/start/platforms/android/gradle.js.map +1 -0
- package/build/src/start/server/BundlerDevServer.js +62 -2
- package/build/src/start/server/BundlerDevServer.js.map +1 -1
- package/build/src/start/server/UrlCreator.js +2 -1
- package/build/src/start/server/UrlCreator.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +11 -14
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +22 -9
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/middleware/ClassicManifestMiddleware.js +1 -1
- package/build/src/start/server/middleware/createDevServerMiddleware.js +2 -2
- package/build/src/start/server/middleware/createDevServerMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/resolveAssets.js +4 -1
- package/build/src/start/server/middleware/resolveAssets.js.map +1 -1
- package/build/src/start/server/webpack/WebpackBundlerDevServer.js +10 -14
- package/build/src/start/server/webpack/WebpackBundlerDevServer.js.map +1 -1
- package/build/src/utils/analytics/rudderstackClient.js +2 -2
- package/build/src/utils/args.js +14 -0
- package/build/src/utils/args.js.map +1 -1
- package/build/src/utils/array.js +29 -0
- package/build/src/utils/array.js.map +1 -1
- package/build/src/utils/dir.js +5 -1
- package/build/src/utils/dir.js.map +1 -1
- package/build/src/utils/downloadAppAsync.js +3 -0
- package/build/src/utils/downloadAppAsync.js.map +1 -1
- package/build/src/utils/downloadExpoGoAsync.js +11 -5
- package/build/src/utils/downloadExpoGoAsync.js.map +1 -1
- package/build/src/utils/env.js +3 -0
- package/build/src/utils/env.js.map +1 -1
- package/build/src/utils/resolveArgs.js +94 -0
- package/build/src/utils/resolveArgs.js.map +1 -0
- package/build/src/whoami/index.js +1 -17
- package/build/src/whoami/index.js.map +1 -1
- package/package.json +17 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/start/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport chalk from 'chalk';\n\nimport { Command } from '../../bin/cli';\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/start/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport chalk from 'chalk';\n\nimport { Command } from '../../bin/cli';\nimport { assertArgs, getProjectRoot, printHelp } from '../utils/args';\nimport { logCmdError } from '../utils/errors';\n\nexport const expoStart: Command = async (argv) => {\n const args = assertArgs(\n {\n // Types\n '--help': Boolean,\n '--clear': Boolean,\n '--max-workers': Number,\n '--no-dev': Boolean,\n '--minify': Boolean,\n '--https': Boolean,\n '--force-manifest-type': String,\n '--private-key-path': String,\n '--port': Number,\n '--dev-client': Boolean,\n '--scheme': String,\n '--android': Boolean,\n '--ios': Boolean,\n '--web': Boolean,\n '--host': String,\n '--tunnel': Boolean,\n '--lan': Boolean,\n '--localhost': Boolean,\n '--offline': Boolean,\n // Aliases\n '-h': '--help',\n '-c': '--clear',\n '-p': '--port',\n '-a': '--android',\n '-i': '--ios',\n '-w': '--web',\n '-m': '--host',\n },\n argv\n );\n\n if (args['--help']) {\n printHelp(\n `Start a local dev server for the app`,\n chalk`npx expo start {dim <dir>}`,\n [\n chalk`<dir> Directory of the Expo project. {dim Default: Current working directory}`,\n `-a, --android Opens your app in Expo Go on a connected Android device`,\n `-i, --ios Opens your app in Expo Go in a currently running iOS simulator on your computer`,\n `-w, --web Opens your app in a web browser`,\n ``,\n `-c, --clear Clear the bundler cache`,\n `--max-workers <num> Maximum number of tasks to allow Metro to spawn`,\n `--no-dev Bundle in production mode`,\n `--minify Minify JavaScript`,\n ``,\n chalk`-m, --host <mode> Dev server hosting type. {dim Default: lan}`,\n chalk` {bold lan}: Use the local network`,\n chalk` {bold tunnel}: Use any network by tunnel through ngrok`,\n chalk` {bold localhost}: Connect to the dev server over localhost`,\n `--tunnel Same as --host tunnel`,\n `--lan Same as --host lan`,\n `--localhost Same as --host localhost`,\n ``,\n `--offline Skip network requests and use anonymous manifest signatures`,\n `--https Start the dev server with https protocol`,\n `--scheme <scheme> Custom URI protocol to use when launching an app`,\n chalk`-p, --port <port> Port to start the dev server on (does not apply to web or tunnel). {dim Default: 19000}`,\n ``,\n chalk`--dev-client {yellow Experimental:} Starts the bundler for use with the expo-development-client`,\n `--force-manifest-type <manifest-type> Override auto detection of manifest type`,\n `--private-key-path <path> Path to private key for code signing. Default: \"private-key.pem\" in the same directory as the certificate specified by the expo-updates configuration in app.json.`,\n `-h, --help Usage info`,\n ].join('\\n')\n );\n }\n\n const projectRoot = getProjectRoot(args);\n const { resolveOptionsAsync } = await import('./resolveOptions');\n const options = await resolveOptionsAsync(projectRoot, args).catch(logCmdError);\n\n const { APISettings } = await import('../api/settings');\n APISettings.isOffline = options.offline;\n\n const { startAsync } = await import('./startAsync');\n return startAsync(projectRoot, options, { webOnly: false }).catch(logCmdError);\n};\n"],"names":["expoStart","argv","args","assertArgs","Boolean","Number","String","printHelp","chalk","join","projectRoot","getProjectRoot","resolveOptionsAsync","options","catch","logCmdError","APISettings","isOffline","offline","startAsync","webOnly"],"mappings":"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"}
|
|
@@ -49,6 +49,7 @@ class ExpoGoInstaller {
|
|
|
49
49
|
return true;
|
|
50
50
|
}
|
|
51
51
|
const version = await this._getExpectedClientVersionAsync();
|
|
52
|
+
Log.debug(`Expected Expo Go version: ${version}, installed version: ${installedVersion}`);
|
|
52
53
|
return version ? _semver.default.lt(installedVersion, version) : true;
|
|
53
54
|
}
|
|
54
55
|
/** Returns the expected version of Expo Go given the project SDK Version. Exposed for testing. */ async _getExpectedClientVersionAsync() {
|
|
@@ -90,7 +91,9 @@ class ExpoGoInstaller {
|
|
|
90
91
|
}
|
|
91
92
|
if (shouldInstall) {
|
|
92
93
|
// Download the Expo Go app from the Expo servers.
|
|
93
|
-
const binaryPath = await (0, _downloadExpoGoAsync).downloadExpoGoAsync(this.platform
|
|
94
|
+
const binaryPath = await (0, _downloadExpoGoAsync).downloadExpoGoAsync(this.platform, {
|
|
95
|
+
sdkVersion: this.sdkVersion
|
|
96
|
+
});
|
|
94
97
|
// Install the app on the device.
|
|
95
98
|
const ora = (0, _ora).logNewSection(`Installing Expo Go on ${deviceManager.name}`);
|
|
96
99
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/platforms/ExpoGoInstaller.ts"],"sourcesContent":["import semver from 'semver';\n\nimport { getVersionsAsync } from '../../api/getVersions';\nimport * as Log from '../../log';\nimport { downloadExpoGoAsync } from '../../utils/downloadExpoGoAsync';\nimport { logNewSection } from '../../utils/ora';\nimport { confirmAsync } from '../../utils/prompts';\nimport type { DeviceManager } from './DeviceManager';\n\n/** Given a platform, appId, and sdkVersion, this module will ensure that Expo Go is up-to-date on the provided device. */\nexport class ExpoGoInstaller<IDevice> {\n // Keep a list of [platform-deviceId] so we can prevent asking multiple times if a user wants to upgrade.\n // This can prevent annoying interactions when they don't want to upgrade for whatever reason.\n static cache: Record<string, boolean> = {};\n\n constructor(\n private platform: 'ios' | 'android',\n // Ultimately this should be inlined since we know the platform.\n private appId: string,\n private sdkVersion?: string\n ) {}\n\n /** Returns true if the installed app matching the previously provided `appId` is outdated. */\n async isClientOutdatedAsync(device: DeviceManager<IDevice>): Promise<boolean> {\n const installedVersion = await device.getAppVersionAsync(this.appId);\n if (!installedVersion) {\n return true;\n }\n const version = await this._getExpectedClientVersionAsync();\n return version ? semver.lt(installedVersion, version) : true;\n }\n\n /** Returns the expected version of Expo Go given the project SDK Version. Exposed for testing. */\n async _getExpectedClientVersionAsync(): Promise<string | null> {\n const versions = await getVersionsAsync();\n // Like `sdkVersions['44.0.0']['androidClientVersion'] = '1.0.0'`\n const specificVersion =\n versions?.sdkVersions?.[this.sdkVersion!]?.[`${this.platform}ClientVersion`];\n const latestVersion = versions[`${this.platform}Version`];\n return specificVersion ?? latestVersion ?? null;\n }\n\n /** Returns a boolean indicating if Expo Go should be installed. Returns `true` if the app was uninstalled. */\n async uninstallExpoGoIfOutdatedAsync(deviceManager: DeviceManager<IDevice>): Promise<boolean> {\n const cacheId = `${this.platform}-${deviceManager.identifier}`;\n\n if (ExpoGoInstaller.cache[cacheId]) {\n return false;\n }\n if (await this.isClientOutdatedAsync(deviceManager)) {\n // Only prompt once per device, per run.\n ExpoGoInstaller.cache[cacheId] = true;\n const confirm = await confirmAsync({\n initial: true,\n message: `Expo Go on ${deviceManager.name} is outdated, would you like to upgrade?`,\n });\n if (confirm) {\n // Don't need to uninstall to update on iOS.\n if (this.platform !== 'ios') {\n Log.log(`Uninstalling Expo Go from ${this.platform} device ${deviceManager.name}.`);\n await deviceManager.uninstallAppAsync(this.appId);\n }\n return true;\n }\n }\n return false;\n }\n\n /** Check if a given device has Expo Go installed, if not then download and install it. */\n async ensureAsync(deviceManager: DeviceManager<IDevice>): Promise<boolean> {\n let shouldInstall = !(await deviceManager.isAppInstalledAsync(this.appId));\n\n if (!shouldInstall) {\n shouldInstall = await this.uninstallExpoGoIfOutdatedAsync(deviceManager);\n }\n\n if (shouldInstall) {\n // Download the Expo Go app from the Expo servers.\n const binaryPath = await downloadExpoGoAsync(this.platform);\n // Install the app on the device.\n const ora = logNewSection(`Installing Expo Go on ${deviceManager.name}`);\n try {\n await deviceManager.installAppAsync(binaryPath);\n } finally {\n ora.stop();\n }\n return true;\n }\n return false;\n }\n}\n"],"names":["Log","ExpoGoInstaller","cache","constructor","platform","appId","sdkVersion","isClientOutdatedAsync","device","installedVersion","getAppVersionAsync","version","_getExpectedClientVersionAsync","semver","lt","versions","getVersionsAsync","specificVersion","sdkVersions","latestVersion","uninstallExpoGoIfOutdatedAsync","deviceManager","cacheId","identifier","confirm","confirmAsync","initial","message","name","log","uninstallAppAsync","ensureAsync","shouldInstall","isAppInstalledAsync","binaryPath","downloadExpoGoAsync","ora","logNewSection","installAppAsync","stop"],"mappings":"AAAA;;;;AAAmB,IAAA,OAAQ,kCAAR,QAAQ,EAAA;AAEM,IAAA,YAAuB,WAAvB,uBAAuB,CAAA;AAC5CA,IAAAA,GAAG,mCAAM,WAAW,EAAjB;AACqB,IAAA,oBAAiC,WAAjC,iCAAiC,CAAA;AACvC,IAAA,IAAiB,WAAjB,iBAAiB,CAAA;AAClB,IAAA,QAAqB,WAArB,qBAAqB,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAI3C,MAAMC,eAAe;IAC1B,yGAAyG;IACzG,8FAA8F;IAC9F,OAAOC,KAAK,GAA4B,EAAE,CAAC;IAE3CC,YACUC,QAA2B,EAE3BC,KAAa,EACbC,UAAmB,CAC3B;aAJQF,QAA2B,GAA3BA,QAA2B;aAE3BC,KAAa,GAAbA,KAAa;aACbC,UAAmB,GAAnBA,UAAmB;KACzB;IAEJ,8FAA8F,CAC9F,MAAMC,qBAAqB,CAACC,MAA8B,EAAoB;QAC5E,MAAMC,gBAAgB,GAAG,MAAMD,MAAM,CAACE,kBAAkB,CAAC,IAAI,CAACL,KAAK,CAAC,AAAC;QACrE,IAAI,CAACI,gBAAgB,EAAE;YACrB,OAAO,IAAI,CAAC;SACb;QACD,MAAME,OAAO,GAAG,MAAM,IAAI,CAACC,8BAA8B,EAAE,AAAC;
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/platforms/ExpoGoInstaller.ts"],"sourcesContent":["import semver from 'semver';\n\nimport { getVersionsAsync } from '../../api/getVersions';\nimport * as Log from '../../log';\nimport { downloadExpoGoAsync } from '../../utils/downloadExpoGoAsync';\nimport { logNewSection } from '../../utils/ora';\nimport { confirmAsync } from '../../utils/prompts';\nimport type { DeviceManager } from './DeviceManager';\n\n/** Given a platform, appId, and sdkVersion, this module will ensure that Expo Go is up-to-date on the provided device. */\nexport class ExpoGoInstaller<IDevice> {\n // Keep a list of [platform-deviceId] so we can prevent asking multiple times if a user wants to upgrade.\n // This can prevent annoying interactions when they don't want to upgrade for whatever reason.\n static cache: Record<string, boolean> = {};\n\n constructor(\n private platform: 'ios' | 'android',\n // Ultimately this should be inlined since we know the platform.\n private appId: string,\n private sdkVersion?: string\n ) {}\n\n /** Returns true if the installed app matching the previously provided `appId` is outdated. */\n async isClientOutdatedAsync(device: DeviceManager<IDevice>): Promise<boolean> {\n const installedVersion = await device.getAppVersionAsync(this.appId);\n if (!installedVersion) {\n return true;\n }\n const version = await this._getExpectedClientVersionAsync();\n Log.debug(`Expected Expo Go version: ${version}, installed version: ${installedVersion}`);\n return version ? semver.lt(installedVersion, version) : true;\n }\n\n /** Returns the expected version of Expo Go given the project SDK Version. Exposed for testing. */\n async _getExpectedClientVersionAsync(): Promise<string | null> {\n const versions = await getVersionsAsync();\n // Like `sdkVersions['44.0.0']['androidClientVersion'] = '1.0.0'`\n const specificVersion =\n versions?.sdkVersions?.[this.sdkVersion!]?.[`${this.platform}ClientVersion`];\n const latestVersion = versions[`${this.platform}Version`];\n return specificVersion ?? latestVersion ?? null;\n }\n\n /** Returns a boolean indicating if Expo Go should be installed. Returns `true` if the app was uninstalled. */\n async uninstallExpoGoIfOutdatedAsync(deviceManager: DeviceManager<IDevice>): Promise<boolean> {\n const cacheId = `${this.platform}-${deviceManager.identifier}`;\n\n if (ExpoGoInstaller.cache[cacheId]) {\n return false;\n }\n if (await this.isClientOutdatedAsync(deviceManager)) {\n // Only prompt once per device, per run.\n ExpoGoInstaller.cache[cacheId] = true;\n const confirm = await confirmAsync({\n initial: true,\n message: `Expo Go on ${deviceManager.name} is outdated, would you like to upgrade?`,\n });\n if (confirm) {\n // Don't need to uninstall to update on iOS.\n if (this.platform !== 'ios') {\n Log.log(`Uninstalling Expo Go from ${this.platform} device ${deviceManager.name}.`);\n await deviceManager.uninstallAppAsync(this.appId);\n }\n return true;\n }\n }\n return false;\n }\n\n /** Check if a given device has Expo Go installed, if not then download and install it. */\n async ensureAsync(deviceManager: DeviceManager<IDevice>): Promise<boolean> {\n let shouldInstall = !(await deviceManager.isAppInstalledAsync(this.appId));\n\n if (!shouldInstall) {\n shouldInstall = await this.uninstallExpoGoIfOutdatedAsync(deviceManager);\n }\n\n if (shouldInstall) {\n // Download the Expo Go app from the Expo servers.\n const binaryPath = await downloadExpoGoAsync(this.platform, { sdkVersion: this.sdkVersion });\n // Install the app on the device.\n const ora = logNewSection(`Installing Expo Go on ${deviceManager.name}`);\n try {\n await deviceManager.installAppAsync(binaryPath);\n } finally {\n ora.stop();\n }\n return true;\n }\n return false;\n }\n}\n"],"names":["Log","ExpoGoInstaller","cache","constructor","platform","appId","sdkVersion","isClientOutdatedAsync","device","installedVersion","getAppVersionAsync","version","_getExpectedClientVersionAsync","debug","semver","lt","versions","getVersionsAsync","specificVersion","sdkVersions","latestVersion","uninstallExpoGoIfOutdatedAsync","deviceManager","cacheId","identifier","confirm","confirmAsync","initial","message","name","log","uninstallAppAsync","ensureAsync","shouldInstall","isAppInstalledAsync","binaryPath","downloadExpoGoAsync","ora","logNewSection","installAppAsync","stop"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
var _config = require("@expo/config");
|
|
6
6
|
var _assert = _interopRequireDefault(require("assert"));
|
|
7
|
+
var Log = _interopRequireWildcard(require("../../log"));
|
|
7
8
|
var _rudderstackClient = require("../../utils/analytics/rudderstackClient");
|
|
8
9
|
var _errors = require("../../utils/errors");
|
|
9
10
|
var _link = require("../../utils/link");
|
|
@@ -12,6 +13,27 @@ function _interopRequireDefault(obj) {
|
|
|
12
13
|
default: obj
|
|
13
14
|
};
|
|
14
15
|
}
|
|
16
|
+
function _interopRequireWildcard(obj) {
|
|
17
|
+
if (obj && obj.__esModule) {
|
|
18
|
+
return obj;
|
|
19
|
+
} else {
|
|
20
|
+
var newObj = {};
|
|
21
|
+
if (obj != null) {
|
|
22
|
+
for(var key in obj){
|
|
23
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
24
|
+
var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
|
|
25
|
+
if (desc.get || desc.set) {
|
|
26
|
+
Object.defineProperty(newObj, key, desc);
|
|
27
|
+
} else {
|
|
28
|
+
newObj[key] = obj[key];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
newObj.default = obj;
|
|
34
|
+
return newObj;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
15
37
|
class PlatformManager {
|
|
16
38
|
constructor(projectRoot, props){
|
|
17
39
|
this.projectRoot = projectRoot;
|
|
@@ -40,6 +62,8 @@ class PlatformManager {
|
|
|
40
62
|
};
|
|
41
63
|
}
|
|
42
64
|
async openProjectInCustomRuntimeAsync(resolveSettings = {}, props = {}) {
|
|
65
|
+
Log.debug(`open custom (${Object.entries(props).map(([k, v])=>`${k}: ${v}`
|
|
66
|
+
).join(", ")})`);
|
|
43
67
|
let url = this.props.getCustomRuntimeUrl({
|
|
44
68
|
scheme: props.scheme
|
|
45
69
|
});
|
|
@@ -66,6 +90,7 @@ class PlatformManager {
|
|
|
66
90
|
};
|
|
67
91
|
}
|
|
68
92
|
/** Launch the project on a device given the input runtime. */ async openAsync(options, resolveSettings = {}) {
|
|
93
|
+
Log.debug(`open (runtime: ${options.runtime}, platform: ${this.props.platform}, device: %O, shouldPrompt: ${resolveSettings.shouldPrompt})`, resolveSettings.device);
|
|
69
94
|
if (options.runtime === "expo") {
|
|
70
95
|
return this.openProjectInExpoGoAsync(resolveSettings);
|
|
71
96
|
} else if (options.runtime === "web") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/platforms/PlatformManager.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport assert from 'assert';\n\nimport { logEvent } from '../../utils/analytics/rudderstackClient';\nimport { CommandError, UnimplementedError } from '../../utils/errors';\nimport { learnMore } from '../../utils/link';\nimport { AppIdResolver } from './AppIdResolver';\nimport { DeviceManager } from './DeviceManager';\n\nexport interface BaseOpenInCustomProps {\n scheme?: string;\n applicationId?: string | null;\n}\n\nexport interface BaseResolveDeviceProps<IDevice> {\n /** Should prompt the user to select a device. */\n shouldPrompt?: boolean;\n /** The target device to use. */\n device?: IDevice;\n}\n\n/** An abstract class for launching a URL on a device. */\nexport class PlatformManager<\n IDevice,\n IOpenInCustomProps extends BaseOpenInCustomProps = BaseOpenInCustomProps,\n IResolveDeviceProps extends BaseResolveDeviceProps<IDevice> = BaseResolveDeviceProps<IDevice>\n> {\n constructor(\n protected projectRoot: string,\n protected props: {\n platform: 'ios' | 'android';\n /** Get the base URL for the dev server hosting this platform manager. */\n getDevServerUrl: () => string | null;\n /** Expo Go URL */\n getExpoGoUrl: () => string | null;\n /** Dev Client */\n getCustomRuntimeUrl: (props?: { scheme?: string }) => string | null;\n /** Resolve a device, this function should automatically handle opening the device and asserting any system validations. */\n resolveDeviceAsync: (\n resolver?: Partial<IResolveDeviceProps>\n ) => Promise<DeviceManager<IDevice>>;\n }\n ) {}\n\n /** Returns the project application identifier or asserts that one is not defined. Exposed for testing. */\n _getAppIdResolver(): AppIdResolver {\n throw new UnimplementedError();\n }\n\n protected async openProjectInExpoGoAsync(\n resolveSettings: Partial<IResolveDeviceProps> = {}\n ): Promise<{ url: string }> {\n const url = this.props.getExpoGoUrl();\n // This should never happen, but just in case...\n assert(url, 'Could not get dev server URL');\n\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n deviceManager.logOpeningUrl(url);\n\n // TODO: Expensive, we should only do this once.\n const { exp } = getConfig(this.projectRoot);\n const installedExpo = await deviceManager.ensureExpoGoAsync(exp.sdkVersion);\n\n await deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n logEvent('Open Url on Device', {\n platform: this.props.platform,\n installedExpo,\n });\n\n return { url };\n }\n\n private async openProjectInCustomRuntimeAsync(\n resolveSettings: Partial<IResolveDeviceProps> = {},\n props: Partial<IOpenInCustomProps> = {}\n ): Promise<{ url: string }> {\n let url = this.props.getCustomRuntimeUrl({ scheme: props.scheme });\n // TODO: It's unclear why we do application id validation when opening with a URL\n const applicationId = props.applicationId ?? (await this._getAppIdResolver().getAppIdAsync());\n\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n\n if (!(await deviceManager.isAppInstalledAsync(applicationId))) {\n throw new CommandError(\n `The development client (${applicationId}) for this project is not installed. ` +\n `Please build and install the client on the device first.\\n${learnMore(\n 'https://docs.expo.dev/development/build/'\n )}`\n );\n }\n\n // TODO: Rethink analytics\n logEvent('Open Url on Device', {\n platform: this.props.platform,\n installedExpo: false,\n });\n\n if (!url) {\n url = this._resolveAlternativeLaunchUrl(applicationId, props);\n }\n\n deviceManager.logOpeningUrl(url);\n await deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n return {\n url,\n };\n }\n\n /** Launch the project on a device given the input runtime. */\n async openAsync(\n options:\n | {\n runtime: 'expo' | 'web';\n }\n | {\n runtime: 'custom';\n props?: Partial<IOpenInCustomProps>;\n },\n resolveSettings: Partial<IResolveDeviceProps> = {}\n ): Promise<{ url: string }> {\n if (options.runtime === 'expo') {\n return this.openProjectInExpoGoAsync(resolveSettings);\n } else if (options.runtime === 'web') {\n return this.openWebProjectAsync(resolveSettings);\n } else if (options.runtime === 'custom') {\n return this.openProjectInCustomRuntimeAsync(resolveSettings, options.props);\n } else {\n throw new CommandError(`Invalid runtime target: ${options.runtime}`);\n }\n }\n\n /** Open the current web project (Webpack) in a device . */\n private async openWebProjectAsync(resolveSettings: Partial<IResolveDeviceProps> = {}): Promise<{\n url: string;\n }> {\n const url = this.props.getDevServerUrl();\n assert(url, 'Dev server is not running.');\n\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n deviceManager.logOpeningUrl(url);\n await deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n return { url };\n }\n\n /** If the launch URL cannot be determined (`custom` runtimes) then an alternative string can be provided to open the device. Often a device ID or activity to launch. Exposed for testing. */\n _resolveAlternativeLaunchUrl(\n applicationId: string,\n props: Partial<IOpenInCustomProps> = {}\n ): string {\n throw new UnimplementedError();\n }\n}\n"],"names":["PlatformManager","constructor","projectRoot","props","_getAppIdResolver","UnimplementedError","openProjectInExpoGoAsync","resolveSettings","url","getExpoGoUrl","assert","deviceManager","resolveDeviceAsync","logOpeningUrl","exp","getConfig","installedExpo","ensureExpoGoAsync","sdkVersion","activateWindowAsync","openUrlAsync","logEvent","platform","openProjectInCustomRuntimeAsync","getCustomRuntimeUrl","scheme","applicationId","getAppIdAsync","isAppInstalledAsync","CommandError","learnMore","_resolveAlternativeLaunchUrl","openAsync","options","runtime","openWebProjectAsync","getDevServerUrl"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/platforms/PlatformManager.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport assert from 'assert';\n\nimport * as Log from '../../log';\nimport { logEvent } from '../../utils/analytics/rudderstackClient';\nimport { CommandError, UnimplementedError } from '../../utils/errors';\nimport { learnMore } from '../../utils/link';\nimport { AppIdResolver } from './AppIdResolver';\nimport { DeviceManager } from './DeviceManager';\n\nexport interface BaseOpenInCustomProps {\n scheme?: string;\n applicationId?: string | null;\n}\n\nexport interface BaseResolveDeviceProps<IDevice> {\n /** Should prompt the user to select a device. */\n shouldPrompt?: boolean;\n /** The target device to use. */\n device?: IDevice;\n}\n\n/** An abstract class for launching a URL on a device. */\nexport class PlatformManager<\n IDevice,\n IOpenInCustomProps extends BaseOpenInCustomProps = BaseOpenInCustomProps,\n IResolveDeviceProps extends BaseResolveDeviceProps<IDevice> = BaseResolveDeviceProps<IDevice>\n> {\n constructor(\n protected projectRoot: string,\n protected props: {\n platform: 'ios' | 'android';\n /** Get the base URL for the dev server hosting this platform manager. */\n getDevServerUrl: () => string | null;\n /** Expo Go URL */\n getExpoGoUrl: () => string | null;\n /** Dev Client */\n getCustomRuntimeUrl: (props?: { scheme?: string }) => string | null;\n /** Resolve a device, this function should automatically handle opening the device and asserting any system validations. */\n resolveDeviceAsync: (\n resolver?: Partial<IResolveDeviceProps>\n ) => Promise<DeviceManager<IDevice>>;\n }\n ) {}\n\n /** Returns the project application identifier or asserts that one is not defined. Exposed for testing. */\n _getAppIdResolver(): AppIdResolver {\n throw new UnimplementedError();\n }\n\n protected async openProjectInExpoGoAsync(\n resolveSettings: Partial<IResolveDeviceProps> = {}\n ): Promise<{ url: string }> {\n const url = this.props.getExpoGoUrl();\n // This should never happen, but just in case...\n assert(url, 'Could not get dev server URL');\n\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n deviceManager.logOpeningUrl(url);\n\n // TODO: Expensive, we should only do this once.\n const { exp } = getConfig(this.projectRoot);\n const installedExpo = await deviceManager.ensureExpoGoAsync(exp.sdkVersion);\n\n await deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n logEvent('Open Url on Device', {\n platform: this.props.platform,\n installedExpo,\n });\n\n return { url };\n }\n\n private async openProjectInCustomRuntimeAsync(\n resolveSettings: Partial<IResolveDeviceProps> = {},\n props: Partial<IOpenInCustomProps> = {}\n ): Promise<{ url: string }> {\n Log.debug(\n `open custom (${Object.entries(props)\n .map(([k, v]) => `${k}: ${v}`)\n .join(', ')})`\n );\n\n let url = this.props.getCustomRuntimeUrl({ scheme: props.scheme });\n // TODO: It's unclear why we do application id validation when opening with a URL\n const applicationId = props.applicationId ?? (await this._getAppIdResolver().getAppIdAsync());\n\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n\n if (!(await deviceManager.isAppInstalledAsync(applicationId))) {\n throw new CommandError(\n `The development client (${applicationId}) for this project is not installed. ` +\n `Please build and install the client on the device first.\\n${learnMore(\n 'https://docs.expo.dev/development/build/'\n )}`\n );\n }\n\n // TODO: Rethink analytics\n logEvent('Open Url on Device', {\n platform: this.props.platform,\n installedExpo: false,\n });\n\n if (!url) {\n url = this._resolveAlternativeLaunchUrl(applicationId, props);\n }\n\n deviceManager.logOpeningUrl(url);\n await deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n return {\n url,\n };\n }\n\n /** Launch the project on a device given the input runtime. */\n async openAsync(\n options:\n | {\n runtime: 'expo' | 'web';\n }\n | {\n runtime: 'custom';\n props?: Partial<IOpenInCustomProps>;\n },\n resolveSettings: Partial<IResolveDeviceProps> = {}\n ): Promise<{ url: string }> {\n Log.debug(\n `open (runtime: ${options.runtime}, platform: ${this.props.platform}, device: %O, shouldPrompt: ${resolveSettings.shouldPrompt})`,\n resolveSettings.device\n );\n if (options.runtime === 'expo') {\n return this.openProjectInExpoGoAsync(resolveSettings);\n } else if (options.runtime === 'web') {\n return this.openWebProjectAsync(resolveSettings);\n } else if (options.runtime === 'custom') {\n return this.openProjectInCustomRuntimeAsync(resolveSettings, options.props);\n } else {\n throw new CommandError(`Invalid runtime target: ${options.runtime}`);\n }\n }\n\n /** Open the current web project (Webpack) in a device . */\n private async openWebProjectAsync(resolveSettings: Partial<IResolveDeviceProps> = {}): Promise<{\n url: string;\n }> {\n const url = this.props.getDevServerUrl();\n assert(url, 'Dev server is not running.');\n\n const deviceManager = await this.props.resolveDeviceAsync(resolveSettings);\n deviceManager.logOpeningUrl(url);\n await deviceManager.activateWindowAsync();\n await deviceManager.openUrlAsync(url);\n\n return { url };\n }\n\n /** If the launch URL cannot be determined (`custom` runtimes) then an alternative string can be provided to open the device. Often a device ID or activity to launch. Exposed for testing. */\n _resolveAlternativeLaunchUrl(\n applicationId: string,\n props: Partial<IOpenInCustomProps> = {}\n ): string {\n throw new UnimplementedError();\n }\n}\n"],"names":["Log","PlatformManager","constructor","projectRoot","props","_getAppIdResolver","UnimplementedError","openProjectInExpoGoAsync","resolveSettings","url","getExpoGoUrl","assert","deviceManager","resolveDeviceAsync","logOpeningUrl","exp","getConfig","installedExpo","ensureExpoGoAsync","sdkVersion","activateWindowAsync","openUrlAsync","logEvent","platform","openProjectInCustomRuntimeAsync","debug","Object","entries","map","k","v","join","getCustomRuntimeUrl","scheme","applicationId","getAppIdAsync","isAppInstalledAsync","CommandError","learnMore","_resolveAlternativeLaunchUrl","openAsync","options","runtime","shouldPrompt","device","openWebProjectAsync","getDevServerUrl"],"mappings":"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"}
|
|
@@ -99,10 +99,12 @@ class ADBServer {
|
|
|
99
99
|
// TODO: Add a global package that installs adb to the path.
|
|
100
100
|
const adb = this.getAdbExecutablePath();
|
|
101
101
|
await this.startAsync();
|
|
102
|
-
|
|
102
|
+
const results = await this.resolveAdbPromise((0, _childProcess).execFileSync(adb, args, {
|
|
103
103
|
encoding: "latin1",
|
|
104
104
|
stdio: "pipe"
|
|
105
105
|
}));
|
|
106
|
+
Log.debug("[ADB] File output:\n", results);
|
|
107
|
+
return results;
|
|
106
108
|
}
|
|
107
109
|
/** Formats error info. */ async resolveAdbPromise(promise) {
|
|
108
110
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/platforms/android/ADBServer.ts"],"sourcesContent":["import spawnAsync from '@expo/spawn-async';\nimport { execFileSync } from 'child_process';\n\nimport * as Log from '../../../log';\nimport { AbortCommandError } from '../../../utils/errors';\nimport { installExitHooks } from '../../../utils/exit';\n\nconst BEGINNING_OF_ADB_ERROR_MESSAGE = 'error: ';\n\n// This is a tricky class since it controls a system state (side-effects).\n// A more ideal solution would be to implement ADB in JS.\n// The main reason this is a class is to control the flow of testing.\n\nexport class ADBServer {\n isRunning: boolean = false;\n removeExitHook: () => void = () => {};\n\n /** Returns the command line reference to ADB. */\n getAdbExecutablePath(): string {\n // https://developer.android.com/studio/command-line/variables\n // TODO: Add ANDROID_SDK_ROOT support as well https://github.com/expo/expo/pull/16516#discussion_r820037917\n if (process.env.ANDROID_HOME) {\n return `${process.env.ANDROID_HOME}/platform-tools/adb`;\n }\n return 'adb';\n }\n\n /** Start the ADB server. */\n async startAsync(): Promise<boolean> {\n if (this.isRunning) {\n return false;\n }\n // clean up\n this.removeExitHook = installExitHooks(() => {\n if (this.isRunning) {\n this.stopAsync();\n }\n });\n const adb = this.getAdbExecutablePath();\n const result = await this.resolveAdbPromise(spawnAsync(adb, ['start-server']));\n const lines = result.stderr.trim().split(/\\r?\\n/);\n const isStarted = lines.includes('* daemon started successfully');\n this.isRunning = isStarted;\n return isStarted;\n }\n\n /** Kill the ADB server. */\n async stopAsync(): Promise<boolean> {\n Log.debug('Stopping ADB server');\n\n if (!this.isRunning) {\n Log.debug('ADB server is not running');\n return false;\n }\n this.removeExitHook();\n try {\n await this.runAsync(['kill-server']);\n return true;\n } catch (error: any) {\n Log.error('Failed to stop ADB server: ' + error.message);\n return false;\n } finally {\n Log.debug('Stopped ADB server');\n this.isRunning = false;\n }\n }\n\n /** Execute an ADB command with given args. */\n async runAsync(args: string[]): Promise<string> {\n // TODO: Add a global package that installs adb to the path.\n const adb = this.getAdbExecutablePath();\n\n await this.startAsync();\n\n Log.debug([adb, ...args].join(' '));\n const result = await this.resolveAdbPromise(spawnAsync(adb, args));\n return result.output.join('\\n');\n }\n\n /** Get ADB file output. Useful for reading device state/settings. */\n async getFileOutputAsync(args: string[]): Promise<string> {\n // TODO: Add a global package that installs adb to the path.\n const adb = this.getAdbExecutablePath();\n\n await this.startAsync();\n\n
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/platforms/android/ADBServer.ts"],"sourcesContent":["import spawnAsync from '@expo/spawn-async';\nimport { execFileSync } from 'child_process';\n\nimport * as Log from '../../../log';\nimport { AbortCommandError } from '../../../utils/errors';\nimport { installExitHooks } from '../../../utils/exit';\n\nconst BEGINNING_OF_ADB_ERROR_MESSAGE = 'error: ';\n\n// This is a tricky class since it controls a system state (side-effects).\n// A more ideal solution would be to implement ADB in JS.\n// The main reason this is a class is to control the flow of testing.\n\nexport class ADBServer {\n isRunning: boolean = false;\n removeExitHook: () => void = () => {};\n\n /** Returns the command line reference to ADB. */\n getAdbExecutablePath(): string {\n // https://developer.android.com/studio/command-line/variables\n // TODO: Add ANDROID_SDK_ROOT support as well https://github.com/expo/expo/pull/16516#discussion_r820037917\n if (process.env.ANDROID_HOME) {\n return `${process.env.ANDROID_HOME}/platform-tools/adb`;\n }\n return 'adb';\n }\n\n /** Start the ADB server. */\n async startAsync(): Promise<boolean> {\n if (this.isRunning) {\n return false;\n }\n // clean up\n this.removeExitHook = installExitHooks(() => {\n if (this.isRunning) {\n this.stopAsync();\n }\n });\n const adb = this.getAdbExecutablePath();\n const result = await this.resolveAdbPromise(spawnAsync(adb, ['start-server']));\n const lines = result.stderr.trim().split(/\\r?\\n/);\n const isStarted = lines.includes('* daemon started successfully');\n this.isRunning = isStarted;\n return isStarted;\n }\n\n /** Kill the ADB server. */\n async stopAsync(): Promise<boolean> {\n Log.debug('Stopping ADB server');\n\n if (!this.isRunning) {\n Log.debug('ADB server is not running');\n return false;\n }\n this.removeExitHook();\n try {\n await this.runAsync(['kill-server']);\n return true;\n } catch (error: any) {\n Log.error('Failed to stop ADB server: ' + error.message);\n return false;\n } finally {\n Log.debug('Stopped ADB server');\n this.isRunning = false;\n }\n }\n\n /** Execute an ADB command with given args. */\n async runAsync(args: string[]): Promise<string> {\n // TODO: Add a global package that installs adb to the path.\n const adb = this.getAdbExecutablePath();\n\n await this.startAsync();\n\n Log.debug([adb, ...args].join(' '));\n const result = await this.resolveAdbPromise(spawnAsync(adb, args));\n return result.output.join('\\n');\n }\n\n /** Get ADB file output. Useful for reading device state/settings. */\n async getFileOutputAsync(args: string[]): Promise<string> {\n // TODO: Add a global package that installs adb to the path.\n const adb = this.getAdbExecutablePath();\n\n await this.startAsync();\n\n const results = await this.resolveAdbPromise(\n execFileSync(adb, args, {\n encoding: 'latin1',\n stdio: 'pipe',\n })\n );\n Log.debug('[ADB] File output:\\n', results);\n return results;\n }\n\n /** Formats error info. */\n async resolveAdbPromise<T>(promise: T | Promise<T>): Promise<T> {\n try {\n return await promise;\n } catch (error: any) {\n // User pressed ctrl+c to cancel the process...\n if (error.signal === 'SIGINT') {\n throw new AbortCommandError();\n }\n // TODO: Support heap corruption for adb 29 (process exits with code -1073740940) (windows and linux)\n let errorMessage = (error.stderr || error.stdout || error.message).trim();\n if (errorMessage.startsWith(BEGINNING_OF_ADB_ERROR_MESSAGE)) {\n errorMessage = errorMessage.substring(BEGINNING_OF_ADB_ERROR_MESSAGE.length);\n }\n error.message = errorMessage;\n throw error;\n }\n }\n}\n"],"names":["Log","BEGINNING_OF_ADB_ERROR_MESSAGE","ADBServer","isRunning","removeExitHook","getAdbExecutablePath","process","env","ANDROID_HOME","startAsync","installExitHooks","stopAsync","adb","result","resolveAdbPromise","spawnAsync","lines","stderr","trim","split","isStarted","includes","debug","runAsync","error","message","args","join","output","getFileOutputAsync","results","execFileSync","encoding","stdio","promise","signal","AbortCommandError","errorMessage","stdout","startsWith","substring","length"],"mappings":"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"}
|
|
@@ -42,6 +42,18 @@ function _interopRequireWildcard(obj) {
|
|
|
42
42
|
}
|
|
43
43
|
const EXPO_GO_APPLICATION_IDENTIFIER = "host.exp.exponent";
|
|
44
44
|
class AndroidDeviceManager extends _deviceManager.DeviceManager {
|
|
45
|
+
static async resolveFromNameAsync(name) {
|
|
46
|
+
const devices = await (0, _getDevices).getDevicesAsync();
|
|
47
|
+
const device1 = devices.find((device)=>device.name === name
|
|
48
|
+
);
|
|
49
|
+
if (!device1) {
|
|
50
|
+
throw new _errors.CommandError("Could not find device with name: " + name);
|
|
51
|
+
}
|
|
52
|
+
return AndroidDeviceManager.resolveAsync({
|
|
53
|
+
device: device1,
|
|
54
|
+
shouldPrompt: false
|
|
55
|
+
});
|
|
56
|
+
}
|
|
45
57
|
static async resolveAsync({ device , shouldPrompt } = {}) {
|
|
46
58
|
if (device) {
|
|
47
59
|
const manager = new AndroidDeviceManager(device);
|
|
@@ -79,7 +91,7 @@ class AndroidDeviceManager extends _deviceManager.DeviceManager {
|
|
|
79
91
|
if (!await AndroidDebugBridge.isDeviceBootedAsync(this.device)) {
|
|
80
92
|
this.device = await (0, _emulator).startDeviceAsync(this.device);
|
|
81
93
|
}
|
|
82
|
-
if (
|
|
94
|
+
if (this.device.isAuthorized === false) {
|
|
83
95
|
AndroidDebugBridge.logUnauthorized(this.device);
|
|
84
96
|
return null;
|
|
85
97
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/platforms/android/AndroidDeviceManager.ts"],"sourcesContent":["import assert from 'assert';\nimport chalk from 'chalk';\n\nimport * as Log from '../../../log';\nimport { AbortCommandError, CommandError } from '../../../utils/errors';\nimport { validateUrl } from '../../../utils/url';\nimport { DeviceManager } from '../DeviceManager';\nimport { ExpoGoInstaller } from '../ExpoGoInstaller';\nimport { BaseResolveDeviceProps } from '../PlatformManager';\nimport { activateWindowAsync } from './activateWindow';\nimport * as AndroidDebugBridge from './adb';\nimport { startDeviceAsync } from './emulator';\nimport { getDevicesAsync } from './getDevices';\nimport { promptForDeviceAsync } from './promptAndroidDevice';\n\nconst EXPO_GO_APPLICATION_IDENTIFIER = 'host.exp.exponent';\n\nexport class AndroidDeviceManager extends DeviceManager<AndroidDebugBridge.Device> {\n static async resolveAsync({\n device,\n shouldPrompt,\n }: BaseResolveDeviceProps<AndroidDebugBridge.Device> = {}): Promise<AndroidDeviceManager> {\n if (device) {\n const manager = new AndroidDeviceManager(device);\n if (!(await manager.attemptToStartAsync())) {\n throw new AbortCommandError();\n }\n return manager;\n }\n\n const devices = await getDevicesAsync();\n const _device = shouldPrompt ? await promptForDeviceAsync(devices) : devices[0];\n return AndroidDeviceManager.resolveAsync({ device: _device, shouldPrompt: false });\n }\n\n get name() {\n // TODO: Maybe strip `_` from the device name?\n return this.device.name;\n }\n\n get identifier(): string {\n return this.device.pid ?? 'unknown';\n }\n\n async getAppVersionAsync(applicationId: string): Promise<string | null> {\n const info = await AndroidDebugBridge.getPackageInfoAsync(this.device, {\n appId: applicationId,\n });\n\n const regex = /versionName=([0-9.]+)/;\n return regex.exec(info)?.[1] ?? null;\n }\n\n protected async attemptToStartAsync(): Promise<AndroidDebugBridge.Device | null> {\n // TODO: Add a light-weight method for checking since a device could disconnect.\n if (!(await AndroidDebugBridge.isDeviceBootedAsync(this.device))) {\n this.device = await startDeviceAsync(this.device);\n }\n\n if (!this.device.isAuthorized) {\n AndroidDebugBridge.logUnauthorized(this.device);\n return null;\n }\n\n return this.device;\n }\n\n async startAsync(): Promise<AndroidDebugBridge.Device> {\n const device = await this.attemptToStartAsync();\n assert(device, `Failed to boot emulator.`);\n return this.device;\n }\n\n async installAppAsync(binaryPath: string) {\n await AndroidDebugBridge.installAsync(this.device, {\n filePath: binaryPath,\n });\n }\n\n async uninstallAppAsync(appId: string) {\n // we need to check if the app is installed, else we might bump into \"Failure [DELETE_FAILED_INTERNAL_ERROR]\"\n const isInstalled = await this.isAppInstalledAsync(appId);\n if (!isInstalled) {\n return;\n }\n\n try {\n await AndroidDebugBridge.uninstallAsync(this.device, {\n appId,\n });\n } catch (e) {\n Log.error(\n `Could not uninstall app \"${appId}\" from your device, please uninstall it manually and try again.`\n );\n throw e;\n }\n }\n\n /**\n * @param launchActivity Activity to launch `[application identifier]/.[main activity name]`, ex: `com.bacon.app/.MainActivity`\n */\n async launchActivityAsync(launchActivity: string): Promise<string> {\n try {\n return await AndroidDebugBridge.launchActivityAsync(this.device, {\n launchActivity,\n });\n } catch (error: any) {\n let errorMessage = `Couldn't open Android app with activity \"${launchActivity}\" on device \"${this.name}\".`;\n if (error instanceof CommandError && error.code === 'APP_NOT_INSTALLED') {\n errorMessage += `\\nThe app might not be installed, try installing it with: ${chalk.bold(\n `npx expo run:android -d ${this.name}`\n )}`;\n }\n errorMessage += chalk.gray(`\\n${error.message}`);\n error.message = errorMessage;\n throw error;\n }\n }\n\n async isAppInstalledAsync(applicationId: string) {\n return await AndroidDebugBridge.isPackageInstalledAsync(this.device, applicationId);\n }\n\n async openUrlAsync(url: string) {\n // Non-compliant URLs will be treated as application identifiers.\n if (!validateUrl(url, { requireProtocol: true })) {\n await this.launchActivityAsync(url);\n return;\n }\n\n const parsed = new URL(url);\n\n if (parsed.protocol === 'exp:') {\n // NOTE(brentvatne): temporary workaround! launch Expo Go first, then\n // launch the project!\n // https://github.com/expo/expo/issues/7772\n // adb shell monkey -p host.exp.exponent -c android.intent.category.LAUNCHER 1\n // Note: this is not needed in Expo Development Client, it only applies to Expo Go\n await AndroidDebugBridge.openAppIdAsync(\n { pid: this.device.pid },\n { applicationId: EXPO_GO_APPLICATION_IDENTIFIER }\n );\n }\n\n await AndroidDebugBridge.openUrlAsync({ pid: this.device.pid }, { url });\n }\n\n async activateWindowAsync() {\n // Bring the emulator window to the front on macos devices.\n await activateWindowAsync(this.device);\n }\n\n async ensureExpoGoAsync(sdkVersion?: string): Promise<boolean> {\n const installer = new ExpoGoInstaller('android', EXPO_GO_APPLICATION_IDENTIFIER, sdkVersion);\n return installer.ensureAsync(this);\n }\n}\n"],"names":["Log","AndroidDebugBridge","EXPO_GO_APPLICATION_IDENTIFIER","AndroidDeviceManager","DeviceManager","resolveAsync","device","shouldPrompt","manager","attemptToStartAsync","AbortCommandError","devices","getDevicesAsync","_device","promptForDeviceAsync","name","identifier","pid","getAppVersionAsync","applicationId","regex","info","getPackageInfoAsync","appId","exec","isDeviceBootedAsync","startDeviceAsync","isAuthorized","logUnauthorized","startAsync","assert","installAppAsync","binaryPath","installAsync","filePath","uninstallAppAsync","isInstalled","isAppInstalledAsync","uninstallAsync","e","error","launchActivityAsync","launchActivity","errorMessage","CommandError","code","chalk","bold","gray","message","isPackageInstalledAsync","openUrlAsync","url","validateUrl","requireProtocol","parsed","URL","protocol","openAppIdAsync","activateWindowAsync","ensureExpoGoAsync","sdkVersion","installer","ExpoGoInstaller","ensureAsync"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/platforms/android/AndroidDeviceManager.ts"],"sourcesContent":["import assert from 'assert';\nimport chalk from 'chalk';\n\nimport * as Log from '../../../log';\nimport { AbortCommandError, CommandError } from '../../../utils/errors';\nimport { validateUrl } from '../../../utils/url';\nimport { DeviceManager } from '../DeviceManager';\nimport { ExpoGoInstaller } from '../ExpoGoInstaller';\nimport { BaseResolveDeviceProps } from '../PlatformManager';\nimport { activateWindowAsync } from './activateWindow';\nimport * as AndroidDebugBridge from './adb';\nimport { startDeviceAsync } from './emulator';\nimport { getDevicesAsync } from './getDevices';\nimport { promptForDeviceAsync } from './promptAndroidDevice';\n\nconst EXPO_GO_APPLICATION_IDENTIFIER = 'host.exp.exponent';\n\nexport class AndroidDeviceManager extends DeviceManager<AndroidDebugBridge.Device> {\n static async resolveFromNameAsync(name: string): Promise<AndroidDeviceManager> {\n const devices = await getDevicesAsync();\n const device = devices.find((device) => device.name === name);\n\n if (!device) {\n throw new CommandError('Could not find device with name: ' + name);\n }\n return AndroidDeviceManager.resolveAsync({ device, shouldPrompt: false });\n }\n\n static async resolveAsync({\n device,\n shouldPrompt,\n }: BaseResolveDeviceProps<AndroidDebugBridge.Device> = {}): Promise<AndroidDeviceManager> {\n if (device) {\n const manager = new AndroidDeviceManager(device);\n if (!(await manager.attemptToStartAsync())) {\n throw new AbortCommandError();\n }\n return manager;\n }\n\n const devices = await getDevicesAsync();\n const _device = shouldPrompt ? await promptForDeviceAsync(devices) : devices[0];\n return AndroidDeviceManager.resolveAsync({ device: _device, shouldPrompt: false });\n }\n\n get name() {\n // TODO: Maybe strip `_` from the device name?\n return this.device.name;\n }\n\n get identifier(): string {\n return this.device.pid ?? 'unknown';\n }\n\n async getAppVersionAsync(applicationId: string): Promise<string | null> {\n const info = await AndroidDebugBridge.getPackageInfoAsync(this.device, {\n appId: applicationId,\n });\n\n const regex = /versionName=([0-9.]+)/;\n return regex.exec(info)?.[1] ?? null;\n }\n\n protected async attemptToStartAsync(): Promise<AndroidDebugBridge.Device | null> {\n // TODO: Add a light-weight method for checking since a device could disconnect.\n if (!(await AndroidDebugBridge.isDeviceBootedAsync(this.device))) {\n this.device = await startDeviceAsync(this.device);\n }\n\n if (this.device.isAuthorized === false) {\n AndroidDebugBridge.logUnauthorized(this.device);\n return null;\n }\n\n return this.device;\n }\n\n async startAsync(): Promise<AndroidDebugBridge.Device> {\n const device = await this.attemptToStartAsync();\n assert(device, `Failed to boot emulator.`);\n return this.device;\n }\n\n async installAppAsync(binaryPath: string) {\n await AndroidDebugBridge.installAsync(this.device, {\n filePath: binaryPath,\n });\n }\n\n async uninstallAppAsync(appId: string) {\n // we need to check if the app is installed, else we might bump into \"Failure [DELETE_FAILED_INTERNAL_ERROR]\"\n const isInstalled = await this.isAppInstalledAsync(appId);\n if (!isInstalled) {\n return;\n }\n\n try {\n await AndroidDebugBridge.uninstallAsync(this.device, {\n appId,\n });\n } catch (e) {\n Log.error(\n `Could not uninstall app \"${appId}\" from your device, please uninstall it manually and try again.`\n );\n throw e;\n }\n }\n\n /**\n * @param launchActivity Activity to launch `[application identifier]/.[main activity name]`, ex: `com.bacon.app/.MainActivity`\n */\n async launchActivityAsync(launchActivity: string): Promise<string> {\n try {\n return await AndroidDebugBridge.launchActivityAsync(this.device, {\n launchActivity,\n });\n } catch (error: any) {\n let errorMessage = `Couldn't open Android app with activity \"${launchActivity}\" on device \"${this.name}\".`;\n if (error instanceof CommandError && error.code === 'APP_NOT_INSTALLED') {\n errorMessage += `\\nThe app might not be installed, try installing it with: ${chalk.bold(\n `npx expo run:android -d ${this.name}`\n )}`;\n }\n errorMessage += chalk.gray(`\\n${error.message}`);\n error.message = errorMessage;\n throw error;\n }\n }\n\n async isAppInstalledAsync(applicationId: string) {\n return await AndroidDebugBridge.isPackageInstalledAsync(this.device, applicationId);\n }\n\n async openUrlAsync(url: string) {\n // Non-compliant URLs will be treated as application identifiers.\n if (!validateUrl(url, { requireProtocol: true })) {\n await this.launchActivityAsync(url);\n return;\n }\n\n const parsed = new URL(url);\n\n if (parsed.protocol === 'exp:') {\n // NOTE(brentvatne): temporary workaround! launch Expo Go first, then\n // launch the project!\n // https://github.com/expo/expo/issues/7772\n // adb shell monkey -p host.exp.exponent -c android.intent.category.LAUNCHER 1\n // Note: this is not needed in Expo Development Client, it only applies to Expo Go\n await AndroidDebugBridge.openAppIdAsync(\n { pid: this.device.pid },\n { applicationId: EXPO_GO_APPLICATION_IDENTIFIER }\n );\n }\n\n await AndroidDebugBridge.openUrlAsync({ pid: this.device.pid }, { url });\n }\n\n async activateWindowAsync() {\n // Bring the emulator window to the front on macos devices.\n await activateWindowAsync(this.device);\n }\n\n async ensureExpoGoAsync(sdkVersion?: string): Promise<boolean> {\n const installer = new ExpoGoInstaller('android', EXPO_GO_APPLICATION_IDENTIFIER, sdkVersion);\n return installer.ensureAsync(this);\n }\n}\n"],"names":["Log","AndroidDebugBridge","EXPO_GO_APPLICATION_IDENTIFIER","AndroidDeviceManager","DeviceManager","resolveFromNameAsync","name","devices","getDevicesAsync","device","find","CommandError","resolveAsync","shouldPrompt","manager","attemptToStartAsync","AbortCommandError","_device","promptForDeviceAsync","identifier","pid","getAppVersionAsync","applicationId","regex","info","getPackageInfoAsync","appId","exec","isDeviceBootedAsync","startDeviceAsync","isAuthorized","logUnauthorized","startAsync","assert","installAppAsync","binaryPath","installAsync","filePath","uninstallAppAsync","isInstalled","isAppInstalledAsync","uninstallAsync","e","error","launchActivityAsync","launchActivity","errorMessage","code","chalk","bold","gray","message","isPackageInstalledAsync","openUrlAsync","url","validateUrl","requireProtocol","parsed","URL","protocol","openAppIdAsync","activateWindowAsync","ensureExpoGoAsync","sdkVersion","installer","ExpoGoInstaller","ensureAsync"],"mappings":"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"}
|
|
@@ -48,6 +48,7 @@ function getUnixPID(port) {
|
|
|
48
48
|
}
|
|
49
49
|
async function activateWindowAsync(device) {
|
|
50
50
|
var ref;
|
|
51
|
+
Log.debug(`Activating window for device (pid: ${device.pid}, type: ${device.type})`);
|
|
51
52
|
if (// only mac is supported for now.
|
|
52
53
|
process.platform !== "darwin" || // can only focus emulators
|
|
53
54
|
device.type !== "emulator") {
|
|
@@ -63,6 +64,7 @@ async function activateWindowAsync(device) {
|
|
|
63
64
|
if (!pid) {
|
|
64
65
|
return false;
|
|
65
66
|
}
|
|
67
|
+
Log.debug(`Activate window for pid:`, pid);
|
|
66
68
|
try {
|
|
67
69
|
await osascript.execAsync(`
|
|
68
70
|
tell application "System Events"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/platforms/android/activateWindow.ts"],"sourcesContent":["import * as osascript from '@expo/osascript';\nimport { execFileSync } from 'child_process';\n\nimport * as Log from '../../../log';\nimport { Device } from './adb';\n\nfunction getUnixPID(port: number | string): string {\n // Runs like `lsof -i:8081 -P -t -sTCP:LISTEN`\n const args = [`-i:${port}`, '-P', '-t', '-sTCP:LISTEN'];\n Log.debug('lsof ' + args.join(' '));\n return execFileSync('lsof', args, {\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'ignore'],\n })\n .split('\\n')[0]\n ?.trim?.();\n}\n\n/** Activate the Emulator window on macOS. */\nexport async function activateWindowAsync(device: Pick<Device, 'type' | 'pid'>): Promise<boolean> {\n if (\n // only mac is supported for now.\n process.platform !== 'darwin' ||\n // can only focus emulators\n device.type !== 'emulator'\n ) {\n return false;\n }\n\n // Google Emulator ID: `emulator-5554` -> `5554`\n const androidPid = device.pid!.match(/-(\\d+)/)?.[1];\n if (!androidPid) {\n return false;\n }\n // Unix PID\n const pid = getUnixPID(androidPid);\n\n if (!pid) {\n return false;\n }\n try {\n await osascript.execAsync(`\n tell application \"System Events\"\n set frontmost of the first process whose unix id is ${pid} to true\n end tell`);\n return true;\n } catch {\n // noop -- this feature is very specific and subject to failure.\n return false;\n }\n}\n"],"names":["activateWindowAsync","osascript","Log","getUnixPID","port","execFileSync","args","debug","join","encoding","stdio","split","trim","device","
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/platforms/android/activateWindow.ts"],"sourcesContent":["import * as osascript from '@expo/osascript';\nimport { execFileSync } from 'child_process';\n\nimport * as Log from '../../../log';\nimport { Device } from './adb';\n\nfunction getUnixPID(port: number | string): string {\n // Runs like `lsof -i:8081 -P -t -sTCP:LISTEN`\n const args = [`-i:${port}`, '-P', '-t', '-sTCP:LISTEN'];\n Log.debug('lsof ' + args.join(' '));\n return execFileSync('lsof', args, {\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'ignore'],\n })\n .split('\\n')[0]\n ?.trim?.();\n}\n\n/** Activate the Emulator window on macOS. */\nexport async function activateWindowAsync(device: Pick<Device, 'type' | 'pid'>): Promise<boolean> {\n Log.debug(`Activating window for device (pid: ${device.pid}, type: ${device.type})`);\n if (\n // only mac is supported for now.\n process.platform !== 'darwin' ||\n // can only focus emulators\n device.type !== 'emulator'\n ) {\n return false;\n }\n\n // Google Emulator ID: `emulator-5554` -> `5554`\n const androidPid = device.pid!.match(/-(\\d+)/)?.[1];\n if (!androidPid) {\n return false;\n }\n // Unix PID\n const pid = getUnixPID(androidPid);\n\n if (!pid) {\n return false;\n }\n Log.debug(`Activate window for pid:`, pid);\n try {\n await osascript.execAsync(`\n tell application \"System Events\"\n set frontmost of the first process whose unix id is ${pid} to true\n end tell`);\n return true;\n } catch {\n // noop -- this feature is very specific and subject to failure.\n return false;\n }\n}\n"],"names":["activateWindowAsync","osascript","Log","getUnixPID","port","execFileSync","args","debug","join","encoding","stdio","split","trim","device","pid","type","process","platform","androidPid","match","execAsync"],"mappings":"AAAA;;;;QAmBsBA,mBAAmB,GAAnBA,mBAAmB;AAnB7BC,IAAAA,SAAS,mCAAM,iBAAiB,EAAvB;AACQ,IAAA,aAAe,WAAf,eAAe,CAAA;AAEhCC,IAAAA,GAAG,mCAAM,cAAc,EAApB;;;;;;;;;;;;;;;;;;;;;;AAGf,SAASC,UAAU,CAACC,IAAqB,EAAU;QAI1CC,GAIU;IAPjB,8CAA8C;IAC9C,MAAMC,IAAI,GAAG;QAAC,CAAC,GAAG,EAAEF,IAAI,CAAC,CAAC;QAAE,IAAI;QAAE,IAAI;QAAE,cAAc;KAAC,AAAC;IACxDF,GAAG,CAACK,KAAK,CAAC,OAAO,GAAGD,IAAI,CAACE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,OAAOH,CAAAA,GAIU,GAJVA,CAAAA,GAAAA,aAAY,AAGjB,CAAA,aAHiB,CAAC,MAAM,EAAEC,IAAI,EAAE;QAChCG,QAAQ,EAAE,MAAM;QAChBC,KAAK,EAAE;YAAC,MAAM;YAAE,MAAM;YAAE,QAAQ;SAAC;KAClC,CAAC,CACCC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SACT,GALDN,KAAAA,CAKC,GALDA,GAIU,CACbO,IAAI,QAAI,GALLP,KAAAA,CAKK,GALLA,GAIU,CACbO,IAAI,EAAI,CAAC;CACd;AAGM,eAAeZ,mBAAmB,CAACa,MAAoC,EAAoB;QAY7EA,GAA2B;IAX9CX,GAAG,CAACK,KAAK,CAAC,CAAC,mCAAmC,EAAEM,MAAM,CAACC,GAAG,CAAC,QAAQ,EAAED,MAAM,CAACE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,IACE,iCAAiC;IACjCC,OAAO,CAACC,QAAQ,KAAK,QAAQ,IAC7B,2BAA2B;IAC3BJ,MAAM,CAACE,IAAI,KAAK,UAAU,EAC1B;QACA,OAAO,KAAK,CAAC;KACd;IAED,gDAAgD;IAChD,MAAMG,UAAU,GAAGL,CAAAA,GAA2B,GAA3BA,MAAM,CAACC,GAAG,CAAEK,KAAK,UAAU,SAAK,GAAhCN,KAAAA,CAAgC,GAAhCA,GAA2B,AAAE,CAAC,CAAC,CAAC,AAAC;IACpD,IAAI,CAACK,UAAU,EAAE;QACf,OAAO,KAAK,CAAC;KACd;IACD,WAAW;IACX,MAAMJ,GAAG,GAAGX,UAAU,CAACe,UAAU,CAAC,AAAC;IAEnC,IAAI,CAACJ,GAAG,EAAE;QACR,OAAO,KAAK,CAAC;KACd;IACDZ,GAAG,CAACK,KAAK,CAAC,CAAC,wBAAwB,CAAC,EAAEO,GAAG,CAAC,CAAC;IAC3C,IAAI;QACF,MAAMb,SAAS,CAACmB,SAAS,CAAC,CAAC;;0DAE2B,EAAEN,GAAG,CAAC;YACpD,CAAC,CAAC,CAAC;QACX,OAAO,IAAI,CAAC;KACb,CAAC,OAAM;QACN,gEAAgE;QAChE,OAAO,KAAK,CAAC;KACd;CACF"}
|
|
@@ -16,7 +16,9 @@ exports.getAttachedDevicesAsync = getAttachedDevicesAsync;
|
|
|
16
16
|
exports.getAdbNameForDeviceIdAsync = getAdbNameForDeviceIdAsync;
|
|
17
17
|
exports.isDeviceBootedAsync = isDeviceBootedAsync;
|
|
18
18
|
exports.isBootAnimationCompleteAsync = isBootAnimationCompleteAsync;
|
|
19
|
+
exports.getDeviceABIsAsync = getDeviceABIsAsync;
|
|
19
20
|
exports.getPropertyDataForDeviceAsync = getPropertyDataForDeviceAsync;
|
|
21
|
+
exports.DeviceABI = void 0;
|
|
20
22
|
var _chalk = _interopRequireDefault(require("chalk"));
|
|
21
23
|
var _os = _interopRequireDefault(require("os"));
|
|
22
24
|
var Log = _interopRequireWildcard(require("../../../log"));
|
|
@@ -49,7 +51,28 @@ function _interopRequireWildcard(obj) {
|
|
|
49
51
|
return newObj;
|
|
50
52
|
}
|
|
51
53
|
}
|
|
54
|
+
var DeviceABI;
|
|
55
|
+
exports.DeviceABI = DeviceABI;
|
|
56
|
+
(function(DeviceABI) {
|
|
57
|
+
DeviceABI[// The arch specific android target platforms are soft-deprecated.
|
|
58
|
+
// Instead of using TargetPlatform as a combination arch + platform
|
|
59
|
+
// the code will be updated to carry arch information in [DarwinArch]
|
|
60
|
+
// and [AndroidArch].
|
|
61
|
+
"arm"] = "arm";
|
|
62
|
+
DeviceABI["arm64"] = "arm64";
|
|
63
|
+
DeviceABI["x64"] = "x64";
|
|
64
|
+
DeviceABI["x86"] = "x86";
|
|
65
|
+
DeviceABI["armeabiV7a"] = "armeabi-v7a";
|
|
66
|
+
DeviceABI["armeabi"] = "armeabi";
|
|
67
|
+
DeviceABI["universal"] = "universal";
|
|
68
|
+
})(DeviceABI || (exports.DeviceABI = DeviceABI = {}));
|
|
52
69
|
const CANT_START_ACTIVITY_ERROR = "Activity not started, unable to resolve Intent";
|
|
70
|
+
// http://developer.android.com/ndk/guides/abis.html
|
|
71
|
+
const PROP_CPU_NAME = "ro.product.cpu.abi";
|
|
72
|
+
const PROP_CPU_ABI_LIST_NAME = "ro.product.cpu.abilist";
|
|
73
|
+
// Can sometimes be null
|
|
74
|
+
// http://developer.android.com/ndk/guides/abis.html
|
|
75
|
+
const PROP_BOOT_ANIMATION_STATE = "init.svc.bootanim";
|
|
53
76
|
let _server;
|
|
54
77
|
function getServer() {
|
|
55
78
|
_server != null ? _server : _server = new _adbserver.ADBServer();
|
|
@@ -180,9 +203,6 @@ async function isDeviceBootedAsync({ name } = {}) {
|
|
|
180
203
|
return (ref1 = devices.find((device)=>device.name === name
|
|
181
204
|
)) != null ? ref1 : null;
|
|
182
205
|
}
|
|
183
|
-
// Can sometimes be null
|
|
184
|
-
// http://developer.android.com/ndk/guides/abis.html
|
|
185
|
-
const PROP_BOOT_ANIMATION_STATE = "init.svc.bootanim";
|
|
186
206
|
async function isBootAnimationCompleteAsync(pid) {
|
|
187
207
|
try {
|
|
188
208
|
const props = await getPropertyDataForDeviceAsync({
|
|
@@ -193,6 +213,16 @@ async function isBootAnimationCompleteAsync(pid) {
|
|
|
193
213
|
return false;
|
|
194
214
|
}
|
|
195
215
|
}
|
|
216
|
+
async function getDeviceABIsAsync(device) {
|
|
217
|
+
const cpuAbiList = (await getPropertyDataForDeviceAsync(device, PROP_CPU_ABI_LIST_NAME))[PROP_CPU_ABI_LIST_NAME];
|
|
218
|
+
if (cpuAbiList) {
|
|
219
|
+
return cpuAbiList.trim().split(",");
|
|
220
|
+
}
|
|
221
|
+
const abi = (await getPropertyDataForDeviceAsync(device, PROP_CPU_NAME))[PROP_CPU_NAME];
|
|
222
|
+
return [
|
|
223
|
+
abi
|
|
224
|
+
];
|
|
225
|
+
}
|
|
196
226
|
async function getPropertyDataForDeviceAsync(device, prop) {
|
|
197
227
|
// @ts-ignore
|
|
198
228
|
const propCommand = adbArgs(...[
|
|
@@ -208,11 +238,14 @@ async function getPropertyDataForDeviceAsync(device, prop) {
|
|
|
208
238
|
// [wifi.direct.interface]: [p2p-dev-wlan0]
|
|
209
239
|
// [wifi.interface]: [wlan0]
|
|
210
240
|
if (prop) {
|
|
241
|
+
Log.debug(`[ADB] property data: (device pid: ${device.pid}, prop: ${prop}, data: ${results})`);
|
|
211
242
|
return {
|
|
212
243
|
[prop]: results
|
|
213
244
|
};
|
|
214
245
|
}
|
|
215
|
-
|
|
246
|
+
const props = parseAdbDeviceProperties(results);
|
|
247
|
+
Log.debug(`[ADB] parsed data:`, props);
|
|
248
|
+
return props;
|
|
216
249
|
} catch (error) {
|
|
217
250
|
// TODO: Ensure error has message and not stderr
|
|
218
251
|
throw new _errors.CommandError(`Failed to get properties for device (${device.pid}): ${error.message}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/platforms/android/adb.ts"],"sourcesContent":["import chalk from 'chalk';\nimport os from 'os';\n\nimport * as Log from '../../../log';\nimport { CommandError } from '../../../utils/errors';\nimport { learnMore } from '../../../utils/link';\nimport { ADBServer } from './ADBServer';\n\n/** Represents a connected Android device. */\nexport type Device = {\n /** Process ID. */\n pid?: string;\n /** Name of the device, also used as the ID for opening devices. */\n name: string;\n /** Is emulator or connected device. */\n type: 'emulator' | 'device';\n /** Is the device booted (emulator). */\n isBooted: boolean;\n /** Is device authorized for developing. https://expo.fyi/authorize-android-device */\n isAuthorized: boolean;\n};\n\ntype DeviceContext = Pick<Device, 'pid'>;\n\ntype DeviceProperties = Record<string, string>;\n\nconst CANT_START_ACTIVITY_ERROR = 'Activity not started, unable to resolve Intent';\n\nlet _server: ADBServer | null;\n\n/** Return the lazily loaded ADB server instance. */\nexport function getServer() {\n _server ??= new ADBServer();\n return _server;\n}\n\n/** Logs an FYI message about authorizing your device. */\nexport function logUnauthorized(device: Device) {\n Log.warn(\n `\\nThis computer is not authorized for developing on ${chalk.bold(device.name)}. ${chalk.dim(\n learnMore('https://expo.fyi/authorize-android-device')\n )}`\n );\n}\n\n/** Returns true if the provided package name is installed on the provided Android device. */\nexport async function isPackageInstalledAsync(\n device: DeviceContext,\n androidPackage: string\n): Promise<boolean> {\n const packages = await getServer().runAsync(\n adbArgs(device.pid, 'shell', 'pm', 'list', 'packages', androidPackage)\n );\n\n const lines = packages.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line === `package:${androidPackage}`) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * @param device.pid Process ID of the Android device to launch.\n * @param props.launchActivity Activity to launch `[application identifier]/.[main activity name]`, ex: `com.bacon.app/.MainActivity`\n */\nexport async function launchActivityAsync(\n device: DeviceContext,\n {\n launchActivity,\n }: {\n launchActivity: string;\n }\n) {\n return openAsync(\n adbArgs(\n device.pid,\n 'shell',\n 'am',\n 'start',\n '-a',\n 'android.intent.action.RUN',\n // FLAG_ACTIVITY_SINGLE_TOP -- If set, the activity will not be launched if it is already running at the top of the history stack.\n '-f',\n '0x20000000',\n // Activity to open first: com.bacon.app/.MainActivity\n '-n',\n launchActivity\n )\n );\n}\n\n/**\n * @param device.pid Process ID of the Android device to launch.\n * @param props.applicationId package name to launch.\n */\nexport async function openAppIdAsync(\n device: DeviceContext,\n {\n applicationId,\n }: {\n applicationId: string;\n }\n) {\n return openAsync(\n adbArgs(\n device.pid,\n 'shell',\n 'monkey',\n '-p',\n applicationId,\n '-c',\n 'android.intent.category.LAUNCHER',\n '1'\n )\n );\n}\n\n/**\n * @param device.pid Process ID of the Android device to launch.\n * @param props.url URL to launch.\n */\nexport async function openUrlAsync(\n device: DeviceContext,\n {\n url,\n }: {\n url: string;\n }\n) {\n return openAsync(\n adbArgs(device.pid, 'shell', 'am', 'start', '-a', 'android.intent.action.VIEW', '-d', url)\n );\n}\n\n/** Runs a generic command watches for common errors in order to throw with an expected code. */\nasync function openAsync(args: string[]): Promise<string> {\n const results = await getServer().runAsync(args);\n if (\n results.includes(CANT_START_ACTIVITY_ERROR) ||\n results.match(/Error: Activity class .* does not exist\\./g)\n ) {\n throw new CommandError('APP_NOT_INSTALLED', results.substring(results.indexOf('Error: ')));\n }\n return results;\n}\n\n/** Uninstall an app given its Android package name. */\nexport async function uninstallAsync(\n device: DeviceContext,\n { appId }: { appId: string }\n): Promise<string> {\n return await getServer().runAsync(adbArgs(device.pid, 'uninstall', appId));\n}\n\n/** Get package info from an app based on its Android package name. */\nexport async function getPackageInfoAsync(\n device: DeviceContext,\n { appId }: { appId: string }\n): Promise<string> {\n return await getServer().runAsync(adbArgs(device.pid, 'shell', 'dumpsys', 'package', appId));\n}\n\n/** Install an app on a connected device. */\nexport async function installAsync(device: DeviceContext, { filePath }: { filePath: string }) {\n // TODO: Handle the `INSTALL_FAILED_INSUFFICIENT_STORAGE` error.\n return await getServer().runAsync(adbArgs(device.pid, 'install', '-r', '-d', filePath));\n}\n\n/** Format ADB args with process ID. */\nexport function adbArgs(pid: Device['pid'], ...options: string[]): string[] {\n const args = [];\n if (pid) {\n args.push('-s', pid);\n }\n return args.concat(options);\n}\n\n// TODO: This is very expensive for some operations.\nexport async function getAttachedDevicesAsync(): Promise<Device[]> {\n const output = await getServer().runAsync(['devices', '-l']);\n\n const splitItems = output.trim().replace(/\\n$/, '').split(os.EOL);\n // First line is `\"List of devices attached\"`, remove it\n // @ts-ignore: todo\n const attachedDevices: {\n props: string[];\n type: Device['type'];\n isAuthorized: Device['isAuthorized'];\n }[] = splitItems\n .slice(1, splitItems.length)\n .map((line) => {\n // unauthorized: ['FA8251A00719', 'unauthorized', 'usb:338690048X', 'transport_id:5']\n // authorized: ['FA8251A00719', 'device', 'usb:336592896X', 'product:walleye', 'model:Pixel_2', 'device:walleye', 'transport_id:4']\n // emulator: ['emulator-5554', 'offline', 'transport_id:1']\n const props = line.split(' ').filter(Boolean);\n\n const isAuthorized = props[1] !== 'unauthorized';\n const type = line.includes('emulator') ? 'emulator' : 'device';\n return { props, type, isAuthorized };\n })\n .filter(({ props: [pid] }) => !!pid);\n\n const devicePromises = attachedDevices.map<Promise<Device>>(async (props) => {\n const {\n type,\n props: [pid, ...deviceInfo],\n isAuthorized,\n } = props;\n\n let name: string | null = null;\n\n if (type === 'device') {\n if (isAuthorized) {\n // Possibly formatted like `model:Pixel_2`\n // Transform to `Pixel_2`\n const modelItem = deviceInfo.find((info) => info.includes('model:'));\n if (modelItem) {\n name = modelItem.replace('model:', '');\n }\n }\n // unauthorized devices don't have a name available to read\n if (!name) {\n // Device FA8251A00719\n name = `Device ${pid}`;\n }\n } else {\n // Given an emulator pid, get the emulator name which can be used to start the emulator later.\n name = (await getAdbNameForDeviceIdAsync({ pid })) ?? '';\n }\n\n return {\n pid,\n name,\n type,\n isAuthorized,\n isBooted: true,\n };\n });\n\n return Promise.all(devicePromises);\n}\n\n/**\n * Return the Emulator name for an emulator ID, this can be used to determine if an emulator is booted.\n *\n * @param device.pid a value like `emulator-5554` from `abd devices`\n */\nexport async function getAdbNameForDeviceIdAsync(device: DeviceContext): Promise<string | null> {\n const results = await getServer().runAsync(adbArgs(device.pid, 'emu', 'avd', 'name'));\n\n if (results.match(/could not connect to TCP port .*: Connection refused/)) {\n // Can also occur when the emulator does not exist.\n throw new CommandError('EMULATOR_NOT_FOUND', results);\n }\n\n return results.trim().split(/\\r?\\n/).shift() ?? null;\n}\n\nexport async function isDeviceBootedAsync({\n name,\n}: { name?: string } = {}): Promise<Device | null> {\n const devices = await getAttachedDevicesAsync();\n\n if (!name) {\n return devices[0] ?? null;\n }\n\n return devices.find((device) => device.name === name) ?? null;\n}\n\n// Can sometimes be null\n// http://developer.android.com/ndk/guides/abis.html\nconst PROP_BOOT_ANIMATION_STATE = 'init.svc.bootanim';\n\n/**\n * Returns true when a device's splash screen animation has stopped.\n * This can be used to detect when a device is fully booted and ready to use.\n *\n * @param pid\n */\nexport async function isBootAnimationCompleteAsync(pid?: string): Promise<boolean> {\n try {\n const props = await getPropertyDataForDeviceAsync({ pid }, PROP_BOOT_ANIMATION_STATE);\n return !!props[PROP_BOOT_ANIMATION_STATE].match(/stopped/);\n } catch {\n return false;\n }\n}\n\nexport async function getPropertyDataForDeviceAsync(\n device: DeviceContext,\n prop?: string\n): Promise<DeviceProperties> {\n // @ts-ignore\n const propCommand = adbArgs(...[device.pid, 'shell', 'getprop', prop].filter(Boolean));\n try {\n // Prevent reading as UTF8.\n const results = await getServer().getFileOutputAsync(propCommand);\n // Like:\n // [wifi.direct.interface]: [p2p-dev-wlan0]\n // [wifi.interface]: [wlan0]\n\n if (prop) {\n return {\n [prop]: results,\n };\n }\n return parseAdbDeviceProperties(results);\n } catch (error: any) {\n // TODO: Ensure error has message and not stderr\n throw new CommandError(`Failed to get properties for device (${device.pid}): ${error.message}`);\n }\n}\n\nfunction parseAdbDeviceProperties(devicePropertiesString: string) {\n const properties: DeviceProperties = {};\n const propertyExp = /\\[(.*?)\\]: \\[(.*?)\\]/gm;\n for (const match of devicePropertiesString.matchAll(propertyExp)) {\n properties[match[1]] = match[2];\n }\n return properties;\n}\n"],"names":["getServer","logUnauthorized","isPackageInstalledAsync","launchActivityAsync","openAppIdAsync","openUrlAsync","uninstallAsync","getPackageInfoAsync","installAsync","adbArgs","getAttachedDevicesAsync","getAdbNameForDeviceIdAsync","isDeviceBootedAsync","isBootAnimationCompleteAsync","getPropertyDataForDeviceAsync","Log","CANT_START_ACTIVITY_ERROR","_server","ADBServer","device","warn","chalk","bold","name","dim","learnMore","androidPackage","packages","runAsync","pid","lines","split","i","length","line","trim","launchActivity","openAsync","applicationId","url","args","results","includes","match","CommandError","substring","indexOf","appId","filePath","options","push","concat","output","splitItems","replace","os","EOL","attachedDevices","slice","map","props","filter","Boolean","isAuthorized","type","devicePromises","deviceInfo","modelItem","find","info","isBooted","Promise","all","shift","devices","PROP_BOOT_ANIMATION_STATE","prop","propCommand","getFileOutputAsync","parseAdbDeviceProperties","error","message","devicePropertiesString","properties","propertyExp","matchAll"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/platforms/android/adb.ts"],"sourcesContent":["import chalk from 'chalk';\nimport os from 'os';\n\nimport * as Log from '../../../log';\nimport { CommandError } from '../../../utils/errors';\nimport { learnMore } from '../../../utils/link';\nimport { ADBServer } from './ADBServer';\n\nexport enum DeviceABI {\n // The arch specific android target platforms are soft-deprecated.\n // Instead of using TargetPlatform as a combination arch + platform\n // the code will be updated to carry arch information in [DarwinArch]\n // and [AndroidArch].\n arm = 'arm',\n arm64 = 'arm64',\n x64 = 'x64',\n x86 = 'x86',\n armeabiV7a = 'armeabi-v7a',\n armeabi = 'armeabi',\n universal = 'universal',\n}\n\n/** Represents a connected Android device. */\nexport type Device = {\n /** Process ID. */\n pid?: string;\n /** Name of the device, also used as the ID for opening devices. */\n name: string;\n /** Is emulator or connected device. */\n type: 'emulator' | 'device';\n /** Is the device booted (emulator). */\n isBooted: boolean;\n /** Is device authorized for developing. https://expo.fyi/authorize-android-device */\n isAuthorized: boolean;\n};\n\ntype DeviceContext = Pick<Device, 'pid'>;\n\ntype DeviceProperties = Record<string, string>;\n\nconst CANT_START_ACTIVITY_ERROR = 'Activity not started, unable to resolve Intent';\n// http://developer.android.com/ndk/guides/abis.html\nconst PROP_CPU_NAME = 'ro.product.cpu.abi';\n\nconst PROP_CPU_ABI_LIST_NAME = 'ro.product.cpu.abilist';\n\n// Can sometimes be null\n// http://developer.android.com/ndk/guides/abis.html\nconst PROP_BOOT_ANIMATION_STATE = 'init.svc.bootanim';\n\nlet _server: ADBServer | null;\n\n/** Return the lazily loaded ADB server instance. */\nexport function getServer() {\n _server ??= new ADBServer();\n return _server;\n}\n\n/** Logs an FYI message about authorizing your device. */\nexport function logUnauthorized(device: Device) {\n Log.warn(\n `\\nThis computer is not authorized for developing on ${chalk.bold(device.name)}. ${chalk.dim(\n learnMore('https://expo.fyi/authorize-android-device')\n )}`\n );\n}\n\n/** Returns true if the provided package name is installed on the provided Android device. */\nexport async function isPackageInstalledAsync(\n device: DeviceContext,\n androidPackage: string\n): Promise<boolean> {\n const packages = await getServer().runAsync(\n adbArgs(device.pid, 'shell', 'pm', 'list', 'packages', androidPackage)\n );\n\n const lines = packages.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line === `package:${androidPackage}`) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * @param device.pid Process ID of the Android device to launch.\n * @param props.launchActivity Activity to launch `[application identifier]/.[main activity name]`, ex: `com.bacon.app/.MainActivity`\n */\nexport async function launchActivityAsync(\n device: DeviceContext,\n {\n launchActivity,\n }: {\n launchActivity: string;\n }\n) {\n return openAsync(\n adbArgs(\n device.pid,\n 'shell',\n 'am',\n 'start',\n '-a',\n 'android.intent.action.RUN',\n // FLAG_ACTIVITY_SINGLE_TOP -- If set, the activity will not be launched if it is already running at the top of the history stack.\n '-f',\n '0x20000000',\n // Activity to open first: com.bacon.app/.MainActivity\n '-n',\n launchActivity\n )\n );\n}\n\n/**\n * @param device.pid Process ID of the Android device to launch.\n * @param props.applicationId package name to launch.\n */\nexport async function openAppIdAsync(\n device: DeviceContext,\n {\n applicationId,\n }: {\n applicationId: string;\n }\n) {\n return openAsync(\n adbArgs(\n device.pid,\n 'shell',\n 'monkey',\n '-p',\n applicationId,\n '-c',\n 'android.intent.category.LAUNCHER',\n '1'\n )\n );\n}\n\n/**\n * @param device.pid Process ID of the Android device to launch.\n * @param props.url URL to launch.\n */\nexport async function openUrlAsync(\n device: DeviceContext,\n {\n url,\n }: {\n url: string;\n }\n) {\n return openAsync(\n adbArgs(device.pid, 'shell', 'am', 'start', '-a', 'android.intent.action.VIEW', '-d', url)\n );\n}\n\n/** Runs a generic command watches for common errors in order to throw with an expected code. */\nasync function openAsync(args: string[]): Promise<string> {\n const results = await getServer().runAsync(args);\n if (\n results.includes(CANT_START_ACTIVITY_ERROR) ||\n results.match(/Error: Activity class .* does not exist\\./g)\n ) {\n throw new CommandError('APP_NOT_INSTALLED', results.substring(results.indexOf('Error: ')));\n }\n return results;\n}\n\n/** Uninstall an app given its Android package name. */\nexport async function uninstallAsync(\n device: DeviceContext,\n { appId }: { appId: string }\n): Promise<string> {\n return await getServer().runAsync(adbArgs(device.pid, 'uninstall', appId));\n}\n\n/** Get package info from an app based on its Android package name. */\nexport async function getPackageInfoAsync(\n device: DeviceContext,\n { appId }: { appId: string }\n): Promise<string> {\n return await getServer().runAsync(adbArgs(device.pid, 'shell', 'dumpsys', 'package', appId));\n}\n\n/** Install an app on a connected device. */\nexport async function installAsync(device: DeviceContext, { filePath }: { filePath: string }) {\n // TODO: Handle the `INSTALL_FAILED_INSUFFICIENT_STORAGE` error.\n return await getServer().runAsync(adbArgs(device.pid, 'install', '-r', '-d', filePath));\n}\n\n/** Format ADB args with process ID. */\nexport function adbArgs(pid: Device['pid'], ...options: string[]): string[] {\n const args = [];\n if (pid) {\n args.push('-s', pid);\n }\n return args.concat(options);\n}\n\n// TODO: This is very expensive for some operations.\nexport async function getAttachedDevicesAsync(): Promise<Device[]> {\n const output = await getServer().runAsync(['devices', '-l']);\n\n const splitItems = output.trim().replace(/\\n$/, '').split(os.EOL);\n // First line is `\"List of devices attached\"`, remove it\n // @ts-ignore: todo\n const attachedDevices: {\n props: string[];\n type: Device['type'];\n isAuthorized: Device['isAuthorized'];\n }[] = splitItems\n .slice(1, splitItems.length)\n .map((line) => {\n // unauthorized: ['FA8251A00719', 'unauthorized', 'usb:338690048X', 'transport_id:5']\n // authorized: ['FA8251A00719', 'device', 'usb:336592896X', 'product:walleye', 'model:Pixel_2', 'device:walleye', 'transport_id:4']\n // emulator: ['emulator-5554', 'offline', 'transport_id:1']\n const props = line.split(' ').filter(Boolean);\n\n const isAuthorized = props[1] !== 'unauthorized';\n const type = line.includes('emulator') ? 'emulator' : 'device';\n return { props, type, isAuthorized };\n })\n .filter(({ props: [pid] }) => !!pid);\n\n const devicePromises = attachedDevices.map<Promise<Device>>(async (props) => {\n const {\n type,\n props: [pid, ...deviceInfo],\n isAuthorized,\n } = props;\n\n let name: string | null = null;\n\n if (type === 'device') {\n if (isAuthorized) {\n // Possibly formatted like `model:Pixel_2`\n // Transform to `Pixel_2`\n const modelItem = deviceInfo.find((info) => info.includes('model:'));\n if (modelItem) {\n name = modelItem.replace('model:', '');\n }\n }\n // unauthorized devices don't have a name available to read\n if (!name) {\n // Device FA8251A00719\n name = `Device ${pid}`;\n }\n } else {\n // Given an emulator pid, get the emulator name which can be used to start the emulator later.\n name = (await getAdbNameForDeviceIdAsync({ pid })) ?? '';\n }\n\n return {\n pid,\n name,\n type,\n isAuthorized,\n isBooted: true,\n };\n });\n\n return Promise.all(devicePromises);\n}\n\n/**\n * Return the Emulator name for an emulator ID, this can be used to determine if an emulator is booted.\n *\n * @param device.pid a value like `emulator-5554` from `abd devices`\n */\nexport async function getAdbNameForDeviceIdAsync(device: DeviceContext): Promise<string | null> {\n const results = await getServer().runAsync(adbArgs(device.pid, 'emu', 'avd', 'name'));\n\n if (results.match(/could not connect to TCP port .*: Connection refused/)) {\n // Can also occur when the emulator does not exist.\n throw new CommandError('EMULATOR_NOT_FOUND', results);\n }\n\n return results.trim().split(/\\r?\\n/).shift() ?? null;\n}\n\nexport async function isDeviceBootedAsync({\n name,\n}: { name?: string } = {}): Promise<Device | null> {\n const devices = await getAttachedDevicesAsync();\n\n if (!name) {\n return devices[0] ?? null;\n }\n\n return devices.find((device) => device.name === name) ?? null;\n}\n\n/**\n * Returns true when a device's splash screen animation has stopped.\n * This can be used to detect when a device is fully booted and ready to use.\n *\n * @param pid\n */\nexport async function isBootAnimationCompleteAsync(pid?: string): Promise<boolean> {\n try {\n const props = await getPropertyDataForDeviceAsync({ pid }, PROP_BOOT_ANIMATION_STATE);\n return !!props[PROP_BOOT_ANIMATION_STATE].match(/stopped/);\n } catch {\n return false;\n }\n}\n\n/** Get a list of ABIs for the provided device. */\nexport async function getDeviceABIsAsync(\n device: Pick<Device, 'name' | 'pid'>\n): Promise<DeviceABI[]> {\n const cpuAbiList = (await getPropertyDataForDeviceAsync(device, PROP_CPU_ABI_LIST_NAME))[\n PROP_CPU_ABI_LIST_NAME\n ];\n\n if (cpuAbiList) {\n return cpuAbiList.trim().split(',') as DeviceABI[];\n }\n\n const abi = (await getPropertyDataForDeviceAsync(device, PROP_CPU_NAME))[\n PROP_CPU_NAME\n ] as DeviceABI;\n return [abi];\n}\n\nexport async function getPropertyDataForDeviceAsync(\n device: DeviceContext,\n prop?: string\n): Promise<DeviceProperties> {\n // @ts-ignore\n const propCommand = adbArgs(...[device.pid, 'shell', 'getprop', prop].filter(Boolean));\n try {\n // Prevent reading as UTF8.\n const results = await getServer().getFileOutputAsync(propCommand);\n // Like:\n // [wifi.direct.interface]: [p2p-dev-wlan0]\n // [wifi.interface]: [wlan0]\n\n if (prop) {\n Log.debug(\n `[ADB] property data: (device pid: ${device.pid}, prop: ${prop}, data: ${results})`\n );\n return {\n [prop]: results,\n };\n }\n const props = parseAdbDeviceProperties(results);\n\n Log.debug(`[ADB] parsed data:`, props);\n\n return props;\n } catch (error: any) {\n // TODO: Ensure error has message and not stderr\n throw new CommandError(`Failed to get properties for device (${device.pid}): ${error.message}`);\n }\n}\n\nfunction parseAdbDeviceProperties(devicePropertiesString: string) {\n const properties: DeviceProperties = {};\n const propertyExp = /\\[(.*?)\\]: \\[(.*?)\\]/gm;\n for (const match of devicePropertiesString.matchAll(propertyExp)) {\n properties[match[1]] = match[2];\n }\n return properties;\n}\n"],"names":["getServer","logUnauthorized","isPackageInstalledAsync","launchActivityAsync","openAppIdAsync","openUrlAsync","uninstallAsync","getPackageInfoAsync","installAsync","adbArgs","getAttachedDevicesAsync","getAdbNameForDeviceIdAsync","isDeviceBootedAsync","isBootAnimationCompleteAsync","getDeviceABIsAsync","getPropertyDataForDeviceAsync","Log","DeviceABI","arm","arm64","x64","x86","armeabiV7a","armeabi","universal","CANT_START_ACTIVITY_ERROR","PROP_CPU_NAME","PROP_CPU_ABI_LIST_NAME","PROP_BOOT_ANIMATION_STATE","_server","ADBServer","device","warn","chalk","bold","name","dim","learnMore","androidPackage","packages","runAsync","pid","lines","split","i","length","line","trim","launchActivity","openAsync","applicationId","url","args","results","includes","match","CommandError","substring","indexOf","appId","filePath","options","push","concat","output","splitItems","replace","os","EOL","attachedDevices","slice","map","props","filter","Boolean","isAuthorized","type","devicePromises","deviceInfo","modelItem","find","info","isBooted","Promise","all","shift","devices","cpuAbiList","abi","prop","propCommand","getFileOutputAsync","debug","parseAdbDeviceProperties","error","message","devicePropertiesString","properties","propertyExp","matchAll"],"mappings":"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"}
|