summaryrefslogtreecommitdiffstats
path: root/adb
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2019-03-28 15:47:44 -0700
committerJosh Gao <jmgao@google.com>2019-03-28 15:47:44 -0700
commit3705b346b9595c07e17efe8d0dcc88f287c05067 (patch)
tree2be2a27cb8a832ae094b6cc9def255868ee7f1dc /adb
parentee9ba3efe7ce31f231e1e8d0500a7180dcc0c4f8 (diff)
downloadsystem_core-3705b346b9595c07e17efe8d0dcc88f287c05067.tar.gz
system_core-3705b346b9595c07e17efe8d0dcc88f287c05067.tar.bz2
system_core-3705b346b9595c07e17efe8d0dcc88f287c05067.zip
adb: make `adb reconnect` perform a USB reset.
Bug: http://b/128941083 Test: manual Change-Id: Iaf46d2c46cc82b590768004486d119244591c8e2
Diffstat (limited to 'adb')
-rw-r--r--adb/adb.cpp4
-rw-r--r--adb/client/usb_dispatch.cpp5
-rw-r--r--adb/client/usb_libusb.cpp5
-rw-r--r--adb/client/usb_linux.cpp5
-rw-r--r--adb/client/usb_osx.cpp7
-rw-r--r--adb/client/usb_windows.cpp5
-rw-r--r--adb/daemon/usb_dummy.cpp4
-rw-r--r--adb/daemon/usb_legacy.cpp4
-rw-r--r--adb/transport.cpp54
-rw-r--r--adb/transport.h17
-rw-r--r--adb/transport_usb.cpp5
-rw-r--r--adb/usb.h1
12 files changed, 104 insertions, 12 deletions
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 3c0788254..e417f05e3 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -1114,7 +1114,7 @@ HostRequestResult handle_host_request(std::string_view service, TransportType ty
return true;
}
return false;
- });
+ }, true);
if (!response.empty()) {
response.resize(response.size() - 1);
}
@@ -1229,7 +1229,7 @@ HostRequestResult handle_host_request(std::string_view service, TransportType ty
std::string response;
atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &response, true);
if (t != nullptr) {
- kick_transport(t);
+ kick_transport(t, true);
response =
"reconnecting " + t->serial_name() + " [" + t->connection_state_name() + "]\n";
}
diff --git a/adb/client/usb_dispatch.cpp b/adb/client/usb_dispatch.cpp
index ce5773175..f55ae9010 100644
--- a/adb/client/usb_dispatch.cpp
+++ b/adb/client/usb_dispatch.cpp
@@ -52,6 +52,11 @@ int usb_close(usb_handle* h) {
: native::usb_close(reinterpret_cast<native::usb_handle*>(h));
}
+void usb_reset(usb_handle* h) {
+ should_use_libusb() ? libusb::usb_reset(reinterpret_cast<libusb::usb_handle*>(h))
+ : native::usb_reset(reinterpret_cast<native::usb_handle*>(h));
+}
+
void usb_kick(usb_handle* h) {
should_use_libusb() ? libusb::usb_kick(reinterpret_cast<libusb::usb_handle*>(h))
: native::usb_kick(reinterpret_cast<native::usb_handle*>(h));
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index f2ca63ba3..53f01a0ce 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -622,6 +622,11 @@ int usb_close(usb_handle* h) {
return 0;
}
+void usb_reset(usb_handle* h) {
+ libusb_reset_device(h->device_handle);
+ usb_kick(h);
+}
+
void usb_kick(usb_handle* h) {
h->Close();
}
diff --git a/adb/client/usb_linux.cpp b/adb/client/usb_linux.cpp
index 116895894..81b830643 100644
--- a/adb/client/usb_linux.cpp
+++ b/adb/client/usb_linux.cpp
@@ -458,6 +458,11 @@ int usb_read(usb_handle *h, void *_data, int len)
return orig_len - len;
}
+void usb_reset(usb_handle* h) {
+ ioctl(h->fd, USBDEVFS_RESET);
+ usb_kick(h);
+}
+
void usb_kick(usb_handle* h) {
std::lock_guard<std::mutex> lock(h->mutex);
D("[ kicking %p (fd = %d) ]", h, h->fd);
diff --git a/adb/client/usb_osx.cpp b/adb/client/usb_osx.cpp
index e380c8406..381ded4bb 100644
--- a/adb/client/usb_osx.cpp
+++ b/adb/client/usb_osx.cpp
@@ -556,6 +556,13 @@ int usb_close(usb_handle *handle)
return 0;
}
+void usb_reset(usb_handle* handle) {
+ if (!handle->dead) {
+ (*handle->interface)->USBDeviceReEnumerate(handle->interface, 0);
+ }
+ usb_kick(handle);
+}
+
static void usb_kick_locked(usb_handle *handle)
{
LOG(INFO) << "Kicking handle";
diff --git a/adb/client/usb_windows.cpp b/adb/client/usb_windows.cpp
index cfa5cf40b..f23c3a5e6 100644
--- a/adb/client/usb_windows.cpp
+++ b/adb/client/usb_windows.cpp
@@ -448,6 +448,11 @@ void usb_cleanup_handle(usb_handle* handle) {
}
}
+void usb_reset(usb_handle* handle) {
+ // Unimplemented on Windows.
+ usb_kick(handle);
+}
+
static void usb_kick_locked(usb_handle* handle) {
// The reason the lock must be acquired before calling this function is in
// case multiple threads are trying to kick the same device at the same time.
diff --git a/adb/daemon/usb_dummy.cpp b/adb/daemon/usb_dummy.cpp
index 984bc25ef..c9bf79731 100644
--- a/adb/daemon/usb_dummy.cpp
+++ b/adb/daemon/usb_dummy.cpp
@@ -33,6 +33,10 @@ int usb_close(usb_handle*) {
return -1;
}
+void usb_reset(usb_handle*) {
+ LOG(FATAL) << "unimplemented";
+}
+
void usb_kick(usb_handle*) {
LOG(FATAL) << "unimplemented";
}
diff --git a/adb/daemon/usb_legacy.cpp b/adb/daemon/usb_legacy.cpp
index 7ace59d3e..b65727a0c 100644
--- a/adb/daemon/usb_legacy.cpp
+++ b/adb/daemon/usb_legacy.cpp
@@ -307,6 +307,10 @@ int usb_close(usb_handle* h) {
return 0;
}
+void usb_reset(usb_handle* h) {
+ usb_close(h);
+}
+
void usb_kick(usb_handle* h) {
h->kick(h);
}
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 0b4e08431..15c3a9a32 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -257,6 +257,11 @@ TransportId NextTransportId() {
return next++;
}
+void Connection::Reset() {
+ LOG(INFO) << "Connection::Reset(): stopping";
+ Stop();
+}
+
BlockingConnectionAdapter::BlockingConnectionAdapter(std::unique_ptr<BlockingConnection> connection)
: underlying_(std::move(connection)) {}
@@ -312,6 +317,26 @@ void BlockingConnectionAdapter::Start() {
started_ = true;
}
+void BlockingConnectionAdapter::Reset() {
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ if (!started_) {
+ LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): not started";
+ return;
+ }
+
+ if (stopped_) {
+ LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_
+ << "): already stopped";
+ return;
+ }
+ }
+
+ LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): resetting";
+ this->underlying_->Reset();
+ Stop();
+}
+
void BlockingConnectionAdapter::Stop() {
{
std::lock_guard<std::mutex> lock(mutex_);
@@ -424,14 +449,18 @@ void send_packet(apacket* p, atransport* t) {
}
}
-void kick_transport(atransport* t) {
+void kick_transport(atransport* t, bool reset) {
std::lock_guard<std::recursive_mutex> lock(transport_lock);
// As kick_transport() can be called from threads without guarantee that t is valid,
// check if the transport is in transport_list first.
//
// TODO(jmgao): WTF? Is this actually true?
if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) {
- t->Kick();
+ if (reset) {
+ t->Reset();
+ } else {
+ t->Kick();
+ }
}
#if ADB_HOST
@@ -942,9 +971,16 @@ int atransport::Write(apacket* p) {
return this->connection()->Write(std::unique_ptr<apacket>(p)) ? 0 : -1;
}
+void atransport::Reset() {
+ if (!kicked_.exchange(true)) {
+ LOG(INFO) << "resetting transport " << this << " " << this->serial;
+ this->connection()->Reset();
+ }
+}
+
void atransport::Kick() {
if (!kicked_.exchange(true)) {
- D("kicking transport %p %s", this, this->serial.c_str());
+ LOG(INFO) << "kicking transport " << this << " " << this->serial;
this->connection()->Stop();
}
}
@@ -1173,18 +1209,22 @@ std::string list_transports(bool long_listing) {
return result;
}
-void close_usb_devices(std::function<bool(const atransport*)> predicate) {
+void close_usb_devices(std::function<bool(const atransport*)> predicate, bool reset) {
std::lock_guard<std::recursive_mutex> lock(transport_lock);
for (auto& t : transport_list) {
if (predicate(t)) {
- t->Kick();
+ if (reset) {
+ t->Reset();
+ } else {
+ t->Kick();
+ }
}
}
}
/* hack for osx */
-void close_usb_devices() {
- close_usb_devices([](const atransport*) { return true; });
+void close_usb_devices(bool reset) {
+ close_usb_devices([](const atransport*) { return true; }, reset);
}
#endif // ADB_HOST
diff --git a/adb/transport.h b/adb/transport.h
index a0174b8fc..f4490eded 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -99,6 +99,9 @@ struct Connection {
virtual void Start() = 0;
virtual void Stop() = 0;
+ // Stop, and reset the device if it's a USB connection.
+ virtual void Reset();
+
std::string transport_name_;
ReadCallback read_callback_;
ErrorCallback error_callback_;
@@ -124,6 +127,9 @@ struct BlockingConnection {
// This method must be thread-safe, and must cause concurrent Reads/Writes to terminate.
// Formerly known as 'Kick' in atransport.
virtual void Close() = 0;
+
+ // Terminate a connection, and reset it.
+ virtual void Reset() = 0;
};
struct BlockingConnectionAdapter : public Connection {
@@ -136,6 +142,8 @@ struct BlockingConnectionAdapter : public Connection {
virtual void Start() override final;
virtual void Stop() override final;
+ virtual void Reset() override final;
+
bool started_ GUARDED_BY(mutex_) = false;
bool stopped_ GUARDED_BY(mutex_) = false;
@@ -157,6 +165,7 @@ struct FdConnection : public BlockingConnection {
bool Write(apacket* packet) override final;
void Close() override;
+ virtual void Reset() override final { Close(); }
private:
unique_fd fd_;
@@ -170,6 +179,7 @@ struct UsbConnection : public BlockingConnection {
bool Write(apacket* packet) override final;
void Close() override final;
+ virtual void Reset() override final;
usb_handle* handle_;
};
@@ -235,6 +245,7 @@ class atransport {
virtual ~atransport();
int Write(apacket* p);
+ void Reset();
void Kick();
bool kicked() const { return kicked_; }
@@ -364,7 +375,7 @@ class atransport {
atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id,
bool* is_ambiguous, std::string* error_out,
bool accept_any_state = false);
-void kick_transport(atransport* t);
+void kick_transport(atransport* t, bool reset = false);
void update_transports(void);
// Iterates across all of the current and pending transports.
@@ -395,8 +406,8 @@ void unregister_usb_transport(usb_handle* usb);
bool check_header(apacket* p, atransport* t);
-void close_usb_devices();
-void close_usb_devices(std::function<bool(const atransport*)> predicate);
+void close_usb_devices(bool reset = false);
+void close_usb_devices(std::function<bool(const atransport*)> predicate, bool reset = false);
void send_packet(apacket* p, atransport* t);
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index 2e5918ab6..3e87522e5 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -171,6 +171,11 @@ bool UsbConnection::Write(apacket* packet) {
return true;
}
+void UsbConnection::Reset() {
+ usb_reset(handle_);
+ usb_kick(handle_);
+}
+
void UsbConnection::Close() {
usb_kick(handle_);
}
diff --git a/adb/usb.h b/adb/usb.h
index cd83c42ae..eb8ca6cc0 100644
--- a/adb/usb.h
+++ b/adb/usb.h
@@ -26,6 +26,7 @@
int usb_write(handle_ref_type h, const void* data, int len); \
int usb_read(handle_ref_type h, void* data, int len); \
int usb_close(handle_ref_type h); \
+ void usb_reset(handle_ref_type h); \
void usb_kick(handle_ref_type h); \
size_t usb_get_max_packet_size(handle_ref_type)