Security News
Cloudflare Adds Security.txt Setup Wizard
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
adbkit is a pure Node.js client for the Android Debug Bridge server. It can be used either as a library in your own application, or simply as a convenient utility for playing with your device.
Most of the adb
command line tool's functionality is supported (including pushing/pulling files, installing APKs and processing logs), with some added functionality such as being able to generate touch/key events and take screenshots. Some shims are provided for older devices, but we have not and will not test anything below Android 2.3.
Internally, we use this library to drive a multitude of Android devices from a variety of manufacturers, so we can say with a fairly high degree of confidence that it will most likely work with your device(s), too.
adb
command line toolPlease note that although it may happen at some point, this project is NOT an implementation of the ADB server. The target host (where the devices are connected) must still have ADB installed and either already running (e.g. via adb start-server
) or available in $PATH
. An attempt will be made to start the server locally via the aforementioned command if the initial connection fails. This is the only case where we fall back to the adb
binary.
When targeting a remote host, starting the server is entirely your responsibility.
Alternatively, you may want to consider using the Chrome ADB extension, as it includes the ADB server and can be started/stopped quite easily.
Install via NPM:
npm install --save adbkit
We use debug, and our debug namespace is adb
. Some of the dependencies may provide debug output of their own. To see the debug output, set the DEBUG
environment variable. For example, run your program with DEBUG=adb:* node app.js
.
Note that even though the module is written in CoffeeScript, only the compiled JavaScript is published to NPM, which means that it can easily be used with pure JavaScript codebases, too.
var adb = require('adbkit');
var client = adb.createClient();
client.listDevices(function(err, devices) {
devices.forEach(function(device) {
client.getFeatures(device.id, function(err, features) {
if (features['android.hardware.nfc']) {
console.log('Device %s supports NFC', device.id);
}
});
});
});
var adb = require('adbkit');
var client = adb.createClient();
var apk = 'vendor/app.apk';
client.listDevices(function(err, devices) {
devices.forEach(function(device) {
client.install(device.id, apk, function(err) {
if (!err) {
console.log('Installed %s on device %s', apk, device.id);
}
});
});
});
var adb = require('adbkit');
var client = adb.createClient();
client.trackDevices(function(err, tracker) {
tracker.on('add', function(device) {
console.log('Device %s was plugged in', device.id);
});
tracker.on('remove', function(device) {
console.log('Device %s was unplugged', device.id);
});
});
var fs = require('fs');
var adb = require('adbkit');
var client = adb.createClient();
client.listDevices(function(err, devices) {
devices.forEach(function(device) {
client.pull(device.id, '/system/build.prop', function(err, transfer) {
transfer.on('progress', function(stats) {
console.log('Pulled %d bytes so far', stats.bytesTransferred);
});
transfer.on('end', function() {
console.log('Pull complete');
});
transfer.pipe(fs.createWriteStream(device.id + '.build.prop'));
});
});
});
var adb = require('adbkit');
var client = adb.createClient();
client.listDevices(function(err, devices) {
devices.forEach(function(device) {
client.push(device.id, 'foo.txt', '/data/local/tmp/foo.txt', function(err, transfer) {
transfer.on('progress', function(stats) {
console.log('Pushed %d bytes so far', stats.bytesTransferred);
});
transfer.on('end', function() {
console.log('Push complete');
});
});
});
});
var adb = require('adbkit');
var client = adb.createClient();
client.listDevices(function(err, devices) {
devices.forEach(function(device) {
client.readdir(device.id, '/sdcard', function(err, files) {
files.forEach(function(file) {
if (file.isFile()) {
console.log("Found file '%s' in /sdcard", file.name);
}
});
});
});
});
Creates a client instance with the provided options. Note that this will not automatically establish a connection, it will only be done when necessary.
5037
.'localhost'
.adb
binary, used for starting the server locally if initial connection fails. Defaults to 'adb'
.Deletes all data associated with a package from the device. This is roughly analogous to adb shell pm clear <pkg>
.
client.listDevices()
.null
when successful, Error
otherwise.Forwards socket connections from the ADB server host (local) to the device (remote). This is analogous to adb forward <local> <remote>
. It's important to note that if you are connected to a remote ADB server, the forward will be created on that host.
client.listDevices()
.tcp:<port>
localabstract:<unix domain socket name>
localreserved:<unix domain socket name>
localfilesystem:<unix domain socket name>
dev:<character device name>
local
argumentjdwp:<process pid>
null
when successful, Error
otherwise.Fetches the current raw framebuffer (i.e. what is visible on the screen) from the device, and optionally converts it into something more usable by using GraphicsMagick's gm
command, which must be available in $PATH
if conversion is desired. Note that we don't bother supporting really old framebuffer formats such as RGB_565. If for some mysterious reason you happen to run into a >=2.3
device that uses RGB_565, let us know.
Note that high-resolution devices can have quite massive framebuffers. For example, a device with a resolution of 1920x1080 and 32 bit colors would have a roughly 8MB (1920*1080*4
byte) RGBA framebuffer. Empirical tests point to about 5MB/s bandwidth limit for the ADB USB connection, which means that it can take ~1.6 seconds for the raw data to arrive, or even more if the USB connection is already congested. Using a conversion will further slow down completion.
client.listDevices()
.'png'
) is supported. Defaults to 'raw'
for raw framebuffer data.null
when successful, Error
otherwise.0
when not available.'bgr'
, 'bgra'
, 'rgb'
, 'rgba'
.Gets the device path of the device identified by the given serial number.
client.listDevices()
.null
when successful, Error
otherwise.client.listDevicesWithPaths()
.Retrieves the features of the device identified by the given serial number. This is analogous to adb shell pm list features
. Useful for checking whether hardware features such as NFC are available (you'd check for 'android.hardware.nfc'
).
client.listDevices()
.null
when successful, Error
otherwise.true
for a boolean feature, or the feature value as a string (e.g. '0x20000'
for reqGlEsVersion
).Retrieves the list of packages present on the device. This is analogous to adb shell pm list packages
. If you just want to see if something's installed, consider using client.isInstalled()
instead.
client.listDevices()
.null
when successful, Error
otherwise.Retrieves the properties of the device identified by the given serial number. This is analogous to adb shell getprop
.
client.listDevices()
.null
when successful, Error
otherwise.'ro.product.model'
.Gets the serial number of the device identified by the given serial number. With our API this doesn't really make much sense, but it has been implemented for completeness. FYI: in the raw ADB protocol you can specify a device in other ways, too.
client.listDevices()
.null
when successful, Error
otherwise.Gets the state of the device identified by the given serial number.
client.listDevices()
.null
when successful, Error
otherwise.client.listDevices()
.Installs the APK on the device, replacing any previously installed version. This is roughly analogous to adb install -r <apk>
.
client.listDevices()
.String
, interpreted as a path to an APK file. When Stream
, installs directly from the stream, which must be a valid APK.null
when successful, Error
otherwise.Tells you if the specific package is installed or not. This is analogous to adb shell pm path <pkg>
and some output parsing.
client.listDevices()
.null
when successful, Error
otherwise.true
if the package is installed, false
otherwise.This kills the ADB server. Note that the next connection will attempt to start the server again when it's unable to connect.
null
when successful, Error
otherwise.Gets the list of currently connected devices and emulators.
null
when successful, Error
otherwise.id
and type
.
'emulator'
for emulators, 'device'
for devices, and 'offline'
for offline devices. 'offline'
can occur for example during boot, in low-battery conditions or when the ADB connection has not yet been approved on the device.Like client.listDevices(callback)
, but includes the "path" of every device.
null
when successful, Error
otherwise.client.listDevices()
.client.listDevices()
.usb:FD120000
for real devices.Lists forwarded connections on the device. This is analogous to adb forward --list
.
client.listDevices()
.null
when successful, Error
otherwise.client.forward()
's local
argument.client.forward()
's remote
argument.Opens a direct connection to a binary log file, providing access to the raw log data. Note that it is usually much more convenient to use the client.openLogcat()
method, described separately.
client.listDevices()
.'main'
, 'system'
, 'radio'
and 'events'
.null
when successful, Error
otherwise.log.end()
when you wish to stop receiving data.Calls the logcat
utility on the device and hands off the connection to adbkit-logcat, a pure Node.js Logcat client. This is analogous to adb logcat -B
, but the event stream will be parsed for you and a separate event will be emitted for every log entry, allowing for easy processing.
For more information, check out the adbkit-logcat documentation.
client.listDevices()
.null
when successful, Error
otherwise.Starts the built-in monkey
utility on the device, connects to it using client.openTcp()
and hands the connection to adbkit-monkey, a pure Node.js Monkey client. This allows you to create touch and key events, among other things.
For more information, check out the adbkit-monkey documentation.
client.listDevices()
.1080
.null
when successful, Error
otherwise.Tracks /proc/stat
and emits useful information, such as CPU load. A single sync service instance is used to download the /proc/stat
file for processing. While doing this does consume some resources, it is very light and should not be a problem.
client.listDevices()
.null
when successful, Error
otherwise./proc/stat
tracker, which is an EventEmitter
. Call stat.end()
to stop tracking. The following events are available:
'cpu0'
, 'cpu1'
) and the value an object with the following properties:
nice
d user programs.nice
d guest.Opens a direct TCP connection to a port on the device, without any port forwarding required.
client.listDevices()
.null
when successful, Error
otherwise.net.Socket
). Read and write as you please. Call conn.end()
to end the connection.A convenience shortcut for sync.pull()
, mainly for one-off use cases. The connection cannot be reused, resulting in poorer performance over multiple calls. However, the Sync client will be closed automatically for you, so that's one less thing to worry about.
client.listDevices()
.sync.pull()
for details.sync.pull()
for details.A convenience shortcut for sync.push()
, mainly for one-off use cases. The connection cannot be reused, resulting in poorer performance over multiple calls. However, the Sync client will be closed automatically for you, so that's one less thing to worry about.
client.listDevices()
.sync.push()
for details.sync.push()
for details.sync.push()
for details.sync.push()
for details.A convenience shortcut for sync.readdir()
, mainly for one-off use cases. The connection cannot be reused, resulting in poorer performance over multiple calls. However, the Sync client will be closed automatically for you, so that's one less thing to worry about.
client.listDevices()
.sync.readdir()
for details.sync.readdir()
for details.Attempts to remount the /system
partition in read-write mode. This will usually only work on emulators and developer devices.
client.listDevices()
.null
when successful, Error
otherwise.Takes a screenshot in PNG format using the built-in screencap
utility. This is analogous to adb shell screencap -p
. Sadly, the utility is not available on most Android <=2.3
devices, but a silent fallback to the client.framebuffer()
command in PNG mode is attempted, so you should have its dependencies installed just in case.
Generating the PNG on the device naturally requires considerably more processing time on that side. However, as the data transferred over USB easily decreases by ~95%, and no conversion being required on the host, this method is usually several times faster than using the framebuffer. Naturally, this benefit does not apply if we're forced to fall back to the framebuffer.
client.listDevices()
.null
when successful, Error
otherwise.Runs a shell command on the device. Note that you'll be limited to the permissions of the shell
user, which ADB uses.
client.listDevices()
.String
, the command is run as-is. When Array
, the elements will be rudimentarily escaped (for convenience, not security) and joined to form a command.null
when successful, Error
otherwise.Stream
in non-flowing mode. Unfortunately it is not possible to separate stdout and stderr, you'll get both of them in one stream. It is also not possible to access the exit code of the command. If access to any of these individual properties is needed, the command must be constructed in a way that allows you to parse the information from the output.Starts the configured activity on the device. Roughly analogous to adb shell am start <options>
.
serial The serial number of the device. Corresponds to the device ID in client.listDevices()
.
options The activity configuration. The following options are available:
Array
, each item must be an Object
the following properties:
'string'
, 'null'
, 'bool'
, 'int'
, 'long'
, 'float'
, 'uri'
, 'component'
.'null'
. If an Array
, type is automatically set to be an array of <type>
.Object
, each key is treated as the key name. Simple values like null
, String
, Boolean
and Number
are type-mapped automatically (Number
maps to 'int'
) and can be used as-is. For more complex types, like arrays and URIs, set the value to be an Object
like in the Array syntax (see above), but leave out the key
property.callback(err)
null
when successful, Error
otherwise.Returns: The client instance.
A convenience shortcut for sync.stat()
, mainly for one-off use cases. The connection cannot be reused, resulting in poorer performance over multiple calls. However, the Sync client will be closed automatically for you, so that's one less thing to worry about.
client.listDevices()
.sync.stat()
for details.sync.stat()
for details.Establishes a new Sync connection that can be used to push and pull files. This method provides the most freedom and the best performance for repeated use, but can be a bit cumbersome to use. For simple use cases, consider using client.stat()
, client.push()
and client.pull()
.
client.listDevices()
.null
when successful, Error
otherwise.sync.end()
when done.Gets a device tracker. Events will be emitted when devices are added, removed, or their type changes (i.e. to/from offline
). Note that the same events will be emitted for the initially connected devices also, so that you don't need to use both client.listDevices()
and client.trackDevices()
.
Note that as the tracker will keep a connection open, you must call tracker.end()
if you wish to stop tracking devices.
null
when successful, Error
otherwise.EventEmitter
. The following events are available:
client.listDevices()
for details on the device object.offline
devices, those devices are connected but unavailable to ADB. See client.listDevices()
for details on the device object.type
property of a device changes, once per device. The current value of type
is the new value. This event usually occurs the type changes from 'device'
to 'offline'
or the other way around. See client.listDevices()
for details on the device object and the 'offline'
type.add
event. Empty if none.remove
event. Empty if none.change
event. Empty if none.Uninstalls the package from the device. This is roughly analogous to adb uninstall <pkg>
.
client.listDevices()
.null
when successful, Error
otherwise.Queries the ADB server for its version. This is mainly useful for backwards-compatibility purposes.
null
when successful, Error
otherwise.Waits until the device has finished booting. Note that the device must already be seen by ADB. This is roughly analogous to periodically checking adb shell getprop sys.boot_completed
.
client.listDevices()
.null
if the device has completed booting, Error
otherwise (can occur if the connection dies while checking).Closes the Sync connection, allowing Node to quit (assuming nothing else is keeping it alive, of course).
Pulls a file from the device as a PullTransfer
Stream
.
null
when successfully initialized, Error
otherwise. Note that transfer
may still emit errors that occur during the transfer.PullTransfer
instance returned by the sync.pull()
call.PullTransfer
instance. See below for details.Attempts to identify contents
and calls the appropriate push*
method for it.
String
, treated as a local file path and forwarded to sync.pushFile()
. Otherwise, treated as a Stream
and forwarded to sync.pushStream()
.0644
.null
when successfully initialized, Error
otherwise. Note that transfer
may still emit errors that occur during the transfer.PushTransfer
instance returned by the sync.push()
call.PushTransfer
instance. See below for details.Pushes a local file to the given path. Note that the path must be writable by the ADB user (usually shell
). When in doubt, use '/data/local/tmp'
with an appropriate filename.
sync.push()
for details.sync.push()
for details.sync.push()
for details.sync.push()
for details.Pushes a Stream
to the given path. Note that the path must be writable by the ADB user (usually shell
). When in doubt, use '/data/local/tmp'
with an appropriate filename.
sync.push()
for details.sync.push()
for details.sync.push()
for details.sync.push()
for details.Retrieves a list of directory entries (e.g. files) in the given path, not including the .
and ..
entries, just like fs.readdir
. If given a non-directory path, no entries are returned.
null
when successful, Error
otherwise.Array
of fs.Stats
-compatible instances. While the stats.is*
methods are available, only the following properties are supported (in addition to the name
field which contains the filename):
Date
.Retrieves information about the given path.
null
when successful, Error
otherwise.fs.Stats
instance. While the stats.is*
methods are available, only the following properties are supported:
Date
.A simple helper method for creating appropriate temporary filenames for pushing files. This is essentially the same as taking the basename of the file and appending it to '/data/local/tmp/'
.
A simple EventEmitter, mainly for keeping track of the progress.
List of events:
Error
.Cancels the transfer by ending both the stream that is being pushed and the sync connection. This will most likely end up creating a broken file on your device. Use at your own risk. Also note that you must create a new sync connection if you wish to continue using the sync service.
PullTransfer
is a Stream
. Use fs.createWriteStream()
to pipe the stream to a file if necessary.
List of events:
Error
.Cancels the transfer by ending the connection. Can be useful for reading endless streams of data, such as /dev/urandom
or /dev/zero
, perhaps for benchmarking use. Note that you must create a new sync connection if you wish to continue using the sync service.
See CONTRIBUTING.md.
See LICENSE.
Copyright © CyberAgent, Inc. All Rights Reserved.
FAQs
A pure Node.js client for the Android Debug Bridge.
The npm package adbkit receives a total of 14,166 weekly downloads. As such, adbkit popularity was classified as popular.
We found that adbkit demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
Security News
The Socket Research team breaks down a malicious npm package targeting the legitimate DOMPurify library. It uses obfuscated code to hide that it is exfiltrating browser and crypto wallet data.
Security News
ENISA’s 2024 report highlights the EU’s top cybersecurity threats, including rising DDoS attacks, ransomware, supply chain vulnerabilities, and weaponized AI.