2018-08-09 05:27:55 +00:00
|
|
|
/* 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/. */
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const { Cc, Ci } = require("chrome");
|
2018-08-10 07:32:21 +00:00
|
|
|
const { dumpn } = require("devtools/shared/DevToolsUtils");
|
2019-04-23 11:44:44 +00:00
|
|
|
const EventEmitter = require("devtools/shared/event-emitter");
|
2018-08-09 05:27:55 +00:00
|
|
|
const { getFileForBinary } = require("./adb-binary");
|
|
|
|
const { setTimeout } = require("resource://gre/modules/Timer.jsm");
|
|
|
|
|
2018-12-05 20:51:58 +00:00
|
|
|
loader.lazyRequireGetter(
|
|
|
|
this,
|
|
|
|
"runCommand",
|
|
|
|
"devtools/shared/adb/commands/index",
|
|
|
|
true
|
|
|
|
);
|
|
|
|
loader.lazyRequireGetter(
|
|
|
|
this,
|
|
|
|
"check",
|
|
|
|
"devtools/shared/adb/adb-running-checker",
|
2019-07-05 09:29:32 +00:00
|
|
|
true
|
|
|
|
);
|
2018-08-09 05:27:55 +00:00
|
|
|
|
2018-12-05 20:51:58 +00:00
|
|
|
// Waits until a predicate returns true or re-tries the predicate calls
|
|
|
|
// |retry| times, we wait for 100ms between each calls.
|
|
|
|
async function waitUntil(predicate, retry = 20) {
|
|
|
|
let count = 0;
|
|
|
|
while (count++ < retry) {
|
|
|
|
if (await predicate()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// Wait for 100 milliseconds.
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
}
|
|
|
|
// Timed out after trying too many times.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Class representing the ADB process.
|
2019-04-23 11:44:44 +00:00
|
|
|
class AdbProcess extends EventEmitter {
|
2018-12-05 20:51:58 +00:00
|
|
|
constructor() {
|
2019-04-23 11:44:44 +00:00
|
|
|
super();
|
|
|
|
|
2018-12-05 20:51:58 +00:00
|
|
|
this._ready = false;
|
|
|
|
this._didRunInitially = false;
|
|
|
|
}
|
2018-08-09 05:27:55 +00:00
|
|
|
|
|
|
|
get ready() {
|
2018-12-05 20:51:58 +00:00
|
|
|
return this._ready;
|
|
|
|
}
|
2018-08-09 05:27:55 +00:00
|
|
|
|
2018-12-05 20:51:58 +00:00
|
|
|
_getAdbFile() {
|
2018-08-09 05:27:55 +00:00
|
|
|
if (this._adbFilePromise) {
|
|
|
|
return this._adbFilePromise;
|
|
|
|
}
|
|
|
|
this._adbFilePromise = getFileForBinary();
|
|
|
|
return this._adbFilePromise;
|
2018-12-05 20:51:58 +00:00
|
|
|
}
|
2018-08-09 05:27:55 +00:00
|
|
|
|
2018-08-09 06:43:39 +00:00
|
|
|
async _runProcess(process, params) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
process.runAsync(
|
|
|
|
params,
|
|
|
|
params.length,
|
|
|
|
{
|
|
|
|
observe(subject, topic, data) {
|
|
|
|
switch (topic) {
|
|
|
|
case "process-finished":
|
|
|
|
resolve();
|
|
|
|
break;
|
|
|
|
case "process-failed":
|
|
|
|
reject();
|
|
|
|
break;
|
|
|
|
}
|
2019-07-05 09:29:32 +00:00
|
|
|
},
|
2018-10-19 12:55:39 +00:00
|
|
|
},
|
2018-08-09 06:43:39 +00:00
|
|
|
false
|
|
|
|
);
|
|
|
|
});
|
2018-12-05 20:51:58 +00:00
|
|
|
}
|
2018-08-09 06:43:39 +00:00
|
|
|
|
2018-08-09 05:27:55 +00:00
|
|
|
// We startup by launching adb in server mode, and setting
|
|
|
|
// the tcp socket preference to |true|
|
2018-08-09 05:27:56 +00:00
|
|
|
async start() {
|
2018-08-09 05:27:55 +00:00
|
|
|
return new Promise(async (resolve, reject) => {
|
2018-08-09 05:27:55 +00:00
|
|
|
const onSuccessfulStart = () => {
|
2018-12-05 20:51:58 +00:00
|
|
|
this._ready = true;
|
2019-04-23 11:44:44 +00:00
|
|
|
this.emit("adb-ready");
|
2018-08-09 05:27:55 +00:00
|
|
|
resolve();
|
|
|
|
};
|
|
|
|
|
2018-08-09 05:27:55 +00:00
|
|
|
const isAdbRunning = await check();
|
2018-08-09 05:27:55 +00:00
|
|
|
if (isAdbRunning) {
|
2018-08-10 07:32:21 +00:00
|
|
|
dumpn("Found ADB process running, not restarting");
|
2018-08-09 05:27:55 +00:00
|
|
|
onSuccessfulStart();
|
|
|
|
return;
|
|
|
|
}
|
2018-08-10 07:32:21 +00:00
|
|
|
dumpn("Didn't find ADB process running, restarting");
|
2018-08-09 05:27:55 +00:00
|
|
|
|
2018-12-05 20:51:58 +00:00
|
|
|
this._didRunInitially = true;
|
|
|
|
const process = Cc["@mozilla.org/process/util;1"].createInstance(
|
|
|
|
Ci.nsIProcess
|
|
|
|
);
|
|
|
|
|
2018-08-09 05:27:55 +00:00
|
|
|
// FIXME: Bug 1481691 - We should avoid extracting files every time.
|
2018-12-05 20:51:58 +00:00
|
|
|
const adbFile = await this._getAdbFile();
|
2018-08-09 05:27:55 +00:00
|
|
|
process.init(adbFile);
|
|
|
|
// Hide command prompt window on Windows
|
2018-08-10 07:32:21 +00:00
|
|
|
process.startHidden = true;
|
|
|
|
process.noShell = true;
|
2018-08-09 05:27:55 +00:00
|
|
|
const params = ["start-server"];
|
2018-08-09 06:43:39 +00:00
|
|
|
let isStarted = false;
|
|
|
|
try {
|
|
|
|
await this._runProcess(process, params);
|
2018-12-05 20:51:58 +00:00
|
|
|
isStarted = await waitUntil(check);
|
2018-08-09 06:43:39 +00:00
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
if (isStarted) {
|
|
|
|
onSuccessfulStart();
|
|
|
|
} else {
|
2018-12-05 20:51:58 +00:00
|
|
|
this._ready = false;
|
2018-08-09 06:43:39 +00:00
|
|
|
reject();
|
|
|
|
}
|
2018-08-09 05:27:55 +00:00
|
|
|
});
|
2018-12-05 20:51:58 +00:00
|
|
|
}
|
2018-08-09 05:27:55 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop the ADB server, but only if we started it. If it was started before
|
|
|
|
* us, we return immediately.
|
|
|
|
*/
|
2018-08-10 07:32:21 +00:00
|
|
|
async stop() {
|
2018-12-05 20:51:58 +00:00
|
|
|
if (!this._didRunInitially) {
|
2018-08-09 05:27:55 +00:00
|
|
|
return; // We didn't start the server, nothing to do
|
|
|
|
}
|
2018-08-10 07:32:21 +00:00
|
|
|
await this.kill();
|
2018-12-05 20:51:58 +00:00
|
|
|
}
|
2018-08-09 05:27:55 +00:00
|
|
|
|
|
|
|
/**
|
2018-08-12 21:12:55 +00:00
|
|
|
* Kill the ADB server.
|
2018-08-09 05:27:55 +00:00
|
|
|
*/
|
2018-08-10 07:32:21 +00:00
|
|
|
async kill() {
|
2018-08-12 21:12:55 +00:00
|
|
|
try {
|
2018-12-05 20:47:34 +00:00
|
|
|
await runCommand("host:kill");
|
2018-08-12 21:12:55 +00:00
|
|
|
} catch (e) {
|
2018-08-12 21:12:55 +00:00
|
|
|
dumpn("Failed to send host:kill command");
|
2018-08-12 21:12:55 +00:00
|
|
|
}
|
2018-08-12 21:12:55 +00:00
|
|
|
dumpn("adb server was terminated by host:kill");
|
2018-12-05 20:51:58 +00:00
|
|
|
this._ready = false;
|
|
|
|
this._didRunInitially = false;
|
|
|
|
}
|
|
|
|
}
|
2018-08-09 05:27:55 +00:00
|
|
|
|
2018-12-05 20:51:58 +00:00
|
|
|
exports.adbProcess = new AdbProcess();
|