microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
6f8b71fe85533260cf2134f19ea58e076315bb37

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/android/androidPlatform.ts

120lines · 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";
710f8655digeff10 years ago7import {ExtensionMessageSender, ExtensionMessage} from "../../common/extensionMessaging";
8import {IRunOptions} from "../../common/launchArgs";
c2bf3c4fdigeff10 years ago9import {Log} from "../../common/log/log";
8953be57dlebu10 years ago10import {PackageNameResolver} from "../../common/android/packageNameResolver";
f8b7022ddigeff10 years ago11import {OutputVerifier, PatternToFailure} from "../../common/outputVerifier";
aab2095edigeff10 years ago12import {IDeviceHelper, DeviceHelper, IDevice} from "../../common/android/deviceHelper";
710f8655digeff10 years ago13import {Package} from "../../common/node/package";
aab2095edigeff10 years ago14import {FileSystem} from "../../common/node/fileSystem";
15import {IReactNative, ReactNative} from "../../common/reactNative";
e639e7a4Daniel10 years ago16
17/**
18* Android specific platform implementation for debugging RN applications.
19*/
f8d32439dlebu10 years ago20export class AndroidPlatform implements IAppPlatform {
710f8655digeff10 years ago21private extensionMessageSender: ExtensionMessageSender;
22
a1348eeddigeff10 years ago23private static MULTIPLE_DEVICES_ERROR = "error: more than one device/emulator";
24
7cc67271digeff10 years ago25// We should add the common Android build/run erros we find to this list
26private static RUN_ANDROID_FAILURE_PATTERNS: PatternToFailure = {
27"Failed to install on any devices": "Could not install the app on any available device. Make sure you have a correctly"
28+ " configured device or emulator running. See https://facebook.github.io/react-native/docs/android-setup.html",
9ce5a776digeff10 years ago29"com.android.ddmlib.ShellCommandUnresponsiveException": "An Android shell command timed-out. Please retry the operation.",
a1348eeddigeff10 years ago30"Android project not found": "Android project not found.",
cdf34447digeff10 years ago31"error: more than one device/emulator": AndroidPlatform.MULTIPLE_DEVICES_ERROR,
32};
7cc67271digeff10 years ago33
34private static RUN_ANDROID_SUCCESS_PATTERNS: string[] = ["BUILD SUCCESSFUL", "Starting the app", "Starting: Intent"];
bc7a32ceJimmy Thomson10 years ago35
74e87372dlebu10 years ago36private debugTarget: string;
a1348eeddigeff10 years ago37private devices: IDevice[];
9f34c1bddigeff10 years ago38private packageName: string;
aab2095edigeff10 years ago39private deviceHelper: IDeviceHelper;
40private reactNative: IReactNative;
41private fileSystem: FileSystem;
fcb6a5dadlebu10 years ago42
aab2095edigeff10 years ago43constructor({ extensionMessageSender = new ExtensionMessageSender(),
44deviceHelper = <IDeviceHelper>new DeviceHelper(),
45reactNative = <IReactNative>new ReactNative(),
46fileSystem = new FileSystem(),
47} = {}) {
710f8655digeff10 years ago48this.extensionMessageSender = extensionMessageSender;
aab2095edigeff10 years ago49this.deviceHelper = deviceHelper;
50this.reactNative = reactNative;
51this.fileSystem = fileSystem;
fcb6a5dadlebu10 years ago52}
e639e7a4Daniel10 years ago53
54public runApp(runOptions: IRunOptions): Q.Promise<void> {
aab2095edigeff10 years ago55const runAndroidSpawn = this.reactNative.runAndroid(runOptions.projectRoot);
ae883d21digeff10 years ago56const output = new OutputVerifier(
7cc67271digeff10 years ago57() =>
58Q(AndroidPlatform.RUN_ANDROID_SUCCESS_PATTERNS),
59() =>
60Q(AndroidPlatform.RUN_ANDROID_FAILURE_PATTERNS)).process(runAndroidSpawn);
8953be57dlebu10 years ago61
c7819f8cdigeff10 years ago62return output
63.finally(() => {
64return this.deviceHelper.getConnectedDevices().then(devices => {
65this.devices = devices;
66this.debugTarget = this.getTargetEmulator(runOptions, devices);
67return this.getPackageName(runOptions.projectRoot).then(packageName =>
68this.packageName = packageName);
69});
70}).catch(reason => {
a1348eeddigeff10 years ago71if (reason.message === AndroidPlatform.MULTIPLE_DEVICES_ERROR && this.devices.length > 1 && this.debugTarget) {
72/* If it failed due to multiple devices, we'll apply this workaround to make it work anyways */
9f34c1bddigeff10 years ago73return this.deviceHelper.launchApp(runOptions.projectRoot, this.packageName, this.debugTarget);
a1348eeddigeff10 years ago74} else {
75return Q.reject<void>(reason);
76}
710f8655digeff10 years ago77}).then(() =>
a9d77c8bdigeff10 years ago78this.startMonitoringLogCat(runOptions.logCatArguments).catch(error => // The LogCatMonitor failing won't stop the debugging experience
710f8655digeff10 years ago79Log.logWarning("Couldn't start LogCat monitor", error)));
e639e7a4Daniel10 years ago80}
2f567aafdlebu10 years ago81
74e87372dlebu10 years ago82public enableJSDebuggingMode(runOptions: IRunOptions): Q.Promise<void> {
9f34c1bddigeff10 years ago83return this.deviceHelper.reloadAppInDebugMode(runOptions.projectRoot, this.packageName, this.debugTarget);
a1348eeddigeff10 years ago84}
85
86private getPackageName(projectRoot: string): Q.Promise<string> {
aab2095edigeff10 years ago87return new Package(projectRoot, { fileSystem: this.fileSystem }).name().then(appName =>
a1348eeddigeff10 years ago88new PackageNameResolver(appName).resolvePackageName(projectRoot));
74e87372dlebu10 years ago89}
90
2f567aafdlebu10 years ago91/**
92* Returns the target emulator, using the following logic:
93* * If an emulator is specified and it is connected, use that one.
94* * Otherwise, use the first one in the list.
95*/
96private getTargetEmulator(runOptions: IRunOptions, devices: IDevice[]): string {
97let activeFilterFunction = (device: IDevice) => {
74e87372dlebu10 years ago98return device.isOnline;
2f567aafdlebu10 years ago99};
100
101let targetFilterFunction = (device: IDevice) => {
102return device.id === runOptions.target && activeFilterFunction(device);
103};
104
74e87372dlebu10 years ago105if (runOptions && runOptions.target && devices) {
2f567aafdlebu10 years ago106/* check if the specified target is active */
74e87372dlebu10 years ago107if (devices.some(targetFilterFunction)) {
2f567aafdlebu10 years ago108return runOptions.target;
109}
110}
111
112/* return the first active device in the list */
113let activeDevices = devices && devices.filter(activeFilterFunction);
114return activeDevices && activeDevices[0] && activeDevices[0].id;
115}
710f8655digeff10 years ago116
a9d77c8bdigeff10 years ago117private startMonitoringLogCat(logCatArguments: string): Q.Promise<void> {
c2bf3c4fdigeff10 years ago118return this.extensionMessageSender.sendMessage(ExtensionMessage.START_MONITORING_LOGCAT, [this.debugTarget, logCatArguments]);
710f8655digeff10 years ago119}
e639e7a4Daniel10 years ago120}