Refactor libfastboot
This change creates a nice and clean API for issuing
fastboot commands without using the fastboot tool itself.
Test: fastboot tool itself (now using libfastboot2)
on sailfish, walleye, and other devices.
Test: flash bootloader bootloader.img
Test: flash radio radio.img
Test: -w update img.zip
Test: Manually getvar and reboot commands.
Bug: 111126621
Change-Id: I0022536b204ce0c5ad8329367fd522fa3c57877d
diff --git a/fastboot/engine.cpp b/fastboot/engine.cpp
index 1087573..63ee2af 100644
--- a/fastboot/engine.cpp
+++ b/fastboot/engine.cpp
@@ -25,8 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
-#include "fastboot.h"
+#include "engine.h"
#include <errno.h>
#include <stdarg.h>
@@ -78,17 +77,20 @@
};
static std::vector<std::unique_ptr<Action>> action_list;
+static fastboot::FastBootDriver* fb = nullptr;
-bool fb_getvar(Transport* transport, const std::string& key, std::string* value) {
- std::string cmd = FB_CMD_GETVAR ":" + key;
+void fb_init(fastboot::FastBootDriver& fbi) {
+ fb = &fbi;
+ auto cb = [](std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); };
+ fb->SetInfoCallback(cb);
+}
- char buf[FB_RESPONSE_SZ + 1];
- memset(buf, 0, sizeof(buf));
- if (fb_command_response(transport, cmd, buf)) {
- return false;
- }
- *value = buf;
- return true;
+const std::string fb_get_error() {
+ return fb->Error();
+}
+
+bool fb_getvar(const std::string& key, std::string* value) {
+ return !fb->GetVar(key, value);
}
static int cb_default(Action& a, int status, const char* resp) {
@@ -310,7 +312,7 @@
queue_action(OP_WAIT_FOR_DISCONNECT, "");
}
-int64_t fb_execute_queue(Transport* transport) {
+int64_t fb_execute_queue() {
int64_t status = 0;
for (auto& a : action_list) {
a->start = now();
@@ -319,33 +321,34 @@
verbose("\n");
}
if (a->op == OP_DOWNLOAD) {
- status = fb_download_data(transport, a->data, a->size);
+ char* cbuf = static_cast<char*>(a->data);
+ status = fb->Download(cbuf, a->size);
status = a->func(*a, status, status ? fb_get_error().c_str() : "");
if (status) break;
} else if (a->op == OP_DOWNLOAD_FD) {
- status = fb_download_data_fd(transport, a->fd, a->size);
+ status = fb->Download(a->fd, a->size);
status = a->func(*a, status, status ? fb_get_error().c_str() : "");
if (status) break;
} else if (a->op == OP_COMMAND) {
- status = fb_command(transport, a->cmd);
+ status = fb->RawCommand(a->cmd);
status = a->func(*a, status, status ? fb_get_error().c_str() : "");
if (status) break;
} else if (a->op == OP_QUERY) {
- char resp[FB_RESPONSE_SZ + 1] = {};
- status = fb_command_response(transport, a->cmd, resp);
- status = a->func(*a, status, status ? fb_get_error().c_str() : resp);
+ std::string resp;
+ status = fb->RawCommand(a->cmd, &resp);
+ status = a->func(*a, status, status ? fb_get_error().c_str() : resp.c_str());
if (status) break;
} else if (a->op == OP_NOTICE) {
// We already showed the notice because it's in `Action::msg`.
fprintf(stderr, "\n");
} else if (a->op == OP_DOWNLOAD_SPARSE) {
- status = fb_download_data_sparse(transport, reinterpret_cast<sparse_file*>(a->data));
+ status = fb->Download(reinterpret_cast<sparse_file*>(a->data));
status = a->func(*a, status, status ? fb_get_error().c_str() : "");
if (status) break;
} else if (a->op == OP_WAIT_FOR_DISCONNECT) {
- transport->WaitForDisconnect();
+ fb->WaitForDisconnect();
} else if (a->op == OP_UPLOAD) {
- status = fb_upload_data(transport, reinterpret_cast<char*>(a->data));
+ status = fb->Upload(reinterpret_cast<const char*>(a->data));
status = a->func(*a, status, status ? fb_get_error().c_str() : "");
} else {
die("unknown action: %d", a->op);