Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(455)

Unified Diff: chrome/browser/devtools/adb/android_usb_device.cc

Issue 230773003: DevTools: do not retain android_usb_devices in their manager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review comments addressed. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/devtools/adb/android_usb_device.h ('k') | chrome/browser/devtools/adb/android_usb_socket.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/devtools/adb/android_usb_device.cc
diff --git a/chrome/browser/devtools/adb/android_usb_device.cc b/chrome/browser/devtools/adb/android_usb_device.cc
index 8af74040e7aa4557c7f405dbc7b6402d744bd979..63b12520ce1d4e45b2e3b19f7d712e359a119763 100644
--- a/chrome/browser/devtools/adb/android_usb_device.cc
+++ b/chrome/browser/devtools/adb/android_usb_device.cc
@@ -45,7 +45,8 @@ using content::BrowserThread;
typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices;
typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet;
-base::LazyInstance<AndroidUsbDevices>::Leaky g_devices =
+// Stores android wrappers around claimed usb devices on caller thread.
+base::LazyInstance<std::vector<AndroidUsbDevice*> >::Leaky g_devices =
LAZY_INSTANCE_INITIALIZER;
bool IsAndroidInterface(
@@ -100,7 +101,8 @@ scoped_refptr<AndroidUsbDevice> ClaimInterface(
return NULL;
return new AndroidUsbDevice(rsa_key, usb_handle, base::UTF16ToASCII(serial),
- inbound_address, outbound_address, zero_mask);
+ inbound_address, outbound_address, zero_mask,
+ interface_id);
}
uint32 Checksum(const std::string& data) {
@@ -141,8 +143,9 @@ void DumpMessage(bool outgoing, const char* data, size_t length) {
#endif // 0
}
-void ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device) {
- usb_device->ReleaseInterface(1);
+void ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device,
+ int interface_id) {
+ usb_device->ReleaseInterface(interface_id);
usb_device->Close();
}
@@ -168,21 +171,32 @@ static void RespondWithCountOnUIThread(base::Callback<void(int)> callback,
}
static void RespondOnCallerThread(const AndroidUsbDevicesCallback& callback,
- const AndroidUsbDevices& devices) {
- callback.Run(devices);
+ AndroidUsbDevices* new_devices) {
+ scoped_ptr<AndroidUsbDevices> devices(new_devices);
+
+ // Add raw pointers to the newly claimed devices.
+ for (AndroidUsbDevices::iterator it = devices->begin(); it != devices->end();
+ ++it) {
+ g_devices.Get().push_back(*it);
+ }
+
+ // Return all claimed devices.
+ AndroidUsbDevices result(g_devices.Get().begin(), g_devices.Get().end());
+ callback.Run(result);
}
static void RespondOnFileThread(
const AndroidUsbDevicesCallback& callback,
+ AndroidUsbDevices* devices,
scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- // Copy g_devices.Get() on file thread.
caller_message_loop_proxy->PostTask(
FROM_HERE,
- base::Bind(&RespondOnCallerThread, callback, g_devices.Get()));
+ base::Bind(&RespondOnCallerThread, callback, devices));
}
-static void OpenAndroidDevicesOnFileThread(
+static void OpenAndroidDeviceOnFileThread(
+ AndroidUsbDevices* devices,
crypto::RSAPrivateKey* rsa_key,
const base::Closure& barrier,
scoped_refptr<UsbDevice> device,
@@ -193,11 +207,11 @@ static void OpenAndroidDevicesOnFileThread(
scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces();
scoped_refptr<UsbDeviceHandle> usb_handle = device->Open();
if (usb_handle) {
- scoped_refptr<AndroidUsbDevice> device =
+ scoped_refptr<AndroidUsbDevice> android_device =
ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id),
interface_id);
- if (device.get())
- g_devices.Get().push_back(device);
+ if (android_device.get())
+ devices->push_back(android_device.get());
else
usb_handle->Close();
}
@@ -239,42 +253,16 @@ static void EnumerateOnFileThread(
if (service != NULL)
service->GetDevices(&usb_devices);
- AndroidUsbDevices& devices = g_devices.Get();
-
- // GC Android devices with no actual usb device.
- AndroidUsbDevices::iterator it = devices.begin();
- UsbDeviceSet claimed_devices;
- while (it != devices.end()) {
- bool found_device = false;
- for (UsbDevices::iterator it2 = usb_devices.begin();
- it2 != usb_devices.end() && !found_device; ++it2) {
- UsbDevice* usb_device = it2->get();
- AndroidUsbDevice* device = it->get();
- if (usb_device == device->usb_device()->device()) {
- found_device = true;
- claimed_devices.insert(usb_device);
- }
- }
-
- if (!found_device)
- it = devices.erase(it);
- else
- ++it;
- }
-
// Add new devices.
+ AndroidUsbDevices* devices = new AndroidUsbDevices();
base::Closure barrier = base::BarrierClosure(
usb_devices.size(), base::Bind(&RespondOnFileThread,
callback,
+ devices,
caller_message_loop_proxy));
for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
++it) {
- if (ContainsKey(claimed_devices, it->get())) {
- barrier.Run();
- continue;
- }
-
scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces();
if (!config) {
barrier.Run();
@@ -288,10 +276,10 @@ static void EnumerateOnFileThread(
// Request permission on Chrome OS.
#if defined(OS_CHROMEOS)
- (*it)->RequestUsbAcess(j, base::Bind(&OpenAndroidDevicesOnFileThread,
- rsa_key, barrier, *it, j));
+ (*it)->RequestUsbAcess(j, base::Bind(&OpenAndroidDeviceOnFileThread,
+ devices, rsa_key, barrier, *it, j));
#else
- OpenAndroidDevicesOnFileThread(rsa_key, barrier, *it, j, true);
+ OpenAndroidDeviceOnFileThread(devices, rsa_key, barrier, *it, j, true);
#endif // defined(OS_CHROMEOS)
has_android_interface = true;
@@ -313,6 +301,18 @@ void AndroidUsbDevice::CountDevices(
// static
void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key,
const AndroidUsbDevicesCallback& callback) {
+
+ // Collect devices with closed handles.
+ for (std::vector<AndroidUsbDevice*>::iterator it = g_devices.Get().begin();
+ it != g_devices.Get().end(); ++it) {
+ if ((*it)->usb_handle_) {
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&AndroidUsbDevice::TerminateIfReleased, *it,
+ (*it)->usb_handle_));
+ }
+ }
+
+ // Then look for the new devices.
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&EnumerateOnFileThread, rsa_key, callback,
base::MessageLoopProxy::current()));
@@ -323,18 +323,20 @@ AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
const std::string& serial,
int inbound_address,
int outbound_address,
- int zero_mask)
+ int zero_mask,
+ int interface_id)
: message_loop_(NULL),
rsa_key_(rsa_key->Copy()),
- usb_device_(usb_device),
+ usb_handle_(usb_device),
serial_(serial),
inbound_address_(inbound_address),
outbound_address_(outbound_address),
zero_mask_(zero_mask),
+ interface_id_(interface_id),
is_connected_(false),
signature_sent_(false),
last_socket_id_(256),
- terminated_(false) {
+ weak_factory_(this) {
}
void AndroidUsbDevice::InitOnCallerThread() {
@@ -343,10 +345,13 @@ void AndroidUsbDevice::InitOnCallerThread() {
message_loop_ = base::MessageLoop::current();
Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload,
kHostConnectMessage));
- ReadHeader(true);
+ ReadHeader();
}
net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) {
+ if (!usb_handle_)
+ return NULL;
+
uint32 socket_id = ++last_socket_id_;
sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command,
base::Bind(&AndroidUsbDevice::SocketDeleted, this));
@@ -367,13 +372,13 @@ void AndroidUsbDevice::Send(uint32 command,
}
AndroidUsbDevice::~AndroidUsbDevice() {
+ DCHECK(message_loop_ == base::MessageLoop::current());
Terminate();
- usb_device_->AddRef();
- BrowserThread::ReleaseSoon(BrowserThread::FILE, FROM_HERE,
- usb_device_.get());
}
void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) {
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
// Queue header.
std::vector<uint32> header;
header.push_back(message->command);
@@ -412,45 +417,51 @@ void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) {
}
void AndroidUsbDevice::ProcessOutgoing() {
- if (outgoing_queue_.empty() || terminated_)
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
+ if (outgoing_queue_.empty() || !usb_handle_)
return;
BulkMessage message = outgoing_queue_.front();
outgoing_queue_.pop();
DumpMessage(true, message.first->data(), message.second);
- usb_device_->BulkTransfer(USB_DIRECTION_OUTBOUND, outbound_address_,
+ usb_handle_->BulkTransfer(USB_DIRECTION_OUTBOUND, outbound_address_,
message.first, message.second, kUsbTimeout,
- base::Bind(&AndroidUsbDevice::OutgoingMessageSent, this));
+ base::Bind(&AndroidUsbDevice::OutgoingMessageSent,
+ weak_factory_.GetWeakPtr()));
}
void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status,
scoped_refptr<net::IOBuffer> buffer,
size_t result) {
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
if (status != USB_TRANSFER_COMPLETED)
return;
message_loop_->PostTask(FROM_HERE,
- base::Bind(&AndroidUsbDevice::ProcessOutgoing,
- this));
+ base::Bind(&AndroidUsbDevice::ProcessOutgoing, this));
}
-void AndroidUsbDevice::ReadHeader(bool initial) {
- if (terminated_)
+void AndroidUsbDevice::ReadHeader() {
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
+ if (!usb_handle_)
return;
- if (!initial && HasOneRef())
- return; // Stop polling.
scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize);
- usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
+ usb_handle_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
buffer, kHeaderSize, kUsbTimeout,
- base::Bind(&AndroidUsbDevice::ParseHeader, this));
+ base::Bind(&AndroidUsbDevice::ParseHeader,
+ weak_factory_.GetWeakPtr()));
}
void AndroidUsbDevice::ParseHeader(UsbTransferStatus status,
scoped_refptr<net::IOBuffer> buffer,
size_t result) {
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
if (status == USB_TRANSFER_TIMEOUT) {
message_loop_->PostTask(FROM_HERE,
- base::Bind(&AndroidUsbDevice::ReadHeader, this,
- false));
+ base::Bind(&AndroidUsbDevice::ReadHeader, this));
return;
}
@@ -487,11 +498,15 @@ void AndroidUsbDevice::ParseHeader(UsbTransferStatus status,
void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message,
uint32 data_length,
uint32 data_check) {
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
+ if (!usb_handle_)
+ return;
scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length);
- usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
+ usb_handle_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
buffer, data_length, kUsbTimeout,
- base::Bind(&AndroidUsbDevice::ParseBody, this, message, data_length,
- data_check));
+ base::Bind(&AndroidUsbDevice::ParseBody, weak_factory_.GetWeakPtr(),
+ message, data_length, data_check));
}
void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message,
@@ -500,6 +515,8 @@ void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message,
UsbTransferStatus status,
scoped_refptr<net::IOBuffer> buffer,
size_t result) {
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
if (status == USB_TRANSFER_TIMEOUT) {
message_loop_->PostTask(FROM_HERE,
base::Bind(&AndroidUsbDevice::ReadBody, this,
@@ -526,6 +543,8 @@ void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message,
}
void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) {
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
switch (message->command) {
case AdbMessage::kCommandAUTH:
{
@@ -572,20 +591,40 @@ void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) {
default:
break;
}
- ReadHeader(false);
+ ReadHeader();
}
void AndroidUsbDevice::TransferError(UsbTransferStatus status) {
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
message_loop_->PostTask(FROM_HERE,
- base::Bind(&AndroidUsbDevice::Terminate,
- this));
+ base::Bind(&AndroidUsbDevice::Terminate, this));
+}
+
+void AndroidUsbDevice::TerminateIfReleased(
+ scoped_refptr<UsbDeviceHandle> usb_handle) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ if (usb_handle->device())
+ return;
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&AndroidUsbDevice::Terminate, this));
}
void AndroidUsbDevice::Terminate() {
- if (terminated_)
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
+ std::vector<AndroidUsbDevice*>::iterator it =
+ std::find(g_devices.Get().begin(), g_devices.Get().end(), this);
+ if (it != g_devices.Get().end())
+ g_devices.Get().erase(it);
+
+ if (!usb_handle_)
return;
- terminated_ = true;
+ // Make sure we zero-out handle so that closing connections did not open
+ // new connections.
+ scoped_refptr<UsbDeviceHandle> usb_handle = usb_handle_;
+ usb_handle_ = NULL;
// Iterate over copy.
AndroidUsbSockets sockets(sockets_);
@@ -593,12 +632,15 @@ void AndroidUsbDevice::Terminate() {
it != sockets.end(); ++it) {
it->second->Terminated();
}
+ DCHECK(sockets_.empty());
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&ReleaseInterface, usb_device_));
+ base::Bind(&ReleaseInterface, usb_handle, interface_id_));
}
void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
+ DCHECK(message_loop_ == base::MessageLoop::current());
+
sockets_.erase(socket_id);
}
« no previous file with comments | « chrome/browser/devtools/adb/android_usb_device.h ('k') | chrome/browser/devtools/adb/android_usb_socket.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698