microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
smoke-actionbar-use-packager-helper

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/ios/iOSDeviceTracker.ts

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