microsoft/vscode-react-native

Public

mirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
bdad2966e136bda7c0f98643513f5e2cc9130bb6

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/android/androidPlatform.ts

107lines · modecode

1// 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 Q from "q";
5
6import {IAppPlatform} from "../platformResolver";
7import {CommandExecutor} from "../../common/commandExecutor";
8import {ExtensionMessageSender, ExtensionMessage} from "../../common/extensionMessaging";
9import {IRunOptions} from "../../common/launchArgs";
10import {Log} from "../../common/log/log";
11import {PackageNameResolver} from "../../common/android/packageNameResolver";
12import {OutputVerifier, PatternToFailure} from "../../common/outputVerifier";
13import {DeviceHelper, IDevice} from "../../common/android/deviceHelper";
14import {Package} from "../../common/node/package";
15
16/**
17 * Android specific platform implementation for debugging RN applications.
18 */
19export class AndroidPlatform implements IAppPlatform {
20 private extensionMessageSender: ExtensionMessageSender;
21
22 // We should add the common Android build/run erros we find to this list
23 private static RUN_ANDROID_FAILURE_PATTERNS: PatternToFailure = {
24 "Failed to install on any devices": "Could not install the app on any available device. Make sure you have a correctly"
25 + " configured device or emulator running. See https://facebook.github.io/react-native/docs/android-setup.html",
26 "com.android.ddmlib.ShellCommandUnresponsiveException": "An Android shell command timed-out. Please retry the operation.",
27 "Android project not found": "Android project not found." };
28
29 private static RUN_ANDROID_SUCCESS_PATTERNS: string[] = ["BUILD SUCCESSFUL", "Starting the app", "Starting: Intent"];
30
31 private debugTarget: string;
32 private packageName: string;
33 private deviceHelper: DeviceHelper;
34
35 constructor({ extensionMessageSender = new ExtensionMessageSender()} = {}) {
36 this.extensionMessageSender = extensionMessageSender;
37 this.deviceHelper = new DeviceHelper();
38 }
39
40 public runApp(runOptions: IRunOptions): Q.Promise<void> {
41 let pkg = new Package(runOptions.projectRoot);
42 let cexec = new CommandExecutor(runOptions.projectRoot);
43
44 const runAndroidSpawn = cexec.spawnChildReactCommandProcess("run-android");
45 const output = new OutputVerifier(
46 () =>
47 Q(AndroidPlatform.RUN_ANDROID_SUCCESS_PATTERNS),
48 () =>
49 Q(AndroidPlatform.RUN_ANDROID_FAILURE_PATTERNS)).process(runAndroidSpawn);
50
51 return output
52 .then(() => pkg.name())
53 .then(appName => new PackageNameResolver(appName).resolvePackageName(runOptions.projectRoot))
54 .then(packageName => {
55 this.packageName = packageName;
56 return this.deviceHelper.getConnectedDevices()
57 .then((devices: IDevice[]) => {
58 if (devices.length > 1) {
59 /* more than one device or emulator */
60 this.debugTarget = this.getTargetEmulator(runOptions, devices);
61 if (this.debugTarget) {
62 /* Launching is needed only if we have more than one device active */
63 return this.deviceHelper.launchApp(runOptions.projectRoot, packageName, this.debugTarget);
64 }
65 } else if (devices.length === 1) {
66 this.debugTarget = devices[0].id;
67 }
68 });
69 }).then(() =>
70 this.startMonitoringLogCat(runOptions.logCatArguments).catch(error => // The LogCatMonitor failing won't stop the debugging experience
71 Log.logWarning("Couldn't start LogCat monitor", error)));
72 }
73
74 public enableJSDebuggingMode(runOptions: IRunOptions): Q.Promise<void> {
75 return this.deviceHelper.reloadAppInDebugMode(runOptions.projectRoot, this.packageName, this.debugTarget);
76 }
77
78 /**
79 * Returns the target emulator, using the following logic:
80 * * If an emulator is specified and it is connected, use that one.
81 * * Otherwise, use the first one in the list.
82 */
83 private getTargetEmulator(runOptions: IRunOptions, devices: IDevice[]): string {
84 let activeFilterFunction = (device: IDevice) => {
85 return device.isOnline;
86 };
87
88 let targetFilterFunction = (device: IDevice) => {
89 return device.id === runOptions.target && activeFilterFunction(device);
90 };
91
92 if (runOptions && runOptions.target && devices) {
93 /* check if the specified target is active */
94 if (devices.some(targetFilterFunction)) {
95 return runOptions.target;
96 }
97 }
98
99 /* return the first active device in the list */
100 let activeDevices = devices && devices.filter(activeFilterFunction);
101 return activeDevices && activeDevices[0] && activeDevices[0].id;
102 }
103
104 private startMonitoringLogCat(logCatArguments: string): Q.Promise<void> {
105 return this.extensionMessageSender.sendMessage(ExtensionMessage.START_MONITORING_LOGCAT, [this.debugTarget, logCatArguments]);
106 }
107}