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

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

Issue 23953002: DevTools: request usb permission on ChromeOS. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 | « no previous file | chrome/browser/devtools/devtools_adb_bridge.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 69fa4007a796c463edf3c94a99682777dde7050f..148721744a9039ae1fe917362c28744985a26c78 100644
--- a/chrome/browser/devtools/adb/android_usb_device.cc
+++ b/chrome/browser/devtools/adb/android_usb_device.cc
@@ -6,6 +6,7 @@
#include <set>
+#include "base/barrier_closure.h"
#include "base/base64.h"
#include "base/lazy_instance.h"
#include "base/message_loop/message_loop.h"
@@ -41,17 +42,15 @@ static const char kHostConnectMessage[] = "host::";
using content::BrowserThread;
typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices;
+typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet;
base::LazyInstance<AndroidUsbDevices>::Leaky g_devices =
LAZY_INSTANCE_INITIALIZER;
-scoped_refptr<AndroidUsbDevice> ClaimInterface(
- crypto::RSAPrivateKey* rsa_key,
- scoped_refptr<UsbDeviceHandle> usb_device,
- scoped_refptr<const UsbInterfaceDescriptor> interface,
- int interface_id) {
+bool IsAndroidInterface(
+ scoped_refptr<const UsbInterfaceDescriptor> interface) {
if (interface->GetNumAltSettings() == 0)
- return NULL;
+ return false;
scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc =
interface->GetAltSetting(0);
@@ -60,8 +59,18 @@ scoped_refptr<AndroidUsbDevice> ClaimInterface(
idesc->GetInterfaceSubclass() != kAdbSubclass ||
idesc->GetInterfaceProtocol() != kAdbProtocol ||
idesc->GetNumEndpoints() != 2) {
- return NULL;
+ return false;
}
+ return true;
+}
+
+scoped_refptr<AndroidUsbDevice> ClaimInterface(
+ crypto::RSAPrivateKey* rsa_key,
+ scoped_refptr<UsbDeviceHandle> usb_handle,
+ scoped_refptr<const UsbInterfaceDescriptor> interface,
+ int interface_id) {
+ scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc =
+ interface->GetAltSetting(0);
int inbound_address = 0;
int outbound_address = 0;
@@ -82,14 +91,14 @@ scoped_refptr<AndroidUsbDevice> ClaimInterface(
if (inbound_address == 0 || outbound_address == 0)
return NULL;
- if (!usb_device->ClaimInterface(interface_id))
+ if (!usb_handle->ClaimInterface(interface_id))
return NULL;
base::string16 serial;
- if (!usb_device->GetSerial(&serial) || serial.empty())
+ if (!usb_handle->GetSerial(&serial) || serial.empty())
return NULL;
- return new AndroidUsbDevice(rsa_key, usb_device, UTF16ToASCII(serial),
+ return new AndroidUsbDevice(rsa_key, usb_handle, UTF16ToASCII(serial),
inbound_address, outbound_address, zero_mask);
}
@@ -151,19 +160,56 @@ AdbMessage::AdbMessage(uint32 command,
AdbMessage::~AdbMessage() {
}
+static void RespondOnUIThread(const AndroidUsbDevicesCallback& callback,
+ const AndroidUsbDevices& devices) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ callback.Run(devices);
+}
+
+static void RespondOnFileThread(const AndroidUsbDevicesCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ // Copy g_devices.Get() on file thread.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&RespondOnUIThread, callback, g_devices.Get()));
+}
+
+static void OpenAndroidDevicesOnFileThread(
+ crypto::RSAPrivateKey* rsa_key,
+ const base::Closure& barrier,
+ scoped_refptr<UsbDevice> device,
+ int interface_id,
+ bool success) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ if (success) {
+ scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces();
+ scoped_refptr<UsbDeviceHandle> usb_handle = device->Open();
+ if (usb_handle) {
+ scoped_refptr<AndroidUsbDevice> device =
+ ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id),
+ interface_id);
+ if (device.get())
+ g_devices.Get().push_back(device);
+ else
+ usb_handle->Close();
+ }
+ }
+ barrier.Run();
+}
+
static void EnumerateOnFileThread(crypto::RSAPrivateKey* rsa_key,
- AndroidUsbDevices* result) {
+ const AndroidUsbDevicesCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
UsbService* service = UsbService::GetInstance();
- AndroidUsbDevices& devices = g_devices.Get();
-
UsbDevices usb_devices;
service->GetDevices(&usb_devices);
+ AndroidUsbDevices& devices = g_devices.Get();
+
// GC Android devices with no actual usb device.
AndroidUsbDevices::iterator it = devices.begin();
- std::set<UsbDevice*> claimed_devices;
+ UsbDeviceSet claimed_devices;
while (it != devices.end()) {
bool found_device = false;
for (UsbDevices::iterator it2 = usb_devices.begin();
@@ -183,54 +229,50 @@ static void EnumerateOnFileThread(crypto::RSAPrivateKey* rsa_key,
}
// Add new devices.
+ base::Closure barrier = base::BarrierClosure(
+ usb_devices.size(), base::Bind(&RespondOnFileThread, callback));
+
for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
++it) {
- if (ContainsKey(claimed_devices, it->get()))
+ if (ContainsKey(claimed_devices, it->get())) {
+ barrier.Run();
continue;
+ }
scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces();
- if (!config)
- continue;
-
- scoped_refptr<UsbDeviceHandle> usb_device = (*it)->Open();
- if (!usb_device)
+ if (!config) {
+ barrier.Run();
continue;
+ }
- bool claimed = false;
+ bool has_android_interface = false;
for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
- scoped_refptr<AndroidUsbDevice> device =
- ClaimInterface(rsa_key, usb_device, config->GetInterface(j), j);
- if (device.get()) {
- devices.push_back(device);
- claimed = true;
- }
+ if (!IsAndroidInterface(config->GetInterface(j)))
+ continue;
+
+ // Request permission on Chrome OS.
+#if defined(OS_CHROMEOS)
+ (*it)->RequestUsbAcess(j, base::Bind(&OpenAndroidDevicesOnFileThread,
+ rsa_key, barrier, *it, j));
+#else
+ OpenAndroidDevicesOnFileThread(rsa_key, barrier, *it, j, true);
+#endif // defined(OS_CHROMEOS)
+
+ has_android_interface = true;
+ break;
}
- if (!claimed)
- usb_device->Close();
+ if (!has_android_interface)
+ barrier.Run();
}
-
- *result = devices;
-}
-
-static void InitDevicesOnCallerThread(
- AndroidUsbDevices* devices,
- const AndroidUsbDevicesCallback& callback) {
- for (AndroidUsbDevices::iterator it = devices->begin(); it != devices->end();
- ++it) {
- (*it)->InitOnCallerThread();
- }
- callback.Run(*devices);
- delete devices;
}
// static
void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key,
const AndroidUsbDevicesCallback& callback) {
- AndroidUsbDevices* devices = new AndroidUsbDevices();
- BrowserThread::PostTaskAndReply(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&EnumerateOnFileThread, rsa_key, devices),
- base::Bind(&InitDevicesOnCallerThread, devices, callback));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&EnumerateOnFileThread, rsa_key,
+ callback));
}
AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
@@ -283,6 +325,9 @@ void AndroidUsbDevice::Send(uint32 command,
AndroidUsbDevice::~AndroidUsbDevice() {
Terminate();
+ usb_device_->AddRef();
+ BrowserThread::ReleaseSoon(BrowserThread::FILE, FROM_HERE,
+ usb_device_.get());
}
void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) {
« no previous file with comments | « no previous file | chrome/browser/devtools/devtools_adb_bridge.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698