microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
8f322bcd71555e02f0b00a89a99da351ef8412b7

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/ios/iOSDeviceTracker.ts

170lines · 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 iosUtil, { DeviceTarget, isXcodeDetected } from "./iOSContainerUtility";
6import { DeviceStorage } from "../networkInspector/devices/deviceStorage";
7import { ClientOS } from "../networkInspector/clientUtils";
8import { IOSClienDevice } from "../networkInspector/devices/iOSClienDevice";
9import { findFileInFolderHierarchy } from "../../common/extensionHelper";
10import { ChildProcess, execFile } from "child_process";
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 let 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: ${err?.message}, ${stdout}, ${stderr}`,
123 );
124 }
125 },
126 );
127 this.logger.debug(`Port forwarding app started for ${port} port`);
128 childProcess.addListener("error", err => {
129 this.logger.error("Port forwarding app error", err);
130 });
131 childProcess.addListener("exit", code => {
132 this.logger.debug(`Port forwarding app exited with code ${code}`);
133 });
134 return childProcess;
135 }
136
137 /**
138 * @preserve
139 * End region: https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L63-L79
140 */
141
142 private async getRunningSimulators(): Promise<IDebuggableIOSTarget[]> {
143 return (await this.iOSTargetManager.getTargetList(
144 target => target.isOnline,
145 )) as IDebuggableIOSTarget[];
146 }
147
148 /**
149 * @preserve
150 * Start region: the code is borrowed from https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L227-L232
151 *
152 * Copyright (c) Facebook, Inc. and its affiliates.
153 *
154 * This source code is licensed under the MIT license found in the
155 * LICENSE file in the root directory of this source tree.
156 *
157 * @format
158 */
159 private getActiveDevices(): Promise<Array<DeviceTarget>> {
160 return iosUtil.targets().catch(e => {
161 this.logger.error(e.message);
162 return [];
163 });
164 }
165
166 /**
167 * @preserve
168 * End region: https://github.com/facebook/flipper/blob/v0.79.1/desktop/app/src/dispatcher/iOSDevice.tsx#L227-L232
169 */
170}
171