Class DeviceClient

Hierarchy

  • DeviceClient

Constructors

Properties

client: Client
serial: string

Accessors

Methods

  • Retrieves the list of available services

    Returns

    a PsEntry array

    Parameters

    • serviceName: string

    Returns Promise<boolean>

  • Deletes all data associated with a package from the device. This is roughly analogous to adb shell pm clear <pkg>.

    Returns

    true

    Parameters

    • pkg: string

      The package name. This is NOT the APK.

    Returns Promise<boolean>

  • execute a single shell command and get stdout responce as a buffer of a string.

    Parameters

    • command: string | ArrayLike<WithToString>

      the command to execute

    Returns Promise<Buffer>

  • Parameters

    • command: string | ArrayLike<WithToString>
    • encoding: BufferEncoding

    Returns Promise<string>

  • 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.

    Returns

    true

    Parameters

    • local: string

      A string representing the local endpoint on the ADB host. At time of writing, can be one of:

      • tcp:<port>
      • localabstract:<unix domain socket name>
      • localreserved:<unix domain socket name>
      • localfilesystem:<unix domain socket name>
      • dev:<character device name>
    • remote: string

      A string representing the remote endpoint on the device. At time of writing, can be one of: Any value accepted by the local argument jdwp:<process pid>

    Returns Promise<boolean>

  • 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][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.

    Returns

    The possibly converted framebuffer stream. The stream also has a meta.:

    Parameters

    • format: string = 'raw'

      The desired output format. Any output format supported by [GraphicsMagick][graphicsmagick] (such as 'png') is supported. Defaults to 'raw' for raw framebuffer data.

    Returns Promise<FramebufferStreamWithMeta>

  • Gets the device path of the device identified by the given serial number.

    Returns

    The device path. This corresponds to the device path in client.listDevicesWithPaths().

    Example

    List devices withPath

    import Adb from '@u4/adbkit';
    const client = Adb.createClient();
    const devices = client.listDevicesWithPaths();
    devices.then((devices) => {
    devices.forEach(function (d) {
    console.log('id: ' + d.id);
    console.log('type: ' + d.type);
    console.log('model ' + d.model);
    console.log('path: ' + d.path);
    console.log('product: ' + d.product);
    console.log('transportId: ' + d.transportId + '\n');
    });
    });

    Returns Promise<string>

  • 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').

    Returns

    An object of device features. Each key corresponds to a device feature, with the value being either true for a boolean feature, or the feature value as a string (e.g. '0x20000' for reqGlEsVersion).

    Example

    Checking for NFC support

    import Adb from '@u4/adbkit';

    const client = Adb.createClient();

    const test = async () => {
    try {
    const devices = await client.listDevices();
    const supportedDevices: string[] = [];
    for (const device of devices) {
    const client = device.client();
    const features = await client.getFeatures(device.id);
    if (features['android.hardware.nfc'])
    supportedDevices.push(device.serial);
    }
    console.log('The following devices support NFC:', supportedDevices);
    } catch (err) {
    console.error('Something went wrong:', err.stack);
    }
    };

    Returns Promise<Features>

  • Attemps to retrieve the IP addresses of the device. using ip addr show command.

    Returns

    The IP addresses as string[] starting with IPv4 then IPv6.

    Parameters

    • Optional iface: string = 'wlan0'

      The network interface. Defaults to 'wlan0'.

    Returns Promise<string[]>

  • 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.

    Returns

    An object of device features. Each key corresponds to a device feature, with the value being either true for a boolean feature, or the feature value as a string (e.g. '0x20000' for reqGlEsVersion)

    Parameters

    • Optional flags: string

      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

    Returns Promise<string[]>

  • Retrieves the properties of the device identified by the given serial number. This is analogous to adb shell getprop.

    Returns

    An object of device properties. Each key corresponds to a device property. Convenient for accessing things like 'ro.product.model'.

    Returns Promise<Properties>

  • Retrieves the list of running Process

    Returns

    a PsEntry array

    Parameters

    • Rest ...flags: string[]

      TODO

    Returns Promise<Partial<PsEntry>[]>

  • 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.

    Returns

    The serial number of the device.

    Returns Promise<string>

  • Gets the state of the device identified by the given serial number.

    Returns

    The device state. This corresponds to the device type in client.listDevices().

    Returns Promise<DeviceType>

  • 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.

    Returns

    true

    Example

    This example requires the request module. It also doesn't do any error handling (404 responses, timeouts, invalid URLs etc).

    import Adb from '@u4/adbkit';
    import request from 'request';
    import { Readable } from 'stream';

    const client = Adb.createClient();

    const test = async () => {
    // The request module implements old-style streams, so we have to wrap it.
    try {
    // request is deprecated
    const device = client.getClient('<serial>');
    await device.install(new Readable().wrap(request('http://example.org/app.apk') as any) as any)
    console.log('Installed')
    } catch (err) {
    console.error('Something went wrong:', err.stack)
    }
    }

    Example

    Install an apk to all connected devices

    import Adb from '@u4/adbkit';

    const client = Adb.createClient();
    const apk = 'vendor/app.apk';

    const test = async () => {
    try {
    const devices = await client.listDevices();
    for (const device of devices) {
    await device.getClient().install(apk);
    console.log(`Installed ${apk} on all connected devices`);
    }
    } catch (err) {
    console.error('Something went wrong:', err.stack);
    }
    };

    Parameters

    • apk: string | ReadStream

      When String, interpreted as a path to an APK file. When [Stream][node-stream], installs directly from the stream, which must be a valid APK.

    Returns Promise<boolean>

  • 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.

    Returns

    true

    Parameters

    • apk: string

      The path to the APK file on the device. The file will be removed when the command completes.

    Returns Promise<boolean>

  • Tells you if the specific package is installed or not. This is analogous to adb shell pm path <pkg> and some output parsing.

    Returns

    true if the package is installed, false otherwise.

    Parameters

    • pkg: string

      The package name. This is NOT the APK.

    Returns Promise<boolean>

  • Lists forwarded connections on the device. This is analogous to adb forward --list.

    Returns

    An array of forward objects with the following properties:

    • serial The device serial.
    • local The local endpoint. Same format as client.forward()'s local argument.
    • remote The remote endpoint on the device. Same format as client.forward()'s remote argument.

    Returns Promise<Forward[]>

  • List package installed into the devices,

    Returns

    an array of DevicePackage

    Parameters

    • Optional options: {
          thirdparty?: boolean;
      }

      list all or only third party apps

      • Optional thirdparty?: boolean

    Returns Promise<DevicePackage[]>

  • Lists forwarded connections on the device. This is analogous to adb reverse --list.

    Returns

    An array of Reverse objects with the following properties:

    • remote The remote endpoint on the device. Same format as client.reverse()'s remote argument.
    • local The local endpoint on the host. Same format as client.reverse()'s local argument.

    Returns Promise<Reverse[]>

  • Opens a direct connection to a unix domain socket in the given path.

    Returns

    The connection (i.e. [net.Socket][node-net]). Read and write as you please. Call conn.end() to end the connection.

    Parameters

    • path: string

      The path to the socket. Prefixed with 'localfilesystem:' by default, include another prefix (e.g. 'localabstract:') in the path to override.

    Returns Promise<Duplex>

  • Testing only

    Parameters

    • path: string
    • debugCtxt: string = ''

    Returns Promise<PromiseDuplex<Duplex>>

  • 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.

    Returns

    The binary log stream. Call log.end() when you wish to stop receiving data.

    Parameters

    • name: string

      The name of the log. Available logs include 'main', 'system', 'radio' and 'events'.

    Returns Promise<Duplex>

  • Calls the logcat utility on the device and hands off the connection to [adbkit-logcat][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][adbkit-logcat] documentation.

    Returns

    The Logcat client. Please see the [adbkit-logcat][adbkit-logcat] documentation for details.

    Parameters

    • options: {
          clear?: boolean;
      } = {}

      Optional. The following options are supported:

      • clear When true, clears logcat before opening the reader. Not set by default.
      • Optional clear?: boolean

    Returns Promise<Logcat>

  • Starts the built-in monkey utility on the device, connects to it using client.openTcp() and hands the connection to [adbkit-monkey][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][adbkit-monkey] documentation.

    Returns

    The Monkey client. Please see the [adbkit-monkey][adbkit-monkey] documentation for details.

    Parameters

    • port: number = 1080

      Optional. The device port where you'd like Monkey to run at. Defaults to 1080.

    Returns Promise<default>

  • 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. /proc/stat is pulled once per sec, and emit a 'load' event.

    Returns

    The /proc/stat tracker, which is an [EventEmitter][node-events]. Call stat.end() to stop tracking. The following events are available:

    • load (loads) Emitted when a CPU load calculation is available.
    • loads CPU loads of online CPUs. Each key is a CPU id (e.g. 'cpu0', 'cpu1') and the value an object with the following properties: - user Percentage (0-100) of ticks spent on user programs. - nice Percentage (0-100) of ticks spent on niced user programs. - system Percentage (0-100) of ticks spent on system programs. - idle Percentage (0-100) of ticks spent idling. - iowait Percentage (0-100) of ticks spent waiting for IO. - irq Percentage (0-100) of ticks spent on hardware interrupts. - softirq Percentage (0-100) of ticks spent on software interrupts. - steal Percentage (0-100) of ticks stolen by others. - guest Percentage (0-100) of ticks spent by a guest. - guestnice Percentage (0-100) of ticks spent by a niced guest. - total Total. Always 100.

    Returns Promise<ProcStat>

  • Opens a direct TCP connection to a port on the device, without any port forwarding required.

    Returns

    The TCP connection (i.e. [net.Socket][node-net]). Read and write as you please. Call conn.end() to end the connection.

    Parameters

    • port: number

      The port number to connect to.

    • Optional host: string

      Optional. The host to connect to. Allegedly this is supposed to establish a connection to the given host from the device, but we have not been able to get it to work at all. Skip the host and everything works great.

    Returns Promise<Duplex>

  • 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.

    Returns

    A PullTransfer instance.

    Example

    Pulling a file from all cofnnected devices

    import Bluebird from 'bluebird';
    import fs from 'fs';
    import Adb from '@u4/adbkit';
    const client = Adb.createClient();

    const test = async () => {
    try {
    const devices = await client.listDevices();
    await Bluebird.map(devices, async (device) => {
    const transfer = await client.pull(device.id, '/system/build.prop');
    const fn = `/tmp/${device.id}.build.prop`;
    await new Bluebird((resolve, reject) => {
    transfer.on('progress', (stats) =>
    console.log(`[${device.id}] Pulled ${stats.bytesTransferred} bytes so far`),
    );
    transfer.on('end', () => {
    console.log(`[${device.id}] Pull complete`);
    resolve(device.id);
    });
    transfer.on('error', reject);
    transfer.pipe(fs.createWriteStream(fn));
    });
    });
    console.log('Done pulling /system/build.prop from all connected devices');
    } catch (err) {
    console.error('Something went wrong:', err.stack);
    }
    };

    Parameters

    • path: string

      See sync.pull() for details.

    Returns Promise<PullTransfer>

  • 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.

    Example

    Pushing a file to all connected devices

    import Bluebird from 'bluebird';
    import Adb from '@u4/adbkit';
    const client = Adb.createClient();

    const test = async () => {
    try {
    const devices = await client.listDevices();
    await Bluebird.map(devices, async (device) => {
    const transfer = await client.push(device.id, 'temp/foo.txt', '/data/local/tmp/foo.txt');
    await new Bluebird(function (resolve, reject) {
    transfer.on('progress', (stats) =>
    console.log(`[${device.id}] Pushed ${stats.bytesTransferred} bytes so far`),
    );
    transfer.on('end', () => {
    console.log('[${device.id}] Push complete');
    resolve();
    });
    transfer.on('error', reject);
    });
    });
    console.log('Done pushing foo.txt to all connected devices');
    } catch (err) {
    console.error('Something went wrong:', err.stack);
    }
    };

    Parameters

    • contents: string | ReadStream

      See sync.push() for details.

    • path: string

      See sync.push() for details.

    • Optional mode: number

      See sync.push() for details.

    Returns Promise<Pushtransfer>

  • 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.

    Returns

    Files Lists

    Example

    List files in a folder

    import Bluebird from 'bluebird';
    import Adb from '@u4/adbkit';
    const client = Adb.createClient();

    const test = async () => {
    try {
    const devices = await client.listDevices();
    await Bluebird.map(devices, async (device) => {
    const files = await client.readdir(device.id, '/sdcard');
    // Synchronous, so we don't have to care about returning at the
    // right time
    files.forEach((file) => {
    if (file.isFile()) {
    console.log(`[${device.id}] Found file "${file.name}"`);
    }
    });
    });
    console.log('Done checking /sdcard files on connected devices');
    } catch (err) {
    console.error('Something went wrong:', err.stack);
    }
    };

    Parameters

    • path: string

      See sync.readdir() for details.

    Returns Promise<Entry[]>

  • A convenience shortcut for sync.readdir2(), 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.

    Returns

    Files Lists

    Parameters

    • path: string

      See sync.readdir() for details.

    Returns Promise<Entry64[]>

  • 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.

    Returns

    true

    Parameters

    Returns Promise<boolean>

  • Attempts to remount the /system partition in read-write mode. This will usually only work on emulators and developer devices.

    Returns

    true

    Returns Promise<boolean>

  • Remove the port forward at ADB server host (local). This is analogous to adb forward --remove . It's important to note that if you are connected to a remote ADB server, the forward on that host will be removed.

    Returns

    true

    Parameters

    • local: string

      A string representing the local endpoint on the ADB host. At time of writing, can be one of: tcp:<port>, localabstract:<unix domain socket name>, localreserved:<unix domain socket name>, localfilesystem:<unix domain socket name>, dev:<character device name>

    Returns Promise<boolean>

  • 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.

    Returns

    true

    Parameters

    • remote: string

      A string representing the remote endpoint on the device. At time of writing, can be one of:

      • tcp:<port>
      • localabstract:<unix domain socket name>
      • localreserved:<unix domain socket name>
      • localfilesystem:<unix domain socket name>
    • local: string

      A string representing the local endpoint on the ADB host. At time of writing, can be any value accepted by the remote argument.

    Returns 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.

    Returns

    true

    Returns Promise<boolean>

  • 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.

    Returns

    The PNG stream.

    Returns Promise<Duplex>

  • Runs a shell command on the device. Note that you'll be limited to the permissions of the shell user, which ADB uses.

    Returns

    A readable stream (Socket actually) containing the progressive stdout of the command. Use with adb.util.readAll to get a readable String from it.

    Example

    Read the output of an instantaneous command

    import Adb from '@u4/adbkit';

    try {
    const client = Adb.createClient();
    const devices = await client.listDevices();
    for (const device of devices) {
    const stream = await device.getClient().shell('echo $RANDOM');
    // Use the readAll() utility to read all the content without
    // having to deal with the readable stream. `output` will be a Buffer
    // containing all the output.
    const output = await adb.util.readAll(stream);
    console.log('[%s] %s', device.id, output.toString().trim());
    }
    console.log('Done.');
    } catch(err) {
    console.error('Something went wrong:', err.stack);
    }

    Example

    Progressively read the output of a long-running command and terminate it

    import Adb from '@u4/adbkit';

    const client = Adb.createClient();
    const devices = await client.listDevices()
    for (const device of devices) {
    // logcat just for illustration, prefer client.openLogcat in real use
    const conn = await device.getClient().shell('logcat')
    let line = 0
    conn.on('data', function(data) {
    // here `ps` on the device shows the running logcat process
    console.log(data.toString())
    line += 1
    // close the stream and the running process
    // on the device will be gone, gracefully
    if (line > 100) conn.end()
    });
    conn.on('close', function() {
    // here `ps` on the device shows the logcat process is gone
    console.log('100 lines read already, bye')
    })
    }
    console.log('Done.')

    Parameters

    • command: string | ArrayLike<WithToString>

      The shell command to execute. When 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.

    Returns Promise<Duplex>

  • 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.

    Returns

    An [fs.Stats][node-fs-stats] instance. While the stats.is* methods are available, only the following properties are supported:

    • mode The raw mode.
    • size The file size.
    • mtime The time of last modification as a Date.

    Parameters

    • path: string

      The path.

    Returns Promise<Stats>

  • A convenience shortcut for sync.stat64(), 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. * *

    Returns

    An [fs.Stats][node-fs-stats] instance. While the stats.is* methods are available, only the following properties are supported:

      • mode The raw mode.
      • size The file size.
      • mtime The time of last modification as a Date.

    Parameters

    • path: string

      The path.

      * *

    Returns Promise<Stats64>

  • 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().

    Returns

    The Sync client. See below for details. Call sync.end() when done.

    Returns Promise<Sync>

  • 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>.

    Returns

    The port the device started listening on.

    Parameters

    • port: number = 5555

      Optional. The port the device should listen on. Defaults to 5555.

    Returns Promise<number>

  • 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.

    Returns

    The JDWP tracker, which is an [EventEmitter][node-events]. The following events are available:

    • add (pid) Emitted when a new JDWP process becomes available, once per pid.
    • remove (pid) Emitted when a JDWP process becomes unavailable, once per pid.
    • changeSet (changes, pids) All changes in a single event.
    • changes An object with the following properties always present: - added An array of pids that were added. Empty if none. - removed An array of pids that were removed. Empty if none.
    • pids All currently active pids (including pids from previous runs).
    • end Emitted when the underlying connection ends.
    • error (err) Emitted if there's an error.

    Returns Promise<JdwpTracker>

  • Get a localTCP port connected to remote socket, this method will try to get the requested port, but if the port is already taken, will choose an other one. Note if a foward already existe to the same destination with a different port, no new foward will be create.

    Returns

    the used port

    Parameters

    • remote: string

      A string representing the remote endpoint on the device. At time of writing, can be one of: Any value accepted by the local argument jdwp:<process pid>

    • Optional preferedPort: number

      the TCP port you would like to get.

    Returns Promise<number>

  • Uninstalls the package from the device. This is roughly analogous to adb uninstall <pkg>.

    Returns

    true

    Parameters

    • pkg: string

      The package name. This is NOT the APK.

    Returns Promise<boolean>

  • Puts the device's ADB daemon back into USB mode. Reverses client.tcpip(). Same as adb usb.

    Returns

    true

    Returns Promise<boolean>

  • 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.

    Returns

    true

    Returns Promise<boolean>

  • 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.

    Returns

    The device ID. Can be useful for chaining.

    Returns Promise<string>

Generated using TypeDoc