microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
e45838cbf8bb84beab7d36042bcdbc57fe0319c8

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/common/android/adb.ts

133lines · 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 {ChildProcess} from "../../common/node/childProcess";
7import {CommandExecutor} from "../../common/commandExecutor";
8
9// See android versions usage at: http://developer.android.com/about/dashboards/index.html
10export enum AndroidAPILevel {
11 Marshmallow = 23,
12 LOLLIPOP_MR1 = 22,
13 LOLLIPOP = 21, /* Supports adb reverse */
14 KITKAT = 19,
15 JELLY_BEAN_MR2 = 18,
16 JELLY_BEAN_MR1 = 17,
17 JELLY_BEAN = 16,
18 ICE_CREAM_SANDWICH_MR1 = 15,
19 GINGERBREAD_MR1 = 10,
20}
21
22export enum DeviceType {
23 AndroidSdkEmulator, // These seem to have emulator-<port> ids
24 Other
25}
26
27const AndroidSDKEmulatorPattern = /^emulator-\d{1,5}$/;
28
29export interface IDevice {
30 id: string;
31 isOnline: boolean;
32 type: DeviceType;
33}
34
35export interface IAdb {
36 getConnectedDevices(): Q.Promise<IDevice[]>;
37 launchApp(projectRoot: string, packageName: string, debugTarget?: string): Q.Promise<void>;
38 getOnlineDevices(): Q.Promise<IDevice[]>;
39 reloadAppInDebugMode(projectRoot: string, packageName: string, debugTarget?: string): Q.Promise<void>;
40 apiVersion(deviceId: string): Q.Promise<AndroidAPILevel>;
41 reverseAdd(deviceId: string, devicePort: string, computerPort: string): Q.Promise<void>;
42}
43
44export abstract class AdbEnhancements implements IAdb {
45 public abstract getConnectedDevices(): Q.Promise<IDevice[]>;
46 public abstract launchApp(projectRoot: string, packageName: string, debugTarget?: string): Q.Promise<void>;
47 public abstract reloadAppInDebugMode(projectRoot: string, packageName: string, debugTarget?: string): Q.Promise<void>;
48 public abstract apiVersion(deviceId: string): Q.Promise<AndroidAPILevel>;
49 public abstract reverseAdd(deviceId: string, devicePort: string, computerPort: string): Q.Promise<void>;
50
51 public getOnlineDevices(): Q.Promise<IDevice[]> {
52 return this.getConnectedDevices().then(devices => {
53 return devices.filter(device =>
54 device.isOnline);
55 });
56 }
57}
58
59export class Adb extends AdbEnhancements {
60 private childProcess: ChildProcess;
61 private commandExecutor: CommandExecutor;
62
63 constructor({childProcess = new ChildProcess(), commandExecutor = new CommandExecutor()} = {}) {
64 super();
65 this.childProcess = childProcess;
66 this.commandExecutor = commandExecutor;
67 }
68
69 /**
70 * Gets the list of Android connected devices and emulators.
71 */
72 public getConnectedDevices(): Q.Promise<IDevice[]> {
73 let childProcess = new ChildProcess();
74 return childProcess.execToString("adb devices")
75 .then(output => {
76 return this.parseConnectedDevices(output);
77 });
78 }
79
80 /**
81 * Broadcasts an intent to reload the application in debug mode.
82 */
83 public reloadAppInDebugMode(projectRoot: string, packageName: string, debugTarget?: string): Q.Promise<void> {
84 let enableDebugCommand = `adb ${debugTarget ? "-s " + debugTarget : ""} shell am broadcast -a "${packageName}.RELOAD_APP_ACTION" --ez jsproxy true`;
85 return new CommandExecutor(projectRoot).execute(enableDebugCommand);
86 }
87
88 /**
89 * Sends an intent which launches the main activity of the application.
90 */
91 public launchApp(projectRoot: string, packageName: string, debugTarget?: string): Q.Promise<void> {
92 let launchAppCommand = `adb -s ${debugTarget} shell am start -n ${packageName}/.MainActivity`;
93 return new CommandExecutor(projectRoot).execute(launchAppCommand);
94 }
95
96 public apiVersion(deviceId: string): Q.Promise<AndroidAPILevel> {
97 return this.executeQuery(deviceId, "shell getprop ro.build.version.sdk").then(output =>
98 parseInt(output, 10));
99 }
100
101 public reverseAdd(deviceId: string, devicePort: string, computerPort: string): Q.Promise<void> {
102 return this.execute(deviceId, `reverse tcp:${devicePort} tcp:${computerPort}`);
103 }
104
105 private parseConnectedDevices(input: string): IDevice[] {
106 let result: IDevice[] = [];
107 let regex = new RegExp("^(\\S+)\\t(\\S+)$", "mg");
108 let match = regex.exec(input);
109 while (match != null) {
110 result.push({ id: match[1], isOnline: match[2] === "device", type: this.extractDeviceType(match[1]) });
111 match = regex.exec(input);
112 }
113 return result;
114 }
115
116 private extractDeviceType(id: string): DeviceType {
117 return id.match(AndroidSDKEmulatorPattern)
118 ? DeviceType.AndroidSdkEmulator
119 : DeviceType.Other;
120 }
121
122 private executeQuery(deviceId: string, command: string): Q.Promise<string> {
123 return this.childProcess.execToString(this.generateCommandForDevice(deviceId, command));
124 }
125
126 private execute(deviceId: string, command: string): Q.Promise<void> {
127 return this.commandExecutor.execute(this.generateCommandForDevice(deviceId, command));
128 }
129
130 private generateCommandForDevice(deviceId: string, adbCommand: string): string {
131 return `adb -s "${deviceId}" ${adbCommand}`;
132 }
133}
134