diff options
Diffstat (limited to 'devtools/client/shared/remote-debugging/adb/commands/shell.js')
-rw-r--r-- | devtools/client/shared/remote-debugging/adb/commands/shell.js | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/devtools/client/shared/remote-debugging/adb/commands/shell.js b/devtools/client/shared/remote-debugging/adb/commands/shell.js new file mode 100644 index 0000000000..03f4bfcf78 --- /dev/null +++ b/devtools/client/shared/remote-debugging/adb/commands/shell.js @@ -0,0 +1,107 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Wrapper around the ADB utility. + +"use strict"; + +const { dumpn } = require("resource://devtools/shared/DevToolsUtils.js"); +const client = require("resource://devtools/client/shared/remote-debugging/adb/adb-client.js"); + +const OKAY = 0x59414b4f; + +const shell = async function (deviceId, command) { + if (!deviceId) { + throw new Error("ADB shell command needs the device id"); + } + + let state; + let stdout = ""; + + dumpn("shell " + command + " on " + deviceId); + + return new Promise((resolve, reject) => { + const shutdown = function () { + dumpn("shell shutdown"); + socket.close(); + reject("BAD_RESPONSE"); + }; + + const runFSM = function runFSM(data) { + dumpn("runFSM " + state); + let req; + let ignoreResponseCode = false; + switch (state) { + case "start": + state = "send-transport"; + runFSM(); + break; + case "send-transport": + req = client.createRequest("host:transport:" + deviceId); + socket.send(req); + state = "wait-transport"; + break; + case "wait-transport": + if (!client.checkResponse(data, OKAY)) { + shutdown(); + return; + } + state = "send-shell"; + runFSM(); + break; + case "send-shell": + req = client.createRequest("shell:" + command); + socket.send(req); + state = "rec-shell"; + break; + case "rec-shell": + if (!client.checkResponse(data, OKAY)) { + shutdown(); + return; + } + state = "decode-shell"; + if (client.getBuffer(data).byteLength == 4) { + break; + } + ignoreResponseCode = true; + // eslint-disable-next-lined no-fallthrough + case "decode-shell": + const decoder = new TextDecoder(); + const text = new Uint8Array( + client.getBuffer(data), + ignoreResponseCode ? 4 : 0 + ); + stdout += decoder.decode(text); + break; + default: + dumpn("shell Unexpected State: " + state); + reject("UNEXPECTED_STATE"); + } + }; + + const socket = client.connect(); + socket.s.onerror = function (event) { + dumpn("shell onerror"); + reject("SOCKET_ERROR"); + }; + + socket.s.onopen = function (event) { + dumpn("shell onopen"); + state = "start"; + runFSM(); + }; + + socket.s.onclose = function (event) { + resolve(stdout); + dumpn("shell onclose"); + }; + + socket.s.ondata = function (event) { + dumpn("shell ondata"); + runFSM(event.data); + }; + }); +}; + +exports.shell = shell; |