adbkit
adbkit copied to clipboard
Stuck after track command
I'm trying to use ADBKit inside an Electron app. I call trackClient and the tracker seems to work, BUT, none of the next command called on the same ADBClient object fail to work.
The only way I managed to get it working was by adding a timeout() call on one of the methods I'm trying to call. The error is caught and then suddenly the other methods run.
Here is what (doesn't) happen without the timeout:
adb:command Send '0012host:track-devices' +0ms Tracker detected ADDED device: 094c9a99 Adding tracker item Tracker detected ONLINE device: 094c9a99
Here is the logging with a timeout inserted:
adb:command Send '0012host:track-devices' +0ms Tracker detected ADDED device: 094c9a99 Adding tracker item Tracker detected ONLINE device: 094c9a99 Error receiving informations failed to fetch info on 094c9a99 Not sure what to do here adb:command Send '0017host:transport:094c9a99' +147ms adb:command Send '0017host:transport:094c9a99' +3ms adb:command Send '0022shell:pm list features 2>/dev/null' +1ms adb:command Send '000Dshell:getprop' +1ms
I must say that this worked well with NW.js although I'm not sure it's related.
Additional information. The problem seems to stem from Electron or at least Electron's version of Node.js.
I'm digging into ADBkit connection code and noticed the following:
connect: ->
console.log "test"
@socket = new Net.Socket
@socket.setNoDelay true
@parser = new Parser @socket
@socket.on 'connect', =>
console.log "Connected"
this.emit 'connect'
@socket.on 'end', =>
this.emit 'end'
@socket.on 'drain', =>
this.emit 'drain'
@socket.on 'timeout', =>
this.emit 'timeout'
@socket.on 'error', (err) =>
this._handleError err
@socket.on 'close', (hadError) =>
this.emit 'close', hadError
@socket.connect @options
return this
If I remove the first console.log statement, the connection goes through fine and I see the "Connected" console.log message. If I keep it there, the connection is never made. This code is very timing sensitive for some reasons... can't figure out why yet
This sample only ever works reliably in Electron if there is NO console.log statement in ADBKit code, which means there is a race condition somewhere. I admit the bug is probably not in ADBKit...
var adb = require("adbkit");
var util = require("util");
var Promise = require("bluebird");
try {
var Electron = require("electron");
} catch (e) {}
var main = function () {
//console.log("Creating ADB client");
adbClient = adb.createClient();
adbClient.trackDevices()
.then((tracker) => {
tracker.on("add", (device) => {
//console.log("Added: " + device.id);
Promise.join(
adbClient.getFeatures(device.id),
adbClient.getProperties(device.id),
(features, props) => {
console.log("Features: " + util.inspect(features));
console.log("Properties: " + util.inspect(props));
});
});
tracker.on("remove", (device) => {
console.log("Removed: " + device.id);
});
tracker.on("change", (device) => {
console.log("Changed: " + device.id);
});
tracker.on("error", (err) => {
console.log("Error: " + err);
});
});
};
if (Electron)
Electron.app.on("ready", main);
else
main();