fastboot: Automatically reboot to userspace fastboot.
In order to flash logical partitions, "flashall" must be run against
userspace fastboot. When the bootloader supports the "reboot-fastboot"
command, we now attempt to automatically reboot into userspace fastboot.
We do this by closing the transport, sleeping for one second, and then
polling for a new connection until one is available. FastBootDriver is
then assigned the new transport.
Bug: 78793464
Test: fastboot flashall on device with logical partitions, while booted
into bootloader fastboot
Change-Id: I6949871b93ab5e352784cabe0963c6ecfc0af36d
diff --git a/fastboot/fastboot_driver.cpp b/fastboot/fastboot_driver.cpp
index c508abe..e8587c7 100644
--- a/fastboot/fastboot_driver.cpp
+++ b/fastboot/fastboot_driver.cpp
@@ -52,11 +52,15 @@
/*************************** PUBLIC *******************************/
FastBootDriver::FastBootDriver(Transport* transport, std::function<void(std::string&)> info,
bool no_checks)
- : transport(transport) {
+ : transport_(transport) {
info_cb_ = info;
disable_checks_ = no_checks;
}
+FastBootDriver::~FastBootDriver() {
+ set_transport(nullptr);
+}
+
RetCode FastBootDriver::Boot(std::string* response, std::vector<std::string>* info) {
return RawCommand(Commands::BOOT, response, info);
}
@@ -93,6 +97,11 @@
return RawCommand(Commands::REBOOT, response, info);
}
+RetCode FastBootDriver::RebootTo(std::string target, std::string* response,
+ std::vector<std::string>* info) {
+ return RawCommand("reboot-" + target, response, info);
+}
+
RetCode FastBootDriver::SetActive(const std::string& part, std::string* response,
std::vector<std::string>* info) {
return RawCommand(Commands::SET_ACTIVE + part, response, info);
@@ -332,7 +341,7 @@
}
RetCode FastBootDriver::WaitForDisconnect() {
- return transport->WaitForDisconnect() ? IO_ERROR : SUCCESS;
+ return transport_->WaitForDisconnect() ? IO_ERROR : SUCCESS;
}
/****************************** PROTECTED *************************************/
@@ -344,7 +353,7 @@
return BAD_ARG;
}
- if (transport->Write(cmd.c_str(), cmd.size()) != static_cast<int>(cmd.size())) {
+ if (transport_->Write(cmd.c_str(), cmd.size()) != static_cast<int>(cmd.size())) {
error_ = ErrnoStr("Write to device failed");
return IO_ERROR;
}
@@ -378,7 +387,7 @@
// erase response
set_response("");
while ((std::chrono::system_clock::now() - start) < std::chrono::seconds(RESP_TIMEOUT)) {
- int r = transport->Read(status, FB_RESPONSE_SZ);
+ int r = transport_->Read(status, FB_RESPONSE_SZ);
if (r < 0) {
error_ = ErrnoStr("Status read failed");
return IO_ERROR;
@@ -472,7 +481,7 @@
return BAD_ARG;
}
// Write the buffer
- ssize_t tmp = transport->Write(buf, size);
+ ssize_t tmp = transport_->Write(buf, size);
if (tmp < 0) {
error_ = ErrnoStr("Write to device failed in SendBuffer()");
@@ -493,7 +502,7 @@
RetCode FastBootDriver::ReadBuffer(void* buf, size_t size) {
// Read the buffer
- ssize_t tmp = transport->Read(buf, size);
+ ssize_t tmp = transport_->Read(buf, size);
if (tmp < 0) {
error_ = ErrnoStr("Read from device failed in ReadBuffer()");
@@ -539,4 +548,12 @@
return 0;
}
+void FastBootDriver::set_transport(Transport* transport) {
+ if (transport_) {
+ transport_->Close();
+ delete transport_;
+ }
+ transport_ = transport;
+}
+
} // End namespace fastboot