fastboot: create Transport object (take 2).

(Second upload of this CL; original upload had the wrong version of
usb_windows.cpp that caused a compilation error. Fixed error and
re-tested.)

This CL creates a Transport object to provide a generic interface for
various transports. Specifically this is designed to be able to add UDP
support to fastboot in an upcoming CL without changing the main program
logic.

Also includes some minor code style fixes and replaces malloc/free
in the USB implementation files with smart pointers and std::string.

Bug: http://b/22029765
Change-Id: I1175bbce08690fbd15f51e68166be9b3e9973ea0
diff --git a/fastboot/usb_windows.cpp b/fastboot/usb_windows.cpp
index a09610f..1cdeb32 100644
--- a/fastboot/usb_windows.cpp
+++ b/fastboot/usb_windows.cpp
@@ -34,6 +34,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <memory>
+#include <string>
+
 #include "usb.h"
 
 //#define TRACE_USB 1
@@ -60,24 +63,32 @@
     ADBAPIHANDLE  adb_write_pipe;
 
     /// Interface name
-    char*         interface_name;
+    std::string interface_name;
+};
+
+class WindowsUsbTransport : public Transport {
+  public:
+    WindowsUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {}
+    ~WindowsUsbTransport() override = default;
+
+    ssize_t Read(void* data, size_t len) override;
+    ssize_t Write(const void* data, size_t len) override;
+    int Close() override;
+
+  private:
+    std::unique_ptr<usb_handle> handle_;
+
+    DISALLOW_COPY_AND_ASSIGN(WindowsUsbTransport);
 };
 
 /// Class ID assigned to the device by androidusb.sys
 static const GUID usb_class_id = ANDROID_USB_CLASS_ID;
 
-
 /// Checks if interface (device) matches certain criteria
 int recognized_device(usb_handle* handle, ifc_match_func callback);
 
 /// Opens usb interface (device) by interface (device) name.
-usb_handle* do_usb_open(const wchar_t* interface_name);
-
-/// Writes data to the opened usb handle
-int usb_write(usb_handle* handle, const void* data, int len);
-
-/// Reads data using the opened usb handle
-int usb_read(usb_handle *handle, void* data, int len);
+std::unique_ptr<usb_handle> do_usb_open(const wchar_t* interface_name);
 
 /// Cleans up opened usb handle
 void usb_cleanup_handle(usb_handle* handle);
@@ -85,23 +96,17 @@
 /// Cleans up (but don't close) opened usb handle
 void usb_kick(usb_handle* handle);
 
-/// Closes opened usb handle
-int usb_close(usb_handle* handle);
 
-
-usb_handle* do_usb_open(const wchar_t* interface_name) {
+std::unique_ptr<usb_handle> do_usb_open(const wchar_t* interface_name) {
     // Allocate our handle
-    usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle));
-    if (NULL == ret)
-        return NULL;
+    std::unique_ptr<usb_handle> ret(new usb_handle);
 
     // Create interface.
     ret->adb_interface = AdbCreateInterfaceByName(interface_name);
 
-    if (NULL == ret->adb_interface) {
-        free(ret);
+    if (nullptr == ret->adb_interface) {
         errno = GetLastError();
-        return NULL;
+        return nullptr;
     }
 
     // Open read pipe (endpoint)
@@ -109,35 +114,30 @@
         AdbOpenDefaultBulkReadEndpoint(ret->adb_interface,
                                    AdbOpenAccessTypeReadWrite,
                                    AdbOpenSharingModeReadWrite);
-    if (NULL != ret->adb_read_pipe) {
+    if (nullptr != ret->adb_read_pipe) {
         // Open write pipe (endpoint)
         ret->adb_write_pipe =
             AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface,
                                       AdbOpenAccessTypeReadWrite,
                                       AdbOpenSharingModeReadWrite);
-        if (NULL != ret->adb_write_pipe) {
+        if (nullptr != ret->adb_write_pipe) {
             // Save interface name
             unsigned long name_len = 0;
 
             // First get expected name length
             AdbGetInterfaceName(ret->adb_interface,
-                          NULL,
+                          nullptr,
                           &name_len,
                           true);
             if (0 != name_len) {
-                ret->interface_name = (char*)malloc(name_len);
-
-                if (NULL != ret->interface_name) {
-                    // Now save the name
-                    if (AdbGetInterfaceName(ret->adb_interface,
-                                  ret->interface_name,
-                                  &name_len,
-                                  true)) {
-                        // We're done at this point
-                        return ret;
-                    }
-                } else {
-                    SetLastError(ERROR_OUTOFMEMORY);
+                // Now save the name
+                ret->interface_name.resize(name_len);
+                if (AdbGetInterfaceName(ret->adb_interface,
+                              &ret->interface_name[0],
+                              &name_len,
+                              true)) {
+                    // We're done at this point
+                    return ret;
                 }
             }
         }
@@ -145,35 +145,31 @@
 
     // Something went wrong.
     errno = GetLastError();
-    usb_cleanup_handle(ret);
-    free(ret);
+    usb_cleanup_handle(ret.get());
     SetLastError(errno);
 
-    return NULL;
+    return nullptr;
 }
 
-int usb_write(usb_handle* handle, const void* data, int len) {
+ssize_t WindowsUsbTransport::Write(const void* data, size_t len) {
     unsigned long time_out = 5000;
     unsigned long written = 0;
     unsigned count = 0;
     int ret;
 
     DBG("usb_write %d\n", len);
-    if (NULL != handle) {
+    if (nullptr != handle_) {
         // Perform write
         while(len > 0) {
             int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
-            ret = AdbWriteEndpointSync(handle->adb_write_pipe,
-                                   (void*)data,
-                                   (unsigned long)xfer,
-                                   &written,
-                                   time_out);
+            ret = AdbWriteEndpointSync(handle_->adb_write_pipe, const_cast<void*>(data), xfer,
+                                       &written, time_out);
             errno = GetLastError();
             DBG("AdbWriteEndpointSync returned %d, errno: %d\n", ret, errno);
             if (ret == 0) {
                 // assume ERROR_INVALID_HANDLE indicates we are disconnected
                 if (errno == ERROR_INVALID_HANDLE)
-                usb_kick(handle);
+                usb_kick(handle_.get());
                 return -1;
             }
 
@@ -194,21 +190,17 @@
     return -1;
 }
 
-int usb_read(usb_handle *handle, void* data, int len) {
+ssize_t WindowsUsbTransport::Read(void* data, size_t len) {
     unsigned long time_out = 0;
     unsigned long read = 0;
     int ret;
 
     DBG("usb_read %d\n", len);
-    if (NULL != handle) {
+    if (nullptr != handle_) {
         while (1) {
             int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
 
-	        ret = AdbReadEndpointSync(handle->adb_read_pipe,
-	                              (void*)data,
-	                              (unsigned long)xfer,
-	                              &read,
-	                              time_out);
+            ret = AdbReadEndpointSync(handle_->adb_read_pipe, data, xfer, &read, time_out);
             errno = GetLastError();
             DBG("usb_read got: %ld, expected: %d, errno: %d\n", read, xfer, errno);
             if (ret) {
@@ -216,7 +208,7 @@
             } else {
                 // assume ERROR_INVALID_HANDLE indicates we are disconnected
                 if (errno == ERROR_INVALID_HANDLE)
-                    usb_kick(handle);
+                    usb_kick(handle_.get());
                 break;
             }
             // else we timed out - try again
@@ -233,8 +225,6 @@
 
 void usb_cleanup_handle(usb_handle* handle) {
     if (NULL != handle) {
-        if (NULL != handle->interface_name)
-            free(handle->interface_name);
         if (NULL != handle->adb_write_pipe)
             AdbCloseHandle(handle->adb_write_pipe);
         if (NULL != handle->adb_read_pipe)
@@ -242,7 +232,7 @@
         if (NULL != handle->adb_interface)
             AdbCloseHandle(handle->adb_interface);
 
-        handle->interface_name = NULL;
+        handle->interface_name.clear();
         handle->adb_write_pipe = NULL;
         handle->adb_read_pipe = NULL;
         handle->adb_interface = NULL;
@@ -258,23 +248,18 @@
     }
 }
 
-int usb_close(usb_handle* handle) {
+int WindowsUsbTransport::Close() {
     DBG("usb_close\n");
 
-    if (NULL != handle) {
+    if (nullptr != handle_) {
         // Cleanup handle
-        usb_cleanup_handle(handle);
-        free(handle);
+        usb_cleanup_handle(handle_.get());
+        handle_.reset();
     }
 
     return 0;
 }
 
-int usb_wait_for_disconnect(usb_handle *usb) {
-    /* TODO: Punt for now */
-    return 0;
-}
-
 int recognized_device(usb_handle* handle, ifc_match_func callback) {
     struct usb_ifc_info info;
     USB_DEVICE_DESCRIPTOR device_desc;
@@ -326,8 +311,8 @@
     return 0;
 }
 
-static usb_handle *find_usb_device(ifc_match_func callback) {
-	usb_handle* handle = NULL;
+static std::unique_ptr<usb_handle> find_usb_device(ifc_match_func callback) {
+    std::unique_ptr<usb_handle> handle;
     char entry_buffer[2048];
     char interf_name[2048];
     AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]);
@@ -356,13 +341,12 @@
         handle = do_usb_open(next_interface->device_name);
         if (NULL != handle) {
             // Lets see if this interface (device) belongs to us
-            if (recognized_device(handle, callback)) {
+            if (recognized_device(handle.get(), callback)) {
                 // found it!
                 break;
             } else {
-                usb_cleanup_handle(handle);
-                free(handle);
-                handle = NULL;
+                usb_cleanup_handle(handle.get());
+                handle.reset();
             }
         }
 
@@ -373,9 +357,10 @@
     return handle;
 }
 
-usb_handle *usb_open(ifc_match_func callback)
+Transport* usb_open(ifc_match_func callback)
 {
-    return find_usb_device(callback);
+    std::unique_ptr<usb_handle> handle = find_usb_device(callback);
+    return handle ? new WindowsUsbTransport(std::move(handle)) : nullptr;
 }
 
 // called from fastboot.c