-
-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathios-device-base.ts
122 lines (106 loc) · 3.4 KB
/
ios-device-base.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import * as net from "net";
import { performanceLog } from "../../decorators";
import { IDictionary, IErrors } from "../../declarations";
export abstract class IOSDeviceBase implements Mobile.IiOSDevice {
private cachedSockets: IDictionary<net.Socket> = {};
protected abstract $errors: IErrors;
protected abstract $deviceLogProvider: Mobile.IDeviceLogProvider;
protected abstract $iOSDebuggerPortService: IIOSDebuggerPortService;
protected abstract $lockService: ILockService;
protected abstract $logger: ILogger;
abstract deviceInfo: Mobile.IDeviceInfo;
abstract applicationManager: Mobile.IDeviceApplicationManager;
abstract fileSystem: Mobile.IDeviceFileSystem;
abstract isEmulator: boolean;
abstract isOnlyWiFiConnected: boolean;
abstract openDeviceLogStream(
options?: Mobile.IiOSLogStreamOptions
): Promise<void>;
@performanceLog()
public async getDebugSocket(
appId: string,
projectName: string,
projectDir: string,
ensureAppStarted: boolean = false
): Promise<net.Socket> {
return this.$lockService.executeActionWithLock(async () => {
if (this.cachedSockets[appId]) {
return this.cachedSockets[appId];
}
await this.attachToDebuggerFoundEvent(appId, projectName, projectDir);
try {
if (ensureAppStarted) {
await this.applicationManager.startApplication({
appId,
projectName,
projectDir,
});
}
} catch (err) {
this.$logger.trace(
`Unable to start application ${appId} on device ${this.deviceInfo.identifier} in getDebugSocket method. Error is: ${err}`
);
}
this.cachedSockets[appId] = await this.getDebugSocketCore(appId);
if (this.cachedSockets[appId]) {
this.cachedSockets[appId].on("close", async () => {
await this.destroyDebugSocket(appId);
});
}
return this.cachedSockets[appId];
}, `ios-debug-socket-${this.deviceInfo.identifier}-${appId}.lock`);
}
protected abstract getDebugSocketCore(appId: string): Promise<net.Socket>;
protected async attachToDebuggerFoundEvent(
appId: string,
projectName: string,
projectDir: string
): Promise<void> {
await this.startDeviceLogProcess(projectName, projectDir);
await this.$iOSDebuggerPortService.attachToDebuggerPortFoundEvent(appId);
}
protected async getDebuggerPort(appId: string): Promise<number> {
const port = await this.$iOSDebuggerPortService.getPort({
deviceId: this.deviceInfo.identifier,
appId,
});
if (!port) {
this.$errors.fail("Device socket port cannot be found.");
}
return port;
}
public async destroyAllSockets(): Promise<void> {
for (const appId in this.cachedSockets) {
await this.destroySocketSafe(this.cachedSockets[appId]);
}
this.cachedSockets = {};
}
public async destroyDebugSocket(appId: string): Promise<void> {
await this.destroySocketSafe(this.cachedSockets[appId]);
this.cachedSockets[appId] = null;
}
private async destroySocketSafe(socket: net.Socket): Promise<void> {
if (socket && !socket.destroyed) {
return new Promise<void>((resolve, reject) => {
socket.on("close", resolve);
socket.destroy();
});
}
}
private async startDeviceLogProcess(
projectName: string,
projectDir: string
): Promise<void> {
if (projectName) {
this.$deviceLogProvider.setProjectNameForDevice(
this.deviceInfo.identifier,
projectName
);
this.$deviceLogProvider.setProjectDirForDevice(
this.deviceInfo.identifier,
projectDir
);
}
await this.openDeviceLogStream();
}
}