[DO NOT MERGE] Parse BCB recovery reason to enable SOTA(Silent OTA).

After SOTA completed, SOTA application will send "--wipe_data"
and "--reason=enable-sota" into BCB recovery field, then enter
recovery for running factory reset.

Once factory reset completed, recovery must check "--reason",
determine if writing "enable-sota" into vendor misc partition
(from offset 32), and then reboot.

During next booting, bootloader will re-enable SOTA capability
while "enable-sota" found in vendor misc partition.

Bug: 144826346
Note: Issue [6] in b/131680543#comment12
Change-Id: I764f2243b4f4c150d5b9fd9e494770e2ad46d89f
This commit is contained in:
dybertwang
2019-07-18 11:05:13 +08:00
committed by Dybert Wang
parent 98d75f4660
commit e21081b4c8

View File

@@ -22,6 +22,7 @@
#include <android-base/endian.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <app_nugget.h>
#include <bootloader_message/bootloader_message.h>
#include <nos/NuggetClient.h>
@@ -76,6 +77,52 @@ bool WipeBootThemeFlag() {
return true;
}
bool GetReason(std::string* reason) {
bootloader_message boot = {};
std::string err;
bool ret = false;
if (!read_bootloader_message(&boot, &err)) {
LOG(ERROR) << err;
return ret;
}
std::vector<std::string> args;
boot.recovery[sizeof(boot.recovery) - 1] = '\0'; // Ensure termination
std::string boot_recovery(boot.recovery);
std::vector<std::string> tokens = android::base::Split(boot_recovery, "\n");
if (!tokens.empty() && tokens[0] == "recovery") {
for (auto it = tokens.begin() + 1; it != tokens.end(); it++) {
// Skip empty and '\0'-filled tokens.
if (!it->empty() && (*it)[0] != '\0') args.push_back(std::move(*it));
}
LOG(INFO) << "Got " << args.size() << " arguments from boot message";
} else if (boot.recovery[0] != 0) {
LOG(ERROR) << "Bad boot message: \"" << boot_recovery << "\"";
return ret;
}
for (const auto& arg : args) {
if (android::base::StartsWith(arg, "--reason=")) {
*reason = arg.substr(strlen("--reason="));
LOG(INFO) << "reason is " << *reason;
ret = true;
break;
}
}
return ret;
}
bool ProvisionSilentOtaFlag() {
const std::string sota_str("enable-sota");
constexpr size_t kSotaFlagOffsetInVendorSpace = 32;
if (std::string err; !WriteMiscPartitionVendorSpace(sota_str.data(), sota_str.size(),
kSotaFlagOffsetInVendorSpace, &err)) {
LOG(ERROR) << "Failed to write SOTA string: " << err;
return false;
}
LOG(INFO) << "Provision SOTA flag successfully";
return true;
}
} // namespace
class RedfinDevice : public ::Device
@@ -100,6 +147,15 @@ public:
// Extendable to wipe other components
// Additional behavior along with wiping data...
std::string reason;
if (GetReason(&reason) && android::base::StartsWith(reason, "enable-sota")) {
ui->Print("Enabling Silent OTA...\n");
if (!ProvisionSilentOtaFlag()) {
totalSuccess = false;
}
}
return totalSuccess;
}
};