@yume-chan/adb 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.json +26 -0
- package/CHANGELOG.md +15 -1
- package/LICENSE +1 -1
- package/README.md +56 -43
- package/esm/adb.d.ts +48 -0
- package/esm/adb.d.ts.map +1 -0
- package/esm/adb.js +141 -146
- package/esm/adb.js.map +1 -1
- package/{dts → esm}/auth.d.ts +8 -8
- package/esm/auth.d.ts.map +1 -0
- package/esm/auth.js +68 -108
- package/esm/auth.js.map +1 -1
- package/esm/backend.d.ts +9 -0
- package/esm/backend.d.ts.map +1 -0
- package/{dts → esm}/commands/base.d.ts +1 -1
- package/esm/commands/base.d.ts.map +1 -0
- package/esm/commands/base.js +1 -0
- package/esm/commands/base.js.map +1 -1
- package/{dts → esm}/commands/framebuffer.d.ts +3 -3
- package/esm/commands/framebuffer.d.ts.map +1 -0
- package/esm/commands/framebuffer.js +15 -18
- package/esm/commands/framebuffer.js.map +1 -1
- package/esm/commands/index.d.ts +9 -0
- package/esm/commands/index.d.ts.map +1 -0
- package/esm/commands/index.js +8 -8
- package/esm/commands/index.js.map +1 -1
- package/esm/commands/install.d.ts +4 -0
- package/esm/commands/install.d.ts.map +1 -0
- package/esm/commands/install.js +21 -13
- package/esm/commands/install.js.map +1 -1
- package/esm/commands/power.d.ts +23 -0
- package/esm/commands/power.d.ts.map +1 -0
- package/esm/commands/power.js +45 -0
- package/esm/commands/power.js.map +1 -0
- package/{dts → esm}/commands/reverse.d.ts +3 -3
- package/esm/commands/reverse.d.ts.map +1 -0
- package/esm/commands/reverse.js +49 -60
- package/esm/commands/reverse.js.map +1 -1
- package/esm/commands/subprocess/index.d.ts +57 -0
- package/esm/commands/subprocess/index.d.ts.map +1 -0
- package/esm/commands/subprocess/index.js +83 -0
- package/esm/commands/subprocess/index.js.map +1 -0
- package/esm/commands/subprocess/legacy.d.ts +28 -0
- package/esm/commands/subprocess/legacy.d.ts.map +1 -0
- package/esm/commands/subprocess/legacy.js +44 -0
- package/esm/commands/subprocess/legacy.js.map +1 -0
- package/esm/commands/subprocess/protocol.d.ts +38 -0
- package/esm/commands/subprocess/protocol.d.ts.map +1 -0
- package/esm/commands/subprocess/protocol.js +155 -0
- package/esm/commands/subprocess/protocol.js.map +1 -0
- package/esm/commands/subprocess/types.d.ts +47 -0
- package/esm/commands/subprocess/types.d.ts.map +1 -0
- package/esm/commands/{shell → subprocess}/types.js +0 -0
- package/esm/commands/{shell → subprocess}/types.js.map +1 -1
- package/{dts/commands/shell → esm/commands/subprocess}/utils.d.ts +0 -0
- package/esm/commands/subprocess/utils.d.ts.map +1 -0
- package/esm/commands/{shell → subprocess}/utils.js +0 -0
- package/esm/commands/subprocess/utils.js.map +1 -0
- package/esm/commands/sync/index.d.ts +8 -0
- package/esm/commands/sync/index.d.ts.map +1 -0
- package/esm/commands/sync/index.js +7 -7
- package/esm/commands/sync/index.js.map +1 -1
- package/{dts → esm}/commands/sync/list.d.ts +4 -4
- package/esm/commands/sync/list.d.ts.map +1 -0
- package/esm/commands/sync/list.js +16 -19
- package/esm/commands/sync/list.js.map +1 -1
- package/esm/commands/sync/pull.d.ts +11 -0
- package/esm/commands/sync/pull.d.ts.map +1 -0
- package/esm/commands/sync/pull.js +17 -11
- package/esm/commands/sync/pull.js.map +1 -1
- package/esm/commands/sync/push.d.ts +8 -0
- package/esm/commands/sync/push.d.ts.map +1 -0
- package/esm/commands/sync/push.js +19 -37
- package/esm/commands/sync/push.js.map +1 -1
- package/{dts → esm}/commands/sync/request.d.ts +3 -3
- package/esm/commands/sync/request.d.ts.map +1 -0
- package/esm/commands/sync/request.js +24 -27
- package/esm/commands/sync/request.js.map +1 -1
- package/{dts → esm}/commands/sync/response.d.ts +2 -2
- package/esm/commands/sync/response.d.ts.map +1 -0
- package/esm/commands/sync/response.js +16 -20
- package/esm/commands/sync/response.js.map +1 -1
- package/{dts → esm}/commands/sync/stat.d.ts +4 -4
- package/esm/commands/sync/stat.d.ts.map +1 -0
- package/esm/commands/sync/stat.js +22 -27
- package/esm/commands/sync/stat.js.map +1 -1
- package/esm/commands/sync/sync.d.ts +83 -0
- package/esm/commands/sync/sync.d.ts.map +1 -0
- package/esm/commands/sync/sync.js +92 -89
- package/esm/commands/sync/sync.js.map +1 -1
- package/{dts → esm}/commands/tcpip.d.ts +1 -1
- package/{dts → esm}/commands/tcpip.d.ts.map +1 -1
- package/esm/commands/tcpip.js +14 -19
- package/esm/commands/tcpip.js.map +1 -1
- package/{dts → esm}/crypto.d.ts +7 -7
- package/esm/crypto.d.ts.map +1 -0
- package/esm/crypto.js +26 -29
- package/esm/crypto.js.map +1 -1
- package/{dts → esm}/features.d.ts +0 -0
- package/{dts → esm}/features.d.ts.map +0 -0
- package/esm/features.js +1 -1
- package/esm/features.js.map +1 -1
- package/esm/index.d.ts +11 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +10 -10
- package/esm/index.js.map +1 -1
- package/esm/packet.d.ts +28 -0
- package/esm/packet.d.ts.map +1 -0
- package/esm/packet.js +26 -51
- package/esm/packet.js.map +1 -1
- package/esm/socket/controller.d.ts +37 -0
- package/esm/socket/controller.d.ts.map +1 -0
- package/esm/socket/controller.js +52 -66
- package/esm/socket/controller.js.map +1 -1
- package/{dts → esm}/socket/dispatcher.d.ts +10 -23
- package/esm/socket/dispatcher.d.ts.map +1 -0
- package/esm/socket/dispatcher.js +148 -164
- package/esm/socket/dispatcher.js.map +1 -1
- package/esm/socket/index.d.ts +3 -0
- package/esm/socket/index.d.ts.map +1 -0
- package/esm/socket/index.js +2 -6
- package/esm/socket/index.js.map +1 -1
- package/esm/socket/socket.d.ts +34 -0
- package/esm/socket/socket.d.ts.map +1 -0
- package/esm/socket/socket.js +69 -14
- package/esm/socket/socket.js.map +1 -1
- package/esm/stream/buffered.d.ts +35 -0
- package/esm/stream/buffered.d.ts.map +1 -0
- package/esm/stream/buffered.js +123 -0
- package/esm/stream/buffered.js.map +1 -0
- package/esm/stream/detect.bak.d.ts +240 -0
- package/esm/stream/detect.bak.d.ts.map +1 -0
- package/esm/stream/detect.bak.js +60 -0
- package/esm/stream/detect.bak.js.map +1 -0
- package/esm/stream/detect.d.ts +18 -0
- package/esm/stream/detect.d.ts.map +1 -0
- package/esm/stream/detect.js +6 -0
- package/esm/stream/detect.js.map +1 -0
- package/esm/stream/detect.native.d.ts +240 -0
- package/esm/stream/detect.native.d.ts.map +1 -0
- package/esm/stream/detect.native.js +60 -0
- package/esm/stream/detect.native.js.map +1 -0
- package/esm/stream/detect.polyfill.d.ts +18 -0
- package/esm/stream/detect.polyfill.d.ts.map +1 -0
- package/esm/stream/detect.polyfill.js +6 -0
- package/esm/stream/detect.polyfill.js.map +1 -0
- package/esm/stream/index.d.ts +4 -0
- package/esm/stream/index.d.ts.map +1 -0
- package/esm/stream/index.js +3 -2
- package/esm/stream/index.js.map +1 -1
- package/esm/stream/transform.d.ts +98 -0
- package/esm/stream/transform.d.ts.map +1 -0
- package/esm/stream/transform.js +352 -0
- package/esm/stream/transform.js.map +1 -0
- package/{dts → esm}/utils/auto-reset-event.d.ts +1 -1
- package/esm/utils/auto-reset-event.d.ts.map +1 -0
- package/esm/utils/auto-reset-event.js +2 -1
- package/esm/utils/auto-reset-event.js.map +1 -1
- package/esm/utils/base64.d.ts +5 -0
- package/esm/utils/base64.d.ts.map +1 -0
- package/esm/utils/base64.js +116 -80
- package/esm/utils/base64.js.map +1 -1
- package/esm/utils/encoding.d.ts +3 -0
- package/{dts → esm}/utils/encoding.d.ts.map +1 -1
- package/esm/utils/encoding.js +1 -1
- package/esm/utils/encoding.js.map +1 -1
- package/esm/utils/index.d.ts +4 -0
- package/esm/utils/index.d.ts.map +1 -0
- package/esm/utils/index.js +3 -5
- package/esm/utils/index.js.map +1 -1
- package/package.json +50 -44
- package/src/adb.ts +147 -143
- package/src/auth.ts +23 -19
- package/src/backend.ts +3 -12
- package/src/commands/base.ts +1 -1
- package/src/commands/framebuffer.ts +4 -4
- package/src/commands/index.ts +8 -8
- package/src/commands/install.ts +26 -15
- package/src/commands/power.ts +54 -0
- package/src/commands/reverse.ts +10 -8
- package/src/commands/subprocess/index.ts +124 -0
- package/src/commands/subprocess/legacy.ts +58 -0
- package/src/commands/subprocess/protocol.ts +185 -0
- package/src/commands/subprocess/types.ts +55 -0
- package/src/commands/{shell → subprocess}/utils.ts +0 -0
- package/src/commands/sync/index.ts +7 -7
- package/src/commands/sync/list.ts +7 -6
- package/src/commands/sync/pull.ts +27 -18
- package/src/commands/sync/push.ts +25 -30
- package/src/commands/sync/request.ts +7 -7
- package/src/commands/sync/response.ts +4 -4
- package/src/commands/sync/stat.ts +8 -6
- package/src/commands/sync/sync.ts +64 -32
- package/src/commands/tcpip.ts +3 -3
- package/src/crypto.ts +38 -43
- package/src/index.ts +11 -10
- package/src/packet.ts +37 -52
- package/src/socket/dispatcher.ts +90 -103
- package/src/socket/index.ts +2 -6
- package/src/socket/socket.ts +117 -16
- package/src/stream/buffered.ts +147 -0
- package/src/stream/detect.native.ts +362 -0
- package/src/stream/detect.polyfill.ts +25 -0
- package/src/stream/detect.ts +25 -0
- package/src/stream/index.ts +3 -2
- package/src/stream/transform.ts +427 -0
- package/src/utils/auto-reset-event.ts +1 -1
- package/src/utils/base64.ts +161 -129
- package/src/utils/encoding.ts +3 -3
- package/src/utils/index.ts +3 -5
- package/tsconfig.build.json +3 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.test.json +10 -0
- package/dts/adb.d.ts +0 -46
- package/dts/adb.d.ts.map +0 -1
- package/dts/auth.d.ts.map +0 -1
- package/dts/backend.d.ts +0 -13
- package/dts/backend.d.ts.map +0 -1
- package/dts/commands/base.d.ts.map +0 -1
- package/dts/commands/demo-mode.d.ts +0 -41
- package/dts/commands/demo-mode.d.ts.map +0 -1
- package/dts/commands/framebuffer.d.ts.map +0 -1
- package/dts/commands/index.d.ts +0 -9
- package/dts/commands/index.d.ts.map +0 -1
- package/dts/commands/install.d.ts +0 -3
- package/dts/commands/install.d.ts.map +0 -1
- package/dts/commands/reverse.d.ts.map +0 -1
- package/dts/commands/shell/index.d.ts +0 -46
- package/dts/commands/shell/index.d.ts.map +0 -1
- package/dts/commands/shell/legacy.d.ts +0 -38
- package/dts/commands/shell/legacy.d.ts.map +0 -1
- package/dts/commands/shell/protocol.d.ts +0 -45
- package/dts/commands/shell/protocol.d.ts.map +0 -1
- package/dts/commands/shell/types.d.ts +0 -47
- package/dts/commands/shell/types.d.ts.map +0 -1
- package/dts/commands/shell/utils.d.ts.map +0 -1
- package/dts/commands/sync/index.d.ts +0 -8
- package/dts/commands/sync/index.d.ts.map +0 -1
- package/dts/commands/sync/list.d.ts.map +0 -1
- package/dts/commands/sync/pull.d.ts +0 -11
- package/dts/commands/sync/pull.d.ts.map +0 -1
- package/dts/commands/sync/push.d.ts +0 -8
- package/dts/commands/sync/push.d.ts.map +0 -1
- package/dts/commands/sync/request.d.ts.map +0 -1
- package/dts/commands/sync/response.d.ts.map +0 -1
- package/dts/commands/sync/stat.d.ts.map +0 -1
- package/dts/commands/sync/sync.d.ts +0 -68
- package/dts/commands/sync/sync.d.ts.map +0 -1
- package/dts/crypto.d.ts.map +0 -1
- package/dts/index.d.ts +0 -11
- package/dts/index.d.ts.map +0 -1
- package/dts/packet.d.ts +0 -27
- package/dts/packet.d.ts.map +0 -1
- package/dts/socket/close-event-emitter.d.ts +0 -8
- package/dts/socket/close-event-emitter.d.ts.map +0 -1
- package/dts/socket/controller.d.ts +0 -43
- package/dts/socket/controller.d.ts.map +0 -1
- package/dts/socket/data-event-emitter.d.ts +0 -10
- package/dts/socket/data-event-emitter.d.ts.map +0 -1
- package/dts/socket/dispatcher.d.ts.map +0 -1
- package/dts/socket/index.d.ts +0 -7
- package/dts/socket/index.d.ts.map +0 -1
- package/dts/socket/logger.d.ts +0 -9
- package/dts/socket/logger.d.ts.map +0 -1
- package/dts/socket/socket.d.ts +0 -22
- package/dts/socket/socket.d.ts.map +0 -1
- package/dts/stream/buffered-stream.d.ts +0 -28
- package/dts/stream/buffered-stream.d.ts.map +0 -1
- package/dts/stream/index.d.ts +0 -3
- package/dts/stream/index.d.ts.map +0 -1
- package/dts/stream/stream.d.ts +0 -15
- package/dts/stream/stream.d.ts.map +0 -1
- package/dts/utils/auto-reset-event.d.ts.map +0 -1
- package/dts/utils/base64.d.ts +0 -7
- package/dts/utils/base64.d.ts.map +0 -1
- package/dts/utils/chunk.d.ts +0 -3
- package/dts/utils/chunk.d.ts.map +0 -1
- package/dts/utils/encoding.d.ts +0 -3
- package/dts/utils/event-queue.d.ts +0 -35
- package/dts/utils/event-queue.d.ts.map +0 -1
- package/dts/utils/index.d.ts +0 -6
- package/dts/utils/index.d.ts.map +0 -1
- package/esm/commands/demo-mode.js +0 -170
- package/esm/commands/demo-mode.js.map +0 -1
- package/esm/commands/shell/index.js +0 -62
- package/esm/commands/shell/index.js.map +0 -1
- package/esm/commands/shell/legacy.js +0 -49
- package/esm/commands/shell/legacy.js.map +0 -1
- package/esm/commands/shell/protocol.js +0 -106
- package/esm/commands/shell/protocol.js.map +0 -1
- package/esm/commands/shell/utils.js.map +0 -1
- package/esm/socket/close-event-emitter.js +0 -28
- package/esm/socket/close-event-emitter.js.map +0 -1
- package/esm/socket/data-event-emitter.js +0 -25
- package/esm/socket/data-event-emitter.js.map +0 -1
- package/esm/socket/logger.js +0 -2
- package/esm/socket/logger.js.map +0 -1
- package/esm/stream/buffered-stream.js +0 -67
- package/esm/stream/buffered-stream.js.map +0 -1
- package/esm/stream/stream.js +0 -41
- package/esm/stream/stream.js.map +0 -1
- package/esm/utils/chunk.js +0 -70
- package/esm/utils/chunk.js.map +0 -1
- package/esm/utils/event-queue.js +0 -104
- package/esm/utils/event-queue.js.map +0 -1
- package/src/commands/demo-mode.ts +0 -160
- package/src/commands/shell/index.ts +0 -87
- package/src/commands/shell/legacy.ts +0 -59
- package/src/commands/shell/protocol.ts +0 -121
- package/src/commands/shell/types.ts +0 -55
- package/src/socket/close-event-emitter.ts +0 -28
- package/src/socket/controller.ts +0 -105
- package/src/socket/data-event-emitter.ts +0 -27
- package/src/socket/logger.ts +0 -12
- package/src/stream/buffered-stream.ts +0 -92
- package/src/stream/stream.ts +0 -50
- package/src/utils/chunk.ts +0 -70
- package/src/utils/event-queue.ts +0 -145
package/src/adb.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { PromiseResolver } from '@yume-chan/async';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { decodeUtf8 } from "./utils";
|
|
2
|
+
import { AdbAuthenticationHandler, AdbDefaultAuthenticators, type AdbCredentialStore } from './auth.js';
|
|
3
|
+
import { AdbPower, AdbReverseCommand, AdbSubprocess, AdbSync, AdbTcpIpCommand, escapeArg, framebuffer, install, type AdbFrameBuffer } from './commands/index.js';
|
|
4
|
+
import { AdbFeatures } from './features.js';
|
|
5
|
+
import { AdbCommand, AdbPacket, calculateChecksum, type AdbPacketCore, type AdbPacketInit } from './packet.js';
|
|
6
|
+
import { AdbPacketDispatcher, AdbSocket } from './socket/index.js';
|
|
7
|
+
import { AbortController, DecodeUtf8Stream, GatherStringStream, WritableStream, type ReadableWritablePair } from "./stream/index.js";
|
|
8
|
+
import { decodeUtf8, encodeUtf8 } from "./utils/index.js";
|
|
10
9
|
|
|
11
10
|
export enum AdbPropKey {
|
|
12
11
|
Product = 'ro.product.name',
|
|
@@ -15,68 +14,21 @@ export enum AdbPropKey {
|
|
|
15
14
|
Features = 'features',
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
export
|
|
19
|
-
private readonly _backend: AdbBackend;
|
|
20
|
-
|
|
21
|
-
public get backend(): AdbBackend { return this._backend; }
|
|
22
|
-
|
|
23
|
-
private readonly packetDispatcher: AdbPacketDispatcher;
|
|
24
|
-
|
|
25
|
-
public get onDisconnected() { return this.backend.onDisconnected; }
|
|
26
|
-
|
|
27
|
-
private _connected = false;
|
|
28
|
-
public get connected() { return this._connected; }
|
|
29
|
-
|
|
30
|
-
public get name() { return this.backend.name; }
|
|
31
|
-
|
|
32
|
-
private _protocolVersion: number | undefined;
|
|
33
|
-
public get protocolVersion() { return this._protocolVersion; }
|
|
34
|
-
|
|
35
|
-
private _product: string | undefined;
|
|
36
|
-
public get product() { return this._product; }
|
|
37
|
-
|
|
38
|
-
private _model: string | undefined;
|
|
39
|
-
public get model() { return this._model; }
|
|
40
|
-
|
|
41
|
-
private _device: string | undefined;
|
|
42
|
-
public get device() { return this._device; }
|
|
43
|
-
|
|
44
|
-
private _features: AdbFeatures[] | undefined;
|
|
45
|
-
public get features() { return this._features; }
|
|
46
|
-
|
|
47
|
-
public readonly tcpip: AdbTcpIpCommand;
|
|
48
|
-
|
|
49
|
-
public readonly reverse: AdbReverseCommand;
|
|
50
|
-
|
|
51
|
-
public readonly demoMode: AdbDemoMode;
|
|
52
|
-
|
|
53
|
-
public readonly childProcess: AdbChildProcess;
|
|
54
|
-
|
|
55
|
-
public constructor(backend: AdbBackend, logger?: AdbLogger) {
|
|
56
|
-
this._backend = backend;
|
|
57
|
-
this.packetDispatcher = new AdbPacketDispatcher(backend, logger);
|
|
58
|
-
|
|
59
|
-
this.tcpip = new AdbTcpIpCommand(this);
|
|
60
|
-
this.reverse = new AdbReverseCommand(this.packetDispatcher);
|
|
61
|
-
this.demoMode = new AdbDemoMode(this);
|
|
62
|
-
this.childProcess = new AdbChildProcess(this);
|
|
17
|
+
export const VERSION_OMIT_CHECKSUM = 0x01000001;
|
|
63
18
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
19
|
+
export class Adb {
|
|
20
|
+
/**
|
|
21
|
+
* It's possible to call `authenticate` multiple times on a single connection,
|
|
22
|
+
* every time the device receives a `CNXN` packet, it resets its internal state,
|
|
23
|
+
* and starts a new authentication process.
|
|
24
|
+
*/
|
|
25
|
+
public static async authenticate(
|
|
26
|
+
connection: ReadableWritablePair<AdbPacketCore, AdbPacketCore>,
|
|
68
27
|
credentialStore: AdbCredentialStore,
|
|
69
|
-
authenticators = AdbDefaultAuthenticators
|
|
70
|
-
): Promise<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
this.packetDispatcher.calculateChecksum = true;
|
|
74
|
-
this.packetDispatcher.appendNullToServiceString = true;
|
|
75
|
-
this.packetDispatcher.start();
|
|
76
|
-
|
|
77
|
-
const version = 0x01000001;
|
|
78
|
-
const versionNoChecksum = 0x01000001;
|
|
79
|
-
const maxPayloadSize = 0x100000;
|
|
28
|
+
authenticators = AdbDefaultAuthenticators,
|
|
29
|
+
): Promise<Adb> {
|
|
30
|
+
let version = 0x01000001;
|
|
31
|
+
let maxPayloadSize = 0x100000;
|
|
80
32
|
|
|
81
33
|
const features = [
|
|
82
34
|
'shell_v2',
|
|
@@ -97,76 +49,129 @@ export class Adb {
|
|
|
97
49
|
'sendrecv_v2_dry_run_send',
|
|
98
50
|
].join(',');
|
|
99
51
|
|
|
100
|
-
const resolver = new PromiseResolver<
|
|
52
|
+
const resolver = new PromiseResolver<string>();
|
|
101
53
|
const authHandler = new AdbAuthenticationHandler(authenticators, credentialStore);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
//
|
|
119
|
-
this
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
break;
|
|
125
|
-
case AdbCommand.Auth:
|
|
126
|
-
const authPacket = await authHandler.handle(e.packet);
|
|
127
|
-
await this.packetDispatcher.sendPacket(authPacket);
|
|
128
|
-
break;
|
|
129
|
-
case AdbCommand.Close:
|
|
130
|
-
// Last connection was interrupted
|
|
131
|
-
// Ignore this packet, device will recover
|
|
132
|
-
break;
|
|
133
|
-
default:
|
|
134
|
-
throw new Error('Device not in correct state. Reconnect your device and try again');
|
|
54
|
+
|
|
55
|
+
const abortController = new AbortController();
|
|
56
|
+
const pipe = connection.readable
|
|
57
|
+
.pipeTo(new WritableStream({
|
|
58
|
+
async write(packet: AdbPacket) {
|
|
59
|
+
switch (packet.command) {
|
|
60
|
+
case AdbCommand.Connect:
|
|
61
|
+
version = Math.min(version, packet.arg0);
|
|
62
|
+
maxPayloadSize = Math.min(maxPayloadSize, packet.arg1);
|
|
63
|
+
resolver.resolve(decodeUtf8(packet.payload));
|
|
64
|
+
break;
|
|
65
|
+
case AdbCommand.Auth:
|
|
66
|
+
const response = await authHandler.handle(packet);
|
|
67
|
+
await sendPacket(response);
|
|
68
|
+
break;
|
|
69
|
+
case AdbCommand.Close:
|
|
70
|
+
// Last connection was interrupted
|
|
71
|
+
// Ignore this packet, device will recover
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
throw new Error('Device not in correct state. Reconnect your device and try again');
|
|
75
|
+
}
|
|
135
76
|
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
await
|
|
150
|
-
AdbCommand.Connect,
|
|
151
|
-
version,
|
|
152
|
-
maxPayloadSize,
|
|
153
|
-
|
|
154
|
-
|
|
77
|
+
}), {
|
|
78
|
+
preventCancel: true,
|
|
79
|
+
signal: abortController.signal,
|
|
80
|
+
})
|
|
81
|
+
.catch((e) => { resolver.reject(e); });
|
|
82
|
+
|
|
83
|
+
const writer = connection.writable.getWriter();
|
|
84
|
+
async function sendPacket(init: AdbPacketCore) {
|
|
85
|
+
// Always send checksum in auth steps
|
|
86
|
+
// Because we don't know if the device will ignore it yet.
|
|
87
|
+
await writer.write(calculateChecksum(init));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
await sendPacket({
|
|
91
|
+
command: AdbCommand.Connect,
|
|
92
|
+
arg0: version,
|
|
93
|
+
arg1: maxPayloadSize,
|
|
94
|
+
// The terminating `;` is required in formal definition
|
|
95
|
+
// But ADB daemon (all versions) can still work without it
|
|
96
|
+
payload: encodeUtf8(`host::features=${features};`),
|
|
97
|
+
});
|
|
155
98
|
|
|
156
99
|
try {
|
|
157
|
-
await resolver.promise;
|
|
158
|
-
|
|
100
|
+
const banner = await resolver.promise;
|
|
101
|
+
|
|
102
|
+
// Stop piping before creating Adb object
|
|
103
|
+
// Because AdbPacketDispatcher will try to lock the streams when initializing
|
|
104
|
+
abortController.abort();
|
|
105
|
+
await pipe;
|
|
106
|
+
|
|
107
|
+
writer.releaseLock();
|
|
108
|
+
|
|
109
|
+
return new Adb(
|
|
110
|
+
connection,
|
|
111
|
+
version,
|
|
112
|
+
maxPayloadSize,
|
|
113
|
+
banner,
|
|
114
|
+
);
|
|
159
115
|
} finally {
|
|
160
|
-
|
|
116
|
+
abortController.abort();
|
|
117
|
+
writer.releaseLock();
|
|
161
118
|
}
|
|
162
119
|
}
|
|
163
120
|
|
|
121
|
+
private readonly packetDispatcher: AdbPacketDispatcher;
|
|
122
|
+
|
|
123
|
+
public get disconnected() { return this.packetDispatcher.disconnected; }
|
|
124
|
+
|
|
125
|
+
private _protocolVersion: number | undefined;
|
|
126
|
+
public get protocolVersion() { return this._protocolVersion; }
|
|
127
|
+
|
|
128
|
+
private _product: string | undefined;
|
|
129
|
+
public get product() { return this._product; }
|
|
130
|
+
|
|
131
|
+
private _model: string | undefined;
|
|
132
|
+
public get model() { return this._model; }
|
|
133
|
+
|
|
134
|
+
private _device: string | undefined;
|
|
135
|
+
public get device() { return this._device; }
|
|
136
|
+
|
|
137
|
+
private _features: AdbFeatures[] | undefined;
|
|
138
|
+
public get features() { return this._features; }
|
|
139
|
+
|
|
140
|
+
public readonly subprocess: AdbSubprocess;
|
|
141
|
+
public readonly power: AdbPower;
|
|
142
|
+
public readonly reverse: AdbReverseCommand;
|
|
143
|
+
public readonly tcpip: AdbTcpIpCommand;
|
|
144
|
+
|
|
145
|
+
public constructor(
|
|
146
|
+
connection: ReadableWritablePair<AdbPacketCore, AdbPacketInit>,
|
|
147
|
+
version: number,
|
|
148
|
+
maxPayloadSize: number,
|
|
149
|
+
banner: string,
|
|
150
|
+
) {
|
|
151
|
+
this.parseBanner(banner);
|
|
152
|
+
this.packetDispatcher = new AdbPacketDispatcher(connection);
|
|
153
|
+
|
|
154
|
+
this._protocolVersion = version;
|
|
155
|
+
if (version >= VERSION_OMIT_CHECKSUM) {
|
|
156
|
+
this.packetDispatcher.calculateChecksum = false;
|
|
157
|
+
// Android prior to 9.0.0 uses char* to parse service string
|
|
158
|
+
// thus requires an extra null character
|
|
159
|
+
this.packetDispatcher.appendNullToServiceString = false;
|
|
160
|
+
}
|
|
161
|
+
this.packetDispatcher.maxPayloadSize = maxPayloadSize;
|
|
162
|
+
|
|
163
|
+
this.subprocess = new AdbSubprocess(this);
|
|
164
|
+
this.power = new AdbPower(this);
|
|
165
|
+
this.reverse = new AdbReverseCommand(this.packetDispatcher);
|
|
166
|
+
this.tcpip = new AdbTcpIpCommand(this);
|
|
167
|
+
}
|
|
168
|
+
|
|
164
169
|
private parseBanner(banner: string): void {
|
|
165
170
|
this._features = [];
|
|
166
171
|
|
|
167
172
|
const pieces = banner.split('::');
|
|
168
173
|
if (pieces.length > 1) {
|
|
169
|
-
const props = pieces[1]
|
|
174
|
+
const props = pieces[1]!;
|
|
170
175
|
for (const prop of props.split(';')) {
|
|
171
176
|
if (!prop) {
|
|
172
177
|
continue;
|
|
@@ -189,7 +194,7 @@ export class Adb {
|
|
|
189
194
|
this._device = value;
|
|
190
195
|
break;
|
|
191
196
|
case AdbPropKey.Features:
|
|
192
|
-
this._features = value
|
|
197
|
+
this._features = value!.split(',') as AdbFeatures[];
|
|
193
198
|
break;
|
|
194
199
|
}
|
|
195
200
|
}
|
|
@@ -197,19 +202,21 @@ export class Adb {
|
|
|
197
202
|
}
|
|
198
203
|
|
|
199
204
|
public async getProp(key: string): Promise<string> {
|
|
200
|
-
const
|
|
201
|
-
|
|
205
|
+
const stdout = await this.subprocess.spawnAndWaitLegacy(
|
|
206
|
+
['getprop', key]
|
|
207
|
+
);
|
|
208
|
+
return stdout.trim();
|
|
202
209
|
}
|
|
203
210
|
|
|
204
211
|
public async rm(...filenames: string[]): Promise<string> {
|
|
205
|
-
|
|
212
|
+
const stdout = await this.subprocess.spawnAndWaitLegacy(
|
|
213
|
+
['rm', '-rf', ...filenames.map(arg => escapeArg(arg))],
|
|
214
|
+
);
|
|
215
|
+
return stdout;
|
|
206
216
|
}
|
|
207
217
|
|
|
208
|
-
public
|
|
209
|
-
|
|
210
|
-
onProgress?: (uploaded: number) => void,
|
|
211
|
-
): Promise<void> {
|
|
212
|
-
return await install(this, apk, onProgress);
|
|
218
|
+
public install() {
|
|
219
|
+
return install(this);
|
|
213
220
|
}
|
|
214
221
|
|
|
215
222
|
public async sync(): Promise<AdbSync> {
|
|
@@ -225,19 +232,16 @@ export class Adb {
|
|
|
225
232
|
return this.packetDispatcher.createSocket(service);
|
|
226
233
|
}
|
|
227
234
|
|
|
228
|
-
public async
|
|
235
|
+
public async createSocketAndWait(service: string): Promise<string> {
|
|
229
236
|
const socket = await this.createSocket(service);
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
socket.onClose(() => resolver.resolve(result));
|
|
236
|
-
return resolver.promise;
|
|
237
|
+
const gatherStream = new GatherStringStream();
|
|
238
|
+
await socket.readable
|
|
239
|
+
.pipeThrough(new DecodeUtf8Stream())
|
|
240
|
+
.pipeTo(gatherStream.writable);
|
|
241
|
+
return gatherStream.result;
|
|
237
242
|
}
|
|
238
243
|
|
|
239
244
|
public async dispose(): Promise<void> {
|
|
240
245
|
this.packetDispatcher.dispose();
|
|
241
|
-
await this.backend.dispose();
|
|
242
246
|
}
|
|
243
247
|
}
|
package/src/auth.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { PromiseResolver } from '@yume-chan/async';
|
|
2
|
-
import { Disposable } from '@yume-chan/event';
|
|
3
|
-
import { ValueOrPromise } from '@yume-chan/struct';
|
|
4
|
-
import { calculatePublicKey, calculatePublicKeyLength, sign } from './crypto';
|
|
5
|
-
import { AdbCommand, AdbPacket,
|
|
6
|
-
import { calculateBase64EncodedLength, encodeBase64 } from './utils';
|
|
2
|
+
import type { Disposable } from '@yume-chan/event';
|
|
3
|
+
import type { ValueOrPromise } from '@yume-chan/struct';
|
|
4
|
+
import { calculatePublicKey, calculatePublicKeyLength, sign } from './crypto.js';
|
|
5
|
+
import { AdbCommand, AdbPacket, type AdbPacketCore } from './packet.js';
|
|
6
|
+
import { calculateBase64EncodedLength, encodeBase64 } from './utils/index.js';
|
|
7
7
|
|
|
8
|
-
export type AdbKeyIterable = Iterable<
|
|
8
|
+
export type AdbKeyIterable = Iterable<Uint8Array> | AsyncIterable<Uint8Array>;
|
|
9
9
|
|
|
10
10
|
export interface AdbCredentialStore {
|
|
11
11
|
/**
|
|
12
12
|
* Generate and store a RSA private key with modulus length `2048` and public exponent `65537`.
|
|
13
13
|
*
|
|
14
|
-
* The returned `
|
|
14
|
+
* The returned `Uint8Array` is the private key in PKCS #8 format.
|
|
15
15
|
*/
|
|
16
|
-
generateKey(): ValueOrPromise<
|
|
16
|
+
generateKey(): ValueOrPromise<Uint8Array>;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Synchronously or asynchronously iterate through all stored RSA private keys.
|
|
@@ -44,13 +44,13 @@ export interface AdbAuthenticator {
|
|
|
44
44
|
(
|
|
45
45
|
credentialStore: AdbCredentialStore,
|
|
46
46
|
getNextRequest: () => Promise<AdbPacket>
|
|
47
|
-
): AsyncIterable<
|
|
47
|
+
): AsyncIterable<AdbPacketCore>;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export const AdbSignatureAuthenticator: AdbAuthenticator = async function* (
|
|
51
51
|
credentialStore: AdbCredentialStore,
|
|
52
52
|
getNextRequest: () => Promise<AdbPacket>,
|
|
53
|
-
): AsyncIterable<
|
|
53
|
+
): AsyncIterable<AdbPacketCore> {
|
|
54
54
|
for await (const key of credentialStore.iterateKeys()) {
|
|
55
55
|
const packet = await getNextRequest();
|
|
56
56
|
|
|
@@ -58,12 +58,12 @@ export const AdbSignatureAuthenticator: AdbAuthenticator = async function* (
|
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
const signature = sign(key, packet.payload
|
|
61
|
+
const signature = sign(key, packet.payload);
|
|
62
62
|
yield {
|
|
63
63
|
command: AdbCommand.Auth,
|
|
64
64
|
arg0: AdbAuthType.Signature,
|
|
65
65
|
arg1: 0,
|
|
66
|
-
payload: signature,
|
|
66
|
+
payload: new Uint8Array(signature),
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
};
|
|
@@ -71,19 +71,20 @@ export const AdbSignatureAuthenticator: AdbAuthenticator = async function* (
|
|
|
71
71
|
export const AdbPublicKeyAuthenticator: AdbAuthenticator = async function* (
|
|
72
72
|
credentialStore: AdbCredentialStore,
|
|
73
73
|
getNextRequest: () => Promise<AdbPacket>,
|
|
74
|
-
): AsyncIterable<
|
|
74
|
+
): AsyncIterable<AdbPacketCore> {
|
|
75
75
|
const packet = await getNextRequest();
|
|
76
76
|
|
|
77
77
|
if (packet.arg0 !== AdbAuthType.Token) {
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
let privateKey:
|
|
81
|
+
let privateKey: Uint8Array | undefined;
|
|
82
82
|
for await (const key of credentialStore.iterateKeys()) {
|
|
83
83
|
privateKey = key;
|
|
84
84
|
break;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
|
|
87
88
|
if (!privateKey) {
|
|
88
89
|
privateKey = await credentialStore.generateKey();
|
|
89
90
|
}
|
|
@@ -93,10 +94,13 @@ export const AdbPublicKeyAuthenticator: AdbAuthenticator = async function* (
|
|
|
93
94
|
|
|
94
95
|
// The public key is null terminated,
|
|
95
96
|
// So we allocate the buffer with one extra byte.
|
|
96
|
-
const publicKeyBuffer = new
|
|
97
|
+
const publicKeyBuffer = new Uint8Array(publicKeyBase64Length + 1);
|
|
97
98
|
|
|
98
99
|
calculatePublicKey(privateKey, publicKeyBuffer);
|
|
99
|
-
encodeBase64(
|
|
100
|
+
encodeBase64(
|
|
101
|
+
publicKeyBuffer.subarray(0, publicKeyLength),
|
|
102
|
+
publicKeyBuffer
|
|
103
|
+
);
|
|
100
104
|
|
|
101
105
|
yield {
|
|
102
106
|
command: AdbCommand.Auth,
|
|
@@ -118,7 +122,7 @@ export class AdbAuthenticationHandler implements Disposable {
|
|
|
118
122
|
|
|
119
123
|
private pendingRequest = new PromiseResolver<AdbPacket>();
|
|
120
124
|
|
|
121
|
-
private iterator: AsyncIterator<
|
|
125
|
+
private iterator: AsyncIterator<AdbPacketCore> | undefined;
|
|
122
126
|
|
|
123
127
|
public constructor(
|
|
124
128
|
authenticators: readonly AdbAuthenticator[],
|
|
@@ -132,7 +136,7 @@ export class AdbAuthenticationHandler implements Disposable {
|
|
|
132
136
|
return this.pendingRequest.promise;
|
|
133
137
|
};
|
|
134
138
|
|
|
135
|
-
private async* runAuthenticator(): AsyncGenerator<
|
|
139
|
+
private async* runAuthenticator(): AsyncGenerator<AdbPacketCore> {
|
|
136
140
|
for (const authenticator of this.authenticators) {
|
|
137
141
|
for await (const packet of authenticator(this.credentialStore, this.getNextRequest)) {
|
|
138
142
|
// If the authenticator yielded a response
|
|
@@ -150,7 +154,7 @@ export class AdbAuthenticationHandler implements Disposable {
|
|
|
150
154
|
throw new Error('Cannot authenticate with device');
|
|
151
155
|
}
|
|
152
156
|
|
|
153
|
-
public async handle(packet: AdbPacket): Promise<
|
|
157
|
+
public async handle(packet: AdbPacket): Promise<AdbPacketCore> {
|
|
154
158
|
if (!this.iterator) {
|
|
155
159
|
this.iterator = this.runAuthenticator();
|
|
156
160
|
}
|
package/src/backend.ts
CHANGED
|
@@ -1,20 +1,11 @@
|
|
|
1
|
-
import type { Event } from '@yume-chan/event';
|
|
2
1
|
import type { ValueOrPromise } from '@yume-chan/struct';
|
|
2
|
+
import type { AdbPacketCore, AdbPacketInit } from "./packet.js";
|
|
3
|
+
import type { ReadableWritablePair } from "./stream/index.js";
|
|
3
4
|
|
|
4
5
|
export interface AdbBackend {
|
|
5
6
|
readonly serial: string;
|
|
6
7
|
|
|
7
8
|
readonly name: string | undefined;
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
readonly onDisconnected: Event<void>;
|
|
12
|
-
|
|
13
|
-
connect?(): ValueOrPromise<void>;
|
|
14
|
-
|
|
15
|
-
read(length: number): ValueOrPromise<ArrayBuffer>;
|
|
16
|
-
|
|
17
|
-
write(buffer: ArrayBuffer): ValueOrPromise<void>;
|
|
18
|
-
|
|
19
|
-
dispose(): ValueOrPromise<void>;
|
|
10
|
+
connect(): ValueOrPromise<ReadableWritablePair<AdbPacketCore, AdbPacketInit>>;
|
|
20
11
|
}
|
package/src/commands/base.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Struct from "@yume-chan/struct";
|
|
2
|
-
import { Adb } from '../adb';
|
|
3
|
-
import { AdbBufferedStream } from '../stream';
|
|
2
|
+
import type { Adb } from '../adb.js';
|
|
3
|
+
import { AdbBufferedStream } from '../stream/index.js';
|
|
4
4
|
|
|
5
5
|
const Version =
|
|
6
6
|
new Struct({ littleEndian: true })
|
|
@@ -33,7 +33,7 @@ export const AdbFrameBufferV1 =
|
|
|
33
33
|
.uint32('green_length')
|
|
34
34
|
.uint32('alpha_offset')
|
|
35
35
|
.uint32('alpha_length')
|
|
36
|
-
.
|
|
36
|
+
.uint8Array('data', { lengthField: 'size' });
|
|
37
37
|
|
|
38
38
|
export type AdbFrameBufferV1 = typeof AdbFrameBufferV1['TDeserializeResult'];
|
|
39
39
|
|
|
@@ -52,7 +52,7 @@ export const AdbFrameBufferV2 =
|
|
|
52
52
|
.uint32('green_length')
|
|
53
53
|
.uint32('alpha_offset')
|
|
54
54
|
.uint32('alpha_length')
|
|
55
|
-
.
|
|
55
|
+
.uint8Array('data', { lengthField: 'size' });
|
|
56
56
|
|
|
57
57
|
export type AdbFrameBufferV2 = typeof AdbFrameBufferV2['TDeserializeResult'];
|
|
58
58
|
|
package/src/commands/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export * from './base';
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './reverse';
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './sync';
|
|
8
|
-
export * from './tcpip';
|
|
1
|
+
export * from './base.js';
|
|
2
|
+
export * from './framebuffer.js';
|
|
3
|
+
export * from './install.js';
|
|
4
|
+
export * from './power.js';
|
|
5
|
+
export * from './reverse.js';
|
|
6
|
+
export * from './subprocess/index.js';
|
|
7
|
+
export * from './sync/index.js';
|
|
8
|
+
export * from './tcpip.js';
|
package/src/commands/install.ts
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
|
-
import { Adb } from "../adb";
|
|
2
|
-
import {
|
|
1
|
+
import type { Adb } from "../adb.js";
|
|
2
|
+
import { WrapWritableStream, WritableStream } from "../stream/index.js";
|
|
3
|
+
import { escapeArg } from "./subprocess/index.js";
|
|
4
|
+
import type { AdbSync } from "./sync/index.js";
|
|
3
5
|
|
|
4
|
-
export
|
|
6
|
+
export function install(
|
|
5
7
|
adb: Adb,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
): Promise<void> {
|
|
9
|
-
const filename = `/data/local/tmp/${Math.random().toString().substr(2)}.apk`;
|
|
8
|
+
): WritableStream<Uint8Array> {
|
|
9
|
+
const filename = `/data/local/tmp/${Math.random().toString().substring(2)}.apk`;
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
return new WrapWritableStream<Uint8Array, WritableStream<Uint8Array>, AdbSync>({
|
|
12
|
+
async start() {
|
|
13
|
+
// Upload apk file to tmp folder
|
|
14
|
+
const sync = await adb.sync();
|
|
15
|
+
const writable = sync.write(filename, undefined, undefined);
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
return {
|
|
18
|
+
writable,
|
|
19
|
+
state: sync,
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
async close(sync) {
|
|
23
|
+
sync.dispose();
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
// Invoke `pm install` to install it
|
|
26
|
+
await adb.subprocess.spawnAndWaitLegacy(['pm', 'install', escapeArg(filename)]);
|
|
27
|
+
|
|
28
|
+
// Remove the temp file
|
|
29
|
+
await adb.rm(filename);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
21
32
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// cspell: ignore bootloader
|
|
2
|
+
// cspell: ignore fastboot
|
|
3
|
+
// cspell: ignore keyevent
|
|
4
|
+
// cspell: ignore longpress
|
|
5
|
+
|
|
6
|
+
import { AdbCommandBase } from "./base.js";
|
|
7
|
+
|
|
8
|
+
export class AdbPower extends AdbCommandBase {
|
|
9
|
+
public reboot(name: string = '') {
|
|
10
|
+
return this.adb.createSocketAndWait(`reboot:${name}`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public bootloader() {
|
|
14
|
+
return this.reboot('bootloader');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public fastboot() {
|
|
18
|
+
return this.reboot('fastboot');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public recovery() {
|
|
22
|
+
return this.reboot('recovery');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public sideload() {
|
|
26
|
+
return this.reboot('sideload');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Reboot to Qualcomm Emergency Download (EDL) Mode.
|
|
31
|
+
*
|
|
32
|
+
* Only works on some Qualcomm devices.
|
|
33
|
+
*/
|
|
34
|
+
public qualcommEdlMode() {
|
|
35
|
+
return this.reboot('edl');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public powerOff() {
|
|
39
|
+
return this.adb.subprocess.spawnAndWaitLegacy(['reboot', '-p']);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public powerButton(longPress: boolean = false) {
|
|
43
|
+
return this.adb.subprocess.spawnAndWaitLegacy(['input', 'keyevent', longPress ? '--longpress POWER' : 'POWER']);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Reboot to Samsung Odin download mode.
|
|
48
|
+
*
|
|
49
|
+
* Only works on Samsung devices.
|
|
50
|
+
*/
|
|
51
|
+
public samsungOdin() {
|
|
52
|
+
return this.reboot('download');
|
|
53
|
+
}
|
|
54
|
+
}
|