microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
b7085605384d409e3dc98771f7245039c7ebd70a

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/android/androidPlatform.ts

112lines · modeblame

e639e7a4Daniel10 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 Q from "q";
710f8655digeff10 years ago5
f8d32439dlebu10 years ago6import {IAppPlatform} from "../platformResolver";
b0061ac6Meena Kunnathur Balakrishnan10 years ago7import {CommandExecutor} from "../../common/commandExecutor";
710f8655digeff10 years ago8import {ExtensionMessageSender, ExtensionMessage} from "../../common/extensionMessaging";
9import {IRunOptions} from "../../common/launchArgs";
c2bf3c4fdigeff10 years ago10import {Log} from "../../common/log/log";
8953be57dlebu10 years ago11import {PackageNameResolver} from "../../common/android/packageNameResolver";
f8b7022ddigeff10 years ago12import {OutputVerifier, PatternToFailure} from "../../common/outputVerifier";
fcb6a5dadlebu10 years ago13import {DeviceHelper, IDevice} from "../../common/android/deviceHelper";
710f8655digeff10 years ago14import {Package} from "../../common/node/package";
e639e7a4Daniel10 years ago15
16/**
17* Android specific platform implementation for debugging RN applications.
18*/
f8d32439dlebu10 years ago19export class AndroidPlatform implements IAppPlatform {
710f8655digeff10 years ago20private extensionMessageSender: ExtensionMessageSender;
21
a1348eeddigeff10 years ago22private static MULTIPLE_DEVICES_ERROR = "error: more than one device/emulator";
23
7cc67271digeff10 years ago24// We should add the common Android build/run erros we find to this list
25private static RUN_ANDROID_FAILURE_PATTERNS: PatternToFailure = {
26"Failed to install on any devices": "Could not install the app on any available device. Make sure you have a correctly"
27+ " configured device or emulator running. See https://facebook.github.io/react-native/docs/android-setup.html",
9ce5a776digeff10 years ago28"com.android.ddmlib.ShellCommandUnresponsiveException": "An Android shell command timed-out. Please retry the operation.",
a1348eeddigeff10 years ago29"Android project not found": "Android project not found.",
30"error: more than one device/emulator": AndroidPlatform.MULTIPLE_DEVICES_ERROR };
7cc67271digeff10 years ago31
32private static RUN_ANDROID_SUCCESS_PATTERNS: string[] = ["BUILD SUCCESSFUL", "Starting the app", "Starting: Intent"];
bc7a32ceJimmy Thomson10 years ago33
74e87372dlebu10 years ago34private debugTarget: string;
a1348eeddigeff10 years ago35private devices: IDevice[];
9f34c1bddigeff10 years ago36private packageName: string;
fcb6a5dadlebu10 years ago37private deviceHelper: DeviceHelper;
38
710f8655digeff10 years ago39constructor({ extensionMessageSender = new ExtensionMessageSender()} = {}) {
40this.extensionMessageSender = extensionMessageSender;
fcb6a5dadlebu10 years ago41this.deviceHelper = new DeviceHelper();
42}
e639e7a4Daniel10 years ago43
44public runApp(runOptions: IRunOptions): Q.Promise<void> {
fcb6a5dadlebu10 years ago45let cexec = new CommandExecutor(runOptions.projectRoot);
ae883d21digeff10 years ago46
47const runAndroidSpawn = cexec.spawnChildReactCommandProcess("run-android");
48const output = new OutputVerifier(
7cc67271digeff10 years ago49() =>
50Q(AndroidPlatform.RUN_ANDROID_SUCCESS_PATTERNS),
51() =>
52Q(AndroidPlatform.RUN_ANDROID_FAILURE_PATTERNS)).process(runAndroidSpawn);
8953be57dlebu10 years ago53
c7819f8cdigeff10 years ago54return output
55.finally(() => {
56return this.deviceHelper.getConnectedDevices().then(devices => {
57this.devices = devices;
58this.debugTarget = this.getTargetEmulator(runOptions, devices);
59return this.getPackageName(runOptions.projectRoot).then(packageName =>
60this.packageName = packageName);
61});
62}).catch(reason => {
a1348eeddigeff10 years ago63if (reason.message === AndroidPlatform.MULTIPLE_DEVICES_ERROR && this.devices.length > 1 && this.debugTarget) {
64/* If it failed due to multiple devices, we'll apply this workaround to make it work anyways */
9f34c1bddigeff10 years ago65return this.deviceHelper.launchApp(runOptions.projectRoot, this.packageName, this.debugTarget);
a1348eeddigeff10 years ago66} else {
67return Q.reject<void>(reason);
68}
710f8655digeff10 years ago69}).then(() =>
a9d77c8bdigeff10 years ago70this.startMonitoringLogCat(runOptions.logCatArguments).catch(error => // The LogCatMonitor failing won't stop the debugging experience
710f8655digeff10 years ago71Log.logWarning("Couldn't start LogCat monitor", error)));
e639e7a4Daniel10 years ago72}
2f567aafdlebu10 years ago73
74e87372dlebu10 years ago74public enableJSDebuggingMode(runOptions: IRunOptions): Q.Promise<void> {
9f34c1bddigeff10 years ago75return this.deviceHelper.reloadAppInDebugMode(runOptions.projectRoot, this.packageName, this.debugTarget);
a1348eeddigeff10 years ago76}
77
78private getPackageName(projectRoot: string): Q.Promise<string> {
9f34c1bddigeff10 years ago79return new Package(projectRoot).name().then(appName =>
a1348eeddigeff10 years ago80new PackageNameResolver(appName).resolvePackageName(projectRoot));
74e87372dlebu10 years ago81}
82
2f567aafdlebu10 years ago83/**
84* Returns the target emulator, using the following logic:
85* * If an emulator is specified and it is connected, use that one.
86* * Otherwise, use the first one in the list.
87*/
88private getTargetEmulator(runOptions: IRunOptions, devices: IDevice[]): string {
89let activeFilterFunction = (device: IDevice) => {
74e87372dlebu10 years ago90return device.isOnline;
2f567aafdlebu10 years ago91};
92
93let targetFilterFunction = (device: IDevice) => {
94return device.id === runOptions.target && activeFilterFunction(device);
95};
96
74e87372dlebu10 years ago97if (runOptions && runOptions.target && devices) {
2f567aafdlebu10 years ago98/* check if the specified target is active */
74e87372dlebu10 years ago99if (devices.some(targetFilterFunction)) {
2f567aafdlebu10 years ago100return runOptions.target;
101}
102}
103
104/* return the first active device in the list */
105let activeDevices = devices && devices.filter(activeFilterFunction);
106return activeDevices && activeDevices[0] && activeDevices[0].id;
107}
710f8655digeff10 years ago108
a9d77c8bdigeff10 years ago109private startMonitoringLogCat(logCatArguments: string): Q.Promise<void> {
c2bf3c4fdigeff10 years ago110return this.extensionMessageSender.sendMessage(ExtensionMessage.START_MONITORING_LOGCAT, [this.debugTarget, logCatArguments]);
710f8655digeff10 years ago111}
e639e7a4Daniel10 years ago112}