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/barrier_closure.h" |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 const uint32 kMaxPayload = 4096; | 38 const uint32 kMaxPayload = 4096; |
39 const uint32 kVersion = 0x01000000; | 39 const uint32 kVersion = 0x01000000; |
40 | 40 |
41 static const char kHostConnectMessage[] = "host::"; | 41 static const char kHostConnectMessage[] = "host::"; |
42 | 42 |
43 using content::BrowserThread; | 43 using content::BrowserThread; |
44 | 44 |
45 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices; | 45 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices; |
46 typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet; | 46 typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet; |
47 | 47 |
48 base::LazyInstance<AndroidUsbDevices>::Leaky g_devices = | 48 // Stores android wrappers around claimed usb devices on caller thread. |
| 49 base::LazyInstance<std::vector<AndroidUsbDevice*> >::Leaky g_devices = |
49 LAZY_INSTANCE_INITIALIZER; | 50 LAZY_INSTANCE_INITIALIZER; |
50 | 51 |
51 bool IsAndroidInterface( | 52 bool IsAndroidInterface( |
52 scoped_refptr<const UsbInterfaceDescriptor> interface) { | 53 scoped_refptr<const UsbInterfaceDescriptor> interface) { |
53 if (interface->GetNumAltSettings() == 0) | 54 if (interface->GetNumAltSettings() == 0) |
54 return false; | 55 return false; |
55 | 56 |
56 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc = | 57 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc = |
57 interface->GetAltSetting(0); | 58 interface->GetAltSetting(0); |
58 | 59 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 return NULL; | 94 return NULL; |
94 | 95 |
95 if (!usb_handle->ClaimInterface(interface_id)) | 96 if (!usb_handle->ClaimInterface(interface_id)) |
96 return NULL; | 97 return NULL; |
97 | 98 |
98 base::string16 serial; | 99 base::string16 serial; |
99 if (!usb_handle->GetSerial(&serial) || serial.empty()) | 100 if (!usb_handle->GetSerial(&serial) || serial.empty()) |
100 return NULL; | 101 return NULL; |
101 | 102 |
102 return new AndroidUsbDevice(rsa_key, usb_handle, base::UTF16ToASCII(serial), | 103 return new AndroidUsbDevice(rsa_key, usb_handle, base::UTF16ToASCII(serial), |
103 inbound_address, outbound_address, zero_mask); | 104 inbound_address, outbound_address, zero_mask, |
| 105 interface_id); |
104 } | 106 } |
105 | 107 |
106 uint32 Checksum(const std::string& data) { | 108 uint32 Checksum(const std::string& data) { |
107 unsigned char* x = (unsigned char*)data.data(); | 109 unsigned char* x = (unsigned char*)data.data(); |
108 int count = data.length(); | 110 int count = data.length(); |
109 uint32 sum = 0; | 111 uint32 sum = 0; |
110 while (count-- > 0) | 112 while (count-- > 0) |
111 sum += *x++; | 113 sum += *x++; |
112 return sum; | 114 return sum; |
113 } | 115 } |
(...skipping 20 matching lines...) Expand all Loading... |
134 if (data[i] >= 0x20 && data[i] <= 0x7E) | 136 if (data[i] >= 0x20 && data[i] <= 0x7E) |
135 result += data[i]; | 137 result += data[i]; |
136 else | 138 else |
137 result += "."; | 139 result += "."; |
138 } | 140 } |
139 } | 141 } |
140 LOG(ERROR) << (outgoing ? "[out] " : "[ in] ") << result; | 142 LOG(ERROR) << (outgoing ? "[out] " : "[ in] ") << result; |
141 #endif // 0 | 143 #endif // 0 |
142 } | 144 } |
143 | 145 |
144 void ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device) { | 146 void ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device, |
145 usb_device->ReleaseInterface(1); | 147 int interface_id) { |
| 148 usb_device->ReleaseInterface(interface_id); |
146 usb_device->Close(); | 149 usb_device->Close(); |
147 } | 150 } |
148 | 151 |
149 } // namespace | 152 } // namespace |
150 | 153 |
151 AdbMessage::AdbMessage(uint32 command, | 154 AdbMessage::AdbMessage(uint32 command, |
152 uint32 arg0, | 155 uint32 arg0, |
153 uint32 arg1, | 156 uint32 arg1, |
154 const std::string& body) | 157 const std::string& body) |
155 : command(command), | 158 : command(command), |
156 arg0(arg0), | 159 arg0(arg0), |
157 arg1(arg1), | 160 arg1(arg1), |
158 body(body) { | 161 body(body) { |
159 } | 162 } |
160 | 163 |
161 AdbMessage::~AdbMessage() { | 164 AdbMessage::~AdbMessage() { |
162 } | 165 } |
163 | 166 |
164 static void RespondWithCountOnUIThread(base::Callback<void(int)> callback, | 167 static void RespondWithCountOnUIThread(base::Callback<void(int)> callback, |
165 int count) { | 168 int count) { |
166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
167 callback.Run(count); | 170 callback.Run(count); |
168 } | 171 } |
169 | 172 |
170 static void RespondOnCallerThread(const AndroidUsbDevicesCallback& callback, | 173 static void RespondOnCallerThread(const AndroidUsbDevicesCallback& callback, |
171 const AndroidUsbDevices& devices) { | 174 AndroidUsbDevices* new_devices) { |
172 callback.Run(devices); | 175 scoped_ptr<AndroidUsbDevices> devices(new_devices); |
| 176 |
| 177 // Add raw pointers to the newly claimed devices. |
| 178 for (AndroidUsbDevices::iterator it = devices->begin(); it != devices->end(); |
| 179 ++it) { |
| 180 g_devices.Get().push_back(*it); |
| 181 } |
| 182 |
| 183 // Return all claimed devices. |
| 184 AndroidUsbDevices result(g_devices.Get().begin(), g_devices.Get().end()); |
| 185 callback.Run(result); |
173 } | 186 } |
174 | 187 |
175 static void RespondOnFileThread( | 188 static void RespondOnFileThread( |
176 const AndroidUsbDevicesCallback& callback, | 189 const AndroidUsbDevicesCallback& callback, |
| 190 AndroidUsbDevices* devices, |
177 scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) { | 191 scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) { |
178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
179 // Copy g_devices.Get() on file thread. | |
180 caller_message_loop_proxy->PostTask( | 193 caller_message_loop_proxy->PostTask( |
181 FROM_HERE, | 194 FROM_HERE, |
182 base::Bind(&RespondOnCallerThread, callback, g_devices.Get())); | 195 base::Bind(&RespondOnCallerThread, callback, devices)); |
183 } | 196 } |
184 | 197 |
185 static void OpenAndroidDevicesOnFileThread( | 198 static void OpenAndroidDeviceOnFileThread( |
| 199 AndroidUsbDevices* devices, |
186 crypto::RSAPrivateKey* rsa_key, | 200 crypto::RSAPrivateKey* rsa_key, |
187 const base::Closure& barrier, | 201 const base::Closure& barrier, |
188 scoped_refptr<UsbDevice> device, | 202 scoped_refptr<UsbDevice> device, |
189 int interface_id, | 203 int interface_id, |
190 bool success) { | 204 bool success) { |
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
192 if (success) { | 206 if (success) { |
193 scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces(); | 207 scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces(); |
194 scoped_refptr<UsbDeviceHandle> usb_handle = device->Open(); | 208 scoped_refptr<UsbDeviceHandle> usb_handle = device->Open(); |
195 if (usb_handle) { | 209 if (usb_handle) { |
196 scoped_refptr<AndroidUsbDevice> device = | 210 scoped_refptr<AndroidUsbDevice> android_device = |
197 ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id), | 211 ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id), |
198 interface_id); | 212 interface_id); |
199 if (device.get()) | 213 if (android_device.get()) |
200 g_devices.Get().push_back(device); | 214 devices->push_back(android_device.get()); |
201 else | 215 else |
202 usb_handle->Close(); | 216 usb_handle->Close(); |
203 } | 217 } |
204 } | 218 } |
205 barrier.Run(); | 219 barrier.Run(); |
206 } | 220 } |
207 | 221 |
208 static void CountOnFileThread( | 222 static void CountOnFileThread( |
209 const base::Callback<void(int)>& callback) { | 223 const base::Callback<void(int)>& callback) { |
210 UsbService* service = UsbService::GetInstance(); | 224 UsbService* service = UsbService::GetInstance(); |
(...skipping 21 matching lines...) Expand all Loading... |
232 crypto::RSAPrivateKey* rsa_key, | 246 crypto::RSAPrivateKey* rsa_key, |
233 const AndroidUsbDevicesCallback& callback, | 247 const AndroidUsbDevicesCallback& callback, |
234 scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) { | 248 scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) { |
235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
236 | 250 |
237 UsbService* service = UsbService::GetInstance(); | 251 UsbService* service = UsbService::GetInstance(); |
238 UsbDevices usb_devices; | 252 UsbDevices usb_devices; |
239 if (service != NULL) | 253 if (service != NULL) |
240 service->GetDevices(&usb_devices); | 254 service->GetDevices(&usb_devices); |
241 | 255 |
242 AndroidUsbDevices& devices = g_devices.Get(); | |
243 | |
244 // GC Android devices with no actual usb device. | |
245 AndroidUsbDevices::iterator it = devices.begin(); | |
246 UsbDeviceSet claimed_devices; | |
247 while (it != devices.end()) { | |
248 bool found_device = false; | |
249 for (UsbDevices::iterator it2 = usb_devices.begin(); | |
250 it2 != usb_devices.end() && !found_device; ++it2) { | |
251 UsbDevice* usb_device = it2->get(); | |
252 AndroidUsbDevice* device = it->get(); | |
253 if (usb_device == device->usb_device()->device()) { | |
254 found_device = true; | |
255 claimed_devices.insert(usb_device); | |
256 } | |
257 } | |
258 | |
259 if (!found_device) | |
260 it = devices.erase(it); | |
261 else | |
262 ++it; | |
263 } | |
264 | |
265 // Add new devices. | 256 // Add new devices. |
| 257 AndroidUsbDevices* devices = new AndroidUsbDevices(); |
266 base::Closure barrier = base::BarrierClosure( | 258 base::Closure barrier = base::BarrierClosure( |
267 usb_devices.size(), base::Bind(&RespondOnFileThread, | 259 usb_devices.size(), base::Bind(&RespondOnFileThread, |
268 callback, | 260 callback, |
| 261 devices, |
269 caller_message_loop_proxy)); | 262 caller_message_loop_proxy)); |
270 | 263 |
271 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); | 264 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); |
272 ++it) { | 265 ++it) { |
273 if (ContainsKey(claimed_devices, it->get())) { | |
274 barrier.Run(); | |
275 continue; | |
276 } | |
277 | |
278 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); | 266 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); |
279 if (!config) { | 267 if (!config) { |
280 barrier.Run(); | 268 barrier.Run(); |
281 continue; | 269 continue; |
282 } | 270 } |
283 | 271 |
284 bool has_android_interface = false; | 272 bool has_android_interface = false; |
285 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { | 273 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { |
286 if (!IsAndroidInterface(config->GetInterface(j))) | 274 if (!IsAndroidInterface(config->GetInterface(j))) |
287 continue; | 275 continue; |
288 | 276 |
289 // Request permission on Chrome OS. | 277 // Request permission on Chrome OS. |
290 #if defined(OS_CHROMEOS) | 278 #if defined(OS_CHROMEOS) |
291 (*it)->RequestUsbAcess(j, base::Bind(&OpenAndroidDevicesOnFileThread, | 279 (*it)->RequestUsbAcess(j, base::Bind(&OpenAndroidDeviceOnFileThread, |
292 rsa_key, barrier, *it, j)); | 280 devices, rsa_key, barrier, *it, j)); |
293 #else | 281 #else |
294 OpenAndroidDevicesOnFileThread(rsa_key, barrier, *it, j, true); | 282 OpenAndroidDeviceOnFileThread(devices, rsa_key, barrier, *it, j, true); |
295 #endif // defined(OS_CHROMEOS) | 283 #endif // defined(OS_CHROMEOS) |
296 | 284 |
297 has_android_interface = true; | 285 has_android_interface = true; |
298 break; | 286 break; |
299 } | 287 } |
300 if (!has_android_interface) | 288 if (!has_android_interface) |
301 barrier.Run(); | 289 barrier.Run(); |
302 } | 290 } |
303 } | 291 } |
304 | 292 |
305 // static | 293 // static |
306 void AndroidUsbDevice::CountDevices( | 294 void AndroidUsbDevice::CountDevices( |
307 const base::Callback<void(int)>& callback) { | 295 const base::Callback<void(int)>& callback) { |
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 296 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
309 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 297 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
310 base::Bind(&CountOnFileThread, callback)); | 298 base::Bind(&CountOnFileThread, callback)); |
311 } | 299 } |
312 | 300 |
313 // static | 301 // static |
314 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key, | 302 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key, |
315 const AndroidUsbDevicesCallback& callback) { | 303 const AndroidUsbDevicesCallback& callback) { |
| 304 |
| 305 // Collect devices with closed handles. |
| 306 for (std::vector<AndroidUsbDevice*>::iterator it = g_devices.Get().begin(); |
| 307 it != g_devices.Get().end(); ++it) { |
| 308 if ((*it)->usb_handle_) { |
| 309 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 310 base::Bind(&AndroidUsbDevice::TerminateIfReleased, *it, |
| 311 (*it)->usb_handle_)); |
| 312 } |
| 313 } |
| 314 |
| 315 // Then look for the new devices. |
316 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 316 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
317 base::Bind(&EnumerateOnFileThread, rsa_key, callback, | 317 base::Bind(&EnumerateOnFileThread, rsa_key, callback, |
318 base::MessageLoopProxy::current())); | 318 base::MessageLoopProxy::current())); |
319 } | 319 } |
320 | 320 |
321 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key, | 321 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key, |
322 scoped_refptr<UsbDeviceHandle> usb_device, | 322 scoped_refptr<UsbDeviceHandle> usb_device, |
323 const std::string& serial, | 323 const std::string& serial, |
324 int inbound_address, | 324 int inbound_address, |
325 int outbound_address, | 325 int outbound_address, |
326 int zero_mask) | 326 int zero_mask, |
| 327 int interface_id) |
327 : message_loop_(NULL), | 328 : message_loop_(NULL), |
328 rsa_key_(rsa_key->Copy()), | 329 rsa_key_(rsa_key->Copy()), |
329 usb_device_(usb_device), | 330 usb_handle_(usb_device), |
330 serial_(serial), | 331 serial_(serial), |
331 inbound_address_(inbound_address), | 332 inbound_address_(inbound_address), |
332 outbound_address_(outbound_address), | 333 outbound_address_(outbound_address), |
333 zero_mask_(zero_mask), | 334 zero_mask_(zero_mask), |
| 335 interface_id_(interface_id), |
334 is_connected_(false), | 336 is_connected_(false), |
335 signature_sent_(false), | 337 signature_sent_(false), |
336 last_socket_id_(256), | 338 last_socket_id_(256), |
337 terminated_(false) { | 339 weak_factory_(this) { |
338 } | 340 } |
339 | 341 |
340 void AndroidUsbDevice::InitOnCallerThread() { | 342 void AndroidUsbDevice::InitOnCallerThread() { |
341 if (message_loop_) | 343 if (message_loop_) |
342 return; | 344 return; |
343 message_loop_ = base::MessageLoop::current(); | 345 message_loop_ = base::MessageLoop::current(); |
344 Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload, | 346 Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload, |
345 kHostConnectMessage)); | 347 kHostConnectMessage)); |
346 ReadHeader(true); | 348 ReadHeader(); |
347 } | 349 } |
348 | 350 |
349 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) { | 351 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) { |
| 352 if (!usb_handle_) |
| 353 return NULL; |
| 354 |
350 uint32 socket_id = ++last_socket_id_; | 355 uint32 socket_id = ++last_socket_id_; |
351 sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command, | 356 sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command, |
352 base::Bind(&AndroidUsbDevice::SocketDeleted, this)); | 357 base::Bind(&AndroidUsbDevice::SocketDeleted, this)); |
353 return sockets_[socket_id]; | 358 return sockets_[socket_id]; |
354 } | 359 } |
355 | 360 |
356 void AndroidUsbDevice::Send(uint32 command, | 361 void AndroidUsbDevice::Send(uint32 command, |
357 uint32 arg0, | 362 uint32 arg0, |
358 uint32 arg1, | 363 uint32 arg1, |
359 const std::string& body) { | 364 const std::string& body) { |
360 scoped_refptr<AdbMessage> m = new AdbMessage(command, arg0, arg1, body); | 365 scoped_refptr<AdbMessage> m = new AdbMessage(command, arg0, arg1, body); |
361 // Delay open request if not yet connected. | 366 // Delay open request if not yet connected. |
362 if (!is_connected_) { | 367 if (!is_connected_) { |
363 pending_messages_.push_back(m); | 368 pending_messages_.push_back(m); |
364 return; | 369 return; |
365 } | 370 } |
366 Queue(m); | 371 Queue(m); |
367 } | 372 } |
368 | 373 |
369 AndroidUsbDevice::~AndroidUsbDevice() { | 374 AndroidUsbDevice::~AndroidUsbDevice() { |
| 375 DCHECK(message_loop_ == base::MessageLoop::current()); |
370 Terminate(); | 376 Terminate(); |
371 usb_device_->AddRef(); | |
372 BrowserThread::ReleaseSoon(BrowserThread::FILE, FROM_HERE, | |
373 usb_device_.get()); | |
374 } | 377 } |
375 | 378 |
376 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) { | 379 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) { |
| 380 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 381 |
377 // Queue header. | 382 // Queue header. |
378 std::vector<uint32> header; | 383 std::vector<uint32> header; |
379 header.push_back(message->command); | 384 header.push_back(message->command); |
380 header.push_back(message->arg0); | 385 header.push_back(message->arg0); |
381 header.push_back(message->arg1); | 386 header.push_back(message->arg1); |
382 bool append_zero = true; | 387 bool append_zero = true; |
383 if (message->body.empty()) | 388 if (message->body.empty()) |
384 append_zero = false; | 389 append_zero = false; |
385 if (message->command == AdbMessage::kCommandAUTH && | 390 if (message->command == AdbMessage::kCommandAUTH && |
386 message->arg0 == AdbMessage::kAuthSignature) | 391 message->arg0 == AdbMessage::kAuthSignature) |
(...skipping 18 matching lines...) Expand all Loading... |
405 outgoing_queue_.push(std::make_pair(body_buffer, body_length)); | 410 outgoing_queue_.push(std::make_pair(body_buffer, body_length)); |
406 if (zero_mask_ && (body_length & zero_mask_) == 0) { | 411 if (zero_mask_ && (body_length & zero_mask_) == 0) { |
407 // Send a zero length packet. | 412 // Send a zero length packet. |
408 outgoing_queue_.push(std::make_pair(body_buffer, 0)); | 413 outgoing_queue_.push(std::make_pair(body_buffer, 0)); |
409 } | 414 } |
410 } | 415 } |
411 ProcessOutgoing(); | 416 ProcessOutgoing(); |
412 } | 417 } |
413 | 418 |
414 void AndroidUsbDevice::ProcessOutgoing() { | 419 void AndroidUsbDevice::ProcessOutgoing() { |
415 if (outgoing_queue_.empty() || terminated_) | 420 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 421 |
| 422 if (outgoing_queue_.empty() || !usb_handle_) |
416 return; | 423 return; |
417 | 424 |
418 BulkMessage message = outgoing_queue_.front(); | 425 BulkMessage message = outgoing_queue_.front(); |
419 outgoing_queue_.pop(); | 426 outgoing_queue_.pop(); |
420 DumpMessage(true, message.first->data(), message.second); | 427 DumpMessage(true, message.first->data(), message.second); |
421 usb_device_->BulkTransfer(USB_DIRECTION_OUTBOUND, outbound_address_, | 428 usb_handle_->BulkTransfer(USB_DIRECTION_OUTBOUND, outbound_address_, |
422 message.first, message.second, kUsbTimeout, | 429 message.first, message.second, kUsbTimeout, |
423 base::Bind(&AndroidUsbDevice::OutgoingMessageSent, this)); | 430 base::Bind(&AndroidUsbDevice::OutgoingMessageSent, |
| 431 weak_factory_.GetWeakPtr())); |
424 } | 432 } |
425 | 433 |
426 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status, | 434 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status, |
427 scoped_refptr<net::IOBuffer> buffer, | 435 scoped_refptr<net::IOBuffer> buffer, |
428 size_t result) { | 436 size_t result) { |
| 437 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 438 |
429 if (status != USB_TRANSFER_COMPLETED) | 439 if (status != USB_TRANSFER_COMPLETED) |
430 return; | 440 return; |
431 message_loop_->PostTask(FROM_HERE, | 441 message_loop_->PostTask(FROM_HERE, |
432 base::Bind(&AndroidUsbDevice::ProcessOutgoing, | 442 base::Bind(&AndroidUsbDevice::ProcessOutgoing, this)); |
433 this)); | |
434 } | 443 } |
435 | 444 |
436 void AndroidUsbDevice::ReadHeader(bool initial) { | 445 void AndroidUsbDevice::ReadHeader() { |
437 if (terminated_) | 446 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 447 |
| 448 if (!usb_handle_) |
438 return; | 449 return; |
439 if (!initial && HasOneRef()) | |
440 return; // Stop polling. | |
441 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize); | 450 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize); |
442 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_, | 451 usb_handle_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_, |
443 buffer, kHeaderSize, kUsbTimeout, | 452 buffer, kHeaderSize, kUsbTimeout, |
444 base::Bind(&AndroidUsbDevice::ParseHeader, this)); | 453 base::Bind(&AndroidUsbDevice::ParseHeader, |
| 454 weak_factory_.GetWeakPtr())); |
445 } | 455 } |
446 | 456 |
447 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status, | 457 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status, |
448 scoped_refptr<net::IOBuffer> buffer, | 458 scoped_refptr<net::IOBuffer> buffer, |
449 size_t result) { | 459 size_t result) { |
| 460 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 461 |
450 if (status == USB_TRANSFER_TIMEOUT) { | 462 if (status == USB_TRANSFER_TIMEOUT) { |
451 message_loop_->PostTask(FROM_HERE, | 463 message_loop_->PostTask(FROM_HERE, |
452 base::Bind(&AndroidUsbDevice::ReadHeader, this, | 464 base::Bind(&AndroidUsbDevice::ReadHeader, this)); |
453 false)); | |
454 return; | 465 return; |
455 } | 466 } |
456 | 467 |
457 if (status != USB_TRANSFER_COMPLETED || result != kHeaderSize) { | 468 if (status != USB_TRANSFER_COMPLETED || result != kHeaderSize) { |
458 TransferError(status); | 469 TransferError(status); |
459 return; | 470 return; |
460 } | 471 } |
461 | 472 |
462 DumpMessage(false, buffer->data(), result); | 473 DumpMessage(false, buffer->data(), result); |
463 std::vector<uint32> header(6); | 474 std::vector<uint32> header(6); |
(...skipping 16 matching lines...) Expand all Loading... |
480 } | 491 } |
481 | 492 |
482 message_loop_->PostTask(FROM_HERE, | 493 message_loop_->PostTask(FROM_HERE, |
483 base::Bind(&AndroidUsbDevice::ReadBody, this, | 494 base::Bind(&AndroidUsbDevice::ReadBody, this, |
484 message, data_length, data_check)); | 495 message, data_length, data_check)); |
485 } | 496 } |
486 | 497 |
487 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message, | 498 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message, |
488 uint32 data_length, | 499 uint32 data_length, |
489 uint32 data_check) { | 500 uint32 data_check) { |
| 501 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 502 |
| 503 if (!usb_handle_) |
| 504 return; |
490 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length); | 505 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length); |
491 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_, | 506 usb_handle_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_, |
492 buffer, data_length, kUsbTimeout, | 507 buffer, data_length, kUsbTimeout, |
493 base::Bind(&AndroidUsbDevice::ParseBody, this, message, data_length, | 508 base::Bind(&AndroidUsbDevice::ParseBody, weak_factory_.GetWeakPtr(), |
494 data_check)); | 509 message, data_length, data_check)); |
495 } | 510 } |
496 | 511 |
497 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message, | 512 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message, |
498 uint32 data_length, | 513 uint32 data_length, |
499 uint32 data_check, | 514 uint32 data_check, |
500 UsbTransferStatus status, | 515 UsbTransferStatus status, |
501 scoped_refptr<net::IOBuffer> buffer, | 516 scoped_refptr<net::IOBuffer> buffer, |
502 size_t result) { | 517 size_t result) { |
| 518 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 519 |
503 if (status == USB_TRANSFER_TIMEOUT) { | 520 if (status == USB_TRANSFER_TIMEOUT) { |
504 message_loop_->PostTask(FROM_HERE, | 521 message_loop_->PostTask(FROM_HERE, |
505 base::Bind(&AndroidUsbDevice::ReadBody, this, | 522 base::Bind(&AndroidUsbDevice::ReadBody, this, |
506 message, data_length, data_check)); | 523 message, data_length, data_check)); |
507 return; | 524 return; |
508 } | 525 } |
509 | 526 |
510 if (status != USB_TRANSFER_COMPLETED || | 527 if (status != USB_TRANSFER_COMPLETED || |
511 static_cast<uint32>(result) != data_length) { | 528 static_cast<uint32>(result) != data_length) { |
512 TransferError(status); | 529 TransferError(status); |
513 return; | 530 return; |
514 } | 531 } |
515 | 532 |
516 DumpMessage(false, buffer->data(), data_length); | 533 DumpMessage(false, buffer->data(), data_length); |
517 message->body = std::string(buffer->data(), result); | 534 message->body = std::string(buffer->data(), result); |
518 if (Checksum(message->body) != data_check) { | 535 if (Checksum(message->body) != data_check) { |
519 TransferError(USB_TRANSFER_ERROR); | 536 TransferError(USB_TRANSFER_ERROR); |
520 return; | 537 return; |
521 } | 538 } |
522 | 539 |
523 message_loop_->PostTask(FROM_HERE, | 540 message_loop_->PostTask(FROM_HERE, |
524 base::Bind(&AndroidUsbDevice::HandleIncoming, this, | 541 base::Bind(&AndroidUsbDevice::HandleIncoming, this, |
525 message)); | 542 message)); |
526 } | 543 } |
527 | 544 |
528 void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) { | 545 void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) { |
| 546 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 547 |
529 switch (message->command) { | 548 switch (message->command) { |
530 case AdbMessage::kCommandAUTH: | 549 case AdbMessage::kCommandAUTH: |
531 { | 550 { |
532 DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken)); | 551 DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken)); |
533 if (signature_sent_) { | 552 if (signature_sent_) { |
534 Queue(new AdbMessage(AdbMessage::kCommandAUTH, | 553 Queue(new AdbMessage(AdbMessage::kCommandAUTH, |
535 AdbMessage::kAuthRSAPublicKey, 0, | 554 AdbMessage::kAuthRSAPublicKey, 0, |
536 AndroidRSAPublicKey(rsa_key_.get()))); | 555 AndroidRSAPublicKey(rsa_key_.get()))); |
537 } else { | 556 } else { |
538 signature_sent_ = true; | 557 signature_sent_ = true; |
(...skipping 26 matching lines...) Expand all Loading... |
565 case AdbMessage::kCommandCLSE: | 584 case AdbMessage::kCommandCLSE: |
566 { | 585 { |
567 AndroidUsbSockets::iterator it = sockets_.find(message->arg1); | 586 AndroidUsbSockets::iterator it = sockets_.find(message->arg1); |
568 if (it != sockets_.end()) | 587 if (it != sockets_.end()) |
569 it->second->HandleIncoming(message); | 588 it->second->HandleIncoming(message); |
570 } | 589 } |
571 break; | 590 break; |
572 default: | 591 default: |
573 break; | 592 break; |
574 } | 593 } |
575 ReadHeader(false); | 594 ReadHeader(); |
576 } | 595 } |
577 | 596 |
578 void AndroidUsbDevice::TransferError(UsbTransferStatus status) { | 597 void AndroidUsbDevice::TransferError(UsbTransferStatus status) { |
| 598 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 599 |
579 message_loop_->PostTask(FROM_HERE, | 600 message_loop_->PostTask(FROM_HERE, |
580 base::Bind(&AndroidUsbDevice::Terminate, | 601 base::Bind(&AndroidUsbDevice::Terminate, this)); |
581 this)); | 602 } |
| 603 |
| 604 void AndroidUsbDevice::TerminateIfReleased( |
| 605 scoped_refptr<UsbDeviceHandle> usb_handle) { |
| 606 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 607 if (usb_handle->device()) |
| 608 return; |
| 609 message_loop_->PostTask(FROM_HERE, |
| 610 base::Bind(&AndroidUsbDevice::Terminate, this)); |
582 } | 611 } |
583 | 612 |
584 void AndroidUsbDevice::Terminate() { | 613 void AndroidUsbDevice::Terminate() { |
585 if (terminated_) | 614 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 615 |
| 616 std::vector<AndroidUsbDevice*>::iterator it = |
| 617 std::find(g_devices.Get().begin(), g_devices.Get().end(), this); |
| 618 if (it != g_devices.Get().end()) |
| 619 g_devices.Get().erase(it); |
| 620 |
| 621 if (!usb_handle_) |
586 return; | 622 return; |
587 | 623 |
588 terminated_ = true; | 624 // Make sure we zero-out handle so that closing connections did not open |
| 625 // new connections. |
| 626 scoped_refptr<UsbDeviceHandle> usb_handle = usb_handle_; |
| 627 usb_handle_ = NULL; |
589 | 628 |
590 // Iterate over copy. | 629 // Iterate over copy. |
591 AndroidUsbSockets sockets(sockets_); | 630 AndroidUsbSockets sockets(sockets_); |
592 for (AndroidUsbSockets::iterator it = sockets.begin(); | 631 for (AndroidUsbSockets::iterator it = sockets.begin(); |
593 it != sockets.end(); ++it) { | 632 it != sockets.end(); ++it) { |
594 it->second->Terminated(); | 633 it->second->Terminated(); |
595 } | 634 } |
| 635 DCHECK(sockets_.empty()); |
596 | 636 |
597 BrowserThread::PostTask( | 637 BrowserThread::PostTask( |
598 BrowserThread::FILE, FROM_HERE, | 638 BrowserThread::FILE, FROM_HERE, |
599 base::Bind(&ReleaseInterface, usb_device_)); | 639 base::Bind(&ReleaseInterface, usb_handle, interface_id_)); |
600 } | 640 } |
601 | 641 |
602 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { | 642 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { |
| 643 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 644 |
603 sockets_.erase(socket_id); | 645 sockets_.erase(socket_id); |
604 } | 646 } |
OLD | NEW |