microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
43e6ccc3781e2fec953ee0059638ffa0e5d403ab

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/ios/iOSDeviceTracker.ts

193lines · 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 { AbstractDeviceTracker } from "../abstractDeviceTracker";
5import { IOSSimulatorManager, IiOSSimulator } from "./iOSSimulatorManager";
6import { DeviceType } from "../launchArgs";
7import iosUtil, { DeviceTarget } from "./iOSContainerUtility";
8import { DeviceStorage } from "../networkInspector/devices/deviceStorage";
9import { ClientOS } from "../networkInspector/clientUtils";
10import { IOSClienDevice } from "../networkInspector/devices/iOSClienDevice";
11import { findFileInFolderHierarchy } from "../../common/extensionHelper";
12import { ChildProcess, execFile } from "child_process";
13import { ChildProcess as ChildProcessUtils } from "../../common/node/childProcess";
14
15export class IOSDeviceTracker extends AbstractDeviceTracker {
16 private readonly portForwardingClientPath: string;
17 private iOSSimulatorManager: IOSSimulatorManager;
18 private portForwarders: Array<ChildProcess>;
19
20 constructor() {
21 super();
22 this.portForwardingClientPath =
23 (findFileInFolderHierarchy(__dirname, "static/PortForwardingMacApp.app") || __dirname) +
24 "/Contents/MacOS/PortForwardingMacApp";
25 this.iOSSimulatorManager = new IOSSimulatorManager();
26 this.portForwarders = [];
27 }
28
29 public async start(): Promise<void> {
30 this.logger.debug("Start iOS device tracker");
31 if (await this.isXcodeDetected()) {
32 this.startDevicePortForwarders();
33 }
34 await this.queryDevicesLoop();
35 }
36
37 public stop(): void {
38 this.logger.debug("Stop iOS device tracker");
39 this.isStop = true;
40 this.portForwarders.forEach(process => process.kill());
41 }
42
43 protected async queryDevices(): Promise<void> {
44 const simulators = await this.getRunningSimulators();
45 this.processDevices(simulators, "simulator");
46 const devices = await this.getActiveDevices();
47 this.processDevices(devices, "device");
48 }
49
50 private processDevices(
51 activeDevices: Array<IiOSSimulator | DeviceTarget>,
52 type: DeviceType,
53 ): void {
54 let currentDevicesIds = new Set(
55 [...DeviceStorage.devices.entries()]
56 .filter(entry => entry[1] instanceof IOSClienDevice && entry[1].deviceType === type)
57 .map(entry => entry[0]),
58 );
59
60 for (const activeDevice of activeDevices) {
61 if (currentDevicesIds.has(activeDevice.id)) {
62 currentDevicesIds.delete(activeDevice.id);
63 } else {
64 const androidDevice = new IOSClienDevice(
65 activeDevice.id,
66 type,
67 ClientOS.iOS,
68 activeDevice.state || "active",
69 activeDevice.name,
70 );
71 DeviceStorage.devices.set(androidDevice.id, androidDevice);
72 }
73 }
74
75 currentDevicesIds.forEach(oldDeviceId => {
76 DeviceStorage.devices.delete(oldDeviceId);
77 });
78 }
79
80 /**
81 * @preserve
82 * Start region: The code is borrowed from https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L81-L88
83 *
84 * Copyright (c) Facebook, Inc. and its affiliates.
85 *
86 * This source code is licensed under the MIT license found in the
87 * LICENSE file in the root directory of this source tree.
88 *
89 * @format
90 */
91 private startDevicePortForwarders(): void {
92 if (this.portForwarders.length > 0) {
93 // Only ever start them once.
94 return;
95 }
96 // start port forwarding server for real device connections
97 this.portForwarders = [this.forwardPort(8089, 8079), this.forwardPort(8088, 8078)];
98 }
99
100 /**
101 * @preserve
102 * End region: https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L81-L88
103 */
104
105 /**
106 * @preserve
107 * Start region: the code is borrowed from https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L63-L79
108 *
109 * Copyright (c) Facebook, Inc. and its affiliates.
110 *
111 * This source code is licensed under the MIT license found in the
112 * LICENSE file in the root directory of this source tree.
113 *
114 * @format
115 */
116 private forwardPort(port: number, multiplexChannelPort: number): ChildProcess {
117 const childProcess = execFile(
118 this.portForwardingClientPath,
119 [`-portForward=${port}`, `-multiplexChannelPort=${multiplexChannelPort}`],
120 (err, stdout, stderr) => {
121 if (!err?.killed) {
122 this.logger.error(
123 `Port forwarding app failed to start: ${err?.message}, ${stdout}, ${stderr}`,
124 );
125 }
126 },
127 );
128 this.logger.debug(`Port forwarding app started for ${port} port`);
129 childProcess.addListener("error", err => {
130 this.logger.error("Port forwarding app error", err);
131 });
132 childProcess.addListener("exit", code => {
133 this.logger.debug(`Port forwarding app exited with code ${code}`);
134 });
135 return childProcess;
136 }
137
138 /**
139 * @preserve
140 * End region: https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L63-L79
141 */
142
143 private async getRunningSimulators(): Promise<IiOSSimulator[]> {
144 return this.iOSSimulatorManager.collectSimulators("booted");
145 }
146
147 /**
148 * @preserve
149 * Start region: the code is borrowed from https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L227-L232
150 *
151 * Copyright (c) Facebook, Inc. and its affiliates.
152 *
153 * This source code is licensed under the MIT license found in the
154 * LICENSE file in the root directory of this source tree.
155 *
156 * @format
157 */
158 private getActiveDevices(): Promise<Array<DeviceTarget>> {
159 return iosUtil.targets().catch(e => {
160 this.logger.error(e.message);
161 return [];
162 });
163 }
164
165 /**
166 * @preserve
167 * End region: https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L227-L232
168 */
169
170 /**
171 * @preserve
172 * Start region: the code is borrowed from https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L282-L286
173 *
174 * Copyright (c) Facebook, Inc. and its affiliates.
175 *
176 * This source code is licensed under the MIT license found in the
177 * LICENSE file in the root directory of this source tree.
178 *
179 * @format
180 */
181 private isXcodeDetected(): Promise<boolean> {
182 const cp = new ChildProcessUtils();
183 return cp
184 .execToString("xcode-select -p")
185 .then(() => true)
186 .catch(() => false);
187 }
188
189 /**
190 * @preserve
191 * End region: https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L282-L286
192 */
193}
194