microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1.11.1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/extension/android/androidTargetManager.ts

222lines · modeblame

4cd25962JiglioNero4 years ago1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as nls from "vscode-nls";
5import { MobileTargetManager } from "../mobileTargetManager";
6import { ChildProcess } from "../../common/node/childProcess";
7import { OutputChannelLogger } from "../log/OutputChannelLogger";
8import { IDebuggableMobileTarget, IMobileTarget, MobileTarget } from "../mobileTarget";
9import { TargetType } from "../generalPlatform";
ab0238b7RedMickey4 years ago10import { PromiseUtil } from "../../common/node/promise";
8f322bcdJiglioNero4 years ago11import { InternalErrorCode } from "../../common/error/internalErrorCode";
12import { ErrorHelper } from "../../common/error/errorHelper";
09f6024fHeniker4 years ago13import { AdbHelper } from "./adb";
4cd25962JiglioNero4 years ago14
15nls.config({
16messageFormat: nls.MessageFormat.bundle,
17bundleFormat: nls.BundleFormat.standalone,
18})();
19const localize = nls.loadMessageBundle();
20
21export class AndroidTarget extends MobileTarget {
22public static fromInterface(obj: IDebuggableMobileTarget): AndroidTarget {
23return new AndroidTarget(obj.isOnline, obj.isVirtualTarget, obj.id, obj.name);
24}
25
26constructor(isOnline: boolean, isVirtualTarget: boolean, id: string, name?: string) {
27super(isOnline, isVirtualTarget, id, name ? name : id);
28}
29}
30
31export class AndroidTargetManager extends MobileTargetManager {
32private static readonly EMULATOR_COMMAND = "emulator";
33private static readonly EMULATOR_AVD_START_COMMAND = "-avd";
34private static readonly EMULATOR_START_TIMEOUT = 120;
35
36private logger: OutputChannelLogger;
37private adbHelper: AdbHelper;
38private childProcess: ChildProcess;
39
40constructor(adbHelper: AdbHelper) {
41super();
42this.adbHelper = adbHelper;
43this.logger = OutputChannelLogger.getChannel(OutputChannelLogger.MAIN_CHANNEL_NAME, true);
44this.childProcess = new ChildProcess();
45}
46
47public async isVirtualTarget(target: string): Promise<boolean> {
48try {
49if (target === TargetType.Device) {
50return false;
51} else if (
52target === TargetType.Simulator ||
8f322bcdJiglioNero4 years ago53target.match(AdbHelper.AndroidSDKEmulatorPattern)
4cd25962JiglioNero4 years ago54) {
55return true;
56}
09f6024fHeniker4 years ago57const onlineTarget = await this.adbHelper.findOnlineTargetById(target);
58if (onlineTarget) {
59return onlineTarget.isVirtualTarget;
60} else if ((await this.adbHelper.getAvdsNames()).includes(target)) {
61return true;
62}
63throw new Error("There is no such target");
8f322bcdJiglioNero4 years ago64} catch (error) {
65throw ErrorHelper.getNestedError(
66error,
67InternalErrorCode.CouldNotRecognizeTargetType,
68target,
4cd25962JiglioNero4 years ago69);
70}
71}
72
73public async selectAndPrepareTarget(
74filter?: (el: IMobileTarget) => boolean,
75): Promise<AndroidTarget | undefined> {
76const selectedTarget = await this.startSelection(filter);
77if (selectedTarget) {
78if (!selectedTarget.isOnline && selectedTarget.isVirtualTarget) {
79return this.launchSimulator(selectedTarget);
09f6024fHeniker4 years ago80}
81if (selectedTarget.id) {
82return AndroidTarget.fromInterface(<IDebuggableMobileTarget>selectedTarget);
4cd25962JiglioNero4 years ago83}
84}
85return undefined;
86}
87
8f322bcdJiglioNero4 years ago88public async collectTargets(targetType?: TargetType): Promise<void> {
4cd25962JiglioNero4 years ago89const targetList: IMobileTarget[] = [];
8f322bcdJiglioNero4 years ago90const collectSimulators = !targetType || targetType === TargetType.Simulator;
91const collectDevices = !targetType || targetType === TargetType.Device;
4cd25962JiglioNero4 years ago92
8f322bcdJiglioNero4 years ago93try {
94if (collectSimulators) {
95const emulatorsNames: string[] = await this.adbHelper.getAvdsNames();
96targetList.push(
09f6024fHeniker4 years ago97...emulatorsNames.map(name => ({
98name,
99isOnline: false,
100isVirtualTarget: true,
101})),
8f322bcdJiglioNero4 years ago102);
103}
104} catch (error) {
105// We throw an exception only if the target type is explicitly specified,
106// otherwise we collect only those targets that we can collect
107if (targetType === TargetType.Simulator) {
108throw error;
109}
110this.logger.warning(
111localize(
112"CouldNotUseEmulators",
113"An error occurred while trying to get installed emulators: {0}\nContinue using only online targets",
114error instanceof Error ? error.message : error.toString(),
115),
116);
117}
4cd25962JiglioNero4 years ago118
119const onlineTargets = await this.adbHelper.getOnlineTargets();
09f6024fHeniker4 years ago120for (const device of onlineTargets) {
8f322bcdJiglioNero4 years ago121if (device.isVirtualTarget && collectSimulators) {
4cd25962JiglioNero4 years ago122const avdName = await this.adbHelper.getAvdNameById(device.id);
123const emulatorTarget = targetList.find(target => target.name === avdName);
124if (emulatorTarget) {
125emulatorTarget.isOnline = true;
126emulatorTarget.id = device.id;
127}
8f322bcdJiglioNero4 years ago128} else if (!device.isVirtualTarget && collectDevices) {
4cd25962JiglioNero4 years ago129targetList.push({ id: device.id, isOnline: true, isVirtualTarget: false });
130}
131}
132
133this.targets = targetList;
134}
135
136protected async startSelection(
137filter?: (el: IMobileTarget) => boolean,
138): Promise<IMobileTarget | undefined> {
139return this.selectTarget(filter);
140}
141
142protected async launchSimulator(emulatorTarget: IMobileTarget): Promise<AndroidTarget> {
143return new Promise<AndroidTarget>((resolve, reject) => {
8df9830bSamriel4 years ago144let emulatorLaunchFailed = false;
4cd25962JiglioNero4 years ago145const emulatorProcess = this.childProcess.spawn(
146AndroidTargetManager.EMULATOR_COMMAND,
147[AndroidTargetManager.EMULATOR_AVD_START_COMMAND, emulatorTarget.name as string],
148{
149detached: true,
150},
151true,
152);
153emulatorProcess.outcome.catch(error => {
8df9830bSamriel4 years ago154emulatorLaunchFailed = true;
4cd25962JiglioNero4 years ago155if (
156process.platform == "win32" &&
157process.env.SESSIONNAME &&
158process.env.SESSIONNAME.toLowerCase().includes("rdp-tcp")
159) {
160this.logger.warning(
161localize(
162"RDPEmulatorWarning",
163"Android emulator was launched from the Windows RDP session, this might lead to failures.",
164),
165);
166}
09f6024fHeniker4 years ago167reject(
168new Error(`Virtual device launch finished with an exception: ${String(error)}`),
169);
4cd25962JiglioNero4 years ago170});
171emulatorProcess.spawnedProcess.unref();
172
173const condition = async () => {
8df9830bSamriel4 years ago174if (emulatorLaunchFailed)
175throw new Error("Android emulator launch failed unexpectedly");
4cd25962JiglioNero4 years ago176const connectedDevices = await this.adbHelper.getOnlineTargets();
09f6024fHeniker4 years ago177for (const target of connectedDevices) {
4cd25962JiglioNero4 years ago178const onlineAvdName = await this.adbHelper.getAvdNameById(target.id);
179if (onlineAvdName === emulatorTarget.name) {
180return target.id;
181}
182}
183return null;
184};
185
09f6024fHeniker4 years ago186void PromiseUtil.waitUntil<string>(
4cd25962JiglioNero4 years ago187condition,
1881000,
189AndroidTargetManager.EMULATOR_START_TIMEOUT * 1000,
8df9830bSamriel4 years ago190).then(
191emulatorId => {
192if (emulatorId) {
193emulatorTarget.id = emulatorId;
194emulatorTarget.isOnline = true;
195this.logger.info(
196localize(
197"EmulatorLaunched",
198"Launched Android emulator {0}",
4cd25962JiglioNero4 years ago199emulatorTarget.name,
8df9830bSamriel4 years ago200),
201);
202resolve(
203AndroidTarget.fromInterface(<IDebuggableMobileTarget>emulatorTarget),
204);
205} else {
206reject(
207new Error(
208`Virtual device launch finished with an exception: ${localize(
209"EmulatorStartWarning",
210"Could not start the emulator {0} within {1} seconds.",
211emulatorTarget.name,
212AndroidTargetManager.EMULATOR_START_TIMEOUT,
213)}`,
214),
215);
216}
217},
218() => {},
219);
4cd25962JiglioNero4 years ago220});
221}
222}