OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/devtools/adb/android_usb_device.h" | 5 #include "chrome/browser/devtools/adb/android_usb_device.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
| 9 #include "base/barrier_closure.h" |
9 #include "base/base64.h" | 10 #include "base/base64.h" |
10 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
11 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
15 #include "chrome/browser/devtools/adb/android_rsa.h" | 16 #include "chrome/browser/devtools/adb/android_rsa.h" |
16 #include "chrome/browser/devtools/adb/android_usb_socket.h" | 17 #include "chrome/browser/devtools/adb/android_usb_socket.h" |
17 #include "chrome/browser/usb/usb_device.h" | 18 #include "chrome/browser/usb/usb_device.h" |
18 #include "chrome/browser/usb/usb_interface.h" | 19 #include "chrome/browser/usb/usb_interface.h" |
(...skipping 15 matching lines...) Expand all Loading... |
34 const int kUsbTimeout = 0; | 35 const int kUsbTimeout = 0; |
35 | 36 |
36 const uint32 kMaxPayload = 4096; | 37 const uint32 kMaxPayload = 4096; |
37 const uint32 kVersion = 0x01000000; | 38 const uint32 kVersion = 0x01000000; |
38 | 39 |
39 static const char kHostConnectMessage[] = "host::"; | 40 static const char kHostConnectMessage[] = "host::"; |
40 | 41 |
41 using content::BrowserThread; | 42 using content::BrowserThread; |
42 | 43 |
43 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices; | 44 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices; |
| 45 typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet; |
44 | 46 |
45 base::LazyInstance<AndroidUsbDevices>::Leaky g_devices = | 47 base::LazyInstance<AndroidUsbDevices>::Leaky g_devices = |
46 LAZY_INSTANCE_INITIALIZER; | 48 LAZY_INSTANCE_INITIALIZER; |
47 | 49 |
48 scoped_refptr<AndroidUsbDevice> ClaimInterface( | 50 bool IsAndroidInterface( |
49 crypto::RSAPrivateKey* rsa_key, | 51 scoped_refptr<const UsbInterfaceDescriptor> interface) { |
50 scoped_refptr<UsbDeviceHandle> usb_device, | |
51 scoped_refptr<const UsbInterfaceDescriptor> interface, | |
52 int interface_id) { | |
53 if (interface->GetNumAltSettings() == 0) | 52 if (interface->GetNumAltSettings() == 0) |
54 return NULL; | 53 return false; |
55 | 54 |
56 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc = | 55 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc = |
57 interface->GetAltSetting(0); | 56 interface->GetAltSetting(0); |
58 | 57 |
59 if (idesc->GetInterfaceClass() != kAdbClass || | 58 if (idesc->GetInterfaceClass() != kAdbClass || |
60 idesc->GetInterfaceSubclass() != kAdbSubclass || | 59 idesc->GetInterfaceSubclass() != kAdbSubclass || |
61 idesc->GetInterfaceProtocol() != kAdbProtocol || | 60 idesc->GetInterfaceProtocol() != kAdbProtocol || |
62 idesc->GetNumEndpoints() != 2) { | 61 idesc->GetNumEndpoints() != 2) { |
63 return NULL; | 62 return false; |
64 } | 63 } |
| 64 return true; |
| 65 } |
| 66 |
| 67 scoped_refptr<AndroidUsbDevice> ClaimInterface( |
| 68 crypto::RSAPrivateKey* rsa_key, |
| 69 scoped_refptr<UsbDeviceHandle> usb_handle, |
| 70 scoped_refptr<const UsbInterfaceDescriptor> interface, |
| 71 int interface_id) { |
| 72 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc = |
| 73 interface->GetAltSetting(0); |
65 | 74 |
66 int inbound_address = 0; | 75 int inbound_address = 0; |
67 int outbound_address = 0; | 76 int outbound_address = 0; |
68 int zero_mask = 0; | 77 int zero_mask = 0; |
69 | 78 |
70 for (size_t i = 0; i < idesc->GetNumEndpoints(); ++i) { | 79 for (size_t i = 0; i < idesc->GetNumEndpoints(); ++i) { |
71 scoped_refptr<const UsbEndpointDescriptor> edesc = | 80 scoped_refptr<const UsbEndpointDescriptor> edesc = |
72 idesc->GetEndpoint(i); | 81 idesc->GetEndpoint(i); |
73 if (edesc->GetTransferType() != USB_TRANSFER_BULK) | 82 if (edesc->GetTransferType() != USB_TRANSFER_BULK) |
74 continue; | 83 continue; |
75 if (edesc->GetDirection() == USB_DIRECTION_INBOUND) | 84 if (edesc->GetDirection() == USB_DIRECTION_INBOUND) |
76 inbound_address = edesc->GetAddress(); | 85 inbound_address = edesc->GetAddress(); |
77 else | 86 else |
78 outbound_address = edesc->GetAddress(); | 87 outbound_address = edesc->GetAddress(); |
79 zero_mask = edesc->GetMaximumPacketSize() - 1; | 88 zero_mask = edesc->GetMaximumPacketSize() - 1; |
80 } | 89 } |
81 | 90 |
82 if (inbound_address == 0 || outbound_address == 0) | 91 if (inbound_address == 0 || outbound_address == 0) |
83 return NULL; | 92 return NULL; |
84 | 93 |
85 if (!usb_device->ClaimInterface(interface_id)) | 94 if (!usb_handle->ClaimInterface(interface_id)) |
86 return NULL; | 95 return NULL; |
87 | 96 |
88 base::string16 serial; | 97 base::string16 serial; |
89 if (!usb_device->GetSerial(&serial) || serial.empty()) | 98 if (!usb_handle->GetSerial(&serial) || serial.empty()) |
90 return NULL; | 99 return NULL; |
91 | 100 |
92 return new AndroidUsbDevice(rsa_key, usb_device, UTF16ToASCII(serial), | 101 return new AndroidUsbDevice(rsa_key, usb_handle, UTF16ToASCII(serial), |
93 inbound_address, outbound_address, zero_mask); | 102 inbound_address, outbound_address, zero_mask); |
94 } | 103 } |
95 | 104 |
96 uint32 Checksum(const std::string& data) { | 105 uint32 Checksum(const std::string& data) { |
97 unsigned char* x = (unsigned char*)data.data(); | 106 unsigned char* x = (unsigned char*)data.data(); |
98 int count = data.length(); | 107 int count = data.length(); |
99 uint32 sum = 0; | 108 uint32 sum = 0; |
100 while (count-- > 0) | 109 while (count-- > 0) |
101 sum += *x++; | 110 sum += *x++; |
102 return sum; | 111 return sum; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 const std::string& body) | 153 const std::string& body) |
145 : command(command), | 154 : command(command), |
146 arg0(arg0), | 155 arg0(arg0), |
147 arg1(arg1), | 156 arg1(arg1), |
148 body(body) { | 157 body(body) { |
149 } | 158 } |
150 | 159 |
151 AdbMessage::~AdbMessage() { | 160 AdbMessage::~AdbMessage() { |
152 } | 161 } |
153 | 162 |
| 163 static void RespondOnUIThread(const AndroidUsbDevicesCallback& callback, |
| 164 const AndroidUsbDevices& devices) { |
| 165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 166 callback.Run(devices); |
| 167 } |
| 168 |
| 169 static void RespondOnFileThread(const AndroidUsbDevicesCallback& callback) { |
| 170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 171 // Copy g_devices.Get() on file thread. |
| 172 BrowserThread::PostTask( |
| 173 BrowserThread::UI, FROM_HERE, |
| 174 base::Bind(&RespondOnUIThread, callback, g_devices.Get())); |
| 175 } |
| 176 |
| 177 static void OpenAndroidDevicesOnFileThread( |
| 178 crypto::RSAPrivateKey* rsa_key, |
| 179 const base::Closure& barrier, |
| 180 scoped_refptr<UsbDevice> device, |
| 181 int interface_id, |
| 182 bool success) { |
| 183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 184 if (success) { |
| 185 scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces(); |
| 186 scoped_refptr<UsbDeviceHandle> usb_handle = device->Open(); |
| 187 if (usb_handle) { |
| 188 scoped_refptr<AndroidUsbDevice> device = |
| 189 ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id), |
| 190 interface_id); |
| 191 if (device.get()) |
| 192 g_devices.Get().push_back(device); |
| 193 else |
| 194 usb_handle->Close(); |
| 195 } |
| 196 } |
| 197 barrier.Run(); |
| 198 } |
| 199 |
154 static void EnumerateOnFileThread(crypto::RSAPrivateKey* rsa_key, | 200 static void EnumerateOnFileThread(crypto::RSAPrivateKey* rsa_key, |
155 AndroidUsbDevices* result) { | 201 const AndroidUsbDevicesCallback& callback) { |
156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
157 | 203 |
158 UsbService* service = UsbService::GetInstance(); | 204 UsbService* service = UsbService::GetInstance(); |
159 AndroidUsbDevices& devices = g_devices.Get(); | |
160 | |
161 UsbDevices usb_devices; | 205 UsbDevices usb_devices; |
162 service->GetDevices(&usb_devices); | 206 service->GetDevices(&usb_devices); |
163 | 207 |
| 208 AndroidUsbDevices& devices = g_devices.Get(); |
| 209 |
164 // GC Android devices with no actual usb device. | 210 // GC Android devices with no actual usb device. |
165 AndroidUsbDevices::iterator it = devices.begin(); | 211 AndroidUsbDevices::iterator it = devices.begin(); |
166 std::set<UsbDevice*> claimed_devices; | 212 UsbDeviceSet claimed_devices; |
167 while (it != devices.end()) { | 213 while (it != devices.end()) { |
168 bool found_device = false; | 214 bool found_device = false; |
169 for (UsbDevices::iterator it2 = usb_devices.begin(); | 215 for (UsbDevices::iterator it2 = usb_devices.begin(); |
170 it2 != usb_devices.end() && !found_device; ++it2) { | 216 it2 != usb_devices.end() && !found_device; ++it2) { |
171 UsbDevice* usb_device = it2->get(); | 217 UsbDevice* usb_device = it2->get(); |
172 AndroidUsbDevice* device = it->get(); | 218 AndroidUsbDevice* device = it->get(); |
173 if (usb_device == device->usb_device()->device()) { | 219 if (usb_device == device->usb_device()->device()) { |
174 found_device = true; | 220 found_device = true; |
175 claimed_devices.insert(usb_device); | 221 claimed_devices.insert(usb_device); |
176 } | 222 } |
177 } | 223 } |
178 | 224 |
179 if (!found_device) | 225 if (!found_device) |
180 it = devices.erase(it); | 226 it = devices.erase(it); |
181 else | 227 else |
182 ++it; | 228 ++it; |
183 } | 229 } |
184 | 230 |
185 // Add new devices. | 231 // Add new devices. |
| 232 base::Closure barrier = base::BarrierClosure( |
| 233 usb_devices.size(), base::Bind(&RespondOnFileThread, callback)); |
| 234 |
186 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); | 235 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); |
187 ++it) { | 236 ++it) { |
188 if (ContainsKey(claimed_devices, it->get())) | 237 if (ContainsKey(claimed_devices, it->get())) { |
| 238 barrier.Run(); |
189 continue; | 239 continue; |
| 240 } |
190 | 241 |
191 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); | 242 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); |
192 if (!config) | 243 if (!config) { |
| 244 barrier.Run(); |
193 continue; | 245 continue; |
| 246 } |
194 | 247 |
195 scoped_refptr<UsbDeviceHandle> usb_device = (*it)->Open(); | 248 bool has_android_interface = false; |
196 if (!usb_device) | 249 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { |
197 continue; | 250 if (!IsAndroidInterface(config->GetInterface(j))) |
| 251 continue; |
198 | 252 |
199 bool claimed = false; | 253 // Request permission on Chrome OS. |
200 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { | 254 #if defined(OS_CHROMEOS) |
201 scoped_refptr<AndroidUsbDevice> device = | 255 (*it)->RequestUsbAcess(j, base::Bind(&OpenAndroidDevicesOnFileThread, |
202 ClaimInterface(rsa_key, usb_device, config->GetInterface(j), j); | 256 rsa_key, barrier, *it, j)); |
203 if (device.get()) { | 257 #else |
204 devices.push_back(device); | 258 OpenAndroidDevicesOnFileThread(rsa_key, barrier, *it, j, true); |
205 claimed = true; | 259 #endif // defined(OS_CHROMEOS) |
206 } | 260 |
| 261 has_android_interface = true; |
| 262 break; |
207 } | 263 } |
208 if (!claimed) | 264 if (!has_android_interface) |
209 usb_device->Close(); | 265 barrier.Run(); |
210 } | 266 } |
211 | |
212 *result = devices; | |
213 } | |
214 | |
215 static void InitDevicesOnCallerThread( | |
216 AndroidUsbDevices* devices, | |
217 const AndroidUsbDevicesCallback& callback) { | |
218 for (AndroidUsbDevices::iterator it = devices->begin(); it != devices->end(); | |
219 ++it) { | |
220 (*it)->InitOnCallerThread(); | |
221 } | |
222 callback.Run(*devices); | |
223 delete devices; | |
224 } | 267 } |
225 | 268 |
226 // static | 269 // static |
227 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key, | 270 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key, |
228 const AndroidUsbDevicesCallback& callback) { | 271 const AndroidUsbDevicesCallback& callback) { |
229 AndroidUsbDevices* devices = new AndroidUsbDevices(); | 272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
230 BrowserThread::PostTaskAndReply( | 273 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
231 BrowserThread::FILE, FROM_HERE, | 274 base::Bind(&EnumerateOnFileThread, rsa_key, |
232 base::Bind(&EnumerateOnFileThread, rsa_key, devices), | 275 callback)); |
233 base::Bind(&InitDevicesOnCallerThread, devices, callback)); | |
234 } | 276 } |
235 | 277 |
236 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key, | 278 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key, |
237 scoped_refptr<UsbDeviceHandle> usb_device, | 279 scoped_refptr<UsbDeviceHandle> usb_device, |
238 const std::string& serial, | 280 const std::string& serial, |
239 int inbound_address, | 281 int inbound_address, |
240 int outbound_address, | 282 int outbound_address, |
241 int zero_mask) | 283 int zero_mask) |
242 : message_loop_(NULL), | 284 : message_loop_(NULL), |
243 rsa_key_(rsa_key->Copy()), | 285 rsa_key_(rsa_key->Copy()), |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 // Delay open request if not yet connected. | 318 // Delay open request if not yet connected. |
277 if (!is_connected_) { | 319 if (!is_connected_) { |
278 pending_messages_.push_back(m); | 320 pending_messages_.push_back(m); |
279 return; | 321 return; |
280 } | 322 } |
281 Queue(m); | 323 Queue(m); |
282 } | 324 } |
283 | 325 |
284 AndroidUsbDevice::~AndroidUsbDevice() { | 326 AndroidUsbDevice::~AndroidUsbDevice() { |
285 Terminate(); | 327 Terminate(); |
| 328 usb_device_->AddRef(); |
| 329 BrowserThread::ReleaseSoon(BrowserThread::FILE, FROM_HERE, |
| 330 usb_device_.get()); |
286 } | 331 } |
287 | 332 |
288 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) { | 333 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) { |
289 // Queue header. | 334 // Queue header. |
290 std::vector<uint32> header; | 335 std::vector<uint32> header; |
291 header.push_back(message->command); | 336 header.push_back(message->command); |
292 header.push_back(message->arg0); | 337 header.push_back(message->arg0); |
293 header.push_back(message->arg1); | 338 header.push_back(message->arg1); |
294 bool append_zero = true; | 339 bool append_zero = true; |
295 if (message->body.empty()) | 340 if (message->body.empty()) |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 } | 552 } |
508 | 553 |
509 BrowserThread::PostTask( | 554 BrowserThread::PostTask( |
510 BrowserThread::FILE, FROM_HERE, | 555 BrowserThread::FILE, FROM_HERE, |
511 base::Bind(&ReleaseInterface, usb_device_)); | 556 base::Bind(&ReleaseInterface, usb_device_)); |
512 } | 557 } |
513 | 558 |
514 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { | 559 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { |
515 sockets_.erase(socket_id); | 560 sockets_.erase(socket_id); |
516 } | 561 } |
OLD | NEW |