Skip to content

Commit

Permalink
Refactoring of promise-android-tools (#1487)
Browse files Browse the repository at this point in the history
* testing ground for promise-android-tools refactoring

* Allow initial wait function to use fastboot to detect and identify devices, resolves #902

* Report progress from adb sideload and fastboot flash, resolves #1487

* Ignore irrellevant errors while preparing systemimage

* tweak error handling

* Move to released module

* update deps

* remove defaultMeta from winston, resolves #1507

* Hide speed after download, resolves #1509

* Allow dismissing report prompt temporarily, resolves #1508
  • Loading branch information
NeoTheThird committed Nov 9, 2020
1 parent 4712efb commit ed7974a
Show file tree
Hide file tree
Showing 10 changed files with 7,798 additions and 312 deletions.
7,879 changes: 7,718 additions & 161 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ubports-installer",
"version": "0.6.0-beta",
"version": "0.7.0-beta",
"description": "The easy way to install Ubuntu Touch on UBports devices. A friendly cross-platform Installer for Ubuntu Touch. Just connect a supported device to your PC, follow the on-screen instructions and watch this awesome tool do all the rest.",
"keywords": [
"Ubuntu",
Expand Down Expand Up @@ -44,7 +44,6 @@
},
"dependencies": {
"7zip-min": "^1.2.0",
"android-tools-bin": "^1.0.4",
"axios": "^0.20.0",
"bootstrap": "^3.3.7",
"commander": "^2.9.0",
Expand All @@ -59,7 +58,7 @@
"jquery-i18next": "^1.2.0",
"popper.js": "^1.16.0",
"progressive-downloader": "^1.0.5",
"promise-android-tools": "^3.0.3",
"promise-android-tools": "^4.0.0",
"ps-tree": "^1.2.0",
"sudo-prompt": "^9.2.1",
"system-image-node-module": "^1.1.1",
Expand Down
75 changes: 37 additions & 38 deletions src/devices.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ function installStep(step) {
"user:write:under",
"Formatting " + step.partition
);
return adb.waitForDevice().then(() => adb.format(step.partition));
return adb.wait().then(() => adb.format(step.partition));
};
case "adb:sideload":
return () => {
Expand All @@ -237,16 +237,19 @@ function installStep(step) {
);
global.mainEvent.emit(
"user:write:under",
"Sideloading might take up to ten minutes..."
"Your new operating system is being installed..."
);
return adb.sideload(
path.join(
downloadPath,
global.installProperties.device,
step.group,
step.file
return global.adb
.sideload(
path.join(
utils.getUbuntuTouchDir(),
global.installProperties.device,
step.group,
step.file
),
p => global.mainEvent.emit("user:write:progress", p * 100)
)
);
.then(() => global.mainEvent.emit("user:write:progress", 0));
};
case "adb:reboot":
return () => {
Expand All @@ -267,12 +270,14 @@ function installStep(step) {
"Flashing firmware partitions using fastboot"
);
return fastboot
.waitForDevice()
.wait()
.then(() =>
fastboot.flashArray(
addPathToFiles(step.flash, global.installProperties.device)
fastboot.flash(
addPathToFiles(step.flash, global.installProperties.device),
p => global.mainEvent.emit("user:write:progress", p * 100)
)
);
)
.then(() => global.mainEvent.emit("user:write:progress", 0));
};
case "fastboot:erase":
return () => {
Expand Down Expand Up @@ -379,7 +384,7 @@ function installStep(step) {
"user:write:under",
"Flashing firmware partitions using heimdall"
);
return heimdall.flashArray(
return heimdall.flash(
addPathToFiles(step.flash, global.installProperties.device)
);
};
Expand Down Expand Up @@ -530,7 +535,7 @@ function assembleInstallSteps(steps) {
"user:connection-lost",
step.resumable ? runStep : restartInstall
);
} else if (error.message.includes("Killed")) {
} else if (error.message.includes("killed")) {
reject(); // Used for exiting the installer
} else {
utils.errorToUser(error, step.type, restartInstall, runStep);
Expand Down Expand Up @@ -573,29 +578,23 @@ function install(steps) {
}

module.exports = {
waitForDevice: () => {
adb
.waitForDevice()
.then(() => {
adb
.getDeviceName()
.then(device => {
global.api
.resolveAlias(device)
.then(resolvedDevice => {
global.mainEvent.emit("device:detected", resolvedDevice);
})
.catch(error => {
utils.log.error("getDeviceName error: " + error);
mainEvent.emit("user:no-network");
});
})
.catch(error => {
utils.errorToUser(error, "get device name");
});
})
.catch(e => utils.log.debug("no device detected: " + e));
},
waitForDevice: () =>
deviceTools
.wait()
.then(() => deviceTools.getDeviceName())
.then(device =>
global.api.resolveAlias(device).catch(e => {
utils.log.debug(`failed to resolve device name: ${e}`);
mainEvent.emit("user:no-network");
})
)
.then(resolvedDevice =>
global.mainEvent.emit("device:detected", resolvedDevice)
)
.catch(error => {
if (!error.message.includes("no device"))
utils.errorToUser(error, "get device name");
}),
getOsSelects: osArray => {
// Can't be moved to support custom config files
var osSelects = [];
Expand Down
58 changes: 17 additions & 41 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
global.packageInfo = require("../package.json");

const { Adb, Fastboot, Heimdall } = require("promise-android-tools");
const { DeviceTools } = require("promise-android-tools");
const Api = require("ubports-api-node-module").Installer;
const Store = require("electron-store");

Expand Down Expand Up @@ -57,27 +57,14 @@ const api = new Api({
cachetime: 60000
});
global.api = api;
var adb = new Adb({
exec: (args, callback) => {
utils.execTool("adb", args, callback);
},
log: utils.log.debug
});
global.adb = adb;
var fastboot = new Fastboot({
exec: (args, callback) => {
utils.execTool("fastboot", args, callback);
},
log: utils.log.debug
});
global.fastboot = fastboot;
var heimdall = new Heimdall({
exec: (args, callback) => {
utils.execTool("heimdall", args, callback);
},
log: utils.log.debug
});
global.heimdall = heimdall;
const deviceTools = new DeviceTools();
global.deviceTools = deviceTools;
global.adb = deviceTools.adb;
global.fastboot = deviceTools.fastboot;
global.heimdall = deviceTools.heimdall;
["exec", "spawn:start", "spawn:exit", "spawn:error"].forEach(event =>
deviceTools.on(event, r => global.logger.log("command", event, r))
);

const settings = new Store({
schema: {
Expand Down Expand Up @@ -164,7 +151,6 @@ winston.addColors({

global.logger = winston.createLogger({
format: winston.format.json(),
defaultMeta: { service: "user-service" },
levels: {
error: 0,
warn: 1,
Expand Down Expand Up @@ -235,7 +221,6 @@ ipcMain.on("reportResult", async (event, result, error) => {

// The user selected a device
ipcMain.on("device:selected", (event, device) => {
adb.stopWaiting();
mainEvent.emit("device", device);
});

Expand Down Expand Up @@ -308,6 +293,7 @@ mainEvent.on("user:error", (error, restart, ignore) => {
return;
case "restart":
utils.log.warn("restart after error");
deviceTools.kill();
if (restart) setTimeout(restart, 500);
else mainEvent.emit("restart");
return;
Expand Down Expand Up @@ -358,7 +344,7 @@ mainEvent.on("user:oem-lock", callback => {
"user:write:under",
"You might see a confirmation dialog on your device."
);
fastboot
deviceTools.fastboot
.oemUnlock()
.then(() => {
callback(true);
Expand Down Expand Up @@ -401,7 +387,7 @@ mainEvent.on("user:write:done", () => {
);
if (!settings.get("never.opencuts")) {
setTimeout(() => {
mainWindow.webContents.send("user:report");
mainWindow.webContents.send("user:report", true);
}, 1500);
}
});
Expand Down Expand Up @@ -524,17 +510,10 @@ async function createWindow() {

// Tasks we need for every start and restart
mainWindow.webContents.on("did-finish-load", () => {
adb
.startServer()
.then(() => {
if (!global.installProperties.device) {
devices.waitForDevice();
}
})
.catch(e => {
if (!e.message.includes("Killed"))
utils.errorToUser(e, "Failed to start adb server");
});
if (!global.installProperties.device) {
const wait = devices.waitForDevice();
ipcMain.once("device:selected", () => (wait ? wait.cancel() : null));
}
api
.getDeviceSelects()
.then(out => {
Expand Down Expand Up @@ -585,10 +564,7 @@ async function createWindow() {
app.on("ready", createWindow);

app.on("window-all-closed", function() {
adb
.killServer()
.then(utils.killSubprocesses)
.catch(utils.killSubprocesses);
deviceTools.kill();
utils.log.info("Good bye!");
setTimeout(() => {
app.quit();
Expand Down
2 changes: 1 addition & 1 deletion src/pug/index.pug
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ html
include scripts/root.js
.header.is-over
h3#header-text.text-muted.installer UBports Installer (#{installerVersion})
button#help.help-button.btn.btn-primary Report a bug
button#help.help-button.btn.btn-primary(onclick="requestReport()") Report a bug
button#donate.donate-button.btn.btn-primary Donate
#particles-background.vertical-centered-box
#particles-foreground.vertical-centered-box
Expand Down
14 changes: 11 additions & 3 deletions src/pug/modals/result.pug
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
p Select a result from the buttons below. You will see another window where you can explain your experience in more detail and modify all the data before submitting.
p Select the #[b PASS] option if everything worked as expected. If you experienced minor issues or annoyances, but finally succeeded in installing your device, select the #[b WONKY] result. The #[b FAIL] result indicates a more severe problem.
.modal-footer
button.btn.btn-default(type='button', data-dismiss='modal', onclick='ipcRenderer.invoke("setSettingsValue", "never.opencuts", true)') No, don't ask me again
button.btn.btn-default#resultDoNotAskAgain(type='button', data-dismiss='modal', onclick='ipcRenderer.invoke("setSettingsValue", "never.opencuts", true)') No, don't ask me again
button.btn.btn-secondary(type='button', data-dismiss='modal') Dismiss
button.btn.btn-success(type='button', data-dismiss='modal', onclick="report('PASS');") PASS
button.btn.btn-warning(type='button', data-dismiss='modal', onclick="report('WONKY');") WONKY
button.btn.btn-danger(type='button', data-dismiss='modal', onclick="report('FAIL');") FAIL
Expand All @@ -20,6 +21,13 @@
ipcRenderer.send("reportResult", result);
}

ipcRenderer.on("user:report", () => {
function requestReport(done = false) {
if (done) {
$('#resultDoNotAskAgain').show();
} else {
$('#resultDoNotAskAgain').hide();
}
modals.show('result');
});
}

ipcRenderer.on("user:report", (_, done) => requestReport(done));
4 changes: 0 additions & 4 deletions src/pug/scripts/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,6 @@ const modals = {
}
};

$("#help").click(() => {
modals.show("result");
});

$("#donate").click(() => {
shell.openExternal("https://ubports.com/donate");
});
Expand Down
6 changes: 1 addition & 5 deletions src/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const axios = require("axios");
const FormData = require("form-data");
const util = require("util");
const { osInfo } = require("systeminformation");
const { getAndroidToolBaseDir } = require("android-tools-bin");
const { GraphQLClient, gql } = require("graphql-request");
const { getUbuntuTouchDir } = require("./utils");
require("cross-fetch/polyfill");
Expand Down Expand Up @@ -219,10 +218,7 @@ async function paste(
*/
function getIssueTitle(error) {
if (!error) return "";
else
return error
.replaceAll(getAndroidToolBaseDir(), "$PKG")
.replaceAll(getUbuntuTouchDir(), "$CACHE");
else return error.replaceAll(getUbuntuTouchDir(), "$CACHE");
}

/**
Expand Down
19 changes: 11 additions & 8 deletions src/system-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,16 @@ var installLatestVersion = options => {
)
.then(files => {
mainEvent.emit("user:write:progress", 0);
mainEvent.emit("user:write:speed", 0);
mainEvent.emit("user:write:working", "particles");
mainEvent.emit("user:write:status", "Preparing", true);
mainEvent.emit("user:write:under", "Preparing system-image");
return files;
}),
adb
.waitForDevice()
.then(() => adb.shell("'mount -a || true'"))
.then(() => utils.log.debug("adb mounted all partitions"))
.then(() => adb.wipeCache())
.then(() => utils.log.debug("adb wiped cache"))
.wait()
.then(() => adb.shell("mount -a").catch(() => null))
.then(() => adb.wipeCache().catch(() => null))
.then(() => adb.shell("mkdir -p /cache/recovery"))
.then(() => {
utils.log.debug("adb created /cache/recovery directory");
Expand All @@ -76,9 +75,13 @@ var installLatestVersion = options => {
return ret[0]; // files from download promise
})
.then(files =>
adb.pushArray(files, progress => {
global.mainEvent.emit("user:write:progress", progress * 100);
})
adb.push(
files.map(f => f.src),
files[0].dest,
progress => {
global.mainEvent.emit("user:write:progress", progress * 100);
}
)
)
.catch(e => {
throw new Error(e);
Expand Down

0 comments on commit ed7974a

Please sign in to comment.