Skip to content

Commit

Permalink
Add support for fastboot boot, Display errors, General fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
mariogrip committed May 15, 2017
1 parent 5f239f9 commit 4b4a2f0
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 40 deletions.
4 changes: 2 additions & 2 deletions cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const utils = require("./src/utils");
const systemImage = require("./src/system-image");
const package = require("./package.json")

const defaultChannel = "ubuntu-touch/stable";
const defaultChannel = "ubports-touch/legacy";

process.env.NO_GUI = 1;

Expand Down Expand Up @@ -111,7 +111,7 @@ var bootstrap = (device) => {
cli
.version(package.version)
.option('-d, --device <device>', 'Specify device')
.option('-c, --channel <channel>', 'Specify channel (default: ubuntu-touch/stable)')
.option('-c, --channel <channel>', 'Specify channel (default: ubports-touch/legacy)')
.option('-v, --verbose', "Verbose output")
.option('-b, --bootstrap', "Flash boot and recovery from bootloader")
.parse(process.argv);
Expand Down
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "src/main.js",
"bin": "./src/main.js",
"scripts": {
"test-unit": "NODE_ENV=test mocha 'tests/unit-tests/*.js'",
"start": "electron .",
"install": "node ./build.js -d",
"dist:unix": "node ./build.js -lm",
Expand All @@ -16,26 +17,35 @@
"author": "The Ubports developers <[email protected]>",
"license": "GPL-3.0",
"devDependencies": {
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"electron": "^1.4.1",
"electron-builder": "^15.2.0",
"electron-packager": "^8.5.2",
"istanbul": "^0.4.5",
"mocha": "^3.2.0",
"sinon": "^1.17.7",
"spectron": "^3.6.0",
"unzip": "^0.1.11"
},
"dependencies": {
"bootstrap": "^3.3.7",
"checksum": "^0.1.1",
"commander": "^2.9.0",
"decompress-tarxz": "^2.1.0",
"electron-open-link-in-browser": "^1.0.2",
"electron-sudo": "^3.0.13",
"executable": "^4.1.0",
"forward-emitter": "^0.1.1",
"fs-extra": "^2.0.0",
"ini": "^1.3.4",
"jquery": "^3.1.1",
"mkdirp": "^0.5.1",
"openurl": "^1.1.1",
"request": "^2.79.0",
"request-progress": "^3.0.0",
"tmp": "0.0.31",
"wildcard": "^1.1.2",
"winston": "^2.3.1"
}
}
47 changes: 43 additions & 4 deletions src/adb.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,60 @@ const fs = require("fs");
const events = require("events")
const fEvent = require('forward-emitter');
const utils = require("./utils");
const ini = require('ini');
const adb = utils.getPlatformTools().adb

class event extends events {}

var getDeviceNameFromPropFile = (callback) => {
shell("cat default.prop", (output) => {
output=output.split("\n");
var ret;
output.forEach((prop) => {
if (prop.includes("ro.product.device") && prop !== undefined && !ret){
ret = prop.split("=")[1];
}
})
callback(ret.replace(/\W/g, ""));
})
}

var getDeviceName = (callback, method) => {
if (!method) method = "device";
cp.execFile(adb, ["shell", "getprop ro.product."+method], (err, stdout, stderr) => {
if (err !== null) callback(false);
else callback(stdout.replace(/\W/g, ""));
if (stdout.includes("getprop: not found")){
getDeviceNameFromPropFile(callback);
return;
}
if (err !== null) {
callback(false);
return;
}
callback(stdout.replace(/\W/g, ""));
});
}

var isUbuntuDevice = () => {
shell("cat /etc/system-image/channel.ini", (output) => {
return output ? true : false;
})
}

var readUbuntuChannelINI = () => {
shell("cat /etc/system-image/channel.ini", (output) => {
return ini.parse(output);
})
}

var push = (file, dest, pushEvent) => {
var done;
var fileSize = fs.statSync(file)["size"];
cp.execFile(adb, ["push", file, dest], {maxBuffer: 2000*1024}, (err, stdout, stderr) => {
done=true;
if (err !== null) pushEvent.emit("adbpush:error", err+" stdout: " + stdout.length > 50*1024 ? "overflow" : stdout + " stderr: " + stderr.length > 50*1024 ? "overflow" : stderr)
if (err !== null) {
pushEvent.emit("adbpush:error", err+" stdout: " + stdout.length > 50*1024 ? "overflow" : stdout + " stderr: " + stderr.length > 50*1024 ? "overflow" : stderr)
console.log(stdout.length > 50*1024 ? "overflow" : stdout + " stderr: " + stderr.length > 50*1024 ? "overflow" : stderr)
}
else pushEvent.emit("adbpush:end")
});
var progress = () => {
Expand Down Expand Up @@ -115,5 +151,8 @@ module.exports = {
push: push,
pushMany: pushMany,
hasAdbAccess: hasAdbAccess,
reboot: reboot
reboot: reboot,
getDeviceNameFromPropFile: getDeviceNameFromPropFile,
isUbuntuDevice: isUbuntuDevice,
readUbuntuChannelINI: readUbuntuChannelINI
}
84 changes: 59 additions & 25 deletions src/devices.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const os = require("os");
const path = require("path");
const events = require("events")
const fEvent = require('forward-emitter');
//const wildcard = require("wildcard");

class event extends events {}

Expand Down Expand Up @@ -71,6 +72,7 @@ var getInstallInstructs = (device, callback) => {
}

var getNotWorking = (ww) => {
if (!ww) return false;
var notWorking = [];
var whatsWorking = JSON.parse(ww);
for (var i in whatsWorking) {
Expand All @@ -83,6 +85,7 @@ var getNotWorking = (ww) => {
}

var formatNotWorking = (nw) => {
if (!nw) return false;
return nw.join(", ").replace("/\,(?=[^,]*$)", " and");
}

Expand All @@ -100,9 +103,9 @@ var instructReboot = (state, button, rebootEvent, callback) => {
}
if (state === "bootloader") {
requestPassword(rebootEvent, (pass) => {
fastboot.waitForDevice(pass, (err) => {
fastboot.waitForDevice(pass, (err, errM) => {
if (err){
rebootEvent.emit("Error", err);
rebootEvent.emit("Error", errM);
return;
}
rebootEvent.emit("reboot:done");
Expand Down Expand Up @@ -143,31 +146,49 @@ var requestPassword = (bootstrapEvent, callback) => {
var instructBootstrap = (fastbootboot, images, bootstrapEvent) => {
//TODO check bootloader name/version/device
//TODO OEM unlock

var flash = (p) => {
fastboot.flash(images, (err) => {
fastboot.flash(images, (err, errM) => {
if(err)
if(err.password)
bootstrapEvent.emit("user:password:wrong");
else
bootstrapEvent.emit("error", err)
else
bootstrapEvent.emit("bootstrap:done")
bootstrapEvent.emit("error", errM)
else {
if (fastbootboot) {
utils.log.info("Booting into recovery image...");
// find recovery image
var recoveryImg;
images.forEach((image) => {
if (image.type === "recovery")
recoveryImg = image;
});
// If we can't find it, report error!
if (!recoveryImg){
bootstrapEvent.emit("error", "Cant find recoveryImg to boot: "+images);
}else {
fastboot.boot(recoveryImg, p, (err, errM) => {
if (err) {
if(err.password)
bootstrapEvent.emit("user:password:wrong");
else
bootstrapEvent.emit("error", errM)
}else
bootstrapEvent.emit("bootstrap:done", fastbootboot);
})
}
} else
bootstrapEvent.emit("bootstrap:done", fastbootboot)
}
}, p)
}

if (fastbootboot) {
bootstrapEvent.emit("user:write:status", "Booting into recovery image...")
} else {
bootstrapEvent.emit("bootstrap:flashing")
bootstrapEvent.emit("user:write:status", "Flashing images")
if (!utils.needRoot()) {
flash(false);
}else {
requestPassword(bootstrapEvent, (p) => {
flash(p);
});
}
bootstrapEvent.emit("bootstrap:flashing")
bootstrapEvent.emit("user:write:status", "Flashing images")
if (!utils.needRoot()) {
flash(false);
}else {
requestPassword(bootstrapEvent, (p) => {
flash(p);
});
}
}

Expand All @@ -194,6 +215,7 @@ var setEvents = (downloadEvent) => {
utils.log.error("Devices: Download error "+r);
});
downloadEvent.on("error", (r) => {
downloadEvent.emit("user:error", r);
utils.log.error("Devices: Error: "+r);
});
downloadEvent.on("download:checking", () => {
Expand Down Expand Up @@ -260,14 +282,21 @@ var install = (device, channel, noUserEvents, noSystemImage) => {
postSuccess({
device: device,
channel: channel
})
}, () => {});
});
})
installEvent.on("bootstrap:done", () => {
installEvent.on("bootstrap:done", (fastbootboot) => {
utils.log.info("bootstrap done");
instructReboot("recovery", instructs.buttons, installEvent, () => {
installEvent.emit("system-image:start")
});
if (!fastbootboot){
instructReboot("recovery", instructs.buttons, installEvent, () => {
installEvent.emit("system-image:start")
});
} else {
installEvent.emit("user:write:status", "Waiting for device to enter recovery mode");
adb.waitForDevice(() => {
installEvent.emit("system-image:start");
})
}
})
if (getInstallSettings(instructs, "bootstrap")) {
// We need to be in bootloader
Expand Down Expand Up @@ -296,6 +325,7 @@ var getChannelSelects = (device, callback) => {
setTimeout(function () {
getInstallInstructs(device, (ret) => {
systemImage.getDeviceChannes(device, channels).forEach((channel) => {
var _channel = channel.replace("ubports-touch/", "");
var _channel = channel.replace("ubuntu-touch/", "");
// Ignore blacklisted channels
if (ret["system_server"]["blacklist"].indexOf(channel) > -1)
Expand All @@ -317,6 +347,10 @@ module.exports = {
var waitEvent = adb.waitForDevice(() => {
adb.getDeviceName((name) => {
getDevice(name, (ret) => {
if (!ret){
callback(false, name);
return;
}
getChannelSelects(ret.device.device, (channels) => {
callback(ret, device, channels);
})
Expand Down
31 changes: 27 additions & 4 deletions src/fastboot.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ var waitForDevice = (password, callback) => {
asarExec.done();
}else {
// Unknown error;
utils.log.error("Fastboot: Unknown error: 001");
callback(true);
utils.log.error("Fastboot: Unknown error: " + r.replace(password, "***") + " " + e.replace(password, "***"));
callback(true, "Fastboot: Unknown error: " + r.replace(password, "***") + " " + e.replace(password, "***"));
}
return;
} else {
Expand All @@ -57,7 +57,7 @@ var flash = (images, callback, password) => {
images.forEach((image, l) => {
if (utils.needRoot())
cmd += "echo " + password + " | sudo -S "
cmd += fastboot + " flash " + image.type + " \"" + image.path + "\"/" + path.basename(image.url);
cmd += fastboot + " flash " + image.type + " \"" + path.join(image.path, path.basename(image.url)) + "\"";
if (l !== images.length - 1)
cmd += " && "
});
Expand All @@ -68,6 +68,7 @@ var flash = (images, callback, password) => {
callback({
password: true
});
else callback(true, "Fastboot: Unknown error: " + r.replace(password, "***") + " " + e.replace(password, "***"));
} else {
callback(c, r, e)
}
Expand All @@ -76,7 +77,29 @@ var flash = (images, callback, password) => {
});
}

var boot = (image, password, callback) => {
var cmd="";
if (utils.needRoot())
cmd += "echo " + password + " | sudo -S "
cmd += fastboot + " boot \"" + path.join(image.path, path.basename(image.url)) + "\"";
utils.asarExec(fastboot, (asarExec) => {
asarExec.exec(cmd, (c, r, e) => {
if (c) {
if (c.message.includes("incorrect password"))
callback({
password: true
});
else callback(true, "Fastboot: Unknown error: " + r.replace(password, "***") + " " + e.replace(password, "***"));
} else {
callback(c, r, e)
}
asarExec.done();
})
});
}

module.exports = {
flash: flash,
waitForDevice: waitForDevice
waitForDevice: waitForDevice,
boot: boot
}
Loading

0 comments on commit 4b4a2f0

Please sign in to comment.