Skip to content

Commit 807cf78

Browse files
author
aaron
authored
Merge pull request kkevsekk1#13 from wilinz/master
增加手动连接ADB命令和手动关闭连接命令,修复若干BUG
2 parents 502b943 + d518857 commit 807cf78

File tree

4 files changed

+123
-35
lines changed

4 files changed

+123
-35
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
* 停止服务(Stop Server): 停止插件服务
5757
* 开始监听ADB设备(Start track adb devices): 开启后会自动连接ADB设备
5858
* 停止监听ADB设备(Stop track adb devices)
59+
* 手动连接ADB设备(Manually connect adb device)
60+
* 手动关闭设备连接(Manually disconnect device)
5961
* 打开文档(Open Document): 打开Auto.js开发文档
6062
* 显示服务端二维码(Show qr code): 显示服务端二维码,之后可用客户端扫码连接
6163
* 显示服务端ip地址(Show server address)

package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
"onCommand:extension.stopAllServer",
2121
"onCommand:extension.startTrackADBDevices",
2222
"onCommand:extension.stopTrackADBDevices",
23+
"onCommand:extension.manuallyConnectADB",
24+
"onCommand:extension.manuallyDisconnect",
2325
"onCommand:extension.showQrCode",
2426
"onCommand:extension.showServerAddress",
2527
"onCommand:extension.openDocument",
@@ -126,6 +128,16 @@
126128
"title": "停止监听ADB设备(Stop track adb devices)",
127129
"category": "Auto.js autoxjs"
128130
},
131+
{
132+
"command": "extension.manuallyConnectADB",
133+
"title": "手动连接ADB设备(Manually connect adb device)",
134+
"category": "Auto.js autoxjs"
135+
},
136+
{
137+
"command": "extension.manuallyDisconnect",
138+
"title": "手动关闭设备连接(Manually disconnect device)",
139+
"category": "Auto.js autoxjs"
140+
},
129141
{
130142
"command": "extension.run",
131143
"title": "运行脚本(Run)",

src/autojs-debug.ts

Lines changed: 82 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import * as url from 'url';
66
import * as fs from 'fs'
77
import { Project, ProjectObserser } from './project';
88
import * as vscode from "vscode";
9-
import Adb, { DeviceClient } from '@devicefarmer/adbkit';
9+
import Adb, { DeviceClient, Forward } from '@devicefarmer/adbkit';
1010
import Tracker from '@devicefarmer/adbkit/dist/src/adb/tracker';
11+
import ADBDevice from '@devicefarmer/adbkit/dist/src/Device';
12+
import internal from "stream";
13+
import buffer from "buffer";
1114

1215
const DEBUG = false;
1316

@@ -22,14 +25,16 @@ const HANDSHAKE_TIMEOUT = 10 * 1000;
2225

2326
export class Device extends EventEmitter {
2427
public name: string;
25-
public address: string;
28+
public type: string;
29+
public id: string;
2630
private connection: ws.connection;
27-
private attached: boolean = false;
31+
public attached: boolean = false;
2832
public projectObserser: ProjectObserser;
2933

30-
constructor(connection: ws.connection, address: string) {
34+
constructor(connection: ws.connection, type: string, id: string) {
3135
super();
32-
this.address = address
36+
this.type = type
37+
this.id = id
3338
this.connection = connection;
3439
this.read(this.connection);
3540
this.on('data:hello', data => {
@@ -51,6 +56,14 @@ export class Device extends EventEmitter {
5156
}, HANDSHAKE_TIMEOUT);
5257
}
5358

59+
close() {
60+
let message_id = `${Date.now()}_${Math.random()}`;
61+
let closeMessage = JSON.stringify({ message_id, data: "close", debug: false, type: 'close' })
62+
this.connection.sendUTF(closeMessage);
63+
this.connection.close();
64+
this.connection = null;
65+
}
66+
5467
send(type: string, data: any): void {
5568
let message_id = `${Date.now()}_${Math.random()}`;
5669
console.log(data);
@@ -85,9 +98,9 @@ export class Device extends EventEmitter {
8598

8699
public toString = (): string => {
87100
if (!this.name) {
88-
return `Device (${this.address})`;
101+
return `Device (${this.type}: ${this.id})`;
89102
}
90-
return `Device ${this.name}(${this.address})`;
103+
return `Device ${this.name}(${this.type}: ${this.id})`;
91104
}
92105

93106
private read(connection: ws.connection) {
@@ -116,7 +129,7 @@ export class Device extends EventEmitter {
116129
export class AutoJsDebugServer extends EventEmitter {
117130
public isHttpServerStarted = false
118131
private httpServer: http.Server;
119-
private adbClient = Adb.createClient()
132+
public adbClient = Adb.createClient()
120133
private tracker: Tracker
121134
private port: number;
122135
public devices: Array<Device> = [];
@@ -148,18 +161,24 @@ export class AutoJsDebugServer extends EventEmitter {
148161
response.end();
149162
}
150163
});
151-
var wsServer = new ws.server({ httpServer: this.httpServer });
164+
let wsServer = new ws.server({ httpServer: this.httpServer });
152165
wsServer.on('request', request => {
153166
let connection = request.accept();
154167
if (!connection) {
155168
return;
156169
}
157-
this.newDevice(connection, connection.remoteAddress)
170+
this.newDevice(connection, "tcp", connection.socket.remoteAddress + ":" + connection.socket.remotePort)
158171
})
159172
}
160173

161-
private newDevice(connection: ws.connection, address: string) {
162-
let device = new Device(connection, address);
174+
getDeviceById(id: string): Device {
175+
return this.devices.find((value) => {
176+
return value.id == id
177+
})
178+
}
179+
180+
private newDevice(connection: ws.connection, type: string, id: string) {
181+
let device = new Device(connection, type, id);
163182
logDebug(connection.state, "--->status")
164183
device.on("attach", (device) => {
165184
this.attachDevice(device);
@@ -169,6 +188,12 @@ export class AutoJsDebugServer extends EventEmitter {
169188
})
170189
}
171190

191+
async adbShell(device: DeviceClient, command: string): Promise<string> {
192+
let duplex: internal.Duplex = await device.shell(command)
193+
let brandBuf: buffer.Buffer = await Adb.util.readAll(duplex)
194+
return brandBuf.toString()
195+
}
196+
172197
private connectAutoxjsByADB(port: Number, deviceId: string) {
173198
let autoJsDebugServer = this
174199
let url = `ws://localhost:${port}/`
@@ -183,11 +208,9 @@ export class AutoJsDebugServer extends EventEmitter {
183208

184209
client.on('connect', function (connection) {
185210
console.log("connected to " + url)
186-
autoJsDebugServer.newDevice(connection, "ADB: " + deviceId)
211+
autoJsDebugServer.newDevice(connection, "adb", deviceId)
187212
});
188-
189-
//下面不能加'echo-protocol',否则会报Can`t connect due to "Sec-WebSocket-Protocol header"的错。因为服务器没有返回对应协议规定的信息
190-
client.connect(url); //, 'echo-protocol');
213+
client.connect(url);
191214
}
192215

193216
listen(): void {
@@ -208,31 +231,40 @@ export class AutoJsDebugServer extends EventEmitter {
208231
});
209232
}
210233

234+
235+
async listADBDevices(): Promise<ADBDevice[]> {
236+
return this.adbClient.listDevices();
237+
}
238+
211239
async trackADBDevices() {
212240
let thisServer = this
241+
let devices = await thisServer.adbClient.listDevices()
242+
for (let device0 of devices) {
243+
await thisServer.connectDevice(device0.id)
244+
}
213245
if (this.tracker) {
214246
this.emit("adb:tracking_started");
215247
return
216248
}
217-
let devices = await thisServer.adbClient.listDevices()
218-
for (let device0 of devices) {
219-
const device = thisServer.adbClient.getDevice(device0.id)
220-
await thisServer.connectDevice(device, device0.id)
221-
}
222249
try {
223250
let tracker = await thisServer.adbClient.trackDevices()
224-
this.tracker = tracker
251+
thisServer.tracker = tracker
225252
tracker.on('add', async function (device0) {
226253
console.log("adb device " + device0.id + " added")
227254
const device = thisServer.adbClient.getDevice(device0.id)
228255
await device.waitForDevice()
229-
await thisServer.connectDevice(device, device0.id)
256+
await thisServer.connectDevice(device0.id, device)
230257
})
231258
tracker.on('remove', function (device) {
232259
console.log("adb device " + device.id + " removed")
260+
let wsDevice = thisServer.getDeviceById(device.id)
261+
if (wsDevice) {
262+
wsDevice.close()
263+
}
264+
233265
})
234266
tracker.on('end', function () {
235-
tracker=undefined
267+
thisServer.tracker = undefined
236268
console.log('ADB Tracking stopped')
237269
thisServer.emit("adb:tracking_stop")
238270
})
@@ -245,22 +277,36 @@ export class AutoJsDebugServer extends EventEmitter {
245277
this.emit("adb:tracking_start");
246278
}
247279

248-
private async connectDevice(device: DeviceClient, id: string) {
249-
let forwarded = await device.forward(`tcp:0`, `tcp:9317`)
250-
if (forwarded) {
251-
let forwards = await device.listForwards()
252-
if (forwards.length > 0) {
253-
let forward = forwards[0]
254-
console.log(`forward ${id}: ${forwards.toString()}`)
255-
let port = Number(forward.local.replace("tcp:", ""))
256-
this.connectAutoxjsByADB(port, id)
280+
async connectDevice(id: string, device: DeviceClient = undefined) {
281+
if (!device) device = this.adbClient.getDevice(id)
282+
let wsDevice = this.getDeviceById(id)
283+
if (wsDevice && wsDevice.attached) return
284+
let forwards: Forward[] = await this.listForwards(device, id)
285+
if (forwards.length == 0) {
286+
let forwarded = await device.forward(`tcp:0`, `tcp:9317`)
287+
if (forwarded) {
288+
forwards = await this.listForwards(device, id)
257289
}
258290
}
291+
if (forwards.length > 0) {
292+
let forward = forwards[0]
293+
console.log(`forward ${id}: local -> ${forward.local}, remote -> ${forward.remote}`)
294+
let port = Number(forward.local.replace("tcp:", ""))
295+
this.connectAutoxjsByADB(port, id)
296+
}
297+
}
298+
299+
private async listForwards(device: DeviceClient, id: string): Promise<Forward[]> {
300+
let forwards: Forward[] = await device.listForwards()
301+
return forwards.filter((forward) => {
302+
return forward.serial == id && forward.remote == "tcp:9317"
303+
})
259304
}
260305

261306
stopTrackADBDevices() {
262307
if (this.tracker) {
263308
this.tracker.end()
309+
this.tracker = undefined
264310
}
265311
}
266312

@@ -314,6 +360,9 @@ export class AutoJsDebugServer extends EventEmitter {
314360
channel.dispose();
315361
});
316362
this.logChannels.clear();
363+
this.devices.forEach((device) => {
364+
device.close()
365+
})
317366
}
318367

319368
/** 获取本地IP */

src/extension.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,31 @@ class Extension {
255255
server.stopTrackADBDevices()
256256
}
257257

258+
async manuallyConnectADB() {
259+
let devices = await server.listADBDevices()
260+
let names = await Promise.all(devices.map(async (device) => {
261+
let adbDevice = server.adbClient.getDevice(device.id)
262+
let brand = await server.adbShell(adbDevice, "getprop ro.product.brand")
263+
let model = await server.adbShell(adbDevice, "getprop ro.product.model")
264+
return `${brand} ${model}: ${device.id}`
265+
}));
266+
vscode.window.showQuickPick(names)
267+
.then(name => {
268+
let device = devices[names.indexOf(name)]
269+
server.connectDevice(device.id)
270+
});
271+
}
272+
273+
manuallyDisconnect() {
274+
let devices = server.devices
275+
let names = devices.map((device) => { return device.name + ": " + device.id })
276+
vscode.window.showQuickPick(names)
277+
.then(name => {
278+
let device = devices[names.indexOf(name)]
279+
server.getDeviceById(device.id).close()
280+
});
281+
}
282+
258283
run(url?) {
259284
this.runOrRerun('run', url);
260285
}
@@ -415,13 +440,13 @@ class Extension {
415440
saveProject(url?) {
416441
this.sendProjectCommand("save_project", url);
417442
}
418-
};
443+
}
419444

420445

421446
let _context: any;
422447
let extension = new Extension();
423448
const commands = ['startAllServer', 'stopAllServer', 'startServer', 'stopServer', 'startTrackADBDevices',
424-
'stopTrackADBDevices', 'showServerAddress', 'showQrCode', 'openDocument', 'run', 'runOnDevice',
449+
'stopTrackADBDevices', 'manuallyConnectADB', 'manuallyDisconnect', 'showServerAddress', 'showQrCode', 'openDocument', 'run', 'runOnDevice',
425450
'stop', 'stopAll', 'rerun', 'save', 'saveToDevice', 'newProject', 'runProject', 'saveProject'];
426451

427452
export function activate(context: vscode.ExtensionContext) {

0 commit comments

Comments
 (0)