@@ -6,8 +6,11 @@ import * as url from 'url';
66import * as fs from 'fs'
77import { Project , ProjectObserser } from './project' ;
88import * as vscode from "vscode" ;
9- import Adb , { DeviceClient } from '@devicefarmer/adbkit' ;
9+ import Adb , { DeviceClient , Forward } from '@devicefarmer/adbkit' ;
1010import 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
1215const DEBUG = false ;
1316
@@ -22,14 +25,16 @@ const HANDSHAKE_TIMEOUT = 10 * 1000;
2225
2326export 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 {
116129export 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 */
0 commit comments