Gathering detailed insights and metrics for @devicefarmer/adbkit
Gathering detailed insights and metrics for @devicefarmer/adbkit
Gathering detailed insights and metrics for @devicefarmer/adbkit
Gathering detailed insights and metrics for @devicefarmer/adbkit
npm install @devicefarmer/adbkit
Typescript
Module System
Min. Node Version
Node Version
NPM Version
TypeScript (99.48%)
JavaScript (0.52%)
Total Downloads
5,527,487
Last Day
7,749
Last Week
49,056
Last Month
265,550
Last Year
2,346,049
242 Stars
621 Commits
56 Forks
4 Watching
9 Branches
1 Contributors
Minified
Minified + Gzipped
Latest Version
3.3.8
Package Id
@devicefarmer/adbkit@3.3.8
Unpacked Size
545.45 kB
Size
107.52 kB
File Count
383
NPM Version
8.19.4
Node Version
16.20.2
Publised On
20 Nov 2024
Cumulative downloads
Total Downloads
Last day
-36.6%
7,749
Compared to previous day
Last week
-25.2%
49,056
Compared to previous week
Last month
-15.4%
265,550
Compared to previous month
Last year
84.2%
2,346,049
Compared to previous year
7
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.
For Linux users, adb need plugdev
group acess, So you may need to add your current user to plugdev
group.
sudo usermod -a -G plugdev $USER
Install via NPM:
1npm install --save @devicefarmer/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
.
The examples may be a bit verbose, but that's because we're trying to keep them as close to real-life code as possible, with flow control and error handling taken care of.
1import Bluebird from 'bluebird'; 2import Adb from '@devicefarmer/adbkit'; 3 4const client = Adb.createClient(); 5 6const test = async () => { 7 try { 8 const devices = await client.listDevices(); 9 const supportedDevices = await Bluebird.filter(devices, async (device) => { 10 const features = await client.getFeatures(device.id); 11 return features['android.hardware.nfc']; 12 }); 13 console.log('The following devices support NFC:', supportedDevices); 14 } catch (err) { 15 console.error('Something went wrong:', err.stack); 16 } 17};
1import Bluebird from 'bluebird'; 2import Adb from '@devicefarmer/adbkit'; 3 4const client = Adb.createClient(); 5const apk = 'vendor/app.apk'; 6 7const test = async () => { 8 try { 9 const devices = await client.listDevices(); 10 await Bluebird.map(devices, (device) => client.install(device.id, apk)); 11 console.log(`Installed ${apk} on all connected devices`); 12 } catch (err) { 13 console.error('Something went wrong:', err.stack); 14 } 15};
1import Adb from '@devicefarmer/adbkit'; 2 3const client = Adb.createClient(); 4const test = async () => { 5 try { 6 const tracker = await client.trackDevices(); 7 tracker.on('add', (device) => console.log('Device %s was plugged in', device.id)); 8 tracker.on('remove', (device) => console.log('Device %s was unplugged', device.id)); 9 tracker.on('end', () => console.log('Tracking stopped')); 10 } catch (err) { 11 console.error('Something went wrong:', err.stack); 12 } 13};
1import Bluebird from 'bluebird'; 2import fs from 'fs'; 3import Adb from '@devicefarmer/adbkit'; 4const client = Adb.createClient(); 5 6const test = async () => { 7 try { 8 const devices = await client.listDevices(); 9 await Bluebird.map(devices, async (device) => { 10 const transfer = await client.pull(device.id, '/system/build.prop'); 11 const fn = `/tmp/${device.id}.build.prop`; 12 await new Bluebird((resolve, reject) => { 13 transfer.on('progress', (stats) => 14 console.log(`[${device.id}] Pulled ${stats.bytesTransferred} bytes so far`), 15 ); 16 transfer.on('end', () => { 17 console.log(`[${device.id}] Pull complete`); 18 resolve(device.id); 19 }); 20 transfer.on('error', reject); 21 transfer.pipe(fs.createWriteStream(fn)); 22 }); 23 }); 24 console.log('Done pulling /system/build.prop from all connected devices'); 25 } catch (err) { 26 console.error('Something went wrong:', err.stack); 27 } 28};
1import Bluebird from 'bluebird'; 2import Adb from '@devicefarmer/adbkit'; 3const client = Adb.createClient(); 4 5const test = async () => { 6 try { 7 const devices = await client.listDevices(); 8 await Bluebird.map(devices, async (device) => { 9 const transfer = await client.push(device.id, 'temp/foo.txt', '/data/local/tmp/foo.txt'); 10 await new Bluebird(function (resolve, reject) { 11 transfer.on('progress', (stats) => 12 console.log(`[${device.id}] Pushed ${stats.bytesTransferred} bytes so far`), 13 ); 14 transfer.on('end', () => { 15 console.log('[${device.id}] Push complete'); 16 resolve(); 17 }); 18 transfer.on('error', reject); 19 }); 20 }); 21 console.log('Done pushing foo.txt to all connected devices'); 22 } catch (err) { 23 console.error('Something went wrong:', err.stack); 24 } 25};
1import Bluebird from 'bluebird'; 2import Adb from '@devicefarmer/adbkit'; 3const client = Adb.createClient(); 4 5const test = async () => { 6 try { 7 const devices = await client.listDevices(); 8 await Bluebird.map(devices, async (device) => { 9 const files = await client.readdir(device.id, '/sdcard'); 10 // Synchronous, so we don't have to care about returning at the 11 // right time 12 files.forEach((file) => { 13 if (file.isFile()) { 14 console.log(`[${device.id}] Found file "${file.name}"`); 15 } 16 }); 17 }); 18 console.log('Done checking /sdcard files on connected devices'); 19 } catch (err) { 20 console.error('Something went wrong:', err.stack); 21 } 22};
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
.'127.0.0.1'
.adb
binary, used for starting the server locally if initial connection fails. Defaults to 'adb'
.0
which means no timeout.Parses an Android-formatted mincrypt public key (e.g. ~/.android/adbkey.pub
).
Buffer
to parse. Not a filename.Promise
.
null
when successful, Error
otherwise.forge.ssh.getPublicKeyFingerprint(key)
, because the device fingerprint is based on the original format.Promise
key
(see callback)Takes a Stream
and reads everything it outputs until the stream ends. Then it resolves with the collected output. Convenient with client.shell()
.
Stream
to read.Promise
.
null
when successful, Error
otherwise.Buffer
. Use output.toString('utf-8')
to get a readable string from it.Promise
output
(see callback)Queries the ADB server for its version. This is mainly useful for backwards-compatibility purposes.
Promise
.
null
when successful, Error
otherwise.Promise
version
(see callback)Connects to the given device, which must have its ADB daemon running in tcp mode (see client.tcpip()
) and be accessible on the same network. Same as adb connect <host>:<port>
.
5555
.Promise
.
null
when successful, Error
otherwise.serial
in other commands.Promise
id
(see callback)Note: be careful with using client.listDevices()
together with client.tcpip()
and other similar methods that modify the connection with ADB. You might have the same device twice in your device list (i.e. one device connected via both USB and TCP), which can cause havoc if run simultaneously.
1import Bluebird from 'bluebird'; 2import Adb from '@devicefarmer/adbkit'; 3const client = Adb.createClient(); 4 5const test = async () => { 6 try { 7 const devices = await client.listDevices(); 8 await Bluebird.map(devices, async (device) => { 9 const device = client.getDevice(device.id); 10 const port = await device.tcpip(); 11 // Switching to TCP mode causes ADB to lose the device for a 12 // moment, so let's just wait till we get it back. 13 await device.waitForDevice(); 14 const ip = await device.getDHCPIpAddress(); 15 const deviceTCP = await client.connect(ip, port); 16 // It can take a moment for the connection to happen. 17 await deviceTCP.waitForDevice(); 18 await deviceTCP.forward('tcp:9222', 'localabstract:chrome_devtools_remote'); 19 console.log(`Setup devtools on "${id}"`); 20 }); 21 } catch (err) { 22 console.error('Something went wrong:', err.stack); 23 } 24};
Disconnects from the given device, which should have been connected via client.connect()
or just adb connect <host>:<port>
.
id
you got from client.connect()
here and it will be fine.5555
.Promise
.
null
when successful, Error
otherwise.serial
in other commands until you've connected again.Promise
id
(see callback)This kills the ADB server. Note that the next connection will attempt to start the server again when it's unable to connect.
Promise<true>
true
Gets the list of currently connected devices and emulators.
Promise<devices>
An array of device objects. The device objects are plain JavaScript objects with two properties: 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.- Resolves with: devices
(see callback)Like client.listDevices()
, but includes the "path" of every device.
Promise<devices>
An array of device objects. The device objects are plain JavaScript objects with the following properties:
client.listDevices()
.client.listDevices()
.usb:FD120000
for real devices.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.
Promise
.
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.Promise
tracker
(see callback)Deletes all data associated with a package from the device. This is roughly analogous to adb shell pm clear <pkg>
.
Promise
.
null
when successful, Error
otherwise.Promise
true
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.
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>
Promise
.
null
when successful, Error
otherwise.Promise
true
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.
'png'
) is supported. Defaults to 'raw'
for raw framebuffer data.Promise
.
null
when successful, Error
otherwise.meta
property with the following values:
0
when not available.'bgr'
, 'bgra'
, 'rgb'
, 'rgba'
.Promise
framebuffer
(see callback)Gets the device path of the device identified by the given serial number.
Promise
.
null
when successful, Error
otherwise.client.listDevicesWithPaths()
.Promise
path
(see callback)Attemps to retrieve the IP address of the device. Roughly analogous to adb shell getprop dhcp.<iface>.ipaddress
.
'wlan0'
.Promise
.
null
when successful, Error
otherwise.String
.Promise
ip
(see callback)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'
).
flags Flags to pass to the pm list packages
command to filter the list
-d: filter to only show disabled packages
-e: filter to only show enabled packages
-s: filter to only show system packages
-3: filter to only show third party packages
Promise
.
null
when successful, Error
otherwise.true
for a boolean feature, or the feature value as a string (e.g. '0x20000'
for reqGlEsVersion
).Promise
features
(see callback)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.
Promise
.
null
when successful, Error
otherwise.Promise
packages
(see callback)Retrieves the properties of the device identified by the given serial number. This is analogous to adb shell getprop
.
Promise
.
null
when successful, Error
otherwise.'ro.product.model'
.Promise
properties
(see callback)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.
Promise
.
null
when successful, Error
otherwise.Promise
serial
(see callback)Gets the state of the device identified by the given serial number.
Promise
.
null
when successful, Error
otherwise.client.listDevices()
.Promise
state
(see callback)Installs the APK on the device, replacing any previously installed version. This is roughly analogous to adb install -r <apk>
.
Note that if the call seems to stall, you may have to accept a dialog on the phone first.
String
, interpreted as a path to an APK file. When Stream
, installs directly from the stream, which must be a valid APK.Promise
.
null
when successful, Error
otherwise. It may have a .code
property containing the error code reported by the device.Promise
true
This example requires the request module. It also doesn't do any error handling (404 responses, timeouts, invalid URLs etc).
1import Adb from '@devicefarmer/adbkit'; 2import request from 'request'; 3import { Readable } from 'stream'; 4 5const client = Adb.createClient(); 6 7const test = async () => { 8 // The request module implements old-style streams, so we have to wrap it. 9 try { 10 // request is deprecated 11 const device = client.getClient('<serial>'); 12 await device.install(new Readable().wrap(request('http://example.org/app.apk') as any) as any) 13 console.log('Installed') 14 } catch (err) { 15 console.error('Something went wrong:', err.stack) 16 } 17}
Installs an APK file which must already be located on the device file system, and replaces any previously installed version. Useful if you've previously pushed the file to the device for some reason (perhaps to have direct access to client.push()
's transfer stats). This is roughly analogous to adb shell pm install -r <apk>
followed by adb shell rm -f <apk>
.
Note that if the call seems to stall, you may have to accept a dialog on the phone first.
Promise
.
null
when successful, Error
otherwise.Promise
true
Tells you if the specific package is installed or not. This is analogous to adb shell pm path <pkg>
and some output parsing.
Promise
.
null
when successful, Error
otherwise.true
if the package is installed, false
otherwise.Promise
installed
(see callback)Lists forwarded connections on the device. This is analogous to adb forward --list
.
Promise
.
null
when successful, Error
otherwise.client.forward()
's local
argument.client.forward()
's remote
argument.Promise
forwards
(see callback)Lists forwarded connections on the device. This is analogous to adb reverse --list
.
callback(err, forwards) Optional. Use this or the returned Promise
.
null
when successful, Error
otherwise.client.reverse()
's remote
argument.client.reverse()
's local
argument.Returns: Promise
Resolves with: reverses
(see callback)
Opens a direct connection to a unix domain socket in the given path.
'localfilesystem:'
by default, include another prefix (e.g. 'localabstract:'
) in the path to override.Promise
.
null
when successful, Error
otherwise.net.Socket
). Read and write as you please. Call conn.end()
to end the connection.Promise
conn
(see callback)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.
'main'
, 'system'
, 'radio'
and 'events'
.Promise
.
null
when successful, Error
otherwise.log.end()
when you wish to stop receiving data.Promise
log
(see callback)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.
true
, clears logcat before opening the reader. Not set by default.Promise
.
null
when successful, Error
otherwise.Promise
logcat
(see callback)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.
1080
.Promise
.
null
when successful, Error
otherwise.Promise
monkey
(see callback)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.
Promise
.
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.Promise
stats
(see callback)Opens a direct TCP connection to a port on the device, without any port forwarding required.
Promise
.
null
when successful, Error
otherwise.net.Socket
). Read and write as you please. Call conn.end()
to end the connection.Promise
conn
(see callback)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.
sync.pull()
for details.Promise
.
null
when successful, Error
otherwise.PullTransfer
instance (see below)Promise
transfer
(see callback)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.
sync.push()
for details.sync.push()
for details.sync.push()
for details.Promise
.
null
when successful, Error
otherwise.PushTransfer
instance (see below)Promise
transfer
(see callback)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.
sync.readdir()
for details.Promise
. See sync.readdir()
for details.Promise
sync.readdir()
for details.Reboots the device. Similar to adb reboot
. Note that the method resolves when ADB reports that the device has been rebooted (i.e. the reboot command was successful), not when the device becomes available again.
Promise
.
null
when successful, Error
otherwise.Promise
true
Attempts to remount the /system
partition in read-write mode. This will usually only work on emulators and developer devices.
Promise
.
null
when successful, Error
otherwise.Promise
true
Reverses socket connections from the device (remote) to the ADB server host (local). This is analogous to adb reverse <remote> <local>
. It's important to note that if you are connected to a remote ADB server, the reverse will be created on that host.
tcp:<port>
localabstract:<unix domain socket name>
localreserved:<unix domain socket name>
localfilesystem:<unix domain socket name>
remote
argument.Promise
.
null
when successful, Error
otherwise.Promise
true
Puts the device into root mode which may be needed by certain shell commands. A remount is generally required after a successful root call. Note that this will only work if your device supports this feature. Production devices almost never do.
Promise
.
null
when successful, Error
otherwise.Promise
true
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.
For convenience purposes, if the screencap command fails (e.g. because it doesn't exist on older Androids), we fall back to client.framebuffer(serial, 'png')
, which is slower and has additional installation requirements.
Promise
.
null
when successful, Error
otherwise.Promise
screencap
(see callback)Runs a shell command on the device. Note that you'll be limited to the permissions of the shell
user, which ADB uses.
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.Promise
.
null
when successful, Error
otherwise.Socket
actually) containing the progressive stdout
of the command. Use with adb.util.readAll
to get a readable String from it.Promise
conn
(see callback)1import Bluebird from 'bluebird'; 2import Adb from '@devicefarmer/adbkit'; 3 4const client = Adb.createClient(); 5 6client 7 .listDevices() 8 .then(function (devices) { 9 return Promise.map(devices, function (device) { 10 const device = client.getDevice(device.id); 11 return ( 12 device 13 .shell('echo $RANDOM') 14 // Use the readAll() utility to read all the content without 15 // having to deal with the readable stream. `output` will be a Buffer 16 // containing all the output. 17 .then(adb.util.readAll) 18 .then(function (output) { 19 console.log('[%s] %s', device.id, output.toString().trim()); 20 }) 21 ); 22 }); 23 }) 24 .then(function () { 25 console.log('Done.'); 26 }) 27 .catch(function (err) { 28 console.error('Something went wrong:', err.stack); 29 });
1import Bluebird from 'bluebird'; 2import Adb from '@devicefarmer/adbkit'; 3 4const client = Adb.createClient(); 5client.listDevices() 6 .then(function(devices) { 7 return Bluebird.map(devices, function(device) { 8 const device = client.getDevice(device.id); 9 return device.shell('logcat') // logcat just for illustration, 10 // prefer client.openLogcat in real use 11 .then(function(conn) { 12 var line = 0 13 conn.on('data', function(data) { 14 // here `ps` on the device shows the running logcat process 15 console.log(data.toString()) 16 line += 1 17 // close the stream and the running process 18 // on the device will be gone, gracefully 19 if (line > 100) conn.end() 20 }); 21 conn.on('close', function() { 22 // here `ps` on the device shows the logcat process is gone 23 console.log('100 lines read already, bye') 24 }) 25 }) 26 }) 27 }) 28 .then(function() { 29 console.log('Done.') 30 }) 31 .catch(function(err) { 32 console.error('Something went wrong:', err.stack) 33 })
Starts the configured activity on the device. Roughly analogous to adb shell am start <options>
.
true
to enable debugging.true
to wait for the activity to launch.Array
.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.Promise
.
null
when successful, Error
otherwise.Promise
true
Starts the configured service on the device. Roughly analogous to adb shell am startservice <options>
.
0
. If the option is unsupported by the device, an attempt will be made to run the same command again without the user option.client.startActivity()
for details.client.startActivity()
for details.client.startActivity()
for details.client.startActivity()
for details.client.startActivity()
for details.client.startActivity()
for details.client.startActivity()
for details.Promise
true
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.
sync.stat()
for details.Promise
. See sync.stat()
for details.Promise
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()
.
Promise
.
null
when successful, Error
otherwise.sync.end()
when done.Promise
sync
(see callback)Puts the device's ADB daemon into tcp mode, allowing you to use adb connect
or client.connect()
to connect to it. Note that the device will still be visible to ADB as a regular USB-connected device until you unplug it. Same as adb tcpip <port>
.
5555
.Promise
.
null
when successful, Error
otherwise.Promise
port
(see callback)Starts a JDWP tracker for the given device.
Note that as the tracker will keep a connection open, you must call tracker.end()
if you wish to stop tracking JDWP processes.
Promise
.
null
when successful, Error
otherwise.EventEmitter
. The following events are available:
Promise
tracker
(see callback)Uninstalls the package from the device. This is roughly analogous to adb uninstall <pkg>
.
Promise
.
null
when successful, Error
otherwise.Promise
true
Puts the device's ADB daemon back into USB mode. Reverses client.tcpip()
. Same as adb usb
.
Promise
.
null
when successful, Error
otherwise.Promise
true
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
.
Promise
.
null
if the device has completed booting, Error
otherwise (can occur if the connection dies while checking).Promise
true
Waits until ADB can see the device. Note that you must know the serial in advance. Other than that, works like adb -s serial wait-for-device
. If you're planning on reacting to random devices being plugged in and out, consider using client.trackDevices()
instead.
Promise
.
null
if the device has completed booting, Error
otherwise (can occur if the connection dies while checking).Promise
id
(see callback)Reattaches ADB to the device's ADB USB interface. This re-enables communication between ADB and device, reversing client.detach()
.
Promise
.
null
if the device device was reattached successfully, Error
otherwise (can occur if the device is not detached).Promise
true
Detaches ADB's USB interface from ADB. This releases the device from ADB control, allowing other processes to use it.
Promise
.
null
if the device device was detached successfully, Error
otherwise (can occur if the device is not attached).Promise
true
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
.
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
.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.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.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.
Promise
.
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
.Promise
files
(see callback)Retrieves information about the given path.
Promise
.
null
when successful, Error
otherwise.fs.Stats
instance. While the stats.is*
methods are available, only the following properties are supported:
Date
.Promise
stats
(see callback)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.
Previously, we made extensive use of callbacks in almost every feature. While this normally works okay, ADB connections can be quite fickle, and it was starting to become difficult to handle every possible error. For example, we'd often fail to properly clean up after ourselves when a connection suddenly died in an unexpected place, causing memory and resource leaks.
In version 2, we've replaced nearly all callbacks with Promises (using Bluebird), allowing for much more reliable error propagation and resource cleanup (thanks to .finally()
). Additionally, many commands can now be cancelled on the fly, and although unimplemented at this point, we'll also be able to report progress on long-running commands without any changes to the API.
Unfortunately, some API changes were required for this change. client.framebuffer()
's callback, for example, previously accepted more than one argument, which doesn't translate into Promises so well. Thankfully, it made sense to combine the arguments anyway, and we were able to do it quite cleanly.
Furthermore, most API methods were returning the current instance for chaining purposes. While perhaps useful in some contexts, most of the time it probably didn't quite do what users expected, as chained calls were run in parallel rather than in serial fashion. Now every applicable API method returns a Promise, which is an incompatible but welcome change. This will also allow you to hook into yield
and coroutines in Node 0.12.
However, all methods still accept (and will accept in the future) callbacks for those who prefer them.
Test coverage was also massively improved, although we've still got ways to go.
See CONTRIBUTING.md.
See LICENSE.
Copyright © The OpenSTF Project. All Rights Reserved.
No vulnerabilities found.
Reason
all last 30 commits are reviewed through GitHub
Reason
no vulnerabilities detected
Reason
update tool detected
Details
Reason
tokens are read-only in GitHub workflows
Reason
no dangerous workflow patterns detected
Reason
license file detected
Details
Reason
all dependencies are pinned
Details
Reason
no binaries found in the repo
Reason
branch protection is not maximal on development and all release branches
Details
Reason
3 commit(s) out of 30 and 0 issue activity out of 30 found in the last 90 days -- score normalized to 2
Reason
no badge detected
Reason
security policy file not detected
Reason
project is not fuzzed
Score
Last Scanned on 2022-08-15
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More