first commit

This commit is contained in:
2026-09-08 20:28:54 +08:00
commit 2ada8d3d5a
37380 changed files with 4886169 additions and 0 deletions
+78
View File
@@ -0,0 +1,78 @@
var Auth, BigInteger, Promise, forge;
Promise = require('bluebird');
forge = require('node-forge');
BigInteger = forge.jsbn.BigInteger;
/*
The stucture of an ADB RSAPublicKey is as follows:
#define RSANUMBYTES 256 // 2048 bit key length
#define RSANUMWORDS (RSANUMBYTES / sizeof(uint32_t))
typedef struct RSAPublicKey {
int len; // Length of n[] in number of uint32_t
uint32_t n0inv; // -1 / n[0] mod 2^32
uint32_t n[RSANUMWORDS]; // modulus as little endian array
uint32_t rr[RSANUMWORDS]; // R^2 as little endian array
int exponent; // 3 or 65537
} RSAPublicKey;
*/
Auth = (function() {
var RE, readPublicKeyFromStruct;
function Auth() {}
RE = /^((?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?)\0?( .*|)\s*$/;
readPublicKeyFromStruct = function(struct, comment) {
var e, key, len, md, n, offset;
if (!struct.length) {
throw new Error("Invalid public key");
}
offset = 0;
len = struct.readUInt32LE(offset) * 4;
offset += 4;
if (struct.length !== 4 + 4 + len + len + 4) {
throw new Error("Invalid public key");
}
offset += 4;
n = new Buffer(len);
struct.copy(n, 0, offset, offset + len);
[].reverse.call(n);
offset += len;
offset += len;
e = struct.readUInt32LE(offset);
if (!(e === 3 || e === 65537)) {
throw new Error("Invalid exponent " + e + ", only 3 and 65537 are supported");
}
key = forge.pki.setRsaPublicKey(new BigInteger(n.toString('hex'), 16), new BigInteger(e.toString(), 10));
md = forge.md.md5.create();
md.update(struct.toString('binary'));
key.fingerprint = md.digest().toHex().match(/../g).join(':');
key.comment = comment;
return key;
};
Auth.parsePublicKey = function(buffer) {
return new Promise(function(resolve, reject) {
var comment, match, struct;
if (match = RE.exec(buffer)) {
struct = new Buffer(match[1], 'base64');
comment = match[2].trim();
return resolve(readPublicKeyFromStruct(struct, comment));
} else {
return reject(new Error("Unrecognizable public key format"));
}
});
};
return Auth;
})();
module.exports = Auth;
+573
View File
@@ -0,0 +1,573 @@
var ClearCommand, Client, Connection, ForwardCommand, FrameBufferCommand, GetDevicePathCommand, GetFeaturesCommand, GetPackagesCommand, GetPropertiesCommand, GetSerialNoCommand, GetStateCommand, HostConnectCommand, HostDevicesCommand, HostDevicesWithPathsCommand, HostDisconnectCommand, HostKillCommand, HostTrackDevicesCommand, HostTransportCommand, HostVersionCommand, InstallCommand, IsInstalledCommand, ListForwardsCommand, ListReversesCommand, LocalCommand, LogCommand, Logcat, LogcatCommand, Monkey, MonkeyCommand, Parser, ProcStat, Promise, RebootCommand, RemountCommand, ReverseCommand, RootCommand, ScreencapCommand, ShellCommand, StartActivityCommand, StartServiceCommand, Sync, SyncCommand, TcpCommand, TcpIpCommand, TcpUsbServer, TrackJdwpCommand, UninstallCommand, UsbCommand, WaitBootCompleteCommand, WaitForDeviceCommand, debug;
Monkey = require('adbkit-monkey');
Logcat = require('adbkit-logcat');
Promise = require('bluebird');
debug = require('debug')('adb:client');
Connection = require('./connection');
Sync = require('./sync');
Parser = require('./parser');
ProcStat = require('./proc/stat');
HostVersionCommand = require('./command/host/version');
HostConnectCommand = require('./command/host/connect');
HostDevicesCommand = require('./command/host/devices');
HostDevicesWithPathsCommand = require('./command/host/deviceswithpaths');
HostDisconnectCommand = require('./command/host/disconnect');
HostTrackDevicesCommand = require('./command/host/trackdevices');
HostKillCommand = require('./command/host/kill');
HostTransportCommand = require('./command/host/transport');
ClearCommand = require('./command/host-transport/clear');
FrameBufferCommand = require('./command/host-transport/framebuffer');
GetFeaturesCommand = require('./command/host-transport/getfeatures');
GetPackagesCommand = require('./command/host-transport/getpackages');
GetPropertiesCommand = require('./command/host-transport/getproperties');
InstallCommand = require('./command/host-transport/install');
IsInstalledCommand = require('./command/host-transport/isinstalled');
ListReversesCommand = require('./command/host-transport/listreverses');
LocalCommand = require('./command/host-transport/local');
LogcatCommand = require('./command/host-transport/logcat');
LogCommand = require('./command/host-transport/log');
MonkeyCommand = require('./command/host-transport/monkey');
RebootCommand = require('./command/host-transport/reboot');
RemountCommand = require('./command/host-transport/remount');
RootCommand = require('./command/host-transport/root');
ReverseCommand = require('./command/host-transport/reverse');
ScreencapCommand = require('./command/host-transport/screencap');
ShellCommand = require('./command/host-transport/shell');
StartActivityCommand = require('./command/host-transport/startactivity');
StartServiceCommand = require('./command/host-transport/startservice');
SyncCommand = require('./command/host-transport/sync');
TcpCommand = require('./command/host-transport/tcp');
TcpIpCommand = require('./command/host-transport/tcpip');
TrackJdwpCommand = require('./command/host-transport/trackjdwp');
UninstallCommand = require('./command/host-transport/uninstall');
UsbCommand = require('./command/host-transport/usb');
WaitBootCompleteCommand = require('./command/host-transport/waitbootcomplete');
ForwardCommand = require('./command/host-serial/forward');
GetDevicePathCommand = require('./command/host-serial/getdevicepath');
GetSerialNoCommand = require('./command/host-serial/getserialno');
GetStateCommand = require('./command/host-serial/getstate');
ListForwardsCommand = require('./command/host-serial/listforwards');
WaitForDeviceCommand = require('./command/host-serial/waitfordevice');
TcpUsbServer = require('./tcpusb/server');
Client = (function() {
var NoUserOptionError;
function Client(options1) {
var base, base1;
this.options = options1 != null ? options1 : {};
(base = this.options).port || (base.port = 5037);
(base1 = this.options).bin || (base1.bin = 'adb');
}
Client.prototype.createTcpUsbBridge = function(serial, options) {
return new TcpUsbServer(this, serial, options);
};
Client.prototype.connection = function() {
var conn, connectListener, errorListener, resolver;
resolver = Promise.defer();
conn = new Connection(this.options).on('error', errorListener = function(err) {
return resolver.reject(err);
}).on('connect', connectListener = function() {
return resolver.resolve(conn);
}).connect();
return resolver.promise["finally"](function() {
conn.removeListener('error', errorListener);
return conn.removeListener('connect', connectListener);
});
};
Client.prototype.version = function(callback) {
return this.connection().then(function(conn) {
return new HostVersionCommand(conn).execute();
}).nodeify(callback);
};
Client.prototype.connect = function(host, port, callback) {
var ref;
if (port == null) {
port = 5555;
}
if (typeof port === 'function') {
callback = port;
port = 5555;
}
if (host.indexOf(':') !== -1) {
ref = host.split(':', 2), host = ref[0], port = ref[1];
}
return this.connection().then(function(conn) {
return new HostConnectCommand(conn).execute(host, port);
}).nodeify(callback);
};
Client.prototype.disconnect = function(host, port, callback) {
var ref;
if (port == null) {
port = 5555;
}
if (typeof port === 'function') {
callback = port;
port = 5555;
}
if (host.indexOf(':') !== -1) {
ref = host.split(':', 2), host = ref[0], port = ref[1];
}
return this.connection().then(function(conn) {
return new HostDisconnectCommand(conn).execute(host, port);
}).nodeify(callback);
};
Client.prototype.listDevices = function(callback) {
return this.connection().then(function(conn) {
return new HostDevicesCommand(conn).execute();
}).nodeify(callback);
};
Client.prototype.listDevicesWithPaths = function(callback) {
return this.connection().then(function(conn) {
return new HostDevicesWithPathsCommand(conn).execute();
}).nodeify(callback);
};
Client.prototype.trackDevices = function(callback) {
return this.connection().then(function(conn) {
return new HostTrackDevicesCommand(conn).execute();
}).nodeify(callback);
};
Client.prototype.kill = function(callback) {
return this.connection().then(function(conn) {
return new HostKillCommand(conn).execute();
}).nodeify(callback);
};
Client.prototype.getSerialNo = function(serial, callback) {
return this.connection().then(function(conn) {
return new GetSerialNoCommand(conn).execute(serial);
}).nodeify(callback);
};
Client.prototype.getDevicePath = function(serial, callback) {
return this.connection().then(function(conn) {
return new GetDevicePathCommand(conn).execute(serial);
}).nodeify(callback);
};
Client.prototype.getState = function(serial, callback) {
return this.connection().then(function(conn) {
return new GetStateCommand(conn).execute(serial);
}).nodeify(callback);
};
Client.prototype.getProperties = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new GetPropertiesCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.getFeatures = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new GetFeaturesCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.getPackages = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new GetPackagesCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.getDHCPIpAddress = function(serial, iface, callback) {
if (iface == null) {
iface = 'wlan0';
}
if (typeof iface === 'function') {
callback = iface;
iface = 'wlan0';
}
return this.getProperties(serial).then(function(properties) {
var ip;
if (ip = properties["dhcp." + iface + ".ipaddress"]) {
return ip;
}
throw new Error("Unable to find ipaddress for '" + iface + "'");
});
};
Client.prototype.forward = function(serial, local, remote, callback) {
return this.connection().then(function(conn) {
return new ForwardCommand(conn).execute(serial, local, remote);
}).nodeify(callback);
};
Client.prototype.listForwards = function(serial, callback) {
return this.connection().then(function(conn) {
return new ListForwardsCommand(conn).execute(serial);
}).nodeify(callback);
};
Client.prototype.reverse = function(serial, remote, local, callback) {
return this.transport(serial).then(function(transport) {
return new ReverseCommand(transport).execute(remote, local).nodeify(callback);
});
};
Client.prototype.listReverses = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new ListReversesCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.transport = function(serial, callback) {
return this.connection().then(function(conn) {
return new HostTransportCommand(conn).execute(serial)["return"](conn);
}).nodeify(callback);
};
Client.prototype.shell = function(serial, command, callback) {
return this.transport(serial).then(function(transport) {
return new ShellCommand(transport).execute(command);
}).nodeify(callback);
};
Client.prototype.reboot = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new RebootCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.remount = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new RemountCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.root = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new RootCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.trackJdwp = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new TrackJdwpCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.framebuffer = function(serial, format, callback) {
if (format == null) {
format = 'raw';
}
if (typeof format === 'function') {
callback = format;
format = 'raw';
}
return this.transport(serial).then(function(transport) {
return new FrameBufferCommand(transport).execute(format);
}).nodeify(callback);
};
Client.prototype.screencap = function(serial, callback) {
return this.transport(serial).then((function(_this) {
return function(transport) {
return new ScreencapCommand(transport).execute()["catch"](function(err) {
debug("Emulating screencap command due to '" + err + "'");
return _this.framebuffer(serial, 'png');
});
};
})(this)).nodeify(callback);
};
Client.prototype.openLocal = function(serial, path, callback) {
return this.transport(serial).then(function(transport) {
return new LocalCommand(transport).execute(path);
}).nodeify(callback);
};
Client.prototype.openLog = function(serial, name, callback) {
return this.transport(serial).then(function(transport) {
return new LogCommand(transport).execute(name);
}).nodeify(callback);
};
Client.prototype.openTcp = function(serial, port, host, callback) {
if (typeof host === 'function') {
callback = host;
host = void 0;
}
return this.transport(serial).then(function(transport) {
return new TcpCommand(transport).execute(port, host);
}).nodeify(callback);
};
Client.prototype.openMonkey = function(serial, port, callback) {
var tryConnect;
if (port == null) {
port = 1080;
}
if (typeof port === 'function') {
callback = port;
port = 1080;
}
tryConnect = (function(_this) {
return function(times) {
return _this.openTcp(serial, port).then(function(stream) {
return Monkey.connectStream(stream);
})["catch"](function(err) {
if (times -= 1) {
debug("Monkey can't be reached, trying " + times + " more times");
return Promise.delay(100).then(function() {
return tryConnect(times);
});
} else {
throw err;
}
});
};
})(this);
return tryConnect(1)["catch"]((function(_this) {
return function(err) {
return _this.transport(serial).then(function(transport) {
return new MonkeyCommand(transport).execute(port);
}).then(function(out) {
return tryConnect(20).then(function(monkey) {
return monkey.once('end', function() {
return out.end();
});
});
});
};
})(this)).nodeify(callback);
};
Client.prototype.openLogcat = function(serial, options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
return this.transport(serial).then(function(transport) {
return new LogcatCommand(transport).execute(options);
}).then(function(stream) {
return Logcat.readStream(stream, {
fixLineFeeds: false
});
}).nodeify(callback);
};
Client.prototype.openProcStat = function(serial, callback) {
return this.syncService(serial).then(function(sync) {
return new ProcStat(sync);
}).nodeify(callback);
};
Client.prototype.clear = function(serial, pkg, callback) {
return this.transport(serial).then(function(transport) {
return new ClearCommand(transport).execute(pkg);
}).nodeify(callback);
};
Client.prototype.install = function(serial, apk, callback) {
var temp;
temp = Sync.temp(typeof apk === 'string' ? apk : '_stream.apk');
return this.push(serial, apk, temp).then((function(_this) {
return function(transfer) {
var endListener, errorListener, resolver;
resolver = Promise.defer();
transfer.on('error', errorListener = function(err) {
return resolver.reject(err);
});
transfer.on('end', endListener = function() {
return resolver.resolve(_this.installRemote(serial, temp));
});
return resolver.promise["finally"](function() {
transfer.removeListener('error', errorListener);
return transfer.removeListener('end', endListener);
});
};
})(this)).nodeify(callback);
};
Client.prototype.installRemote = function(serial, apk, callback) {
return this.transport(serial).then((function(_this) {
return function(transport) {
return new InstallCommand(transport).execute(apk).then(function() {
return _this.shell(serial, ['rm', '-f', apk]);
}).then(function(stream) {
return new Parser(stream).readAll();
}).then(function(out) {
return true;
});
};
})(this)).nodeify(callback);
};
Client.prototype.uninstall = function(serial, pkg, callback) {
return this.transport(serial).then(function(transport) {
return new UninstallCommand(transport).execute(pkg);
}).nodeify(callback);
};
Client.prototype.isInstalled = function(serial, pkg, callback) {
return this.transport(serial).then(function(transport) {
return new IsInstalledCommand(transport).execute(pkg);
}).nodeify(callback);
};
Client.prototype.startActivity = function(serial, options, callback) {
return this.transport(serial).then(function(transport) {
return new StartActivityCommand(transport).execute(options);
})["catch"](NoUserOptionError, (function(_this) {
return function() {
options.user = null;
return _this.startActivity(serial, options);
};
})(this)).nodeify(callback);
};
Client.prototype.startService = function(serial, options, callback) {
return this.transport(serial).then(function(transport) {
if (!(options.user || options.user === null)) {
options.user = 0;
}
return new StartServiceCommand(transport).execute(options);
})["catch"](NoUserOptionError, (function(_this) {
return function() {
options.user = null;
return _this.startService(serial, options);
};
})(this)).nodeify(callback);
};
Client.prototype.syncService = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new SyncCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.stat = function(serial, path, callback) {
return this.syncService(serial).then(function(sync) {
return sync.stat(path)["finally"](function() {
return sync.end();
});
}).nodeify(callback);
};
Client.prototype.readdir = function(serial, path, callback) {
return this.syncService(serial).then(function(sync) {
return sync.readdir(path)["finally"](function() {
return sync.end();
});
}).nodeify(callback);
};
Client.prototype.pull = function(serial, path, callback) {
return this.syncService(serial).then(function(sync) {
return sync.pull(path).on('end', function() {
return sync.end();
});
}).nodeify(callback);
};
Client.prototype.push = function(serial, contents, path, mode, callback) {
if (typeof mode === 'function') {
callback = mode;
mode = void 0;
}
return this.syncService(serial).then(function(sync) {
return sync.push(contents, path, mode).on('end', function() {
return sync.end();
});
}).nodeify(callback);
};
Client.prototype.tcpip = function(serial, port, callback) {
if (port == null) {
port = 5555;
}
if (typeof port === 'function') {
callback = port;
port = 5555;
}
return this.transport(serial).then(function(transport) {
return new TcpIpCommand(transport).execute(port);
}).nodeify(callback);
};
Client.prototype.usb = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new UsbCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.waitBootComplete = function(serial, callback) {
return this.transport(serial).then(function(transport) {
return new WaitBootCompleteCommand(transport).execute();
}).nodeify(callback);
};
Client.prototype.waitForDevice = function(serial, callback) {
return this.connection().then(function(conn) {
return new WaitForDeviceCommand(conn).execute(serial);
}).nodeify(callback);
};
NoUserOptionError = function(err) {
return err.message.indexOf('--user') !== -1;
};
return Client;
})();
module.exports = Client;
+56
View File
@@ -0,0 +1,56 @@
var Command, Parser, Protocol, debug;
debug = require('debug')('adb:command');
Parser = require('./parser');
Protocol = require('./protocol');
Command = (function() {
var RE_ESCAPE, RE_SQUOT;
RE_SQUOT = /'/g;
RE_ESCAPE = /([$`\\!"])/g;
function Command(connection) {
this.connection = connection;
this.parser = this.connection.parser;
this.protocol = Protocol;
}
Command.prototype.execute = function() {
throw new Exception('Missing implementation');
};
Command.prototype._send = function(data) {
var encoded;
encoded = Protocol.encodeData(data);
debug("Send '" + encoded + "'");
this.connection.write(encoded);
return this;
};
Command.prototype._escape = function(arg) {
switch (typeof arg) {
case 'number':
return arg;
default:
return "'" + arg.toString().replace(RE_SQUOT, "'\"'\"'") + "'";
}
};
Command.prototype._escapeCompat = function(arg) {
switch (typeof arg) {
case 'number':
return arg;
default:
return '"' + arg.toString().replace(RE_ESCAPE, '\\$1') + '"';
}
};
return Command;
})();
module.exports = Command;
+45
View File
@@ -0,0 +1,45 @@
var Command, ForwardCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
ForwardCommand = (function(superClass) {
extend(ForwardCommand, superClass);
function ForwardCommand() {
return ForwardCommand.__super__.constructor.apply(this, arguments);
}
ForwardCommand.prototype.execute = function(serial, local, remote) {
this._send("host-serial:" + serial + ":forward:" + local + ";" + remote);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAscii(4).then(function(reply) {
switch (reply) {
case Protocol.OKAY:
return true;
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return ForwardCommand;
})(Command);
module.exports = ForwardCommand;
+38
View File
@@ -0,0 +1,38 @@
var Command, GetDevicePathCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
GetDevicePathCommand = (function(superClass) {
extend(GetDevicePathCommand, superClass);
function GetDevicePathCommand() {
return GetDevicePathCommand.__super__.constructor.apply(this, arguments);
}
GetDevicePathCommand.prototype.execute = function(serial) {
this._send("host-serial:" + serial + ":get-devpath");
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readValue().then(function(value) {
return value.toString();
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return GetDevicePathCommand;
})(Command);
module.exports = GetDevicePathCommand;
+38
View File
@@ -0,0 +1,38 @@
var Command, GetSerialNoCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
GetSerialNoCommand = (function(superClass) {
extend(GetSerialNoCommand, superClass);
function GetSerialNoCommand() {
return GetSerialNoCommand.__super__.constructor.apply(this, arguments);
}
GetSerialNoCommand.prototype.execute = function(serial) {
this._send("host-serial:" + serial + ":get-serialno");
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readValue().then(function(value) {
return value.toString();
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return GetSerialNoCommand;
})(Command);
module.exports = GetSerialNoCommand;
+38
View File
@@ -0,0 +1,38 @@
var Command, GetStateCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
GetStateCommand = (function(superClass) {
extend(GetStateCommand, superClass);
function GetStateCommand() {
return GetStateCommand.__super__.constructor.apply(this, arguments);
}
GetStateCommand.prototype.execute = function(serial) {
this._send("host-serial:" + serial + ":get-state");
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readValue().then(function(value) {
return value.toString();
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return GetStateCommand;
})(Command);
module.exports = GetStateCommand;
+56
View File
@@ -0,0 +1,56 @@
var Command, ListForwardsCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
ListForwardsCommand = (function(superClass) {
extend(ListForwardsCommand, superClass);
function ListForwardsCommand() {
return ListForwardsCommand.__super__.constructor.apply(this, arguments);
}
ListForwardsCommand.prototype.execute = function(serial) {
this._send("host-serial:" + serial + ":list-forward");
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readValue().then(function(value) {
return _this._parseForwards(value);
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
ListForwardsCommand.prototype._parseForwards = function(value) {
var forward, forwards, i, len, local, ref, ref1, remote, serial;
forwards = [];
ref = value.toString().split('\n');
for (i = 0, len = ref.length; i < len; i++) {
forward = ref[i];
if (forward) {
ref1 = forward.split(/\s+/), serial = ref1[0], local = ref1[1], remote = ref1[2];
forwards.push({
serial: serial,
local: local,
remote: remote
});
}
}
return forwards;
};
return ListForwardsCommand;
})(Command);
module.exports = ListForwardsCommand;
+45
View File
@@ -0,0 +1,45 @@
var Command, Protocol, WaitForDeviceCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
WaitForDeviceCommand = (function(superClass) {
extend(WaitForDeviceCommand, superClass);
function WaitForDeviceCommand() {
return WaitForDeviceCommand.__super__.constructor.apply(this, arguments);
}
WaitForDeviceCommand.prototype.execute = function(serial) {
this._send("host-serial:" + serial + ":wait-for-any");
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAscii(4).then(function(reply) {
switch (reply) {
case Protocol.OKAY:
return serial;
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return WaitForDeviceCommand;
})(Command);
module.exports = WaitForDeviceCommand;
+45
View File
@@ -0,0 +1,45 @@
var ClearCommand, Command, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
ClearCommand = (function(superClass) {
extend(ClearCommand, superClass);
function ClearCommand() {
return ClearCommand.__super__.constructor.apply(this, arguments);
}
ClearCommand.prototype.execute = function(pkg) {
this._send("shell:pm clear " + pkg);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.searchLine(/^(Success|Failed)$/)["finally"](function() {
return _this.parser.end();
}).then(function(result) {
switch (result[0]) {
case 'Success':
return true;
case 'Failed':
throw new Error("Package '" + pkg + "' could not be cleared");
}
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return ClearCommand;
})(Command);
module.exports = ClearCommand;
+114
View File
@@ -0,0 +1,114 @@
var Assert, Command, FrameBufferCommand, Protocol, RgbTransform, debug, spawn,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Assert = require('assert');
spawn = require('child_process').spawn;
debug = require('debug')('adb:command:framebuffer');
Command = require('../../command');
Protocol = require('../../protocol');
RgbTransform = require('../../framebuffer/rgbtransform');
FrameBufferCommand = (function(superClass) {
extend(FrameBufferCommand, superClass);
function FrameBufferCommand() {
return FrameBufferCommand.__super__.constructor.apply(this, arguments);
}
FrameBufferCommand.prototype.execute = function(format) {
this._send('framebuffer:');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readBytes(52).then(function(header) {
var meta, stream;
meta = _this._parseHeader(header);
switch (format) {
case 'raw':
stream = _this.parser.raw();
stream.meta = meta;
return stream;
default:
stream = _this._convert(meta, format);
stream.meta = meta;
return stream;
}
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
FrameBufferCommand.prototype._convert = function(meta, format, raw) {
var proc, transform;
debug("Converting raw framebuffer stream into " + (format.toUpperCase()));
switch (meta.format) {
case 'rgb':
case 'rgba':
break;
default:
debug("Silently transforming '" + meta.format + "' into 'rgb' for `gm`");
transform = new RgbTransform(meta);
meta.format = 'rgb';
raw = this.parser.raw().pipe(transform);
}
proc = spawn('gm', ['convert', '-size', meta.width + "x" + meta.height, meta.format + ":-", format + ":-"]);
raw.pipe(proc.stdin);
return proc.stdout;
};
FrameBufferCommand.prototype._parseHeader = function(header) {
var meta, offset;
meta = {};
offset = 0;
meta.version = header.readUInt32LE(offset);
if (meta.version === 16) {
throw new Error('Old-style raw images are not supported');
}
offset += 4;
meta.bpp = header.readUInt32LE(offset);
offset += 4;
meta.size = header.readUInt32LE(offset);
offset += 4;
meta.width = header.readUInt32LE(offset);
offset += 4;
meta.height = header.readUInt32LE(offset);
offset += 4;
meta.red_offset = header.readUInt32LE(offset);
offset += 4;
meta.red_length = header.readUInt32LE(offset);
offset += 4;
meta.blue_offset = header.readUInt32LE(offset);
offset += 4;
meta.blue_length = header.readUInt32LE(offset);
offset += 4;
meta.green_offset = header.readUInt32LE(offset);
offset += 4;
meta.green_length = header.readUInt32LE(offset);
offset += 4;
meta.alpha_offset = header.readUInt32LE(offset);
offset += 4;
meta.alpha_length = header.readUInt32LE(offset);
meta.format = meta.blue_offset === 0 ? 'bgr' : 'rgb';
if (meta.bpp === 32 || meta.alpha_length) {
meta.format += 'a';
}
return meta;
};
return FrameBufferCommand;
})(Command);
module.exports = FrameBufferCommand;
+51
View File
@@ -0,0 +1,51 @@
var Command, GetFeaturesCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
GetFeaturesCommand = (function(superClass) {
var RE_FEATURE;
extend(GetFeaturesCommand, superClass);
function GetFeaturesCommand() {
return GetFeaturesCommand.__super__.constructor.apply(this, arguments);
}
RE_FEATURE = /^feature:(.*?)(?:=(.*?))?\r?$/gm;
GetFeaturesCommand.prototype.execute = function() {
this._send('shell:pm list features 2>/dev/null');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAll().then(function(data) {
return _this._parseFeatures(data.toString());
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
GetFeaturesCommand.prototype._parseFeatures = function(value) {
var features, match;
features = {};
while (match = RE_FEATURE.exec(value)) {
features[match[1]] = match[2] || true;
}
return features;
};
return GetFeaturesCommand;
})(Command);
module.exports = GetFeaturesCommand;
+51
View File
@@ -0,0 +1,51 @@
var Command, GetPackagesCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
GetPackagesCommand = (function(superClass) {
var RE_PACKAGE;
extend(GetPackagesCommand, superClass);
function GetPackagesCommand() {
return GetPackagesCommand.__super__.constructor.apply(this, arguments);
}
RE_PACKAGE = /^package:(.*?)\r?$/gm;
GetPackagesCommand.prototype.execute = function() {
this._send('shell:pm list packages 2>/dev/null');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAll().then(function(data) {
return _this._parsePackages(data.toString());
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
GetPackagesCommand.prototype._parsePackages = function(value) {
var features, match;
features = [];
while (match = RE_PACKAGE.exec(value)) {
features.push(match[1]);
}
return features;
};
return GetPackagesCommand;
})(Command);
module.exports = GetPackagesCommand;
+51
View File
@@ -0,0 +1,51 @@
var Command, GetPropertiesCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
GetPropertiesCommand = (function(superClass) {
var RE_KEYVAL;
extend(GetPropertiesCommand, superClass);
function GetPropertiesCommand() {
return GetPropertiesCommand.__super__.constructor.apply(this, arguments);
}
RE_KEYVAL = /^\[([\s\S]*?)\]: \[([\s\S]*?)\]\r?$/gm;
GetPropertiesCommand.prototype.execute = function() {
this._send('shell:getprop');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAll().then(function(data) {
return _this._parseProperties(data.toString());
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
GetPropertiesCommand.prototype._parseProperties = function(value) {
var match, properties;
properties = {};
while (match = RE_KEYVAL.exec(value)) {
properties[match[1]] = match[2];
}
return properties;
};
return GetPropertiesCommand;
})(Command);
module.exports = GetPropertiesCommand;
+48
View File
@@ -0,0 +1,48 @@
var Command, InstallCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
InstallCommand = (function(superClass) {
extend(InstallCommand, superClass);
function InstallCommand() {
return InstallCommand.__super__.constructor.apply(this, arguments);
}
InstallCommand.prototype.execute = function(apk) {
this._send("shell:pm install -r " + (this._escapeCompat(apk)));
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.searchLine(/^(Success|Failure \[(.*?)\])$/).then(function(match) {
var code, err;
if (match[1] === 'Success') {
return true;
} else {
code = match[2];
err = new Error(apk + " could not be installed [" + code + "]");
err.code = code;
throw err;
}
})["finally"](function() {
return _this.parser.readAll();
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return InstallCommand;
})(Command);
module.exports = InstallCommand;
+47
View File
@@ -0,0 +1,47 @@
var Command, IsInstalledCommand, Parser, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
Parser = require('../../parser');
IsInstalledCommand = (function(superClass) {
extend(IsInstalledCommand, superClass);
function IsInstalledCommand() {
return IsInstalledCommand.__super__.constructor.apply(this, arguments);
}
IsInstalledCommand.prototype.execute = function(pkg) {
this._send("shell:pm path " + pkg + " 2>/dev/null");
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAscii(8).then(function(reply) {
switch (reply) {
case 'package:':
return true;
default:
return _this.parser.unexpected(reply, "'package:'");
}
})["catch"](Parser.PrematureEOFError, function(err) {
return false;
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return IsInstalledCommand;
})(Command);
module.exports = IsInstalledCommand;
+55
View File
@@ -0,0 +1,55 @@
var Command, ListReversesCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
ListReversesCommand = (function(superClass) {
extend(ListReversesCommand, superClass);
function ListReversesCommand() {
return ListReversesCommand.__super__.constructor.apply(this, arguments);
}
ListReversesCommand.prototype.execute = function() {
this._send("reverse:list-forward");
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readValue().then(function(value) {
return _this._parseReverses(value);
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
ListReversesCommand.prototype._parseReverses = function(value) {
var i, len, local, ref, ref1, remote, reverse, reverses, serial;
reverses = [];
ref = value.toString().split('\n');
for (i = 0, len = ref.length; i < len; i++) {
reverse = ref[i];
if (reverse) {
ref1 = reverse.split(/\s+/), serial = ref1[0], remote = ref1[1], local = ref1[2];
reverses.push({
remote: remote,
local: local
});
}
}
return reverses;
};
return ListReversesCommand;
})(Command);
module.exports = ListReversesCommand;
+36
View File
@@ -0,0 +1,36 @@
var Command, LocalCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
LocalCommand = (function(superClass) {
extend(LocalCommand, superClass);
function LocalCommand() {
return LocalCommand.__super__.constructor.apply(this, arguments);
}
LocalCommand.prototype.execute = function(path) {
this._send(/:/.test(path) ? path : "localfilesystem:" + path);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.raw();
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return LocalCommand;
})(Command);
module.exports = LocalCommand;
+36
View File
@@ -0,0 +1,36 @@
var Command, LogCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
LogCommand = (function(superClass) {
extend(LogCommand, superClass);
function LogCommand() {
return LogCommand.__super__.constructor.apply(this, arguments);
}
LogCommand.prototype.execute = function(name) {
this._send("log:" + name);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.raw();
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return LogCommand;
})(Command);
module.exports = LogCommand;
+48
View File
@@ -0,0 +1,48 @@
var Command, LineTransform, LogcatCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
LineTransform = require('../../linetransform');
LogcatCommand = (function(superClass) {
extend(LogcatCommand, superClass);
function LogcatCommand() {
return LogcatCommand.__super__.constructor.apply(this, arguments);
}
LogcatCommand.prototype.execute = function(options) {
var cmd;
if (options == null) {
options = {};
}
cmd = 'logcat -B *:I 2>/dev/null';
if (options.clear) {
cmd = "logcat -c 2>/dev/null && " + cmd;
}
this._send("shell:echo && " + cmd);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.raw().pipe(new LineTransform({
autoDetect: true
}));
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return LogcatCommand;
})(Command);
module.exports = LogcatCommand;
+42
View File
@@ -0,0 +1,42 @@
var Command, MonkeyCommand, Promise, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Promise = require('bluebird');
Command = require('../../command');
Protocol = require('../../protocol');
MonkeyCommand = (function(superClass) {
extend(MonkeyCommand, superClass);
function MonkeyCommand() {
return MonkeyCommand.__super__.constructor.apply(this, arguments);
}
MonkeyCommand.prototype.execute = function(port) {
this._send("shell:EXTERNAL_STORAGE=/data/local/tmp monkey --port " + port + " -v");
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.searchLine(/^:Monkey:/).timeout(1000).then(function() {
return _this.parser.raw();
})["catch"](Promise.TimeoutError, function(err) {
return _this.parser.raw();
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return MonkeyCommand;
})(Command);
module.exports = MonkeyCommand;
+36
View File
@@ -0,0 +1,36 @@
var Command, Protocol, RebootCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
RebootCommand = (function(superClass) {
extend(RebootCommand, superClass);
function RebootCommand() {
return RebootCommand.__super__.constructor.apply(this, arguments);
}
RebootCommand.prototype.execute = function() {
this._send('reboot:');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAll()["return"](true);
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return RebootCommand;
})(Command);
module.exports = RebootCommand;
+36
View File
@@ -0,0 +1,36 @@
var Command, Protocol, RemountCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
RemountCommand = (function(superClass) {
extend(RemountCommand, superClass);
function RemountCommand() {
return RemountCommand.__super__.constructor.apply(this, arguments);
}
RemountCommand.prototype.execute = function() {
this._send('remount:');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return true;
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return RemountCommand;
})(Command);
module.exports = RemountCommand;
+45
View File
@@ -0,0 +1,45 @@
var Command, Protocol, ReverseCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
ReverseCommand = (function(superClass) {
extend(ReverseCommand, superClass);
function ReverseCommand() {
return ReverseCommand.__super__.constructor.apply(this, arguments);
}
ReverseCommand.prototype.execute = function(remote, local) {
this._send("reverse:forward:" + remote + ";" + local);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAscii(4).then(function(reply) {
switch (reply) {
case Protocol.OKAY:
return true;
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return ReverseCommand;
})(Command);
module.exports = ReverseCommand;
+46
View File
@@ -0,0 +1,46 @@
var Command, Protocol, RootCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
RootCommand = (function(superClass) {
var RE_OK;
extend(RootCommand, superClass);
function RootCommand() {
return RootCommand.__super__.constructor.apply(this, arguments);
}
RE_OK = /restarting adbd as root/;
RootCommand.prototype.execute = function() {
this._send('root:');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAll().then(function(value) {
if (RE_OK.test(value)) {
return true;
} else {
throw new Error(value.toString().trim());
}
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return RootCommand;
})(Command);
module.exports = RootCommand;
+52
View File
@@ -0,0 +1,52 @@
var Command, LineTransform, Parser, Promise, Protocol, ScreencapCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Promise = require('bluebird');
Command = require('../../command');
Protocol = require('../../protocol');
Parser = require('../../parser');
LineTransform = require('../../linetransform');
ScreencapCommand = (function(superClass) {
extend(ScreencapCommand, superClass);
function ScreencapCommand() {
return ScreencapCommand.__super__.constructor.apply(this, arguments);
}
ScreencapCommand.prototype.execute = function() {
this._send('shell:echo && screencap -p 2>/dev/null');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
var transform;
switch (reply) {
case Protocol.OKAY:
transform = new LineTransform;
return _this.parser.readBytes(1).then(function(chunk) {
transform = new LineTransform({
autoDetect: true
});
transform.write(chunk);
return _this.parser.raw().pipe(transform);
})["catch"](Parser.PrematureEOFError, function() {
throw new Error('No support for the screencap command');
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return ScreencapCommand;
})(Command);
module.exports = ScreencapCommand;
+39
View File
@@ -0,0 +1,39 @@
var Command, Protocol, ShellCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
ShellCommand = (function(superClass) {
extend(ShellCommand, superClass);
function ShellCommand() {
return ShellCommand.__super__.constructor.apply(this, arguments);
}
ShellCommand.prototype.execute = function(command) {
if (Array.isArray(command)) {
command = command.map(this._escape).join(' ');
}
this._send("shell:" + command);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.raw();
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return ShellCommand;
})(Command);
module.exports = ShellCommand;
+184
View File
@@ -0,0 +1,184 @@
var Command, Parser, Protocol, StartActivityCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
Parser = require('../../parser');
StartActivityCommand = (function(superClass) {
var EXTRA_TYPES, RE_ERROR;
extend(StartActivityCommand, superClass);
function StartActivityCommand() {
return StartActivityCommand.__super__.constructor.apply(this, arguments);
}
RE_ERROR = /^Error: (.*)$/;
EXTRA_TYPES = {
string: 's',
"null": 'sn',
bool: 'z',
int: 'i',
long: 'l',
float: 'l',
uri: 'u',
component: 'cn'
};
StartActivityCommand.prototype.execute = function(options) {
var args;
args = this._intentArgs(options);
if (options.debug) {
args.push('-D');
}
if (options.wait) {
args.push('-W');
}
if (options.user || options.user === 0) {
args.push('--user', this._escape(options.user));
}
return this._run('start', args);
};
StartActivityCommand.prototype._run = function(command, args) {
this._send("shell:am " + command + " " + (args.join(' ')));
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.searchLine(RE_ERROR)["finally"](function() {
return _this.parser.end();
}).then(function(match) {
throw new Error(match[1]);
})["catch"](Parser.PrematureEOFError, function(err) {
return true;
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
StartActivityCommand.prototype._intentArgs = function(options) {
var args;
args = [];
if (options.extras) {
args.push.apply(args, this._formatExtras(options.extras));
}
if (options.action) {
args.push('-a', this._escape(options.action));
}
if (options.data) {
args.push('-d', this._escape(options.data));
}
if (options.mimeType) {
args.push('-t', this._escape(options.mimeType));
}
if (options.category) {
if (Array.isArray(options.category)) {
options.category.forEach((function(_this) {
return function(category) {
return args.push('-c', _this._escape(category));
};
})(this));
} else {
args.push('-c', this._escape(options.category));
}
}
if (options.component) {
args.push('-n', this._escape(options.component));
}
if (options.flags) {
args.push('-f', this._escape(options.flags));
}
return args;
};
StartActivityCommand.prototype._formatExtras = function(extras) {
if (!extras) {
return [];
}
if (Array.isArray(extras)) {
return extras.reduce((function(_this) {
return function(all, extra) {
return all.concat(_this._formatLongExtra(extra));
};
})(this), []);
} else {
return Object.keys(extras).reduce((function(_this) {
return function(all, key) {
return all.concat(_this._formatShortExtra(key, extras[key]));
};
})(this), []);
}
};
StartActivityCommand.prototype._formatShortExtra = function(key, value) {
var sugared;
sugared = {
key: key
};
if (value === null) {
sugared.type = 'null';
} else if (Array.isArray(value)) {
throw new Error("Refusing to format array value '" + key + "' using short syntax; empty array would cause unpredictable results due to unknown type. Please use long syntax instead.");
} else {
switch (typeof value) {
case 'string':
sugared.type = 'string';
sugared.value = value;
break;
case 'boolean':
sugared.type = 'bool';
sugared.value = value;
break;
case 'number':
sugared.type = 'int';
sugared.value = value;
break;
case 'object':
sugared = value;
sugared.key = key;
}
}
return this._formatLongExtra(sugared);
};
StartActivityCommand.prototype._formatLongExtra = function(extra) {
var args, type;
args = [];
if (!extra.type) {
extra.type = 'string';
}
type = EXTRA_TYPES[extra.type];
if (!type) {
throw new Error("Unsupported type '" + extra.type + "' for extra '" + extra.key + "'");
}
if (extra.type === 'null') {
args.push("--e" + type);
args.push(this._escape(extra.key));
} else if (Array.isArray(extra.value)) {
args.push("--e" + type + "a");
args.push(this._escape(extra.key));
args.push(this._escape(extra.value.join(',')));
} else {
args.push("--e" + type);
args.push(this._escape(extra.key));
args.push(this._escape(extra.value));
}
return args;
};
return StartActivityCommand;
})(Command);
module.exports = StartActivityCommand;
+33
View File
@@ -0,0 +1,33 @@
var Command, Parser, Protocol, StartActivityCommand, StartServiceCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
Parser = require('../../parser');
StartActivityCommand = require('./startactivity');
StartServiceCommand = (function(superClass) {
extend(StartServiceCommand, superClass);
function StartServiceCommand() {
return StartServiceCommand.__super__.constructor.apply(this, arguments);
}
StartServiceCommand.prototype.execute = function(options) {
var args;
args = this._intentArgs(options);
if (options.user || options.user === 0) {
args.push('--user', this._escape(options.user));
}
return this._run('startservice', args);
};
return StartServiceCommand;
})(StartActivityCommand);
module.exports = StartServiceCommand;
+38
View File
@@ -0,0 +1,38 @@
var Command, Protocol, Sync, SyncCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
Sync = require('../../sync');
SyncCommand = (function(superClass) {
extend(SyncCommand, superClass);
function SyncCommand() {
return SyncCommand.__super__.constructor.apply(this, arguments);
}
SyncCommand.prototype.execute = function() {
this._send('sync:');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return new Sync(_this.connection);
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return SyncCommand;
})(Command);
module.exports = SyncCommand;
+36
View File
@@ -0,0 +1,36 @@
var Command, Protocol, TcpCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
TcpCommand = (function(superClass) {
extend(TcpCommand, superClass);
function TcpCommand() {
return TcpCommand.__super__.constructor.apply(this, arguments);
}
TcpCommand.prototype.execute = function(port, host) {
this._send(("tcp:" + port) + (host ? ":" + host : ''));
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.raw();
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return TcpCommand;
})(Command);
module.exports = TcpCommand;
+46
View File
@@ -0,0 +1,46 @@
var Command, Protocol, TcpIpCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
TcpIpCommand = (function(superClass) {
var RE_OK;
extend(TcpIpCommand, superClass);
function TcpIpCommand() {
return TcpIpCommand.__super__.constructor.apply(this, arguments);
}
RE_OK = /restarting in/;
TcpIpCommand.prototype.execute = function(port) {
this._send("tcpip:" + port);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAll().then(function(value) {
if (RE_OK.test(value)) {
return port;
} else {
throw new Error(value.toString().trim());
}
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return TcpIpCommand;
})(Command);
module.exports = TcpIpCommand;
+120
View File
@@ -0,0 +1,120 @@
var Command, EventEmitter, Parser, Promise, Protocol, TrackJdwpCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('events').EventEmitter;
Promise = require('bluebird');
Command = require('../../command');
Protocol = require('../../protocol');
Parser = require('../../parser');
TrackJdwpCommand = (function(superClass) {
var Tracker;
extend(TrackJdwpCommand, superClass);
function TrackJdwpCommand() {
return TrackJdwpCommand.__super__.constructor.apply(this, arguments);
}
TrackJdwpCommand.prototype.execute = function() {
this._send('track-jdwp');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return new Tracker(_this);
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
Tracker = (function(superClass1) {
extend(Tracker, superClass1);
function Tracker(command) {
this.command = command;
this.pids = [];
this.pidMap = Object.create(null);
this.reader = this.read()["catch"](Parser.PrematureEOFError, (function(_this) {
return function(err) {
return _this.emit('end');
};
})(this))["catch"](Promise.CancellationError, (function(_this) {
return function(err) {
_this.command.connection.end();
return _this.emit('end');
};
})(this))["catch"]((function(_this) {
return function(err) {
_this.command.connection.end();
_this.emit('error', err);
return _this.emit('end');
};
})(this));
}
Tracker.prototype.read = function() {
return this.command.parser.readValue().cancellable().then((function(_this) {
return function(list) {
var maybeEmpty, pids;
pids = list.toString().split('\n');
if (maybeEmpty = pids.pop()) {
pids.push(maybeEmpty);
}
return _this.update(pids);
};
})(this));
};
Tracker.prototype.update = function(newList) {
var changeSet, i, j, len, len1, newMap, pid, ref;
changeSet = {
removed: [],
added: []
};
newMap = Object.create(null);
for (i = 0, len = newList.length; i < len; i++) {
pid = newList[i];
if (!this.pidMap[pid]) {
changeSet.added.push(pid);
this.emit('add', pid);
newMap[pid] = pid;
}
}
ref = this.pids;
for (j = 0, len1 = ref.length; j < len1; j++) {
pid = ref[j];
if (!newMap[pid]) {
changeSet.removed.push(pid);
this.emit('remove', pid);
}
}
this.pids = newList;
this.pidMap = newMap;
this.emit('changeSet', changeSet, newList);
return this;
};
Tracker.prototype.end = function() {
this.reader.cancel();
return this;
};
return Tracker;
})(EventEmitter);
return TrackJdwpCommand;
})(Command);
module.exports = TrackJdwpCommand;
+44
View File
@@ -0,0 +1,44 @@
var Command, Protocol, UninstallCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
UninstallCommand = (function(superClass) {
extend(UninstallCommand, superClass);
function UninstallCommand() {
return UninstallCommand.__super__.constructor.apply(this, arguments);
}
UninstallCommand.prototype.execute = function(pkg) {
this._send("shell:pm uninstall " + pkg);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.searchLine(/^(Success|Failure.*|.*Unknown package:.*)$/).then(function(match) {
if (match[1] === 'Success') {
return true;
} else {
return true;
}
})["finally"](function() {
return _this.parser.readAll();
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, "OKAY or FAIL");
}
};
})(this));
};
return UninstallCommand;
})(Command);
module.exports = UninstallCommand;
+46
View File
@@ -0,0 +1,46 @@
var Command, Protocol, UsbCommand,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
UsbCommand = (function(superClass) {
var RE_OK;
extend(UsbCommand, superClass);
function UsbCommand() {
return UsbCommand.__super__.constructor.apply(this, arguments);
}
RE_OK = /restarting in/;
UsbCommand.prototype.execute = function() {
this._send('usb:');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readAll().then(function(value) {
if (RE_OK.test(value)) {
return true;
} else {
throw new Error(value.toString().trim());
}
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return UsbCommand;
})(Command);
module.exports = UsbCommand;
+42
View File
@@ -0,0 +1,42 @@
var Command, Protocol, WaitBootCompleteCommand, debug,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
debug = require('debug')('adb:command:waitboot');
Command = require('../../command');
Protocol = require('../../protocol');
WaitBootCompleteCommand = (function(superClass) {
extend(WaitBootCompleteCommand, superClass);
function WaitBootCompleteCommand() {
return WaitBootCompleteCommand.__super__.constructor.apply(this, arguments);
}
WaitBootCompleteCommand.prototype.execute = function() {
this._send('shell:while getprop sys.boot_completed 2>/dev/null; do sleep 1; done');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.searchLine(/^1$/)["finally"](function() {
return _this.parser.end();
}).then(function() {
return true;
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return WaitBootCompleteCommand;
})(Command);
module.exports = WaitBootCompleteCommand;
+46
View File
@@ -0,0 +1,46 @@
var Command, ConnectCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
ConnectCommand = (function(superClass) {
var RE_OK;
extend(ConnectCommand, superClass);
function ConnectCommand() {
return ConnectCommand.__super__.constructor.apply(this, arguments);
}
RE_OK = /connected to|already connected/;
ConnectCommand.prototype.execute = function(host, port) {
this._send("host:connect:" + host + ":" + port);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readValue().then(function(value) {
if (RE_OK.test(value)) {
return host + ":" + port;
} else {
throw new Error(value.toString());
}
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return ConnectCommand;
})(Command);
module.exports = ConnectCommand;
+64
View File
@@ -0,0 +1,64 @@
var Command, HostDevicesCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
HostDevicesCommand = (function(superClass) {
extend(HostDevicesCommand, superClass);
function HostDevicesCommand() {
return HostDevicesCommand.__super__.constructor.apply(this, arguments);
}
HostDevicesCommand.prototype.execute = function() {
this._send('host:devices');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this._readDevices();
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
HostDevicesCommand.prototype._readDevices = function() {
return this.parser.readValue().then((function(_this) {
return function(value) {
return _this._parseDevices(value);
};
})(this));
};
HostDevicesCommand.prototype._parseDevices = function(value) {
var devices, i, id, len, line, ref, ref1, type;
devices = [];
if (!value.length) {
return devices;
}
ref = value.toString('ascii').split('\n');
for (i = 0, len = ref.length; i < len; i++) {
line = ref[i];
if (line) {
ref1 = line.split('\t'), id = ref1[0], type = ref1[1];
devices.push({
id: id,
type: type
});
}
}
return devices;
};
return HostDevicesCommand;
})(Command);
module.exports = HostDevicesCommand;
+65
View File
@@ -0,0 +1,65 @@
var Command, HostDevicesWithPathsCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
HostDevicesWithPathsCommand = (function(superClass) {
extend(HostDevicesWithPathsCommand, superClass);
function HostDevicesWithPathsCommand() {
return HostDevicesWithPathsCommand.__super__.constructor.apply(this, arguments);
}
HostDevicesWithPathsCommand.prototype.execute = function() {
this._send('host:devices-l');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this._readDevices();
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
HostDevicesWithPathsCommand.prototype._readDevices = function() {
return this.parser.readValue().then((function(_this) {
return function(value) {
return _this._parseDevices(value);
};
})(this));
};
HostDevicesWithPathsCommand.prototype._parseDevices = function(value) {
var devices, i, id, len, line, path, ref, ref1, type;
devices = [];
if (!value.length) {
return devices;
}
ref = value.toString('ascii').split('\n');
for (i = 0, len = ref.length; i < len; i++) {
line = ref[i];
if (line) {
ref1 = line.split(/\s+/), id = ref1[0], type = ref1[1], path = ref1[2];
devices.push({
id: id,
type: type,
path: path
});
}
}
return devices;
};
return HostDevicesWithPathsCommand;
})(Command);
module.exports = HostDevicesWithPathsCommand;
+46
View File
@@ -0,0 +1,46 @@
var Command, DisconnectCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
DisconnectCommand = (function(superClass) {
var RE_OK;
extend(DisconnectCommand, superClass);
function DisconnectCommand() {
return DisconnectCommand.__super__.constructor.apply(this, arguments);
}
RE_OK = /^$/;
DisconnectCommand.prototype.execute = function(host, port) {
this._send("host:disconnect:" + host + ":" + port);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readValue().then(function(value) {
if (RE_OK.test(value)) {
return host + ":" + port;
} else {
throw new Error(value.toString());
}
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return DisconnectCommand;
})(Command);
module.exports = DisconnectCommand;
+36
View File
@@ -0,0 +1,36 @@
var Command, HostKillCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
HostKillCommand = (function(superClass) {
extend(HostKillCommand, superClass);
function HostKillCommand() {
return HostKillCommand.__super__.constructor.apply(this, arguments);
}
HostKillCommand.prototype.execute = function() {
this._send('host:kill');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return true;
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return HostKillCommand;
})(Command);
module.exports = HostKillCommand;
+40
View File
@@ -0,0 +1,40 @@
var Command, HostDevicesCommand, HostTrackDevicesCommand, Protocol, Tracker,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
Tracker = require('../../tracker');
HostDevicesCommand = require('./devices');
HostTrackDevicesCommand = (function(superClass) {
extend(HostTrackDevicesCommand, superClass);
function HostTrackDevicesCommand() {
return HostTrackDevicesCommand.__super__.constructor.apply(this, arguments);
}
HostTrackDevicesCommand.prototype.execute = function() {
this._send('host:track-devices');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return new Tracker(_this);
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return HostTrackDevicesCommand;
})(HostDevicesCommand);
module.exports = HostTrackDevicesCommand;
+36
View File
@@ -0,0 +1,36 @@
var Command, HostTransportCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
HostTransportCommand = (function(superClass) {
extend(HostTransportCommand, superClass);
function HostTransportCommand() {
return HostTransportCommand.__super__.constructor.apply(this, arguments);
}
HostTransportCommand.prototype.execute = function(serial) {
this._send("host:transport:" + serial);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return true;
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
};
})(this));
};
return HostTransportCommand;
})(Command);
module.exports = HostTransportCommand;
+42
View File
@@ -0,0 +1,42 @@
var Command, HostVersionCommand, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Command = require('../../command');
Protocol = require('../../protocol');
HostVersionCommand = (function(superClass) {
extend(HostVersionCommand, superClass);
function HostVersionCommand() {
return HostVersionCommand.__super__.constructor.apply(this, arguments);
}
HostVersionCommand.prototype.execute = function() {
this._send('host:version');
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readValue().then(function(value) {
return _this._parseVersion(value);
});
case Protocol.FAIL:
return _this.parser.readError();
default:
return _this._parseVersion(reply);
}
};
})(this));
};
HostVersionCommand.prototype._parseVersion = function(version) {
return parseInt(version, 16);
};
return HostVersionCommand;
})(Command);
module.exports = HostVersionCommand;
+108
View File
@@ -0,0 +1,108 @@
var Connection, EventEmitter, Net, Parser, debug, dump, execFile,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Net = require('net');
debug = require('debug')('adb:connection');
EventEmitter = require('events').EventEmitter;
execFile = require('child_process').execFile;
Parser = require('./parser');
dump = require('./dump');
Connection = (function(superClass) {
extend(Connection, superClass);
function Connection(options1) {
this.options = options1;
this.socket = null;
this.parser = null;
this.triedStarting = false;
}
Connection.prototype.connect = function() {
this.socket = Net.connect(this.options);
this.socket.setNoDelay(true);
this.parser = new Parser(this.socket);
this.socket.on('connect', (function(_this) {
return function() {
return _this.emit('connect');
};
})(this));
this.socket.on('end', (function(_this) {
return function() {
return _this.emit('end');
};
})(this));
this.socket.on('drain', (function(_this) {
return function() {
return _this.emit('drain');
};
})(this));
this.socket.on('timeout', (function(_this) {
return function() {
return _this.emit('timeout');
};
})(this));
this.socket.on('error', (function(_this) {
return function(err) {
return _this._handleError(err);
};
})(this));
this.socket.on('close', (function(_this) {
return function(hadError) {
return _this.emit('close', hadError);
};
})(this));
return this;
};
Connection.prototype.end = function() {
this.socket.end();
return this;
};
Connection.prototype.write = function(data, callback) {
this.socket.write(dump(data), callback);
return this;
};
Connection.prototype.startServer = function(callback) {
debug("Starting ADB server via '" + this.options.bin + " start-server'");
return this._exec(['start-server'], {}, callback);
};
Connection.prototype._exec = function(args, options, callback) {
debug("CLI: " + this.options.bin + " " + (args.join(' ')));
execFile(this.options.bin, args, options, callback);
return this;
};
Connection.prototype._handleError = function(err) {
if (err.code === 'ECONNREFUSED' && !this.triedStarting) {
debug("Connection was refused, let's try starting the server once");
this.triedStarting = true;
this.startServer((function(_this) {
return function(err) {
if (err) {
return _this._handleError(err);
}
return _this.connect();
};
})(this));
} else {
debug("Connection had an error: " + err.message);
this.emit('error', err);
this.end();
}
};
return Connection;
})(EventEmitter);
module.exports = Connection;
+15
View File
@@ -0,0 +1,15 @@
var fs, out;
fs = require('fs');
if (process.env.ADBKIT_DUMP) {
out = fs.createWriteStream('adbkit.dump');
module.exports = function(chunk) {
out.write(chunk);
return chunk;
};
} else {
module.exports = function(chunk) {
return chunk;
};
}
+55
View File
@@ -0,0 +1,55 @@
var Assert, RgbTransform, Stream,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Assert = require('assert');
Stream = require('stream');
RgbTransform = (function(superClass) {
extend(RgbTransform, superClass);
function RgbTransform(meta, options) {
this.meta = meta;
this._buffer = new Buffer('');
Assert.ok(this.meta.bpp === 24 || this.meta.bpp === 32, 'Only 24-bit and 32-bit raw images with 8-bits per color are supported');
this._r_pos = this.meta.red_offset / 8;
this._g_pos = this.meta.green_offset / 8;
this._b_pos = this.meta.blue_offset / 8;
this._a_pos = this.meta.alpha_offset / 8;
this._pixel_bytes = this.meta.bpp / 8;
RgbTransform.__super__.constructor.call(this, options);
}
RgbTransform.prototype._transform = function(chunk, encoding, done) {
var b, g, r, sourceCursor, target, targetCursor;
if (this._buffer.length) {
this._buffer = Buffer.concat([this._buffer, chunk], this._buffer.length + chunk.length);
} else {
this._buffer = chunk;
}
sourceCursor = 0;
targetCursor = 0;
target = this._pixel_bytes === 3 ? this._buffer : new Buffer(Math.max(4, chunk.length / this._pixel_bytes * 3));
while (this._buffer.length - sourceCursor >= this._pixel_bytes) {
r = this._buffer[sourceCursor + this._r_pos];
g = this._buffer[sourceCursor + this._g_pos];
b = this._buffer[sourceCursor + this._b_pos];
target[targetCursor + 0] = r;
target[targetCursor + 1] = g;
target[targetCursor + 2] = b;
sourceCursor += this._pixel_bytes;
targetCursor += 3;
}
if (targetCursor) {
this.push(target.slice(0, targetCursor));
this._buffer = this._buffer.slice(sourceCursor);
}
done();
};
return RgbTransform;
})(Stream.Transform);
module.exports = RgbTransform;
+225
View File
@@ -0,0 +1,225 @@
module.exports = {
KEYCODE_UNKNOWN: 0,
KEYCODE_SOFT_LEFT: 1,
KEYCODE_SOFT_RIGHT: 2,
KEYCODE_HOME: 3,
KEYCODE_BACK: 4,
KEYCODE_CALL: 5,
KEYCODE_ENDCALL: 6,
KEYCODE_0: 7,
KEYCODE_1: 8,
KEYCODE_2: 9,
KEYCODE_3: 10,
KEYCODE_4: 11,
KEYCODE_5: 12,
KEYCODE_6: 13,
KEYCODE_7: 14,
KEYCODE_8: 15,
KEYCODE_9: 16,
KEYCODE_STAR: 17,
KEYCODE_POUND: 18,
KEYCODE_DPAD_UP: 19,
KEYCODE_DPAD_DOWN: 20,
KEYCODE_DPAD_LEFT: 21,
KEYCODE_DPAD_RIGHT: 22,
KEYCODE_DPAD_CENTER: 23,
KEYCODE_VOLUME_UP: 24,
KEYCODE_VOLUME_DOWN: 25,
KEYCODE_POWER: 26,
KEYCODE_CAMERA: 27,
KEYCODE_CLEAR: 28,
KEYCODE_A: 29,
KEYCODE_B: 30,
KEYCODE_C: 31,
KEYCODE_D: 32,
KEYCODE_E: 33,
KEYCODE_F: 34,
KEYCODE_G: 35,
KEYCODE_H: 36,
KEYCODE_I: 37,
KEYCODE_J: 38,
KEYCODE_K: 39,
KEYCODE_L: 40,
KEYCODE_M: 41,
KEYCODE_N: 42,
KEYCODE_O: 43,
KEYCODE_P: 44,
KEYCODE_Q: 45,
KEYCODE_R: 46,
KEYCODE_S: 47,
KEYCODE_T: 48,
KEYCODE_U: 49,
KEYCODE_V: 50,
KEYCODE_W: 51,
KEYCODE_X: 52,
KEYCODE_Y: 53,
KEYCODE_Z: 54,
KEYCODE_COMMA: 55,
KEYCODE_PERIOD: 56,
KEYCODE_ALT_LEFT: 57,
KEYCODE_ALT_RIGHT: 58,
KEYCODE_SHIFT_LEFT: 59,
KEYCODE_SHIFT_RIGHT: 60,
KEYCODE_TAB: 61,
KEYCODE_SPACE: 62,
KEYCODE_SYM: 63,
KEYCODE_EXPLORER: 64,
KEYCODE_ENVELOPE: 65,
KEYCODE_ENTER: 66,
KEYCODE_DEL: 67,
KEYCODE_GRAVE: 68,
KEYCODE_MINUS: 69,
KEYCODE_EQUALS: 70,
KEYCODE_LEFT_BRACKET: 71,
KEYCODE_RIGHT_BRACKET: 72,
KEYCODE_BACKSLASH: 73,
KEYCODE_SEMICOLON: 74,
KEYCODE_APOSTROPHE: 75,
KEYCODE_SLASH: 76,
KEYCODE_AT: 77,
KEYCODE_NUM: 78,
KEYCODE_HEADSETHOOK: 79,
KEYCODE_FOCUS: 80,
KEYCODE_PLUS: 81,
KEYCODE_MENU: 82,
KEYCODE_NOTIFICATION: 83,
KEYCODE_SEARCH: 84,
KEYCODE_MEDIA_PLAY_PAUSE: 85,
KEYCODE_MEDIA_STOP: 86,
KEYCODE_MEDIA_NEXT: 87,
KEYCODE_MEDIA_PREVIOUS: 88,
KEYCODE_MEDIA_REWIND: 89,
KEYCODE_MEDIA_FAST_FORWARD: 90,
KEYCODE_MUTE: 91,
KEYCODE_PAGE_UP: 92,
KEYCODE_PAGE_DOWN: 93,
KEYCODE_PICTSYMBOLS: 94,
KEYCODE_SWITCH_CHARSET: 95,
KEYCODE_BUTTON_A: 96,
KEYCODE_BUTTON_B: 97,
KEYCODE_BUTTON_C: 98,
KEYCODE_BUTTON_X: 99,
KEYCODE_BUTTON_Y: 100,
KEYCODE_BUTTON_Z: 101,
KEYCODE_BUTTON_L1: 102,
KEYCODE_BUTTON_R1: 103,
KEYCODE_BUTTON_L2: 104,
KEYCODE_BUTTON_R2: 105,
KEYCODE_BUTTON_THUMBL: 106,
KEYCODE_BUTTON_THUMBR: 107,
KEYCODE_BUTTON_START: 108,
KEYCODE_BUTTON_SELECT: 109,
KEYCODE_BUTTON_MODE: 110,
KEYCODE_ESCAPE: 111,
KEYCODE_FORWARD_DEL: 112,
KEYCODE_CTRL_LEFT: 113,
KEYCODE_CTRL_RIGHT: 114,
KEYCODE_CAPS_LOCK: 115,
KEYCODE_SCROLL_LOCK: 116,
KEYCODE_META_LEFT: 117,
KEYCODE_META_RIGHT: 118,
KEYCODE_FUNCTION: 119,
KEYCODE_SYSRQ: 120,
KEYCODE_BREAK: 121,
KEYCODE_MOVE_HOME: 122,
KEYCODE_MOVE_END: 123,
KEYCODE_INSERT: 124,
KEYCODE_FORWARD: 125,
KEYCODE_MEDIA_PLAY: 126,
KEYCODE_MEDIA_PAUSE: 127,
KEYCODE_MEDIA_CLOSE: 128,
KEYCODE_MEDIA_EJECT: 129,
KEYCODE_MEDIA_RECORD: 130,
KEYCODE_F1: 131,
KEYCODE_F2: 132,
KEYCODE_F3: 133,
KEYCODE_F4: 134,
KEYCODE_F5: 135,
KEYCODE_F6: 136,
KEYCODE_F7: 137,
KEYCODE_F8: 138,
KEYCODE_F9: 139,
KEYCODE_F10: 140,
KEYCODE_F11: 141,
KEYCODE_F12: 142,
KEYCODE_NUM_LOCK: 143,
KEYCODE_NUMPAD_0: 144,
KEYCODE_NUMPAD_1: 145,
KEYCODE_NUMPAD_2: 146,
KEYCODE_NUMPAD_3: 147,
KEYCODE_NUMPAD_4: 148,
KEYCODE_NUMPAD_5: 149,
KEYCODE_NUMPAD_6: 150,
KEYCODE_NUMPAD_7: 151,
KEYCODE_NUMPAD_8: 152,
KEYCODE_NUMPAD_9: 153,
KEYCODE_NUMPAD_DIVIDE: 154,
KEYCODE_NUMPAD_MULTIPLY: 155,
KEYCODE_NUMPAD_SUBTRACT: 156,
KEYCODE_NUMPAD_ADD: 157,
KEYCODE_NUMPAD_DOT: 158,
KEYCODE_NUMPAD_COMMA: 159,
KEYCODE_NUMPAD_ENTER: 160,
KEYCODE_NUMPAD_EQUALS: 161,
KEYCODE_NUMPAD_LEFT_PAREN: 162,
KEYCODE_NUMPAD_RIGHT_PAREN: 163,
KEYCODE_VOLUME_MUTE: 164,
KEYCODE_INFO: 165,
KEYCODE_CHANNEL_UP: 166,
KEYCODE_CHANNEL_DOWN: 167,
KEYCODE_ZOOM_IN: 168,
KEYCODE_ZOOM_OUT: 169,
KEYCODE_TV: 170,
KEYCODE_WINDOW: 171,
KEYCODE_GUIDE: 172,
KEYCODE_DVR: 173,
KEYCODE_BOOKMARK: 174,
KEYCODE_CAPTIONS: 175,
KEYCODE_SETTINGS: 176,
KEYCODE_TV_POWER: 177,
KEYCODE_TV_INPUT: 178,
KEYCODE_STB_POWER: 179,
KEYCODE_STB_INPUT: 180,
KEYCODE_AVR_POWER: 181,
KEYCODE_AVR_INPUT: 182,
KEYCODE_PROG_RED: 183,
KEYCODE_PROG_GREEN: 184,
KEYCODE_PROG_YELLOW: 185,
KEYCODE_PROG_BLUE: 186,
KEYCODE_APP_SWITCH: 187,
KEYCODE_BUTTON_1: 188,
KEYCODE_BUTTON_2: 189,
KEYCODE_BUTTON_3: 190,
KEYCODE_BUTTON_4: 191,
KEYCODE_BUTTON_5: 192,
KEYCODE_BUTTON_6: 193,
KEYCODE_BUTTON_7: 194,
KEYCODE_BUTTON_8: 195,
KEYCODE_BUTTON_9: 196,
KEYCODE_BUTTON_10: 197,
KEYCODE_BUTTON_11: 198,
KEYCODE_BUTTON_12: 199,
KEYCODE_BUTTON_13: 200,
KEYCODE_BUTTON_14: 201,
KEYCODE_BUTTON_15: 202,
KEYCODE_BUTTON_16: 203,
KEYCODE_LANGUAGE_SWITCH: 204,
KEYCODE_MANNER_MODE: 205,
KEYCODE_3D_MODE: 206,
KEYCODE_CONTACTS: 207,
KEYCODE_CALENDAR: 208,
KEYCODE_MUSIC: 209,
KEYCODE_CALCULATOR: 210,
KEYCODE_ZENKAKU_HANKAKU: 211,
KEYCODE_EISU: 212,
KEYCODE_MUHENKAN: 213,
KEYCODE_HENKAN: 214,
KEYCODE_KATAKANA_HIRAGANA: 215,
KEYCODE_YEN: 216,
KEYCODE_RO: 217,
KEYCODE_KANA: 218,
KEYCODE_ASSIST: 219,
KEYCODE_BRIGHTNESS_DOWN: 220,
KEYCODE_BRIGHTNESS_UP: 221,
KEYCODE_MEDIA_AUDIO_TRACK: 222
};
+87
View File
@@ -0,0 +1,87 @@
var LineTransform, Stream,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Stream = require('stream');
LineTransform = (function(superClass) {
extend(LineTransform, superClass);
function LineTransform(options) {
if (options == null) {
options = {};
}
this.savedR = null;
this.autoDetect = options.autoDetect || false;
this.transformNeeded = true;
this.skipBytes = 0;
delete options.autoDetect;
LineTransform.__super__.constructor.call(this, options);
}
LineTransform.prototype._nullTransform = function(chunk, encoding, done) {
this.push(chunk);
done();
};
LineTransform.prototype._transform = function(chunk, encoding, done) {
var hi, last, lo, skip;
if (this.autoDetect) {
if (chunk[0] === 0x0a) {
this.transformNeeded = false;
this.skipBytes = 1;
} else {
this.skipBytes = 2;
}
this.autoDetect = false;
}
if (this.skipBytes) {
skip = Math.min(chunk.length, this.skipBytes);
chunk = chunk.slice(skip);
this.skipBytes -= skip;
}
if (!chunk.length) {
return done();
}
if (!this.transformNeeded) {
return this._nullTransform(chunk, encoding, done);
}
lo = 0;
hi = 0;
if (this.savedR) {
if (chunk[0] !== 0x0a) {
this.push(this.savedR);
}
this.savedR = null;
}
last = chunk.length - 1;
while (hi <= last) {
if (chunk[hi] === 0x0d) {
if (hi === last) {
this.savedR = chunk.slice(last);
break;
} else if (chunk[hi + 1] === 0x0a) {
this.push(chunk.slice(lo, hi));
lo = hi + 1;
}
}
hi += 1;
}
if (hi !== lo) {
this.push(chunk.slice(lo, hi));
}
done();
};
LineTransform.prototype._flush = function(done) {
if (this.savedR) {
this.push(this.savedR);
}
return done();
};
return LineTransform;
})(Stream.Transform);
module.exports = LineTransform;
+291
View File
@@ -0,0 +1,291 @@
var Parser, Promise, Protocol,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Promise = require('bluebird');
Protocol = require('./protocol');
Parser = (function() {
function Parser(stream) {
this.stream = stream;
this.ended = false;
}
Parser.prototype.end = function() {
var endListener, errorListener, resolver, tryRead;
if (this.ended) {
return Promise.resolve(true);
}
resolver = Promise.defer();
tryRead = (function(_this) {
return function() {
while (_this.stream.read()) {
continue;
}
};
})(this);
this.stream.on('readable', tryRead);
this.stream.on('error', errorListener = function(err) {
return resolver.reject(err);
});
this.stream.on('end', endListener = (function(_this) {
return function() {
_this.ended = true;
return resolver.resolve(true);
};
})(this));
this.stream.read(0);
this.stream.end();
return resolver.promise.cancellable()["finally"]((function(_this) {
return function() {
_this.stream.removeListener('readable', tryRead);
_this.stream.removeListener('error', errorListener);
return _this.stream.removeListener('end', endListener);
};
})(this));
};
Parser.prototype.raw = function() {
return this.stream;
};
Parser.prototype.readAll = function() {
var all, endListener, errorListener, resolver, tryRead;
all = new Buffer(0);
resolver = Promise.defer();
tryRead = (function(_this) {
return function() {
var chunk;
while (chunk = _this.stream.read()) {
all = Buffer.concat([all, chunk]);
}
if (_this.ended) {
return resolver.resolve(all);
}
};
})(this);
this.stream.on('readable', tryRead);
this.stream.on('error', errorListener = function(err) {
return resolver.reject(err);
});
this.stream.on('end', endListener = (function(_this) {
return function() {
_this.ended = true;
return resolver.resolve(all);
};
})(this));
tryRead();
return resolver.promise.cancellable()["finally"]((function(_this) {
return function() {
_this.stream.removeListener('readable', tryRead);
_this.stream.removeListener('error', errorListener);
return _this.stream.removeListener('end', endListener);
};
})(this));
};
Parser.prototype.readAscii = function(howMany) {
return this.readBytes(howMany).then(function(chunk) {
return chunk.toString('ascii');
});
};
Parser.prototype.readBytes = function(howMany) {
var endListener, errorListener, resolver, tryRead;
resolver = Promise.defer();
tryRead = (function(_this) {
return function() {
var chunk;
if (howMany) {
if (chunk = _this.stream.read(howMany)) {
howMany -= chunk.length;
if (howMany === 0) {
return resolver.resolve(chunk);
}
}
if (_this.ended) {
return resolver.reject(new Parser.PrematureEOFError(howMany));
}
} else {
return resolver.resolve(new Buffer(0));
}
};
})(this);
endListener = (function(_this) {
return function() {
_this.ended = true;
return resolver.reject(new Parser.PrematureEOFError(howMany));
};
})(this);
errorListener = function(err) {
return resolver.reject(err);
};
this.stream.on('readable', tryRead);
this.stream.on('error', errorListener);
this.stream.on('end', endListener);
tryRead();
return resolver.promise.cancellable()["finally"]((function(_this) {
return function() {
_this.stream.removeListener('readable', tryRead);
_this.stream.removeListener('error', errorListener);
return _this.stream.removeListener('end', endListener);
};
})(this));
};
Parser.prototype.readByteFlow = function(howMany, targetStream) {
var endListener, errorListener, resolver, tryRead;
resolver = Promise.defer();
tryRead = (function(_this) {
return function() {
var chunk;
if (howMany) {
while (chunk = _this.stream.read(howMany) || _this.stream.read()) {
howMany -= chunk.length;
targetStream.write(chunk);
if (howMany === 0) {
return resolver.resolve();
}
}
if (_this.ended) {
return resolver.reject(new Parser.PrematureEOFError(howMany));
}
} else {
return resolver.resolve();
}
};
})(this);
endListener = (function(_this) {
return function() {
_this.ended = true;
return resolver.reject(new Parser.PrematureEOFError(howMany));
};
})(this);
errorListener = function(err) {
return resolver.reject(err);
};
this.stream.on('readable', tryRead);
this.stream.on('error', errorListener);
this.stream.on('end', endListener);
tryRead();
return resolver.promise.cancellable()["finally"]((function(_this) {
return function() {
_this.stream.removeListener('readable', tryRead);
_this.stream.removeListener('error', errorListener);
return _this.stream.removeListener('end', endListener);
};
})(this));
};
Parser.prototype.readError = function() {
return this.readValue().then(function(value) {
return Promise.reject(new Parser.FailError(value.toString()));
});
};
Parser.prototype.readValue = function() {
return this.readAscii(4).then((function(_this) {
return function(value) {
var length;
length = Protocol.decodeLength(value);
return _this.readBytes(length);
};
})(this));
};
Parser.prototype.readUntil = function(code) {
var read, skipped;
skipped = new Buffer(0);
read = (function(_this) {
return function() {
return _this.readBytes(1).then(function(chunk) {
if (chunk[0] === code) {
return skipped;
} else {
skipped = Buffer.concat([skipped, chunk]);
return read();
}
});
};
})(this);
return read();
};
Parser.prototype.searchLine = function(re) {
return this.readLine().then((function(_this) {
return function(line) {
var match;
if (match = re.exec(line)) {
return match;
} else {
return _this.searchLine(re);
}
};
})(this));
};
Parser.prototype.readLine = function() {
return this.readUntil(0x0a).then(function(line) {
if (line[line.length - 1] === 0x0d) {
return line.slice(0, -1);
} else {
return line;
}
});
};
Parser.prototype.unexpected = function(data, expected) {
return Promise.reject(new Parser.UnexpectedDataError(data, expected));
};
return Parser;
})();
Parser.FailError = (function(superClass) {
extend(FailError, superClass);
function FailError(message) {
Error.call(this);
this.name = 'FailError';
this.message = "Failure: '" + message + "'";
Error.captureStackTrace(this, Parser.FailError);
}
return FailError;
})(Error);
Parser.PrematureEOFError = (function(superClass) {
extend(PrematureEOFError, superClass);
function PrematureEOFError(howManyMissing) {
Error.call(this);
this.name = 'PrematureEOFError';
this.message = "Premature end of stream, needed " + howManyMissing + " more bytes";
this.missingBytes = howManyMissing;
Error.captureStackTrace(this, Parser.PrematureEOFError);
}
return PrematureEOFError;
})(Error);
Parser.UnexpectedDataError = (function(superClass) {
extend(UnexpectedDataError, superClass);
function UnexpectedDataError(unexpected, expected) {
Error.call(this);
this.name = 'UnexpectedDataError';
this.message = "Unexpected '" + unexpected + "', was expecting " + expected;
this.unexpected = unexpected;
this.expected = expected;
Error.captureStackTrace(this, Parser.UnexpectedDataError);
}
return UnexpectedDataError;
})(Error);
module.exports = Parser;
+137
View File
@@ -0,0 +1,137 @@
var EventEmitter, Parser, ProcStat, split,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('events').EventEmitter;
split = require('split');
Parser = require('../parser');
ProcStat = (function(superClass) {
var RE_COLSEP, RE_CPULINE;
extend(ProcStat, superClass);
RE_CPULINE = /^cpu[0-9]+ .*$/mg;
RE_COLSEP = /\ +/g;
function ProcStat(sync) {
this.sync = sync;
this.interval = 1000;
this.stats = this._emptyStats();
this._ignore = {};
this._timer = setInterval((function(_this) {
return function() {
return _this.update();
};
})(this), this.interval);
this.update();
}
ProcStat.prototype.end = function() {
clearInterval(this._timer);
this.sync.end();
return this.sync = null;
};
ProcStat.prototype.update = function() {
return new Parser(this.sync.pull('/proc/stat')).readAll().then((function(_this) {
return function(out) {
return _this._parse(out);
};
})(this))["catch"]((function(_this) {
return function(err) {
_this._error(err);
};
})(this));
};
ProcStat.prototype._parse = function(out) {
var cols, i, len, line, match, stats, total, type, val;
stats = this._emptyStats();
while (match = RE_CPULINE.exec(out)) {
line = match[0];
cols = line.split(RE_COLSEP);
type = cols.shift();
if (this._ignore[type] === line) {
continue;
}
total = 0;
for (i = 0, len = cols.length; i < len; i++) {
val = cols[i];
total += +val;
}
stats.cpus[type] = {
line: line,
user: +cols[0] || 0,
nice: +cols[1] || 0,
system: +cols[2] || 0,
idle: +cols[3] || 0,
iowait: +cols[4] || 0,
irq: +cols[5] || 0,
softirq: +cols[6] || 0,
steal: +cols[7] || 0,
guest: +cols[8] || 0,
guestnice: +cols[9] || 0,
total: total
};
}
return this._set(stats);
};
ProcStat.prototype._set = function(stats) {
var cur, found, id, loads, m, old, ref, ticks;
loads = {};
found = false;
ref = stats.cpus;
for (id in ref) {
cur = ref[id];
old = this.stats.cpus[id];
if (!old) {
continue;
}
ticks = cur.total - old.total;
if (ticks > 0) {
found = true;
m = 100 / ticks;
loads[id] = {
user: Math.floor(m * (cur.user - old.user)),
nice: Math.floor(m * (cur.nice - old.nice)),
system: Math.floor(m * (cur.system - old.system)),
idle: Math.floor(m * (cur.idle - old.idle)),
iowait: Math.floor(m * (cur.iowait - old.iowait)),
irq: Math.floor(m * (cur.irq - old.irq)),
softirq: Math.floor(m * (cur.softirq - old.softirq)),
steal: Math.floor(m * (cur.steal - old.steal)),
guest: Math.floor(m * (cur.guest - old.guest)),
guestnice: Math.floor(m * (cur.guestnice - old.guestnice)),
total: 100
};
} else {
this._ignore[id] = cur.line;
delete stats.cpus[id];
}
}
if (found) {
this.emit('load', loads);
}
return this.stats = stats;
};
ProcStat.prototype._error = function(err) {
return this.emit('error', err);
};
ProcStat.prototype._emptyStats = function() {
return {
cpus: {}
};
};
return ProcStat;
})(EventEmitter);
module.exports = ProcStat;
+45
View File
@@ -0,0 +1,45 @@
var Protocol;
Protocol = (function() {
function Protocol() {}
Protocol.OKAY = 'OKAY';
Protocol.FAIL = 'FAIL';
Protocol.STAT = 'STAT';
Protocol.LIST = 'LIST';
Protocol.DENT = 'DENT';
Protocol.RECV = 'RECV';
Protocol.DATA = 'DATA';
Protocol.DONE = 'DONE';
Protocol.SEND = 'SEND';
Protocol.QUIT = 'QUIT';
Protocol.decodeLength = function(length) {
return parseInt(length, 16);
};
Protocol.encodeLength = function(length) {
return ('0000' + length.toString(16)).slice(-4).toUpperCase();
};
Protocol.encodeData = function(data) {
if (!Buffer.isBuffer(data)) {
data = new Buffer(data);
}
return Buffer.concat([new Buffer(Protocol.encodeLength(data.length)), data]);
};
return Protocol;
})();
module.exports = Protocol;
+336
View File
@@ -0,0 +1,336 @@
var Entry, EventEmitter, Fs, Parser, Path, Promise, Protocol, PullTransfer, PushTransfer, Stats, Sync, debug,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Fs = require('fs');
Path = require('path');
Promise = require('bluebird');
EventEmitter = require('events').EventEmitter;
debug = require('debug')('adb:sync');
Parser = require('./parser');
Protocol = require('./protocol');
Stats = require('./sync/stats');
Entry = require('./sync/entry');
PushTransfer = require('./sync/pushtransfer');
PullTransfer = require('./sync/pulltransfer');
Sync = (function(superClass) {
var DATA_MAX_LENGTH, DEFAULT_CHMOD, TEMP_PATH;
extend(Sync, superClass);
TEMP_PATH = '/data/local/tmp';
DEFAULT_CHMOD = 0x1a4;
DATA_MAX_LENGTH = 65536;
Sync.temp = function(path) {
return TEMP_PATH + "/" + (Path.basename(path));
};
function Sync(connection) {
this.connection = connection;
this.parser = this.connection.parser;
}
Sync.prototype.stat = function(path, callback) {
this._sendCommandWithArg(Protocol.STAT, path);
return this.parser.readAscii(4).then((function(_this) {
return function(reply) {
switch (reply) {
case Protocol.STAT:
return _this.parser.readBytes(12).then(function(stat) {
var mode, mtime, size;
mode = stat.readUInt32LE(0);
size = stat.readUInt32LE(4);
mtime = stat.readUInt32LE(8);
if (mode === 0) {
return _this._enoent(path);
} else {
return new Stats(mode, size, mtime);
}
});
case Protocol.FAIL:
return _this._readError();
default:
return _this.parser.unexpected(reply, 'STAT or FAIL');
}
};
})(this)).nodeify(callback);
};
Sync.prototype.readdir = function(path, callback) {
var files, readNext;
files = [];
readNext = (function(_this) {
return function() {
return _this.parser.readAscii(4).then(function(reply) {
switch (reply) {
case Protocol.DENT:
return _this.parser.readBytes(16).then(function(stat) {
var mode, mtime, namelen, size;
mode = stat.readUInt32LE(0);
size = stat.readUInt32LE(4);
mtime = stat.readUInt32LE(8);
namelen = stat.readUInt32LE(12);
return _this.parser.readBytes(namelen).then(function(name) {
name = name.toString();
if (!(name === '.' || name === '..')) {
files.push(new Entry(name, mode, size, mtime));
}
return readNext();
});
});
case Protocol.DONE:
return _this.parser.readBytes(16).then(function(zero) {
return files;
});
case Protocol.FAIL:
return _this._readError();
default:
return _this.parser.unexpected(reply, 'DENT, DONE or FAIL');
}
});
};
})(this);
this._sendCommandWithArg(Protocol.LIST, path);
return readNext().nodeify(callback);
};
Sync.prototype.push = function(contents, path, mode) {
if (typeof contents === 'string') {
return this.pushFile(contents, path, mode);
} else {
return this.pushStream(contents, path, mode);
}
};
Sync.prototype.pushFile = function(file, path, mode) {
if (mode == null) {
mode = DEFAULT_CHMOD;
}
mode || (mode = DEFAULT_CHMOD);
return this.pushStream(Fs.createReadStream(file), path, mode);
};
Sync.prototype.pushStream = function(stream, path, mode) {
if (mode == null) {
mode = DEFAULT_CHMOD;
}
mode |= Stats.S_IFREG;
this._sendCommandWithArg(Protocol.SEND, path + "," + mode);
return this._writeData(stream, Math.floor(Date.now() / 1000));
};
Sync.prototype.pull = function(path) {
this._sendCommandWithArg(Protocol.RECV, "" + path);
return this._readData();
};
Sync.prototype.end = function() {
this.connection.end();
return this;
};
Sync.prototype.tempFile = function(path) {
return Sync.temp(path);
};
Sync.prototype._writeData = function(stream, timeStamp) {
var readReply, reader, transfer, writeData, writer;
transfer = new PushTransfer;
writeData = (function(_this) {
return function() {
var endListener, errorListener, readableListener, resolver, track, waitForDrain, writeNext, writer;
resolver = Promise.defer();
writer = Promise.resolve().cancellable();
stream.on('end', endListener = function() {
return writer.then(function() {
_this._sendCommandWithLength(Protocol.DONE, timeStamp);
return resolver.resolve();
});
});
waitForDrain = function() {
var drainListener;
resolver = Promise.defer();
_this.connection.on('drain', drainListener = function() {
return resolver.resolve();
});
return resolver.promise["finally"](function() {
return _this.connection.removeListener('drain', drainListener);
});
};
track = function() {
return transfer.pop();
};
writeNext = function() {
var chunk;
if (chunk = stream.read(DATA_MAX_LENGTH) || stream.read()) {
_this._sendCommandWithLength(Protocol.DATA, chunk.length);
transfer.push(chunk.length);
if (_this.connection.write(chunk, track)) {
return writeNext();
} else {
return waitForDrain().then(writeNext);
}
} else {
return Promise.resolve();
}
};
stream.on('readable', readableListener = function() {
return writer.then(writeNext);
});
stream.on('error', errorListener = function(err) {
return resolver.reject(err);
});
return resolver.promise["finally"](function() {
stream.removeListener('end', endListener);
stream.removeListener('readable', readableListener);
stream.removeListener('error', errorListener);
return writer.cancel();
});
};
})(this);
readReply = (function(_this) {
return function() {
return _this.parser.readAscii(4).then(function(reply) {
switch (reply) {
case Protocol.OKAY:
return _this.parser.readBytes(4).then(function(zero) {
return true;
});
case Protocol.FAIL:
return _this._readError();
default:
return _this.parser.unexpected(reply, 'OKAY or FAIL');
}
});
};
})(this);
writer = writeData().cancellable()["catch"](Promise.CancellationError, (function(_this) {
return function(err) {
return _this.connection.end();
};
})(this))["catch"](function(err) {
transfer.emit('error', err);
return reader.cancel();
});
reader = readReply().cancellable()["catch"](Promise.CancellationError, function(err) {
return true;
})["catch"](function(err) {
transfer.emit('error', err);
return writer.cancel();
})["finally"](function() {
return transfer.end();
});
transfer.on('cancel', function() {
writer.cancel();
return reader.cancel();
});
return transfer;
};
Sync.prototype._readData = function() {
var cancelListener, readNext, reader, transfer;
transfer = new PullTransfer;
readNext = (function(_this) {
return function() {
return _this.parser.readAscii(4).cancellable().then(function(reply) {
switch (reply) {
case Protocol.DATA:
return _this.parser.readBytes(4).then(function(lengthData) {
var length;
length = lengthData.readUInt32LE(0);
return _this.parser.readByteFlow(length, transfer).then(readNext);
});
case Protocol.DONE:
return _this.parser.readBytes(4).then(function(zero) {
return true;
});
case Protocol.FAIL:
return _this._readError();
default:
return _this.parser.unexpected(reply, 'DATA, DONE or FAIL');
}
});
};
})(this);
reader = readNext()["catch"](Promise.CancellationError, (function(_this) {
return function(err) {
return _this.connection.end();
};
})(this))["catch"](function(err) {
return transfer.emit('error', err);
})["finally"](function() {
transfer.removeListener('cancel', cancelListener);
return transfer.end();
});
transfer.on('cancel', cancelListener = function() {
return reader.cancel();
});
return transfer;
};
Sync.prototype._readError = function() {
return this.parser.readBytes(4).then((function(_this) {
return function(length) {
return _this.parser.readBytes(length.readUInt32LE(0)).then(function(buf) {
return Promise.reject(new Parser.FailError(buf.toString()));
});
};
})(this))["finally"]((function(_this) {
return function() {
return _this.parser.end();
};
})(this));
};
Sync.prototype._sendCommandWithLength = function(cmd, length) {
var payload;
if (cmd !== Protocol.DATA) {
debug(cmd);
}
payload = new Buffer(cmd.length + 4);
payload.write(cmd, 0, cmd.length);
payload.writeUInt32LE(length, cmd.length);
return this.connection.write(payload);
};
Sync.prototype._sendCommandWithArg = function(cmd, arg) {
var payload, pos;
debug(cmd + " " + arg);
payload = new Buffer(cmd.length + 4 + arg.length);
pos = 0;
payload.write(cmd, pos, cmd.length);
pos += cmd.length;
payload.writeUInt32LE(arg.length, pos);
pos += 4;
payload.write(arg, pos);
return this.connection.write(payload);
};
Sync.prototype._enoent = function(path) {
var err;
err = new Error("ENOENT, no such file or directory '" + path + "'");
err.errno = 34;
err.code = 'ENOENT';
err.path = path;
return Promise.reject(err);
};
return Sync;
})(EventEmitter);
module.exports = Sync;
+23
View File
@@ -0,0 +1,23 @@
var Entry, Stats,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Stats = require('./stats');
Entry = (function(superClass) {
extend(Entry, superClass);
function Entry(name, mode, size, mtime) {
this.name = name;
Entry.__super__.constructor.call(this, mode, size, mtime);
}
Entry.prototype.toString = function() {
return this.name;
};
return Entry;
})(Stats);
module.exports = Entry;
+31
View File
@@ -0,0 +1,31 @@
var PullTransfer, Stream,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Stream = require('stream');
PullTransfer = (function(superClass) {
extend(PullTransfer, superClass);
function PullTransfer() {
this.stats = {
bytesTransferred: 0
};
PullTransfer.__super__.constructor.call(this);
}
PullTransfer.prototype.cancel = function() {
return this.emit('cancel');
};
PullTransfer.prototype.write = function(chunk, encoding, callback) {
this.stats.bytesTransferred += chunk.length;
this.emit('progress', this.stats);
return PullTransfer.__super__.write.call(this, chunk, encoding, callback);
};
return PullTransfer;
})(Stream.PassThrough);
module.exports = PullTransfer;
+40
View File
@@ -0,0 +1,40 @@
var EventEmitter, PushTransfer,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('events').EventEmitter;
PushTransfer = (function(superClass) {
extend(PushTransfer, superClass);
function PushTransfer() {
this._stack = [];
this.stats = {
bytesTransferred: 0
};
}
PushTransfer.prototype.cancel = function() {
return this.emit('cancel');
};
PushTransfer.prototype.push = function(byteCount) {
return this._stack.push(byteCount);
};
PushTransfer.prototype.pop = function() {
var byteCount;
byteCount = this._stack.pop();
this.stats.bytesTransferred += byteCount;
return this.emit('progress', this.stats);
};
PushTransfer.prototype.end = function() {
return this.emit('end');
};
return PushTransfer;
})(EventEmitter);
module.exports = PushTransfer;
+54
View File
@@ -0,0 +1,54 @@
var Fs, Stats,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Fs = require('fs');
Stats = (function(superClass) {
extend(Stats, superClass);
Stats.S_IFMT = 0xf000;
Stats.S_IFSOCK = 0xc000;
Stats.S_IFLNK = 0xa000;
Stats.S_IFREG = 0x8000;
Stats.S_IFBLK = 0x6000;
Stats.S_IFDIR = 0x4000;
Stats.S_IFCHR = 0x2000;
Stats.S_IFIFO = 0x1000;
Stats.S_ISUID = 0x800;
Stats.S_ISGID = 0x400;
Stats.S_ISVTX = 0x200;
Stats.S_IRWXU = 0x1c0;
Stats.S_IRUSR = 0x100;
Stats.S_IWUSR = 0x80;
Stats.S_IXUSR = 0x40;
Stats.S_IRWXG = 0x38;
Stats.S_IRGRP = 0x20;
function Stats(mode, size, mtime) {
this.mode = mode;
this.size = size;
this.mtime = new Date(mtime * 1000);
}
return Stats;
})(Fs.Stats);
module.exports = Stats;
+112
View File
@@ -0,0 +1,112 @@
var Packet;
Packet = (function() {
Packet.A_SYNC = 0x434e5953;
Packet.A_CNXN = 0x4e584e43;
Packet.A_OPEN = 0x4e45504f;
Packet.A_OKAY = 0x59414b4f;
Packet.A_CLSE = 0x45534c43;
Packet.A_WRTE = 0x45545257;
Packet.A_AUTH = 0x48545541;
Packet.checksum = function(data) {
var char, i, len, sum;
sum = 0;
if (data) {
for (i = 0, len = data.length; i < len; i++) {
char = data[i];
sum += char;
}
}
return sum;
};
Packet.magic = function(command) {
return (command ^ 0xffffffff) >>> 0;
};
Packet.assemble = function(command, arg0, arg1, data) {
var chunk;
if (data) {
chunk = new Buffer(24 + data.length);
chunk.writeUInt32LE(command, 0);
chunk.writeUInt32LE(arg0, 4);
chunk.writeUInt32LE(arg1, 8);
chunk.writeUInt32LE(data.length, 12);
chunk.writeUInt32LE(Packet.checksum(data), 16);
chunk.writeUInt32LE(Packet.magic(command), 20);
data.copy(chunk, 24);
return chunk;
} else {
chunk = new Buffer(24);
chunk.writeUInt32LE(command, 0);
chunk.writeUInt32LE(arg0, 4);
chunk.writeUInt32LE(arg1, 8);
chunk.writeUInt32LE(0, 12);
chunk.writeUInt32LE(0, 16);
chunk.writeUInt32LE(Packet.magic(command), 20);
return chunk;
}
};
Packet.swap32 = function(n) {
var buffer;
buffer = new Buffer(4);
buffer.writeUInt32LE(n, 0);
return buffer.readUInt32BE(0);
};
function Packet(command1, arg01, arg11, length, check, magic, data1) {
this.command = command1;
this.arg0 = arg01;
this.arg1 = arg11;
this.length = length;
this.check = check;
this.magic = magic;
this.data = data1;
}
Packet.prototype.verifyChecksum = function() {
return this.check === Packet.checksum(this.data);
};
Packet.prototype.verifyMagic = function() {
return this.magic === Packet.magic(this.command);
};
Packet.prototype.toString = function() {
var type;
type = (function() {
switch (this.command) {
case Packet.A_SYNC:
return "SYNC";
case Packet.A_CNXN:
return "CNXN";
case Packet.A_OPEN:
return "OPEN";
case Packet.A_OKAY:
return "OKAY";
case Packet.A_CLSE:
return "CLSE";
case Packet.A_WRTE:
return "WRTE";
case Packet.A_AUTH:
return "AUTH";
default:
throw new Error("Unknown command {@command}");
}
}).call(this);
return type + " arg0=" + this.arg0 + " arg1=" + this.arg1 + " length=" + this.length;
};
return Packet;
})();
module.exports = Packet;
+121
View File
@@ -0,0 +1,121 @@
var EventEmitter, Packet, PacketReader,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('events').EventEmitter;
Packet = require('./packet');
PacketReader = (function(superClass) {
extend(PacketReader, superClass);
function PacketReader(stream) {
this.stream = stream;
PacketReader.__super__.constructor.call(this);
this.inBody = false;
this.buffer = null;
this.packet = null;
this.stream.on('readable', this._tryRead.bind(this));
this.stream.on('error', (function(_this) {
return function(err) {
return _this.emit('error', err);
};
})(this));
this.stream.on('end', (function(_this) {
return function() {
return _this.emit('end');
};
})(this));
setImmediate(this._tryRead.bind(this));
}
PacketReader.prototype._tryRead = function() {
var header;
while (this._appendChunk()) {
while (this.buffer) {
if (this.inBody) {
if (!(this.buffer.length >= this.packet.length)) {
break;
}
this.packet.data = this._consume(this.packet.length);
if (!this.packet.verifyChecksum()) {
this.emit('error', new PacketReader.ChecksumError(this.packet));
return;
}
this.emit('packet', this.packet);
this.inBody = false;
} else {
if (!(this.buffer.length >= 24)) {
break;
}
header = this._consume(24);
this.packet = new Packet(header.readUInt32LE(0), header.readUInt32LE(4), header.readUInt32LE(8), header.readUInt32LE(12), header.readUInt32LE(16), header.readUInt32LE(20), new Buffer(0));
if (!this.packet.verifyMagic()) {
this.emit('error', new PacketReader.MagicError(this.packet));
return;
}
if (this.packet.length === 0) {
this.emit('packet', this.packet);
} else {
this.inBody = true;
}
}
}
}
};
PacketReader.prototype._appendChunk = function() {
var chunk;
if (chunk = this.stream.read()) {
if (this.buffer) {
return this.buffer = Buffer.concat([this.buffer, chunk], this.buffer.length + chunk.length);
} else {
return this.buffer = chunk;
}
} else {
return null;
}
};
PacketReader.prototype._consume = function(length) {
var chunk;
chunk = this.buffer.slice(0, length);
this.buffer = length === this.buffer.length ? null : this.buffer.slice(length);
return chunk;
};
return PacketReader;
})(EventEmitter);
PacketReader.ChecksumError = (function(superClass) {
extend(ChecksumError, superClass);
function ChecksumError(packet) {
this.packet = packet;
Error.call(this);
this.name = 'ChecksumError';
this.message = "Checksum mismatch";
Error.captureStackTrace(this, PacketReader.ChecksumError);
}
return ChecksumError;
})(Error);
PacketReader.MagicError = (function(superClass) {
extend(MagicError, superClass);
function MagicError(packet) {
this.packet = packet;
Error.call(this);
this.name = 'MagicError';
this.message = "Magic value mismatch";
Error.captureStackTrace(this, PacketReader.MagicError);
}
return MagicError;
})(Error);
module.exports = PacketReader;
+21
View File
@@ -0,0 +1,21 @@
var RollingCounter;
RollingCounter = (function() {
function RollingCounter(max, min) {
this.max = max;
this.min = min != null ? min : 1;
this.now = this.min;
}
RollingCounter.prototype.next = function() {
if (!(this.now < this.max)) {
this.now = this.min;
}
return ++this.now;
};
return RollingCounter;
})();
module.exports = RollingCounter;
+79
View File
@@ -0,0 +1,79 @@
var EventEmitter, Net, Server, Socket,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Net = require('net');
EventEmitter = require('events').EventEmitter;
Socket = require('./socket');
Server = (function(superClass) {
extend(Server, superClass);
function Server(client, serial, options) {
this.client = client;
this.serial = serial;
this.options = options;
this.connections = [];
this.server = Net.createServer({
allowHalfOpen: true
});
this.server.on('error', (function(_this) {
return function(err) {
return _this.emit('error', err);
};
})(this));
this.server.on('listening', (function(_this) {
return function() {
return _this.emit('listening');
};
})(this));
this.server.on('close', (function(_this) {
return function() {
return _this.emit('close');
};
})(this));
this.server.on('connection', (function(_this) {
return function(conn) {
var socket;
socket = new Socket(_this.client, _this.serial, conn, _this.options);
_this.connections.push(socket);
socket.on('error', function(err) {
return _this.emit('error', err);
});
socket.once('end', function() {
return _this.connections = _this.connections.filter(function(val) {
return val !== socket;
});
});
return _this.emit('connection', socket);
};
})(this));
}
Server.prototype.listen = function() {
this.server.listen.apply(this.server, arguments);
return this;
};
Server.prototype.close = function() {
this.server.close();
return this;
};
Server.prototype.end = function() {
var conn, i, len, ref;
ref = this.connections;
for (i = 0, len = ref.length; i < len; i++) {
conn = ref[i];
conn.end();
}
return this;
};
return Server;
})(EventEmitter);
module.exports = Server;
+203
View File
@@ -0,0 +1,203 @@
var EventEmitter, Packet, Parser, Promise, Protocol, Service, debug,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('events').EventEmitter;
Promise = require('bluebird');
debug = require('debug')('adb:tcpusb:service');
Parser = require('../parser');
Protocol = require('../protocol');
Packet = require('./packet');
Service = (function(superClass) {
extend(Service, superClass);
function Service(client, serial, localId1, remoteId, socket) {
this.client = client;
this.serial = serial;
this.localId = localId1;
this.remoteId = remoteId;
this.socket = socket;
Service.__super__.constructor.call(this);
this.opened = false;
this.ended = false;
this.transport = null;
this.needAck = false;
}
Service.prototype.end = function() {
var err, localId;
if (this.transport) {
this.transport.end();
}
if (this.ended) {
return this;
}
debug('O:A_CLSE');
localId = this.opened ? this.localId : 0;
try {
this.socket.write(Packet.assemble(Packet.A_CLSE, localId, this.remoteId, null));
} catch (_error) {
err = _error;
}
this.transport = null;
this.ended = true;
this.emit('end');
return this;
};
Service.prototype.handle = function(packet) {
return Promise["try"]((function(_this) {
return function() {
switch (packet.command) {
case Packet.A_OPEN:
return _this._handleOpenPacket(packet);
case Packet.A_OKAY:
return _this._handleOkayPacket(packet);
case Packet.A_WRTE:
return _this._handleWritePacket(packet);
case Packet.A_CLSE:
return _this._handleClosePacket(packet);
default:
throw new Error("Unexpected packet " + packet.command);
}
};
})(this))["catch"]((function(_this) {
return function(err) {
_this.emit('error', err);
return _this.end();
};
})(this));
};
Service.prototype._handleOpenPacket = function(packet) {
debug('I:A_OPEN', packet);
return this.client.transport(this.serial).then((function(_this) {
return function(transport) {
_this.transport = transport;
if (_this.ended) {
throw new LateTransportError();
}
_this.transport.write(Protocol.encodeData(packet.data.slice(0, -1)));
return _this.transport.parser.readAscii(4).then(function(reply) {
switch (reply) {
case Protocol.OKAY:
debug('O:A_OKAY');
_this.socket.write(Packet.assemble(Packet.A_OKAY, _this.localId, _this.remoteId, null));
return _this.opened = true;
case Protocol.FAIL:
return _this.transport.parser.readError();
default:
return _this.transport.parser.unexpected(reply, 'OKAY or FAIL');
}
});
};
})(this)).then((function(_this) {
return function() {
return new Promise(function(resolve, reject) {
_this.transport.socket.on('readable', function() {
return _this._tryPush();
}).on('end', resolve).on('error', reject);
return _this._tryPush();
});
};
})(this))["finally"]((function(_this) {
return function() {
return _this.end();
};
})(this));
};
Service.prototype._handleOkayPacket = function(packet) {
debug('I:A_OKAY', packet);
if (this.ended) {
return;
}
if (!this.transport) {
throw new Service.PrematurePacketError(packet);
}
this.needAck = false;
return this._tryPush();
};
Service.prototype._handleWritePacket = function(packet) {
debug('I:A_WRTE', packet);
if (this.ended) {
return;
}
if (!this.transport) {
throw new Service.PrematurePacketError(packet);
}
if (packet.data) {
this.transport.write(packet.data);
}
debug('O:A_OKAY');
return this.socket.write(Packet.assemble(Packet.A_OKAY, this.localId, this.remoteId, null));
};
Service.prototype._handleClosePacket = function(packet) {
debug('I:A_CLSE', packet);
if (this.ended) {
return;
}
if (!this.transport) {
throw new Service.PrematurePacketError(packet);
}
return this.end();
};
Service.prototype._tryPush = function() {
var chunk;
if (this.needAck || this.ended) {
return;
}
if (chunk = this._readChunk(this.transport.socket)) {
debug('O:A_WRTE');
this.socket.write(Packet.assemble(Packet.A_WRTE, this.localId, this.remoteId, chunk));
return this.needAck = true;
}
};
Service.prototype._readChunk = function(stream) {
return stream.read(this.socket.maxPayload) || stream.read();
};
return Service;
})(EventEmitter);
Service.PrematurePacketError = (function(superClass) {
extend(PrematurePacketError, superClass);
function PrematurePacketError(packet1) {
this.packet = packet1;
Error.call(this);
this.name = 'PrematurePacketError';
this.message = "Premature packet";
Error.captureStackTrace(this, Service.PrematurePacketError);
}
return PrematurePacketError;
})(Error);
Service.LateTransportError = (function(superClass) {
extend(LateTransportError, superClass);
function LateTransportError() {
Error.call(this);
this.name = 'LateTransportError';
this.message = "Late transport";
Error.captureStackTrace(this, Service.LateTransportError);
}
return LateTransportError;
})(Error);
module.exports = Service;
+48
View File
@@ -0,0 +1,48 @@
var ServiceMap;
ServiceMap = (function() {
function ServiceMap() {
this.remotes = Object.create(null);
this.count = 0;
}
ServiceMap.prototype.end = function() {
var ref, remote, remoteId;
ref = this.remotes;
for (remoteId in ref) {
remote = ref[remoteId];
remote.end();
}
this.remotes = Object.create(null);
this.count = 0;
};
ServiceMap.prototype.insert = function(remoteId, socket) {
if (this.remotes[remoteId]) {
throw new Error("Remote ID " + remoteId + " is already being used");
} else {
this.count += 1;
return this.remotes[remoteId] = socket;
}
};
ServiceMap.prototype.get = function(remoteId) {
return this.remotes[remoteId] || null;
};
ServiceMap.prototype.remove = function(remoteId) {
var remote;
if (remote = this.remotes[remoteId]) {
delete this.remotes[remoteId];
this.count -= 1;
return remote;
} else {
return null;
}
};
return ServiceMap;
})();
module.exports = ServiceMap;
+314
View File
@@ -0,0 +1,314 @@
var Auth, EventEmitter, Forge, Packet, PacketReader, Parser, Promise, Protocol, RollingCounter, Service, ServiceMap, Socket, crypto, debug,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
crypto = require('crypto');
EventEmitter = require('events').EventEmitter;
Promise = require('bluebird');
Forge = require('node-forge');
debug = require('debug')('adb:tcpusb:socket');
Parser = require('../parser');
Protocol = require('../protocol');
Auth = require('../auth');
Packet = require('./packet');
PacketReader = require('./packetreader');
Service = require('./service');
ServiceMap = require('./servicemap');
RollingCounter = require('./rollingcounter');
Socket = (function(superClass) {
var AUTH_RSAPUBLICKEY, AUTH_SIGNATURE, AUTH_TOKEN, TOKEN_LENGTH, UINT16_MAX, UINT32_MAX;
extend(Socket, superClass);
UINT32_MAX = 0xFFFFFFFF;
UINT16_MAX = 0xFFFF;
AUTH_TOKEN = 1;
AUTH_SIGNATURE = 2;
AUTH_RSAPUBLICKEY = 3;
TOKEN_LENGTH = 20;
function Socket(client, serial, socket, options) {
var base;
this.client = client;
this.serial = serial;
this.socket = socket;
this.options = options != null ? options : {};
(base = this.options).auth || (base.auth = Promise.resolve(true));
this.ended = false;
this.socket.setNoDelay(true);
this.reader = new PacketReader(this.socket).on('packet', this._handle.bind(this)).on('error', (function(_this) {
return function(err) {
debug("PacketReader error: " + err.message);
return _this.end();
};
})(this)).on('end', this.end.bind(this));
this.version = 1;
this.maxPayload = 4096;
this.authorized = false;
this.syncToken = new RollingCounter(UINT32_MAX);
this.remoteId = new RollingCounter(UINT32_MAX);
this.services = new ServiceMap;
this.remoteAddress = this.socket.remoteAddress;
this.token = null;
this.signature = null;
}
Socket.prototype.end = function() {
if (this.ended) {
return this;
}
this.services.end();
this.socket.end();
this.ended = true;
this.emit('end');
return this;
};
Socket.prototype._error = function(err) {
this.emit('error', err);
return this.end();
};
Socket.prototype._handle = function(packet) {
if (this.ended) {
return;
}
this.emit('userActivity', packet);
return Promise["try"]((function(_this) {
return function() {
switch (packet.command) {
case Packet.A_SYNC:
return _this._handleSyncPacket(packet);
case Packet.A_CNXN:
return _this._handleConnectionPacket(packet);
case Packet.A_OPEN:
return _this._handleOpenPacket(packet);
case Packet.A_OKAY:
case Packet.A_WRTE:
case Packet.A_CLSE:
return _this._forwardServicePacket(packet);
case Packet.A_AUTH:
return _this._handleAuthPacket(packet);
default:
throw new Error("Unknown command " + packet.command);
}
};
})(this))["catch"](Socket.AuthError, (function(_this) {
return function() {
return _this.end();
};
})(this))["catch"](Socket.UnauthorizedError, (function(_this) {
return function() {
return _this.end();
};
})(this))["catch"]((function(_this) {
return function(err) {
return _this._error(err);
};
})(this));
};
Socket.prototype._handleSyncPacket = function(packet) {
debug('I:A_SYNC');
debug('O:A_SYNC');
return this.write(Packet.assemble(Packet.A_SYNC, 1, this.syncToken.next(), null));
};
Socket.prototype._handleConnectionPacket = function(packet) {
var version;
debug('I:A_CNXN', packet);
version = Packet.swap32(packet.arg0);
this.maxPayload = Math.min(UINT16_MAX, packet.arg1);
return this._createToken().then((function(_this) {
return function(token) {
_this.token = token;
debug("Created challenge '" + (_this.token.toString('base64')) + "'");
debug('O:A_AUTH');
return _this.write(Packet.assemble(Packet.A_AUTH, AUTH_TOKEN, 0, _this.token));
};
})(this));
};
Socket.prototype._handleAuthPacket = function(packet) {
debug('I:A_AUTH', packet);
switch (packet.arg0) {
case AUTH_SIGNATURE:
debug("Received signature '" + (packet.data.toString('base64')) + "'");
if (!this.signature) {
this.signature = packet.data;
}
debug('O:A_AUTH');
return this.write(Packet.assemble(Packet.A_AUTH, AUTH_TOKEN, 0, this.token));
case AUTH_RSAPUBLICKEY:
if (!this.signature) {
throw new Socket.AuthError("Public key sent before signature");
}
if (!(packet.data && packet.data.length >= 2)) {
throw new Socket.AuthError("Empty RSA public key");
}
debug("Received RSA public key '" + (packet.data.toString('base64')) + "'");
return Auth.parsePublicKey(this._skipNull(packet.data)).then((function(_this) {
return function(key) {
var digest, sig;
digest = _this.token.toString('binary');
sig = _this.signature.toString('binary');
if (!key.verify(digest, sig)) {
debug("Signature mismatch");
throw new Socket.AuthError("Signature mismatch");
}
debug("Signature verified");
return key;
};
})(this)).then((function(_this) {
return function(key) {
return _this.options.auth(key)["catch"](function(err) {
debug("Connection rejected by user-defined auth handler");
throw new Socket.AuthError("Rejected by user-defined handler");
});
};
})(this)).then((function(_this) {
return function() {
return _this._deviceId();
};
})(this)).then((function(_this) {
return function(id) {
_this.authorized = true;
debug('O:A_CNXN');
return _this.write(Packet.assemble(Packet.A_CNXN, Packet.swap32(_this.version), _this.maxPayload, id));
};
})(this));
default:
throw new Error("Unknown authentication method " + packet.arg0);
}
};
Socket.prototype._handleOpenPacket = function(packet) {
var localId, name, remoteId, service;
if (!this.authorized) {
throw new Socket.UnauthorizedError();
}
remoteId = packet.arg0;
localId = this.remoteId.next();
if (!(packet.data && packet.data.length >= 2)) {
throw new Error("Empty service name");
}
name = this._skipNull(packet.data);
debug("Calling " + name);
service = new Service(this.client, this.serial, localId, remoteId, this);
return new Promise((function(_this) {
return function(resolve, reject) {
service.on('error', reject);
service.on('end', resolve);
_this.services.insert(localId, service);
debug("Handling " + _this.services.count + " services simultaneously");
return service.handle(packet);
};
})(this))["catch"](function(err) {
return true;
})["finally"]((function(_this) {
return function() {
_this.services.remove(localId);
debug("Handling " + _this.services.count + " services simultaneously");
return service.end();
};
})(this));
};
Socket.prototype._forwardServicePacket = function(packet) {
var localId, remoteId, service;
if (!this.authorized) {
throw new Socket.UnauthorizedError();
}
remoteId = packet.arg0;
localId = packet.arg1;
if (service = this.services.get(localId)) {
return service.handle(packet);
} else {
return debug("Received a packet to a service that may have been closed already");
}
};
Socket.prototype.write = function(chunk) {
if (this.ended) {
return;
}
return this.socket.write(chunk);
};
Socket.prototype._createToken = function() {
return Promise.promisify(crypto.randomBytes)(TOKEN_LENGTH);
};
Socket.prototype._skipNull = function(data) {
return data.slice(0, -1);
};
Socket.prototype._deviceId = function() {
debug("Loading device properties to form a standard device ID");
return this.client.getProperties(this.serial).then(function(properties) {
var id, prop;
id = ((function() {
var i, len, ref, results;
ref = ['ro.product.name', 'ro.product.model', 'ro.product.device'];
results = [];
for (i = 0, len = ref.length; i < len; i++) {
prop = ref[i];
results.push(prop + "=" + properties[prop] + ";");
}
return results;
})()).join('');
return new Buffer("device::" + id + "\0");
});
};
return Socket;
})(EventEmitter);
Socket.AuthError = (function(superClass) {
extend(AuthError, superClass);
function AuthError(message) {
this.message = message;
Error.call(this);
this.name = 'AuthError';
Error.captureStackTrace(this, Socket.AuthError);
}
return AuthError;
})(Error);
Socket.UnauthorizedError = (function(superClass) {
extend(UnauthorizedError, superClass);
function UnauthorizedError() {
Error.call(this);
this.name = 'UnauthorizedError';
this.message = "Unauthorized access";
Error.captureStackTrace(this, Socket.UnauthorizedError);
}
return UnauthorizedError;
})(Error);
module.exports = Socket;
+89
View File
@@ -0,0 +1,89 @@
var EventEmitter, Parser, Promise, Tracker,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EventEmitter = require('events').EventEmitter;
Promise = require('bluebird');
Parser = require('./parser');
Tracker = (function(superClass) {
extend(Tracker, superClass);
function Tracker(command) {
this.command = command;
this.deviceList = [];
this.deviceMap = {};
this.reader = this.read()["catch"](Promise.CancellationError, function() {
return true;
})["catch"](Parser.PrematureEOFError, function() {
throw new Error('Connection closed');
})["catch"]((function(_this) {
return function(err) {
_this.emit('error', err);
};
})(this))["finally"]((function(_this) {
return function() {
return _this.command.parser.end().then(function() {
return _this.emit('end');
});
};
})(this));
}
Tracker.prototype.read = function() {
return this.command._readDevices().cancellable().then((function(_this) {
return function(list) {
_this.update(list);
return _this.read();
};
})(this));
};
Tracker.prototype.update = function(newList) {
var changeSet, device, i, j, len, len1, newMap, oldDevice, ref;
changeSet = {
removed: [],
changed: [],
added: []
};
newMap = {};
for (i = 0, len = newList.length; i < len; i++) {
device = newList[i];
oldDevice = this.deviceMap[device.id];
if (oldDevice) {
if (oldDevice.type !== device.type) {
changeSet.changed.push(device);
this.emit('change', device, oldDevice);
}
} else {
changeSet.added.push(device);
this.emit('add', device);
}
newMap[device.id] = device;
}
ref = this.deviceList;
for (j = 0, len1 = ref.length; j < len1; j++) {
device = ref[j];
if (!newMap[device.id]) {
changeSet.removed.push(device);
this.emit('remove', device);
}
}
this.emit('changeSet', changeSet);
this.deviceList = newList;
this.deviceMap = newMap;
return this;
};
Tracker.prototype.end = function() {
this.reader.cancel();
return this;
};
return Tracker;
})(EventEmitter);
module.exports = Tracker;
+13
View File
@@ -0,0 +1,13 @@
var Auth, Parser;
Parser = require('./parser');
Auth = require('./auth');
module.exports.readAll = function(stream, callback) {
return new Parser(stream).readAll(stream).nodeify(callback);
};
module.exports.parsePublicKey = function(keyString, callback) {
return Auth.parsePublicKey(keyString).nodeify(callback);
};