web-ext 7.10.0 → 7.11.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.
|
@@ -62,7 +62,6 @@ export class FirefoxAndroidExtensionRunner {
|
|
|
62
62
|
});
|
|
63
63
|
await this.adbDevicesDiscoveryAndSelect();
|
|
64
64
|
await this.apkPackagesDiscoveryAndSelect();
|
|
65
|
-
await this.adbCheckRuntimePermissions();
|
|
66
65
|
await this.adbForceStopSelectedPackage();
|
|
67
66
|
|
|
68
67
|
// Create profile prefs (with enabled remote RDP server), prepare the
|
|
@@ -279,28 +278,6 @@ export class FirefoxAndroidExtensionRunner {
|
|
|
279
278
|
log.info(`Stopping existing instances of ${selectedFirefoxApk}...`);
|
|
280
279
|
await adbUtils.amForceStopAPK(selectedAdbDevice, selectedFirefoxApk);
|
|
281
280
|
}
|
|
282
|
-
async adbCheckRuntimePermissions() {
|
|
283
|
-
const {
|
|
284
|
-
adbUtils,
|
|
285
|
-
selectedAdbDevice,
|
|
286
|
-
selectedFirefoxApk
|
|
287
|
-
} = this;
|
|
288
|
-
log.debug(`Discovering Android version for ${selectedAdbDevice}...`);
|
|
289
|
-
const androidVersion = await adbUtils.getAndroidVersionNumber(selectedAdbDevice);
|
|
290
|
-
if (typeof androidVersion !== 'number' || Number.isNaN(androidVersion)) {
|
|
291
|
-
throw new WebExtError(`Invalid Android version: ${androidVersion}`);
|
|
292
|
-
}
|
|
293
|
-
log.debug(`Detected Android version ${androidVersion}`);
|
|
294
|
-
if (androidVersion < 23) {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
log.debug('Checking read/write permissions needed for web-ext' + `on ${selectedFirefoxApk}...`);
|
|
298
|
-
|
|
299
|
-
// Runtime permissions needed to Firefox to be able to access the
|
|
300
|
-
// xpi file uploaded to the android device or emulator.
|
|
301
|
-
const requiredPermissions = ['android.permission.READ_EXTERNAL_STORAGE'];
|
|
302
|
-
await adbUtils.ensureRequiredAPKRuntimePermissions(selectedAdbDevice, selectedFirefoxApk, requiredPermissions);
|
|
303
|
-
}
|
|
304
281
|
async adbPrepareProfileDir() {
|
|
305
282
|
const {
|
|
306
283
|
adbUtils,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firefox-android.js","names":["path","readline","withTempDir","DefaultADBUtils","showDesktopNotification","defaultDesktopNotifications","MultiExtensionsReloadError","UsageError","WebExtError","defaultFirefoxApp","connectWithMaxRetries","defaultFirefoxConnector","findFreeTcpPort","createLogger","isTTY","setRawMode","log","import","meta","url","ignoredParams","profilePath","keepProfileChanges","browserConsole","preInstall","startUrl","args","DEFAULT_ADB_HOST","getIgnoredParamsWarningsMessage","optionName","FirefoxAndroidExtensionRunner","unixSocketDiscoveryRetryInterval","unixSocketDiscoveryMaxTime","constructor","params","cleanupCallbacks","Set","adbExtensionsPathBySourceDir","Map","reloadableExtensions","printIgnoredParamsWarnings","run","adbBin","adbHost","adbPort","ADBUtils","adbUtils","adbDevicesDiscoveryAndSelect","apkPackagesDiscoveryAndSelect","adbCheckRuntimePermissions","adbForceStopSelectedPackage","adbPrepareProfileDir","Promise","all","adbStartSelectedPackage","buildAndPushExtensions","adbDiscoveryAndForwardRDPUnixSocket","rdpInstallExtensions","getName","reloadAllExtensions","runnerName","reloadErrors","sourceDir","extensions","res","reloadExtensionBySourceDir","reloadError","Error","set","size","extensionSourceDir","addonId","get","buildAndPushExtension","remoteFirefox","reloadAddon","error","registerCleanup","fn","add","exit","selectedAdbDevice","selectedArtifactsDir","exiting","debug","clearArtifactsDir","getDeviceProfileDir","Object","keys","forEach","ignoredParam","warn","adbDevice","devices","discoverDevices","length","devicesMsg","map","dev","join","info","foundDevices","filter","device","JSON","stringify","firefoxApk","packages","discoverInstalledFirefoxAPKs","pkgsListMsg","pkgs","pkg","selectedFirefoxApk","filteredPackages","line","pkgsList","amForceStopAPK","androidVersion","getAndroidVersionNumber","Number","isNaN","requiredPermissions","ensureRequiredAPKRuntimePermissions","customPrefs","firefoxApp","adbRemoveOldArtifacts","profile","createProfile","app","foundOldArtifacts","detectOrRemoveOldArtifacts","getOrCreateArtifactsDir","deviceProfileDir","runShellCommand","pushFile","profileDir","firefoxApkComponent","startFirefoxAPK","buildSourceDir","tmpDir","extensionPath","extFileName","basename","adbExtensionPath","adbDiscoveryTimeout","stdin","process","handleCtrlC","str","key","ctrl","name","setUserAbortDiscovery","emitKeypressEvents","on","selectedRDPSocketFile","discoverRDPUnixSocket","maxDiscoveryTime","retryInterval","removeListener","tcpPort","forwardSocketSpec","startsWith","substr","setupForward","selectedTCPPort","firefoxClient","port","client","extension","installTemporaryAddon","then","installResult","addon","id"],"sources":["../../src/extension-runners/firefox-android.js"],"sourcesContent":["/* @flow */\n\n/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Firefox for Android instance.\n */\n\nimport path from 'path';\nimport readline from 'readline';\n\nimport { withTempDir } from '../util/temp-dir.js';\nimport DefaultADBUtils from '../util/adb.js';\nimport { showDesktopNotification as defaultDesktopNotifications } from '../util/desktop-notifier.js';\nimport {\n MultiExtensionsReloadError,\n UsageError,\n WebExtError,\n} from '../errors.js';\nimport * as defaultFirefoxApp from '../firefox/index.js';\nimport {\n connectWithMaxRetries as defaultFirefoxConnector,\n findFreeTcpPort,\n} from '../firefox/remote.js';\nimport { createLogger } from '../util/logger.js';\nimport { isTTY, setRawMode } from '../util/stdin.js';\nimport type {\n ExtensionRunnerParams,\n ExtensionRunnerReloadResult,\n} from './base';\nimport type { FirefoxPreferences } from '../firefox/preferences';\nimport type { FirefoxRDPResponseAddon, RemoteFirefox } from '../firefox/remote';\nimport type { ExtensionBuildResult } from '../cmd/build';\n\nconst log = createLogger(import.meta.url);\n\nconst ignoredParams = {\n profilePath: '--profile-path',\n keepProfileChanges: '--keep-profile-changes',\n browserConsole: '--browser-console',\n preInstall: '--pre-install',\n startUrl: '--start-url',\n args: '--args',\n};\n\n// Default adbHost to 127.0.0.1 to prevent issues with nodejs 17\n// (because if not specified adbkit may default to ipv6 while\n// adb may still only be listening on the ipv4 address),\n// see https://github.com/mozilla/web-ext/issues/2337.\nconst DEFAULT_ADB_HOST = '127.0.0.1';\n\nconst getIgnoredParamsWarningsMessage = (optionName) => {\n return `The Firefox for Android target does not support ${optionName}`;\n};\n\nexport type FirefoxAndroidExtensionRunnerParams = {|\n ...ExtensionRunnerParams,\n\n // Firefox specific.\n customPrefs?: FirefoxPreferences,\n\n // Not supported (currently ignored with logged warning).\n preInstall?: boolean,\n browserConsole?: boolean,\n\n // Firefox android injected dependencies.\n adbBin?: string,\n adbHost?: string,\n adbPort?: string,\n adbDevice?: string,\n adbDiscoveryTimeout?: number,\n adbRemoveOldArtifacts?: boolean,\n firefoxApk?: string,\n firefoxApkComponent?: string,\n\n // Injected Dependencies.\n firefoxApp: typeof defaultFirefoxApp,\n firefoxClient: typeof defaultFirefoxConnector,\n ADBUtils?: typeof DefaultADBUtils,\n buildSourceDir: (string, string) => Promise<ExtensionBuildResult>,\n desktopNotifications: typeof defaultDesktopNotifications,\n stdin?: stream$Readable,\n|};\n\n/**\n * Implements an IExtensionRunner which manages a Firefox for Android instance.\n */\nexport class FirefoxAndroidExtensionRunner {\n // Wait 3s before the next unix socket discovery loop.\n static unixSocketDiscoveryRetryInterval: number = 3 * 1000;\n // Wait for at most 3 minutes before giving up.\n static unixSocketDiscoveryMaxTime: number = 3 * 60 * 1000;\n\n params: FirefoxAndroidExtensionRunnerParams;\n adbUtils: DefaultADBUtils;\n exiting: boolean;\n selectedAdbDevice: string;\n selectedFirefoxApk: string;\n selectedArtifactsDir: string;\n selectedRDPSocketFile: string;\n selectedTCPPort: number;\n cleanupCallbacks: Set<Function>;\n adbExtensionsPathBySourceDir: Map<string, string>;\n reloadableExtensions: Map<string, string>;\n remoteFirefox: RemoteFirefox;\n\n constructor(params: FirefoxAndroidExtensionRunnerParams) {\n this.params = params;\n this.cleanupCallbacks = new Set();\n this.adbExtensionsPathBySourceDir = new Map();\n this.reloadableExtensions = new Map();\n\n // Print warning for not currently supported options (e.g. preInstall,\n // cloned profiles, browser console).\n this.printIgnoredParamsWarnings();\n }\n\n async run(): Promise<void> {\n const {\n adbBin,\n adbHost = DEFAULT_ADB_HOST,\n adbPort,\n ADBUtils = DefaultADBUtils,\n } = this.params;\n\n this.adbUtils = new ADBUtils({\n adbBin,\n adbHost,\n adbPort,\n });\n\n await this.adbDevicesDiscoveryAndSelect();\n await this.apkPackagesDiscoveryAndSelect();\n await this.adbCheckRuntimePermissions();\n await this.adbForceStopSelectedPackage();\n\n // Create profile prefs (with enabled remote RDP server), prepare the\n // artifacts and temporary directory on the selected device, and\n // push the profile preferences to the remote profile dir.\n await this.adbPrepareProfileDir();\n\n // NOTE: running Firefox for Android on the Android Emulator can be\n // pretty slow, we can run the following 3 steps in parallel to speed up\n // it a bit.\n await Promise.all([\n // Start Firefox for Android instance if not started yet.\n // (Fennec would run in an temporary profile and so it is explicitly\n // stopped, Fenix runs on its usual profile and so it may be already\n // running).\n this.adbStartSelectedPackage(),\n\n // Build and push to devices all the extension xpis\n // and keep track of the xpi built and uploaded by extension sourceDir.\n this.buildAndPushExtensions(),\n\n // Wait for RDP unix socket file created and\n // Create an ADB forward connection on a free tcp port\n this.adbDiscoveryAndForwardRDPUnixSocket(),\n ]);\n\n // Connect to RDP socket on the local tcp server, install all the pushed extension\n // and keep track of the built and installed extension by extension sourceDir.\n await this.rdpInstallExtensions();\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Firefox Android';\n }\n\n /**\n * Reloads all the extensions, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const reloadErrors = new Map();\n\n for (const { sourceDir } of this.params.extensions) {\n const [res] = await this.reloadExtensionBySourceDir(sourceDir);\n if (res.reloadError instanceof Error) {\n reloadErrors.set(sourceDir, res.reloadError);\n }\n }\n\n if (reloadErrors.size > 0) {\n return [\n {\n runnerName,\n reloadError: new MultiExtensionsReloadError(reloadErrors),\n },\n ];\n }\n\n return [{ runnerName }];\n }\n\n /**\n * Reloads a single extension, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadExtensionBySourceDir(\n extensionSourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const addonId = this.reloadableExtensions.get(extensionSourceDir);\n\n if (!addonId) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: new WebExtError(\n 'Extension not reloadable: ' +\n `no addonId has been mapped to \"${extensionSourceDir}\"`\n ),\n runnerName,\n },\n ];\n }\n\n try {\n await this.buildAndPushExtension(extensionSourceDir);\n await this.remoteFirefox.reloadAddon(addonId);\n } catch (error) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: error,\n runnerName,\n },\n ];\n }\n\n return [{ runnerName, sourceDir: extensionSourceDir }];\n }\n\n /**\n * Register a callback to be called when the runner has been exited\n * (e.g. the Firefox instance exits or the user has requested web-ext\n * to exit).\n */\n registerCleanup(fn: Function): void {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Firefox instance.\n */\n async exit(): Promise<void> {\n const { adbUtils, selectedAdbDevice, selectedArtifactsDir } = this;\n\n this.exiting = true;\n\n // If a Firefox for Android instance has been started,\n // we should ensure that it has been stopped when we exit.\n await this.adbForceStopSelectedPackage();\n\n if (selectedArtifactsDir) {\n log.debug('Cleaning up artifacts directory on the Android device...');\n await adbUtils.clearArtifactsDir(selectedAdbDevice);\n }\n\n // Call all the registered cleanup callbacks.\n for (const fn of this.cleanupCallbacks) {\n try {\n fn();\n } catch (error) {\n log.error(error);\n }\n }\n }\n\n // Private helper methods.\n\n getDeviceProfileDir(): string {\n return `${this.selectedArtifactsDir}/profile`;\n }\n\n printIgnoredParamsWarnings() {\n Object.keys(ignoredParams).forEach((ignoredParam) => {\n if (this.params[ignoredParam]) {\n log.warn(getIgnoredParamsWarningsMessage(ignoredParams[ignoredParam]));\n }\n });\n }\n\n async adbDevicesDiscoveryAndSelect() {\n const { adbUtils } = this;\n const { adbDevice } = this.params;\n let devices = [];\n\n log.debug('Listing android devices');\n devices = await adbUtils.discoverDevices();\n\n if (devices.length === 0) {\n throw new UsageError(\n 'No Android device found through ADB. ' +\n 'Make sure the device is connected and USB debugging is enabled.'\n );\n }\n\n if (!adbDevice) {\n const devicesMsg = devices.map((dev) => ` - ${dev}`).join('\\n');\n log.info(`\\nAndroid devices found:\\n${devicesMsg}`);\n throw new UsageError(\n 'Select an android device using --android-device=<name>'\n );\n }\n\n const foundDevices = devices.filter((device) => {\n return device === adbDevice;\n });\n\n if (foundDevices.length === 0) {\n const devicesMsg = JSON.stringify(devices);\n throw new UsageError(\n `Android device ${adbDevice} was not found in list: ${devicesMsg}`\n );\n }\n\n this.selectedAdbDevice = foundDevices[0];\n log.info(`Selected ADB device: ${this.selectedAdbDevice}`);\n }\n\n async apkPackagesDiscoveryAndSelect() {\n const {\n adbUtils,\n selectedAdbDevice,\n params: { firefoxApk },\n } = this;\n // Discovery and select a Firefox for Android version.\n const packages = await adbUtils.discoverInstalledFirefoxAPKs(\n selectedAdbDevice,\n firefoxApk\n );\n\n if (packages.length === 0) {\n throw new UsageError(\n 'No Firefox packages were found on the selected Android device'\n );\n }\n\n const pkgsListMsg = (pkgs) => {\n return pkgs.map((pkg) => ` - ${pkg}`).join('\\n');\n };\n\n if (!firefoxApk) {\n log.info(`\\nPackages found:\\n${pkgsListMsg(packages)}`);\n\n if (packages.length > 1) {\n throw new UsageError('Select one of the packages using --firefox-apk');\n }\n\n // If only one APK has been found, select it even if it has not been\n // specified explicitly on the comment line.\n this.selectedFirefoxApk = packages[0];\n log.info(`Selected Firefox for Android APK: ${this.selectedFirefoxApk}`);\n return;\n }\n\n const filteredPackages = packages.filter((line) => line === firefoxApk);\n\n if (filteredPackages.length === 0) {\n const pkgsList = pkgsListMsg(filteredPackages);\n throw new UsageError(\n `Package ${firefoxApk} was not found in list: ${pkgsList}`\n );\n }\n\n this.selectedFirefoxApk = filteredPackages[0];\n log.debug(`Selected Firefox for Android APK: ${this.selectedFirefoxApk}`);\n }\n\n async adbForceStopSelectedPackage() {\n const { adbUtils, selectedAdbDevice, selectedFirefoxApk } = this;\n\n log.info(`Stopping existing instances of ${selectedFirefoxApk}...`);\n await adbUtils.amForceStopAPK(selectedAdbDevice, selectedFirefoxApk);\n }\n\n async adbCheckRuntimePermissions() {\n const { adbUtils, selectedAdbDevice, selectedFirefoxApk } = this;\n\n log.debug(`Discovering Android version for ${selectedAdbDevice}...`);\n\n const androidVersion = await adbUtils.getAndroidVersionNumber(\n selectedAdbDevice\n );\n\n if (typeof androidVersion !== 'number' || Number.isNaN(androidVersion)) {\n throw new WebExtError(`Invalid Android version: ${androidVersion}`);\n }\n\n log.debug(`Detected Android version ${androidVersion}`);\n\n if (androidVersion < 23) {\n return;\n }\n\n log.debug(\n 'Checking read/write permissions needed for web-ext' +\n `on ${selectedFirefoxApk}...`\n );\n\n // Runtime permissions needed to Firefox to be able to access the\n // xpi file uploaded to the android device or emulator.\n const requiredPermissions = ['android.permission.READ_EXTERNAL_STORAGE'];\n\n await adbUtils.ensureRequiredAPKRuntimePermissions(\n selectedAdbDevice,\n selectedFirefoxApk,\n requiredPermissions\n );\n }\n\n async adbPrepareProfileDir() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n params: { customPrefs, firefoxApp, adbRemoveOldArtifacts },\n } = this;\n // Create the preferences file and the Fennec temporary profile.\n log.debug(`Preparing a temporary profile for ${selectedFirefoxApk}...`);\n\n const profile = await firefoxApp.createProfile({\n app: 'fennec',\n customPrefs,\n });\n\n // Check if there are any artifacts dirs from previous runs and\n // automatically remove them if adbRemoteOldArtifacts is true.\n const foundOldArtifacts = await adbUtils.detectOrRemoveOldArtifacts(\n selectedAdbDevice,\n adbRemoveOldArtifacts\n );\n\n if (foundOldArtifacts) {\n if (adbRemoveOldArtifacts) {\n log.info(\n 'Old web-ext artifacts have been found and removed ' +\n `from ${selectedAdbDevice} device`\n );\n } else {\n log.warn(\n `Old artifacts directories have been found on ${selectedAdbDevice} ` +\n 'device. Use --adb-remove-old-artifacts to remove them automatically.'\n );\n }\n }\n\n // Choose a artifacts dir name for the assets pushed to the\n // Android device.\n this.selectedArtifactsDir = await adbUtils.getOrCreateArtifactsDir(\n selectedAdbDevice\n );\n\n const deviceProfileDir = this.getDeviceProfileDir();\n\n await adbUtils.runShellCommand(selectedAdbDevice, [\n 'mkdir',\n '-p',\n deviceProfileDir,\n ]);\n await adbUtils.pushFile(\n selectedAdbDevice,\n path.join(profile.profileDir, 'user.js'),\n `${deviceProfileDir}/user.js`\n );\n\n log.debug(`Created temporary profile at ${deviceProfileDir}.`);\n }\n\n async adbStartSelectedPackage() {\n const {\n adbUtils,\n selectedFirefoxApk,\n selectedAdbDevice,\n params: { firefoxApkComponent },\n } = this;\n\n const deviceProfileDir = this.getDeviceProfileDir();\n\n log.info(`Starting ${selectedFirefoxApk}...`);\n\n log.debug(`Using profile ${deviceProfileDir} (ignored by Fenix)`);\n\n await adbUtils.startFirefoxAPK(\n selectedAdbDevice,\n selectedFirefoxApk,\n firefoxApkComponent,\n deviceProfileDir\n );\n }\n\n async buildAndPushExtension(sourceDir: string) {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedArtifactsDir,\n params: { buildSourceDir },\n } = this;\n\n await withTempDir(async (tmpDir) => {\n const { extensionPath } = await buildSourceDir(sourceDir, tmpDir.path());\n\n const extFileName = path.basename(extensionPath, '.zip');\n\n let adbExtensionPath = this.adbExtensionsPathBySourceDir.get(sourceDir);\n\n if (!adbExtensionPath) {\n adbExtensionPath = `${selectedArtifactsDir}/${extFileName}.xpi`;\n }\n\n log.debug(`Uploading ${extFileName} on the android device`);\n\n await adbUtils.pushFile(\n selectedAdbDevice,\n extensionPath,\n adbExtensionPath\n );\n\n log.debug(`Upload completed: ${adbExtensionPath}`);\n\n this.adbExtensionsPathBySourceDir.set(sourceDir, adbExtensionPath);\n });\n }\n\n async buildAndPushExtensions() {\n for (const { sourceDir } of this.params.extensions) {\n await this.buildAndPushExtension(sourceDir);\n }\n }\n\n async adbDiscoveryAndForwardRDPUnixSocket() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n params: { adbDiscoveryTimeout },\n } = this;\n\n const stdin = this.params.stdin || process.stdin;\n\n const { unixSocketDiscoveryRetryInterval } = FirefoxAndroidExtensionRunner;\n\n let { unixSocketDiscoveryMaxTime } = FirefoxAndroidExtensionRunner;\n\n if (typeof adbDiscoveryTimeout === 'number') {\n unixSocketDiscoveryMaxTime = adbDiscoveryTimeout;\n }\n\n const handleCtrlC = (str, key) => {\n if (key.ctrl && key.name === 'c') {\n adbUtils.setUserAbortDiscovery(true);\n }\n };\n\n // TODO: use noInput property to decide if we should\n // disable direct keypress handling.\n if (isTTY(stdin)) {\n readline.emitKeypressEvents(stdin);\n setRawMode(stdin, true);\n\n stdin.on('keypress', handleCtrlC);\n }\n\n try {\n // Got a debugger socket file to connect.\n this.selectedRDPSocketFile = await adbUtils.discoverRDPUnixSocket(\n selectedAdbDevice,\n selectedFirefoxApk,\n {\n maxDiscoveryTime: unixSocketDiscoveryMaxTime,\n retryInterval: unixSocketDiscoveryRetryInterval,\n }\n );\n } finally {\n if (isTTY(stdin)) {\n stdin.removeListener('keypress', handleCtrlC);\n }\n }\n\n log.debug(`RDP Socket File selected: ${this.selectedRDPSocketFile}`);\n\n const tcpPort = await findFreeTcpPort();\n\n // Log the choosen tcp port at info level (useful to the user to be able\n // to connect the Firefox DevTools to the Firefox for Android instance).\n log.info(`You can connect to this Android device on TCP port ${tcpPort}`);\n\n const forwardSocketSpec = this.selectedRDPSocketFile.startsWith('@')\n ? `localabstract:${this.selectedRDPSocketFile.substr(1)}`\n : `localfilesystem:${this.selectedRDPSocketFile}`;\n\n await adbUtils.setupForward(\n selectedAdbDevice,\n forwardSocketSpec,\n `tcp:${tcpPort}`\n );\n\n this.selectedTCPPort = tcpPort;\n }\n\n async rdpInstallExtensions() {\n const {\n selectedTCPPort,\n params: { extensions, firefoxClient },\n } = this;\n\n const remoteFirefox = (this.remoteFirefox = await firefoxClient({\n port: selectedTCPPort,\n }));\n\n // Exit and cleanup the extension runner if the connection to the\n // remote Firefox for Android instance has been closed.\n remoteFirefox.client.on('end', () => {\n if (!this.exiting) {\n log.info('Exiting the device because Firefox for Android disconnected');\n this.exit();\n }\n });\n\n // Install all the temporary addons.\n for (const extension of extensions) {\n const { sourceDir } = extension;\n const adbExtensionPath = this.adbExtensionsPathBySourceDir.get(sourceDir);\n\n if (!adbExtensionPath) {\n throw new WebExtError(\n `ADB extension path for \"${sourceDir}\" was unexpectedly empty`\n );\n }\n\n const addonId = await remoteFirefox\n .installTemporaryAddon(adbExtensionPath)\n .then((installResult: FirefoxRDPResponseAddon) => {\n return installResult.addon.id;\n });\n\n if (!addonId) {\n throw new WebExtError(\n 'Received an empty addonId from ' +\n `remoteFirefox.installTemporaryAddon(\"${adbExtensionPath}\")`\n );\n }\n\n this.reloadableExtensions.set(extension.sourceDir, addonId);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"firefox-android.js","names":["path","readline","withTempDir","DefaultADBUtils","showDesktopNotification","defaultDesktopNotifications","MultiExtensionsReloadError","UsageError","WebExtError","defaultFirefoxApp","connectWithMaxRetries","defaultFirefoxConnector","findFreeTcpPort","createLogger","isTTY","setRawMode","log","import","meta","url","ignoredParams","profilePath","keepProfileChanges","browserConsole","preInstall","startUrl","args","DEFAULT_ADB_HOST","getIgnoredParamsWarningsMessage","optionName","FirefoxAndroidExtensionRunner","unixSocketDiscoveryRetryInterval","unixSocketDiscoveryMaxTime","constructor","params","cleanupCallbacks","Set","adbExtensionsPathBySourceDir","Map","reloadableExtensions","printIgnoredParamsWarnings","run","adbBin","adbHost","adbPort","ADBUtils","adbUtils","adbDevicesDiscoveryAndSelect","apkPackagesDiscoveryAndSelect","adbForceStopSelectedPackage","adbPrepareProfileDir","Promise","all","adbStartSelectedPackage","buildAndPushExtensions","adbDiscoveryAndForwardRDPUnixSocket","rdpInstallExtensions","getName","reloadAllExtensions","runnerName","reloadErrors","sourceDir","extensions","res","reloadExtensionBySourceDir","reloadError","Error","set","size","extensionSourceDir","addonId","get","buildAndPushExtension","remoteFirefox","reloadAddon","error","registerCleanup","fn","add","exit","selectedAdbDevice","selectedArtifactsDir","exiting","debug","clearArtifactsDir","getDeviceProfileDir","Object","keys","forEach","ignoredParam","warn","adbDevice","devices","discoverDevices","length","devicesMsg","map","dev","join","info","foundDevices","filter","device","JSON","stringify","firefoxApk","packages","discoverInstalledFirefoxAPKs","pkgsListMsg","pkgs","pkg","selectedFirefoxApk","filteredPackages","line","pkgsList","amForceStopAPK","customPrefs","firefoxApp","adbRemoveOldArtifacts","profile","createProfile","app","foundOldArtifacts","detectOrRemoveOldArtifacts","getOrCreateArtifactsDir","deviceProfileDir","runShellCommand","pushFile","profileDir","firefoxApkComponent","startFirefoxAPK","buildSourceDir","tmpDir","extensionPath","extFileName","basename","adbExtensionPath","adbDiscoveryTimeout","stdin","process","handleCtrlC","str","key","ctrl","name","setUserAbortDiscovery","emitKeypressEvents","on","selectedRDPSocketFile","discoverRDPUnixSocket","maxDiscoveryTime","retryInterval","removeListener","tcpPort","forwardSocketSpec","startsWith","substr","setupForward","selectedTCPPort","firefoxClient","port","client","extension","installTemporaryAddon","then","installResult","addon","id"],"sources":["../../src/extension-runners/firefox-android.js"],"sourcesContent":["/* @flow */\n\n/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Firefox for Android instance.\n */\n\nimport path from 'path';\nimport readline from 'readline';\n\nimport { withTempDir } from '../util/temp-dir.js';\nimport DefaultADBUtils from '../util/adb.js';\nimport { showDesktopNotification as defaultDesktopNotifications } from '../util/desktop-notifier.js';\nimport {\n MultiExtensionsReloadError,\n UsageError,\n WebExtError,\n} from '../errors.js';\nimport * as defaultFirefoxApp from '../firefox/index.js';\nimport {\n connectWithMaxRetries as defaultFirefoxConnector,\n findFreeTcpPort,\n} from '../firefox/remote.js';\nimport { createLogger } from '../util/logger.js';\nimport { isTTY, setRawMode } from '../util/stdin.js';\nimport type {\n ExtensionRunnerParams,\n ExtensionRunnerReloadResult,\n} from './base';\nimport type { FirefoxPreferences } from '../firefox/preferences';\nimport type { FirefoxRDPResponseAddon, RemoteFirefox } from '../firefox/remote';\nimport type { ExtensionBuildResult } from '../cmd/build';\n\nconst log = createLogger(import.meta.url);\n\nconst ignoredParams = {\n profilePath: '--profile-path',\n keepProfileChanges: '--keep-profile-changes',\n browserConsole: '--browser-console',\n preInstall: '--pre-install',\n startUrl: '--start-url',\n args: '--args',\n};\n\n// Default adbHost to 127.0.0.1 to prevent issues with nodejs 17\n// (because if not specified adbkit may default to ipv6 while\n// adb may still only be listening on the ipv4 address),\n// see https://github.com/mozilla/web-ext/issues/2337.\nconst DEFAULT_ADB_HOST = '127.0.0.1';\n\nconst getIgnoredParamsWarningsMessage = (optionName) => {\n return `The Firefox for Android target does not support ${optionName}`;\n};\n\nexport type FirefoxAndroidExtensionRunnerParams = {|\n ...ExtensionRunnerParams,\n\n // Firefox specific.\n customPrefs?: FirefoxPreferences,\n\n // Not supported (currently ignored with logged warning).\n preInstall?: boolean,\n browserConsole?: boolean,\n\n // Firefox android injected dependencies.\n adbBin?: string,\n adbHost?: string,\n adbPort?: string,\n adbDevice?: string,\n adbDiscoveryTimeout?: number,\n adbRemoveOldArtifacts?: boolean,\n firefoxApk?: string,\n firefoxApkComponent?: string,\n\n // Injected Dependencies.\n firefoxApp: typeof defaultFirefoxApp,\n firefoxClient: typeof defaultFirefoxConnector,\n ADBUtils?: typeof DefaultADBUtils,\n buildSourceDir: (string, string) => Promise<ExtensionBuildResult>,\n desktopNotifications: typeof defaultDesktopNotifications,\n stdin?: stream$Readable,\n|};\n\n/**\n * Implements an IExtensionRunner which manages a Firefox for Android instance.\n */\nexport class FirefoxAndroidExtensionRunner {\n // Wait 3s before the next unix socket discovery loop.\n static unixSocketDiscoveryRetryInterval: number = 3 * 1000;\n // Wait for at most 3 minutes before giving up.\n static unixSocketDiscoveryMaxTime: number = 3 * 60 * 1000;\n\n params: FirefoxAndroidExtensionRunnerParams;\n adbUtils: DefaultADBUtils;\n exiting: boolean;\n selectedAdbDevice: string;\n selectedFirefoxApk: string;\n selectedArtifactsDir: string;\n selectedRDPSocketFile: string;\n selectedTCPPort: number;\n cleanupCallbacks: Set<Function>;\n adbExtensionsPathBySourceDir: Map<string, string>;\n reloadableExtensions: Map<string, string>;\n remoteFirefox: RemoteFirefox;\n\n constructor(params: FirefoxAndroidExtensionRunnerParams) {\n this.params = params;\n this.cleanupCallbacks = new Set();\n this.adbExtensionsPathBySourceDir = new Map();\n this.reloadableExtensions = new Map();\n\n // Print warning for not currently supported options (e.g. preInstall,\n // cloned profiles, browser console).\n this.printIgnoredParamsWarnings();\n }\n\n async run(): Promise<void> {\n const {\n adbBin,\n adbHost = DEFAULT_ADB_HOST,\n adbPort,\n ADBUtils = DefaultADBUtils,\n } = this.params;\n\n this.adbUtils = new ADBUtils({\n adbBin,\n adbHost,\n adbPort,\n });\n\n await this.adbDevicesDiscoveryAndSelect();\n await this.apkPackagesDiscoveryAndSelect();\n await this.adbForceStopSelectedPackage();\n\n // Create profile prefs (with enabled remote RDP server), prepare the\n // artifacts and temporary directory on the selected device, and\n // push the profile preferences to the remote profile dir.\n await this.adbPrepareProfileDir();\n\n // NOTE: running Firefox for Android on the Android Emulator can be\n // pretty slow, we can run the following 3 steps in parallel to speed up\n // it a bit.\n await Promise.all([\n // Start Firefox for Android instance if not started yet.\n // (Fennec would run in an temporary profile and so it is explicitly\n // stopped, Fenix runs on its usual profile and so it may be already\n // running).\n this.adbStartSelectedPackage(),\n\n // Build and push to devices all the extension xpis\n // and keep track of the xpi built and uploaded by extension sourceDir.\n this.buildAndPushExtensions(),\n\n // Wait for RDP unix socket file created and\n // Create an ADB forward connection on a free tcp port\n this.adbDiscoveryAndForwardRDPUnixSocket(),\n ]);\n\n // Connect to RDP socket on the local tcp server, install all the pushed extension\n // and keep track of the built and installed extension by extension sourceDir.\n await this.rdpInstallExtensions();\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Firefox Android';\n }\n\n /**\n * Reloads all the extensions, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const reloadErrors = new Map();\n\n for (const { sourceDir } of this.params.extensions) {\n const [res] = await this.reloadExtensionBySourceDir(sourceDir);\n if (res.reloadError instanceof Error) {\n reloadErrors.set(sourceDir, res.reloadError);\n }\n }\n\n if (reloadErrors.size > 0) {\n return [\n {\n runnerName,\n reloadError: new MultiExtensionsReloadError(reloadErrors),\n },\n ];\n }\n\n return [{ runnerName }];\n }\n\n /**\n * Reloads a single extension, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadExtensionBySourceDir(\n extensionSourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const addonId = this.reloadableExtensions.get(extensionSourceDir);\n\n if (!addonId) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: new WebExtError(\n 'Extension not reloadable: ' +\n `no addonId has been mapped to \"${extensionSourceDir}\"`\n ),\n runnerName,\n },\n ];\n }\n\n try {\n await this.buildAndPushExtension(extensionSourceDir);\n await this.remoteFirefox.reloadAddon(addonId);\n } catch (error) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: error,\n runnerName,\n },\n ];\n }\n\n return [{ runnerName, sourceDir: extensionSourceDir }];\n }\n\n /**\n * Register a callback to be called when the runner has been exited\n * (e.g. the Firefox instance exits or the user has requested web-ext\n * to exit).\n */\n registerCleanup(fn: Function): void {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Firefox instance.\n */\n async exit(): Promise<void> {\n const { adbUtils, selectedAdbDevice, selectedArtifactsDir } = this;\n\n this.exiting = true;\n\n // If a Firefox for Android instance has been started,\n // we should ensure that it has been stopped when we exit.\n await this.adbForceStopSelectedPackage();\n\n if (selectedArtifactsDir) {\n log.debug('Cleaning up artifacts directory on the Android device...');\n await adbUtils.clearArtifactsDir(selectedAdbDevice);\n }\n\n // Call all the registered cleanup callbacks.\n for (const fn of this.cleanupCallbacks) {\n try {\n fn();\n } catch (error) {\n log.error(error);\n }\n }\n }\n\n // Private helper methods.\n\n getDeviceProfileDir(): string {\n return `${this.selectedArtifactsDir}/profile`;\n }\n\n printIgnoredParamsWarnings() {\n Object.keys(ignoredParams).forEach((ignoredParam) => {\n if (this.params[ignoredParam]) {\n log.warn(getIgnoredParamsWarningsMessage(ignoredParams[ignoredParam]));\n }\n });\n }\n\n async adbDevicesDiscoveryAndSelect() {\n const { adbUtils } = this;\n const { adbDevice } = this.params;\n let devices = [];\n\n log.debug('Listing android devices');\n devices = await adbUtils.discoverDevices();\n\n if (devices.length === 0) {\n throw new UsageError(\n 'No Android device found through ADB. ' +\n 'Make sure the device is connected and USB debugging is enabled.'\n );\n }\n\n if (!adbDevice) {\n const devicesMsg = devices.map((dev) => ` - ${dev}`).join('\\n');\n log.info(`\\nAndroid devices found:\\n${devicesMsg}`);\n throw new UsageError(\n 'Select an android device using --android-device=<name>'\n );\n }\n\n const foundDevices = devices.filter((device) => {\n return device === adbDevice;\n });\n\n if (foundDevices.length === 0) {\n const devicesMsg = JSON.stringify(devices);\n throw new UsageError(\n `Android device ${adbDevice} was not found in list: ${devicesMsg}`\n );\n }\n\n this.selectedAdbDevice = foundDevices[0];\n log.info(`Selected ADB device: ${this.selectedAdbDevice}`);\n }\n\n async apkPackagesDiscoveryAndSelect() {\n const {\n adbUtils,\n selectedAdbDevice,\n params: { firefoxApk },\n } = this;\n // Discovery and select a Firefox for Android version.\n const packages = await adbUtils.discoverInstalledFirefoxAPKs(\n selectedAdbDevice,\n firefoxApk\n );\n\n if (packages.length === 0) {\n throw new UsageError(\n 'No Firefox packages were found on the selected Android device'\n );\n }\n\n const pkgsListMsg = (pkgs) => {\n return pkgs.map((pkg) => ` - ${pkg}`).join('\\n');\n };\n\n if (!firefoxApk) {\n log.info(`\\nPackages found:\\n${pkgsListMsg(packages)}`);\n\n if (packages.length > 1) {\n throw new UsageError('Select one of the packages using --firefox-apk');\n }\n\n // If only one APK has been found, select it even if it has not been\n // specified explicitly on the comment line.\n this.selectedFirefoxApk = packages[0];\n log.info(`Selected Firefox for Android APK: ${this.selectedFirefoxApk}`);\n return;\n }\n\n const filteredPackages = packages.filter((line) => line === firefoxApk);\n\n if (filteredPackages.length === 0) {\n const pkgsList = pkgsListMsg(filteredPackages);\n throw new UsageError(\n `Package ${firefoxApk} was not found in list: ${pkgsList}`\n );\n }\n\n this.selectedFirefoxApk = filteredPackages[0];\n log.debug(`Selected Firefox for Android APK: ${this.selectedFirefoxApk}`);\n }\n\n async adbForceStopSelectedPackage() {\n const { adbUtils, selectedAdbDevice, selectedFirefoxApk } = this;\n\n log.info(`Stopping existing instances of ${selectedFirefoxApk}...`);\n await adbUtils.amForceStopAPK(selectedAdbDevice, selectedFirefoxApk);\n }\n\n async adbPrepareProfileDir() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n params: { customPrefs, firefoxApp, adbRemoveOldArtifacts },\n } = this;\n // Create the preferences file and the Fennec temporary profile.\n log.debug(`Preparing a temporary profile for ${selectedFirefoxApk}...`);\n\n const profile = await firefoxApp.createProfile({\n app: 'fennec',\n customPrefs,\n });\n\n // Check if there are any artifacts dirs from previous runs and\n // automatically remove them if adbRemoteOldArtifacts is true.\n const foundOldArtifacts = await adbUtils.detectOrRemoveOldArtifacts(\n selectedAdbDevice,\n adbRemoveOldArtifacts\n );\n\n if (foundOldArtifacts) {\n if (adbRemoveOldArtifacts) {\n log.info(\n 'Old web-ext artifacts have been found and removed ' +\n `from ${selectedAdbDevice} device`\n );\n } else {\n log.warn(\n `Old artifacts directories have been found on ${selectedAdbDevice} ` +\n 'device. Use --adb-remove-old-artifacts to remove them automatically.'\n );\n }\n }\n\n // Choose a artifacts dir name for the assets pushed to the\n // Android device.\n this.selectedArtifactsDir = await adbUtils.getOrCreateArtifactsDir(\n selectedAdbDevice\n );\n\n const deviceProfileDir = this.getDeviceProfileDir();\n\n await adbUtils.runShellCommand(selectedAdbDevice, [\n 'mkdir',\n '-p',\n deviceProfileDir,\n ]);\n await adbUtils.pushFile(\n selectedAdbDevice,\n path.join(profile.profileDir, 'user.js'),\n `${deviceProfileDir}/user.js`\n );\n\n log.debug(`Created temporary profile at ${deviceProfileDir}.`);\n }\n\n async adbStartSelectedPackage() {\n const {\n adbUtils,\n selectedFirefoxApk,\n selectedAdbDevice,\n params: { firefoxApkComponent },\n } = this;\n\n const deviceProfileDir = this.getDeviceProfileDir();\n\n log.info(`Starting ${selectedFirefoxApk}...`);\n\n log.debug(`Using profile ${deviceProfileDir} (ignored by Fenix)`);\n\n await adbUtils.startFirefoxAPK(\n selectedAdbDevice,\n selectedFirefoxApk,\n firefoxApkComponent,\n deviceProfileDir\n );\n }\n\n async buildAndPushExtension(sourceDir: string) {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedArtifactsDir,\n params: { buildSourceDir },\n } = this;\n\n await withTempDir(async (tmpDir) => {\n const { extensionPath } = await buildSourceDir(sourceDir, tmpDir.path());\n\n const extFileName = path.basename(extensionPath, '.zip');\n\n let adbExtensionPath = this.adbExtensionsPathBySourceDir.get(sourceDir);\n\n if (!adbExtensionPath) {\n adbExtensionPath = `${selectedArtifactsDir}/${extFileName}.xpi`;\n }\n\n log.debug(`Uploading ${extFileName} on the android device`);\n\n await adbUtils.pushFile(\n selectedAdbDevice,\n extensionPath,\n adbExtensionPath\n );\n\n log.debug(`Upload completed: ${adbExtensionPath}`);\n\n this.adbExtensionsPathBySourceDir.set(sourceDir, adbExtensionPath);\n });\n }\n\n async buildAndPushExtensions() {\n for (const { sourceDir } of this.params.extensions) {\n await this.buildAndPushExtension(sourceDir);\n }\n }\n\n async adbDiscoveryAndForwardRDPUnixSocket() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n params: { adbDiscoveryTimeout },\n } = this;\n\n const stdin = this.params.stdin || process.stdin;\n\n const { unixSocketDiscoveryRetryInterval } = FirefoxAndroidExtensionRunner;\n\n let { unixSocketDiscoveryMaxTime } = FirefoxAndroidExtensionRunner;\n\n if (typeof adbDiscoveryTimeout === 'number') {\n unixSocketDiscoveryMaxTime = adbDiscoveryTimeout;\n }\n\n const handleCtrlC = (str, key) => {\n if (key.ctrl && key.name === 'c') {\n adbUtils.setUserAbortDiscovery(true);\n }\n };\n\n // TODO: use noInput property to decide if we should\n // disable direct keypress handling.\n if (isTTY(stdin)) {\n readline.emitKeypressEvents(stdin);\n setRawMode(stdin, true);\n\n stdin.on('keypress', handleCtrlC);\n }\n\n try {\n // Got a debugger socket file to connect.\n this.selectedRDPSocketFile = await adbUtils.discoverRDPUnixSocket(\n selectedAdbDevice,\n selectedFirefoxApk,\n {\n maxDiscoveryTime: unixSocketDiscoveryMaxTime,\n retryInterval: unixSocketDiscoveryRetryInterval,\n }\n );\n } finally {\n if (isTTY(stdin)) {\n stdin.removeListener('keypress', handleCtrlC);\n }\n }\n\n log.debug(`RDP Socket File selected: ${this.selectedRDPSocketFile}`);\n\n const tcpPort = await findFreeTcpPort();\n\n // Log the choosen tcp port at info level (useful to the user to be able\n // to connect the Firefox DevTools to the Firefox for Android instance).\n log.info(`You can connect to this Android device on TCP port ${tcpPort}`);\n\n const forwardSocketSpec = this.selectedRDPSocketFile.startsWith('@')\n ? `localabstract:${this.selectedRDPSocketFile.substr(1)}`\n : `localfilesystem:${this.selectedRDPSocketFile}`;\n\n await adbUtils.setupForward(\n selectedAdbDevice,\n forwardSocketSpec,\n `tcp:${tcpPort}`\n );\n\n this.selectedTCPPort = tcpPort;\n }\n\n async rdpInstallExtensions() {\n const {\n selectedTCPPort,\n params: { extensions, firefoxClient },\n } = this;\n\n const remoteFirefox = (this.remoteFirefox = await firefoxClient({\n port: selectedTCPPort,\n }));\n\n // Exit and cleanup the extension runner if the connection to the\n // remote Firefox for Android instance has been closed.\n remoteFirefox.client.on('end', () => {\n if (!this.exiting) {\n log.info('Exiting the device because Firefox for Android disconnected');\n this.exit();\n }\n });\n\n // Install all the temporary addons.\n for (const extension of extensions) {\n const { sourceDir } = extension;\n const adbExtensionPath = this.adbExtensionsPathBySourceDir.get(sourceDir);\n\n if (!adbExtensionPath) {\n throw new WebExtError(\n `ADB extension path for \"${sourceDir}\" was unexpectedly empty`\n );\n }\n\n const addonId = await remoteFirefox\n .installTemporaryAddon(adbExtensionPath)\n .then((installResult: FirefoxRDPResponseAddon) => {\n return installResult.addon.id;\n });\n\n if (!addonId) {\n throw new WebExtError(\n 'Received an empty addonId from ' +\n `remoteFirefox.installTemporaryAddon(\"${adbExtensionPath}\")`\n );\n }\n\n this.reloadableExtensions.set(extension.sourceDir, addonId);\n }\n }\n}\n"],"mappings":"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"}
|
package/lib/util/adb.js
CHANGED
|
@@ -78,43 +78,6 @@ export default class ADBUtils {
|
|
|
78
78
|
return false;
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
|
-
async getAndroidVersionNumber(deviceId) {
|
|
82
|
-
const androidVersion = (await this.runShellCommand(deviceId, ['getprop', 'ro.build.version.sdk'])).trim();
|
|
83
|
-
const androidVersionNumber = parseInt(androidVersion);
|
|
84
|
-
|
|
85
|
-
// No need to check the granted runtime permissions on Android versions < Lollypop.
|
|
86
|
-
if (isNaN(androidVersionNumber)) {
|
|
87
|
-
throw new WebExtError('Unable to discovery android version on ' + `${deviceId}: ${androidVersion}`);
|
|
88
|
-
}
|
|
89
|
-
return androidVersionNumber;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Raise an UsageError when the given APK does not have the required runtime permissions.
|
|
93
|
-
async ensureRequiredAPKRuntimePermissions(deviceId, apk, permissions) {
|
|
94
|
-
const permissionsMap = {};
|
|
95
|
-
|
|
96
|
-
// Initialize every permission to false in the permissions map.
|
|
97
|
-
for (const perm of permissions) {
|
|
98
|
-
permissionsMap[perm] = false;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Retrieve the permissions information for the given apk.
|
|
102
|
-
const pmDumpLogs = (await this.runShellCommand(deviceId, ['pm', 'dump', apk])).split('\n');
|
|
103
|
-
|
|
104
|
-
// Set to true the required permissions that have been granted.
|
|
105
|
-
for (const line of pmDumpLogs) {
|
|
106
|
-
for (const perm of permissions) {
|
|
107
|
-
if (line.includes(`${perm}: granted=true`) || line.includes(`${perm}, granted=true`)) {
|
|
108
|
-
permissionsMap[perm] = true;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
for (const perm of permissions) {
|
|
113
|
-
if (!permissionsMap[perm]) {
|
|
114
|
-
throw new UsageError(`Required ${perm} has not be granted for ${apk}. ` + 'Please grant them using the Android Settings ' + 'or using the following adb command:\n' + `\t adb shell pm grant ${apk} ${perm}\n`);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
81
|
async amForceStopAPK(deviceId, apk) {
|
|
119
82
|
await this.runShellCommand(deviceId, ['am', 'force-stop', apk]);
|
|
120
83
|
}
|
package/lib/util/adb.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adb.js","names":["ADBKit","isErrorWithCode","UsageError","WebExtError","createLogger","packageIdentifiers","defaultApkComponents","DEVICE_DIR_BASE","ARTIFACTS_DIR_PREFIX","defaultADB","default","log","import","meta","url","wrapADBCall","asyncFn","error","message","includes","ADBUtils","constructor","params","adb","adbBin","adbHost","adbPort","adbClient","createClient","bin","host","port","artifactsDirMap","Map","userAbortDiscovery","runShellCommand","deviceId","cmd","debug","JSON","stringify","getDevice","shell","then","util","readAll","res","toString","discoverDevices","devices","listDevices","map","dev","id","discoverInstalledFirefoxAPKs","firefoxApk","pmList","split","line","replace","trim","filter","browser","startsWith","getAndroidVersionNumber","androidVersion","androidVersionNumber","parseInt","isNaN","ensureRequiredAPKRuntimePermissions","apk","permissions","permissionsMap","perm","pmDumpLogs","amForceStopAPK","getOrCreateArtifactsDir","artifactsDir","get","Date","now","testDirOut","set","detectOrRemoveOldArtifacts","removeArtifactDirs","files","readdir","found","file","isDirectory","name","clearArtifactsDir","delete","pushFile","localPath","devicePath","push","transfer","Promise","resolve","on","startFirefoxAPK","apkComponent","deviceProfileDir","extras","key","value","component","startActivity","wait","action","category","setUserAbortDiscovery","discoverRDPUnixSocket","maxDiscoveryTime","retryInterval","rdpUnixSockets","discoveryStartedAt","msg","length","info","endsWith","setTimeout","pop","setupForward","remote","local","forward","listADBDevices","adbUtils","listADBFirefoxAPKs"],"sources":["../../src/util/adb.js"],"sourcesContent":["/* @flow */\nimport ADBKit from '@devicefarmer/adbkit';\n\nimport { isErrorWithCode, UsageError, WebExtError } from '../errors.js';\nimport { createLogger } from '../util/logger.js';\nimport packageIdentifiers, {\n defaultApkComponents,\n} from '../firefox/package-identifiers.js';\n\nexport const DEVICE_DIR_BASE = '/data/local/tmp/';\nexport const ARTIFACTS_DIR_PREFIX = 'web-ext-artifacts-';\n\nconst defaultADB = ADBKit.default;\n\nconst log = createLogger(import.meta.url);\n\nexport type ADBUtilsParams = {|\n adb?: typeof defaultADB,\n // ADB configs.\n adbBin?: string,\n adbHost?: string,\n adbPort?: string,\n adbDevice?: string,\n|};\n\nexport type DiscoveryParams = {\n maxDiscoveryTime: number,\n retryInterval: number,\n};\n\n// Helper function used to raise an UsageError when the adb binary has not been found.\nasync function wrapADBCall(asyncFn: (...any) => Promise<any>): Promise<any> {\n try {\n return await asyncFn();\n } catch (error) {\n if (\n isErrorWithCode('ENOENT', error) &&\n error.message.includes('spawn adb')\n ) {\n throw new UsageError(\n 'No adb executable has been found. ' +\n 'You can Use --adb-bin, --adb-host/--adb-port ' +\n 'to configure it manually if needed.'\n );\n }\n\n throw error;\n }\n}\n\nexport default class ADBUtils {\n params: ADBUtilsParams;\n adb: typeof defaultADB;\n adbClient: any; // TODO: better flow typing here.\n\n // Map<deviceId -> artifactsDir>\n artifactsDirMap: Map<string, string>;\n // Toggled when the user wants to abort the RDP Unix Socket discovery loop\n // while it is still executing.\n userAbortDiscovery: boolean;\n\n constructor(params: ADBUtilsParams) {\n this.params = params;\n\n const { adb, adbBin, adbHost, adbPort } = params;\n\n this.adb = adb || defaultADB;\n\n this.adbClient = this.adb.createClient({\n bin: adbBin,\n host: adbHost,\n port: adbPort,\n });\n\n this.artifactsDirMap = new Map();\n\n this.userAbortDiscovery = false;\n }\n\n runShellCommand(\n deviceId: string,\n cmd: string | Array<string>\n ): Promise<string> {\n const { adb, adbClient } = this;\n\n log.debug(`Run adb shell command on ${deviceId}: ${JSON.stringify(cmd)}`);\n\n return wrapADBCall(async () => {\n return await adbClient\n .getDevice(deviceId)\n .shell(cmd)\n .then(adb.util.readAll);\n }).then((res) => res.toString());\n }\n\n async discoverDevices(): Promise<Array<string>> {\n const { adbClient } = this;\n\n let devices = [];\n\n log.debug('Listing android devices');\n devices = await wrapADBCall(async () => adbClient.listDevices());\n\n return devices.map((dev) => dev.id);\n }\n\n async discoverInstalledFirefoxAPKs(\n deviceId: string,\n firefoxApk?: string\n ): Promise<Array<string>> {\n log.debug(`Listing installed Firefox APKs on ${deviceId}`);\n\n const pmList = await this.runShellCommand(deviceId, [\n 'pm',\n 'list',\n 'packages',\n ]);\n\n return pmList\n .split('\\n')\n .map((line) => line.replace('package:', '').trim())\n .filter((line) => {\n // Look for an exact match if firefoxApk is defined.\n if (firefoxApk) {\n return line === firefoxApk;\n }\n // Match any package name that starts with the package name of a Firefox for Android browser.\n for (const browser of packageIdentifiers) {\n if (line.startsWith(browser)) {\n return true;\n }\n }\n\n return false;\n });\n }\n\n async getAndroidVersionNumber(deviceId: string): Promise<number> {\n const androidVersion = (\n await this.runShellCommand(deviceId, ['getprop', 'ro.build.version.sdk'])\n ).trim();\n\n const androidVersionNumber = parseInt(androidVersion);\n\n // No need to check the granted runtime permissions on Android versions < Lollypop.\n if (isNaN(androidVersionNumber)) {\n throw new WebExtError(\n 'Unable to discovery android version on ' +\n `${deviceId}: ${androidVersion}`\n );\n }\n\n return androidVersionNumber;\n }\n\n // Raise an UsageError when the given APK does not have the required runtime permissions.\n async ensureRequiredAPKRuntimePermissions(\n deviceId: string,\n apk: string,\n permissions: Array<string>\n ): Promise<void> {\n const permissionsMap = {};\n\n // Initialize every permission to false in the permissions map.\n for (const perm of permissions) {\n permissionsMap[perm] = false;\n }\n\n // Retrieve the permissions information for the given apk.\n const pmDumpLogs = (\n await this.runShellCommand(deviceId, ['pm', 'dump', apk])\n ).split('\\n');\n\n // Set to true the required permissions that have been granted.\n for (const line of pmDumpLogs) {\n for (const perm of permissions) {\n if (\n line.includes(`${perm}: granted=true`) ||\n line.includes(`${perm}, granted=true`)\n ) {\n permissionsMap[perm] = true;\n }\n }\n }\n\n for (const perm of permissions) {\n if (!permissionsMap[perm]) {\n throw new UsageError(\n `Required ${perm} has not be granted for ${apk}. ` +\n 'Please grant them using the Android Settings ' +\n 'or using the following adb command:\\n' +\n `\\t adb shell pm grant ${apk} ${perm}\\n`\n );\n }\n }\n }\n\n async amForceStopAPK(deviceId: string, apk: string): Promise<void> {\n await this.runShellCommand(deviceId, ['am', 'force-stop', apk]);\n }\n\n async getOrCreateArtifactsDir(deviceId: string): Promise<string> {\n let artifactsDir = this.artifactsDirMap.get(deviceId);\n\n if (artifactsDir) {\n return artifactsDir;\n }\n\n artifactsDir = `${DEVICE_DIR_BASE}${ARTIFACTS_DIR_PREFIX}${Date.now()}`;\n\n const testDirOut = (\n await this.runShellCommand(deviceId, `test -d ${artifactsDir} ; echo $?`)\n ).trim();\n\n if (testDirOut !== '1') {\n throw new WebExtError(\n `Cannot create artifacts directory ${artifactsDir} ` +\n `because it exists on ${deviceId}.`\n );\n }\n\n await this.runShellCommand(deviceId, ['mkdir', '-p', artifactsDir]);\n\n this.artifactsDirMap.set(deviceId, artifactsDir);\n\n return artifactsDir;\n }\n\n async detectOrRemoveOldArtifacts(\n deviceId: string,\n removeArtifactDirs?: boolean = false\n ): Promise<boolean> {\n const { adbClient } = this;\n\n log.debug('Checking adb device for existing web-ext artifacts dirs');\n\n return wrapADBCall(async () => {\n const files = await adbClient\n .getDevice(deviceId)\n .readdir(DEVICE_DIR_BASE);\n let found = false;\n\n for (const file of files) {\n if (\n !file.isDirectory() ||\n !file.name.startsWith(ARTIFACTS_DIR_PREFIX)\n ) {\n continue;\n }\n\n // Return earlier if we only need to warn the user that some\n // existing artifacts dirs have been found on the adb device.\n if (!removeArtifactDirs) {\n return true;\n }\n\n found = true;\n\n const artifactsDir = `${DEVICE_DIR_BASE}${file.name}`;\n\n log.debug(\n `Removing artifacts directory ${artifactsDir} from device ${deviceId}`\n );\n\n await this.runShellCommand(deviceId, ['rm', '-rf', artifactsDir]);\n }\n\n return found;\n });\n }\n\n async clearArtifactsDir(deviceId: string): Promise<void> {\n const artifactsDir = this.artifactsDirMap.get(deviceId);\n\n if (!artifactsDir) {\n // nothing to do here.\n return;\n }\n\n this.artifactsDirMap.delete(deviceId);\n\n log.debug(\n `Removing ${artifactsDir} artifacts directory on ${deviceId} device`\n );\n\n await this.runShellCommand(deviceId, ['rm', '-rf', artifactsDir]);\n }\n\n async pushFile(\n deviceId: string,\n localPath: string,\n devicePath: string\n ): Promise<void> {\n const { adbClient } = this;\n\n log.debug(`Pushing ${localPath} to ${devicePath} on ${deviceId}`);\n\n await wrapADBCall(async () => {\n await adbClient\n .getDevice(deviceId)\n .push(localPath, devicePath)\n .then(function (transfer) {\n return new Promise((resolve) => {\n transfer.on('end', resolve);\n });\n });\n });\n }\n\n async startFirefoxAPK(\n deviceId: string,\n apk: string,\n apkComponent: ?string,\n deviceProfileDir: string\n ): Promise<void> {\n const { adbClient } = this;\n\n log.debug(`Starting ${apk} on ${deviceId}`);\n\n // Fenix does ignore the -profile parameter, on the contrary Fennec\n // would run using the given path as the profile to be used during\n // this execution.\n const extras = [\n {\n key: 'args',\n value: `-profile ${deviceProfileDir}`,\n },\n ];\n\n if (!apkComponent) {\n apkComponent = '.App';\n if (defaultApkComponents[apk]) {\n apkComponent = defaultApkComponents[apk];\n }\n } else if (!apkComponent.includes('.')) {\n apkComponent = `.${apkComponent}`;\n }\n\n // if `apk` is a browser package or the `apk` has a\n // browser package prefix: prepend the package identifier\n // before `apkComponent`\n if (apkComponent.startsWith('.')) {\n for (const browser of packageIdentifiers) {\n if (apk === browser || apk.startsWith(`${browser}.`)) {\n apkComponent = browser + apkComponent;\n }\n }\n }\n\n // if `apkComponent` starts with a '.', then adb will expand\n // the following to: `${apk}/${apk}.${apkComponent}`\n const component = `${apk}/${apkComponent}`;\n\n await wrapADBCall(async () => {\n try {\n // TODO: once Fenix (release) uses Android 13, we can get rid of this\n // call and only use the second call in the `catch` block.\n await adbClient.getDevice(deviceId).startActivity({\n wait: true,\n action: 'android.activity.MAIN',\n component,\n extras,\n });\n } catch {\n // Android 13+ requires a different action/category but we still need\n // to support older Fenix builds.\n await adbClient.getDevice(deviceId).startActivity({\n wait: true,\n action: 'android.intent.action.MAIN',\n category: 'android.intent.category.LAUNCHER',\n component,\n extras,\n });\n }\n });\n }\n\n setUserAbortDiscovery(value: boolean) {\n this.userAbortDiscovery = value;\n }\n\n async discoverRDPUnixSocket(\n deviceId: string,\n apk: string,\n { maxDiscoveryTime, retryInterval }: DiscoveryParams = {}\n ): Promise<string> {\n let rdpUnixSockets = [];\n\n const discoveryStartedAt = Date.now();\n const msg =\n `Waiting for ${apk} Remote Debugging Server...` +\n '\\nMake sure to enable \"Remote Debugging via USB\" ' +\n 'from Settings -> Developer Tools if it is not yet enabled.';\n\n while (rdpUnixSockets.length === 0) {\n log.info(msg);\n if (this.userAbortDiscovery) {\n throw new UsageError(\n 'Exiting Firefox Remote Debugging socket discovery on user request'\n );\n }\n\n if (Date.now() - discoveryStartedAt > maxDiscoveryTime) {\n throw new WebExtError(\n 'Timeout while waiting for the Android Firefox Debugger Socket'\n );\n }\n\n rdpUnixSockets = (\n await this.runShellCommand(deviceId, ['cat', '/proc/net/unix'])\n )\n .split('\\n')\n .filter((line) => {\n // The RDP unix socket is expected to be a path in the form:\n // /data/data/org.mozilla.fennec_rpl/firefox-debugger-socket\n return line.trim().endsWith(`${apk}/firefox-debugger-socket`);\n });\n\n if (rdpUnixSockets.length === 0) {\n await new Promise((resolve) => setTimeout(resolve, retryInterval));\n }\n }\n\n // Convert into an array of unix socket filenames.\n rdpUnixSockets = rdpUnixSockets.map((line) => {\n return line.trim().split(/\\s/).pop();\n });\n\n if (rdpUnixSockets.length > 1) {\n throw new WebExtError(\n 'Unexpected multiple RDP sockets: ' +\n `${JSON.stringify(rdpUnixSockets)}`\n );\n }\n\n return rdpUnixSockets[0];\n }\n\n async setupForward(deviceId: string, remote: string, local: string) {\n const { adbClient } = this;\n\n // TODO(rpl): we should use adb.listForwards and reuse the existing one if any (especially\n // because adbkit doesn't seem to support `adb forward --remote` yet).\n log.debug(`Configuring ADB forward for ${deviceId}: ${remote} -> ${local}`);\n\n await wrapADBCall(async () => {\n await adbClient.getDevice(deviceId).forward(local, remote);\n });\n }\n}\n\nexport async function listADBDevices(adbBin?: string): Promise<Array<string>> {\n const adbUtils = new ADBUtils({ adbBin });\n return adbUtils.discoverDevices();\n}\n\nexport async function listADBFirefoxAPKs(\n deviceId: string,\n adbBin?: string\n): Promise<Array<string>> {\n const adbUtils = new ADBUtils({ adbBin });\n return adbUtils.discoverInstalledFirefoxAPKs(deviceId);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adb.js","names":["ADBKit","isErrorWithCode","UsageError","WebExtError","createLogger","packageIdentifiers","defaultApkComponents","DEVICE_DIR_BASE","ARTIFACTS_DIR_PREFIX","defaultADB","default","log","import","meta","url","wrapADBCall","asyncFn","error","message","includes","ADBUtils","constructor","params","adb","adbBin","adbHost","adbPort","adbClient","createClient","bin","host","port","artifactsDirMap","Map","userAbortDiscovery","runShellCommand","deviceId","cmd","debug","JSON","stringify","getDevice","shell","then","util","readAll","res","toString","discoverDevices","devices","listDevices","map","dev","id","discoverInstalledFirefoxAPKs","firefoxApk","pmList","split","line","replace","trim","filter","browser","startsWith","amForceStopAPK","apk","getOrCreateArtifactsDir","artifactsDir","get","Date","now","testDirOut","set","detectOrRemoveOldArtifacts","removeArtifactDirs","files","readdir","found","file","isDirectory","name","clearArtifactsDir","delete","pushFile","localPath","devicePath","push","transfer","Promise","resolve","on","startFirefoxAPK","apkComponent","deviceProfileDir","extras","key","value","component","startActivity","wait","action","category","setUserAbortDiscovery","discoverRDPUnixSocket","maxDiscoveryTime","retryInterval","rdpUnixSockets","discoveryStartedAt","msg","length","info","endsWith","setTimeout","pop","setupForward","remote","local","forward","listADBDevices","adbUtils","listADBFirefoxAPKs"],"sources":["../../src/util/adb.js"],"sourcesContent":["/* @flow */\nimport ADBKit from '@devicefarmer/adbkit';\n\nimport { isErrorWithCode, UsageError, WebExtError } from '../errors.js';\nimport { createLogger } from '../util/logger.js';\nimport packageIdentifiers, {\n defaultApkComponents,\n} from '../firefox/package-identifiers.js';\n\nexport const DEVICE_DIR_BASE = '/data/local/tmp/';\nexport const ARTIFACTS_DIR_PREFIX = 'web-ext-artifacts-';\n\nconst defaultADB = ADBKit.default;\n\nconst log = createLogger(import.meta.url);\n\nexport type ADBUtilsParams = {|\n adb?: typeof defaultADB,\n // ADB configs.\n adbBin?: string,\n adbHost?: string,\n adbPort?: string,\n adbDevice?: string,\n|};\n\nexport type DiscoveryParams = {\n maxDiscoveryTime: number,\n retryInterval: number,\n};\n\n// Helper function used to raise an UsageError when the adb binary has not been found.\nasync function wrapADBCall(asyncFn: (...any) => Promise<any>): Promise<any> {\n try {\n return await asyncFn();\n } catch (error) {\n if (\n isErrorWithCode('ENOENT', error) &&\n error.message.includes('spawn adb')\n ) {\n throw new UsageError(\n 'No adb executable has been found. ' +\n 'You can Use --adb-bin, --adb-host/--adb-port ' +\n 'to configure it manually if needed.'\n );\n }\n\n throw error;\n }\n}\n\nexport default class ADBUtils {\n params: ADBUtilsParams;\n adb: typeof defaultADB;\n adbClient: any; // TODO: better flow typing here.\n\n // Map<deviceId -> artifactsDir>\n artifactsDirMap: Map<string, string>;\n // Toggled when the user wants to abort the RDP Unix Socket discovery loop\n // while it is still executing.\n userAbortDiscovery: boolean;\n\n constructor(params: ADBUtilsParams) {\n this.params = params;\n\n const { adb, adbBin, adbHost, adbPort } = params;\n\n this.adb = adb || defaultADB;\n\n this.adbClient = this.adb.createClient({\n bin: adbBin,\n host: adbHost,\n port: adbPort,\n });\n\n this.artifactsDirMap = new Map();\n\n this.userAbortDiscovery = false;\n }\n\n runShellCommand(\n deviceId: string,\n cmd: string | Array<string>\n ): Promise<string> {\n const { adb, adbClient } = this;\n\n log.debug(`Run adb shell command on ${deviceId}: ${JSON.stringify(cmd)}`);\n\n return wrapADBCall(async () => {\n return await adbClient\n .getDevice(deviceId)\n .shell(cmd)\n .then(adb.util.readAll);\n }).then((res) => res.toString());\n }\n\n async discoverDevices(): Promise<Array<string>> {\n const { adbClient } = this;\n\n let devices = [];\n\n log.debug('Listing android devices');\n devices = await wrapADBCall(async () => adbClient.listDevices());\n\n return devices.map((dev) => dev.id);\n }\n\n async discoverInstalledFirefoxAPKs(\n deviceId: string,\n firefoxApk?: string\n ): Promise<Array<string>> {\n log.debug(`Listing installed Firefox APKs on ${deviceId}`);\n\n const pmList = await this.runShellCommand(deviceId, [\n 'pm',\n 'list',\n 'packages',\n ]);\n\n return pmList\n .split('\\n')\n .map((line) => line.replace('package:', '').trim())\n .filter((line) => {\n // Look for an exact match if firefoxApk is defined.\n if (firefoxApk) {\n return line === firefoxApk;\n }\n // Match any package name that starts with the package name of a Firefox for Android browser.\n for (const browser of packageIdentifiers) {\n if (line.startsWith(browser)) {\n return true;\n }\n }\n\n return false;\n });\n }\n\n async amForceStopAPK(deviceId: string, apk: string): Promise<void> {\n await this.runShellCommand(deviceId, ['am', 'force-stop', apk]);\n }\n\n async getOrCreateArtifactsDir(deviceId: string): Promise<string> {\n let artifactsDir = this.artifactsDirMap.get(deviceId);\n\n if (artifactsDir) {\n return artifactsDir;\n }\n\n artifactsDir = `${DEVICE_DIR_BASE}${ARTIFACTS_DIR_PREFIX}${Date.now()}`;\n\n const testDirOut = (\n await this.runShellCommand(deviceId, `test -d ${artifactsDir} ; echo $?`)\n ).trim();\n\n if (testDirOut !== '1') {\n throw new WebExtError(\n `Cannot create artifacts directory ${artifactsDir} ` +\n `because it exists on ${deviceId}.`\n );\n }\n\n await this.runShellCommand(deviceId, ['mkdir', '-p', artifactsDir]);\n\n this.artifactsDirMap.set(deviceId, artifactsDir);\n\n return artifactsDir;\n }\n\n async detectOrRemoveOldArtifacts(\n deviceId: string,\n removeArtifactDirs?: boolean = false\n ): Promise<boolean> {\n const { adbClient } = this;\n\n log.debug('Checking adb device for existing web-ext artifacts dirs');\n\n return wrapADBCall(async () => {\n const files = await adbClient\n .getDevice(deviceId)\n .readdir(DEVICE_DIR_BASE);\n let found = false;\n\n for (const file of files) {\n if (\n !file.isDirectory() ||\n !file.name.startsWith(ARTIFACTS_DIR_PREFIX)\n ) {\n continue;\n }\n\n // Return earlier if we only need to warn the user that some\n // existing artifacts dirs have been found on the adb device.\n if (!removeArtifactDirs) {\n return true;\n }\n\n found = true;\n\n const artifactsDir = `${DEVICE_DIR_BASE}${file.name}`;\n\n log.debug(\n `Removing artifacts directory ${artifactsDir} from device ${deviceId}`\n );\n\n await this.runShellCommand(deviceId, ['rm', '-rf', artifactsDir]);\n }\n\n return found;\n });\n }\n\n async clearArtifactsDir(deviceId: string): Promise<void> {\n const artifactsDir = this.artifactsDirMap.get(deviceId);\n\n if (!artifactsDir) {\n // nothing to do here.\n return;\n }\n\n this.artifactsDirMap.delete(deviceId);\n\n log.debug(\n `Removing ${artifactsDir} artifacts directory on ${deviceId} device`\n );\n\n await this.runShellCommand(deviceId, ['rm', '-rf', artifactsDir]);\n }\n\n async pushFile(\n deviceId: string,\n localPath: string,\n devicePath: string\n ): Promise<void> {\n const { adbClient } = this;\n\n log.debug(`Pushing ${localPath} to ${devicePath} on ${deviceId}`);\n\n await wrapADBCall(async () => {\n await adbClient\n .getDevice(deviceId)\n .push(localPath, devicePath)\n .then(function (transfer) {\n return new Promise((resolve) => {\n transfer.on('end', resolve);\n });\n });\n });\n }\n\n async startFirefoxAPK(\n deviceId: string,\n apk: string,\n apkComponent: ?string,\n deviceProfileDir: string\n ): Promise<void> {\n const { adbClient } = this;\n\n log.debug(`Starting ${apk} on ${deviceId}`);\n\n // Fenix does ignore the -profile parameter, on the contrary Fennec\n // would run using the given path as the profile to be used during\n // this execution.\n const extras = [\n {\n key: 'args',\n value: `-profile ${deviceProfileDir}`,\n },\n ];\n\n if (!apkComponent) {\n apkComponent = '.App';\n if (defaultApkComponents[apk]) {\n apkComponent = defaultApkComponents[apk];\n }\n } else if (!apkComponent.includes('.')) {\n apkComponent = `.${apkComponent}`;\n }\n\n // if `apk` is a browser package or the `apk` has a\n // browser package prefix: prepend the package identifier\n // before `apkComponent`\n if (apkComponent.startsWith('.')) {\n for (const browser of packageIdentifiers) {\n if (apk === browser || apk.startsWith(`${browser}.`)) {\n apkComponent = browser + apkComponent;\n }\n }\n }\n\n // if `apkComponent` starts with a '.', then adb will expand\n // the following to: `${apk}/${apk}.${apkComponent}`\n const component = `${apk}/${apkComponent}`;\n\n await wrapADBCall(async () => {\n try {\n // TODO: once Fenix (release) uses Android 13, we can get rid of this\n // call and only use the second call in the `catch` block.\n await adbClient.getDevice(deviceId).startActivity({\n wait: true,\n action: 'android.activity.MAIN',\n component,\n extras,\n });\n } catch {\n // Android 13+ requires a different action/category but we still need\n // to support older Fenix builds.\n await adbClient.getDevice(deviceId).startActivity({\n wait: true,\n action: 'android.intent.action.MAIN',\n category: 'android.intent.category.LAUNCHER',\n component,\n extras,\n });\n }\n });\n }\n\n setUserAbortDiscovery(value: boolean) {\n this.userAbortDiscovery = value;\n }\n\n async discoverRDPUnixSocket(\n deviceId: string,\n apk: string,\n { maxDiscoveryTime, retryInterval }: DiscoveryParams = {}\n ): Promise<string> {\n let rdpUnixSockets = [];\n\n const discoveryStartedAt = Date.now();\n const msg =\n `Waiting for ${apk} Remote Debugging Server...` +\n '\\nMake sure to enable \"Remote Debugging via USB\" ' +\n 'from Settings -> Developer Tools if it is not yet enabled.';\n\n while (rdpUnixSockets.length === 0) {\n log.info(msg);\n if (this.userAbortDiscovery) {\n throw new UsageError(\n 'Exiting Firefox Remote Debugging socket discovery on user request'\n );\n }\n\n if (Date.now() - discoveryStartedAt > maxDiscoveryTime) {\n throw new WebExtError(\n 'Timeout while waiting for the Android Firefox Debugger Socket'\n );\n }\n\n rdpUnixSockets = (\n await this.runShellCommand(deviceId, ['cat', '/proc/net/unix'])\n )\n .split('\\n')\n .filter((line) => {\n // The RDP unix socket is expected to be a path in the form:\n // /data/data/org.mozilla.fennec_rpl/firefox-debugger-socket\n return line.trim().endsWith(`${apk}/firefox-debugger-socket`);\n });\n\n if (rdpUnixSockets.length === 0) {\n await new Promise((resolve) => setTimeout(resolve, retryInterval));\n }\n }\n\n // Convert into an array of unix socket filenames.\n rdpUnixSockets = rdpUnixSockets.map((line) => {\n return line.trim().split(/\\s/).pop();\n });\n\n if (rdpUnixSockets.length > 1) {\n throw new WebExtError(\n 'Unexpected multiple RDP sockets: ' +\n `${JSON.stringify(rdpUnixSockets)}`\n );\n }\n\n return rdpUnixSockets[0];\n }\n\n async setupForward(deviceId: string, remote: string, local: string) {\n const { adbClient } = this;\n\n // TODO(rpl): we should use adb.listForwards and reuse the existing one if any (especially\n // because adbkit doesn't seem to support `adb forward --remote` yet).\n log.debug(`Configuring ADB forward for ${deviceId}: ${remote} -> ${local}`);\n\n await wrapADBCall(async () => {\n await adbClient.getDevice(deviceId).forward(local, remote);\n });\n }\n}\n\nexport async function listADBDevices(adbBin?: string): Promise<Array<string>> {\n const adbUtils = new ADBUtils({ adbBin });\n return adbUtils.discoverDevices();\n}\n\nexport async function listADBFirefoxAPKs(\n deviceId: string,\n adbBin?: string\n): Promise<Array<string>> {\n const adbUtils = new ADBUtils({ adbBin });\n return adbUtils.discoverInstalledFirefoxAPKs(deviceId);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "web-ext",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.11.0",
|
|
4
4
|
"description": "A command line tool to help build, run, and test web extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@babel/runtime": "7.21.0",
|
|
62
62
|
"@devicefarmer/adbkit": "3.2.3",
|
|
63
|
-
"addons-linter": "6.
|
|
63
|
+
"addons-linter": "6.21.0",
|
|
64
64
|
"bunyan": "1.8.15",
|
|
65
65
|
"camelcase": "7.0.1",
|
|
66
66
|
"chrome-launcher": "0.15.1",
|