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);