Chromium Code Reviews| 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* claimed_devices) { |
|
Vladislav Kaznacheev
2014/04/10 14:38:11
Unclear name (already claimed or newly claimed?)
pfeldman
2014/04/10 15:37:46
Done.
| |
| 172 callback.Run(devices); | 175 scoped_ptr<AndroidUsbDevices> devices(claimed_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 OpenAndroidDevicesOnFileThread( |
|
Vladislav Kaznacheev
2014/04/10 14:38:11
's' at the end of 'devices' seems out of place
pfeldman
2014/04/10 15:37:46
Done.
| |
| 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, | |
|
Vladislav Kaznacheev
2014/04/10 14:38:11
I suggest using base::Owned for this parameter.
pfeldman
2014/04/10 15:37:46
Done.
| |
| 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(&OpenAndroidDevicesOnFileThread, |
| 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 OpenAndroidDevicesOnFileThread(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)->terminated_) { | |
|
Vladislav Kaznacheev
2014/04/10 14:38:11
AndroidUsbDevice::terminated() exists (but not use
pfeldman
2014/04/10 15:37:46
Done.
| |
| 309 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | |
| 310 base::Bind(&AndroidUsbDevice::TerminateIfReleased, *it)); | |
| 311 } | |
| 312 } | |
| 313 | |
| 314 // Then look for the new devices. | |
| 316 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 315 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 317 base::Bind(&EnumerateOnFileThread, rsa_key, callback, | 316 base::Bind(&EnumerateOnFileThread, rsa_key, callback, |
| 318 base::MessageLoopProxy::current())); | 317 base::MessageLoopProxy::current())); |
| 319 } | 318 } |
| 320 | 319 |
| 321 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key, | 320 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key, |
| 322 scoped_refptr<UsbDeviceHandle> usb_device, | 321 scoped_refptr<UsbDeviceHandle> usb_device, |
| 323 const std::string& serial, | 322 const std::string& serial, |
| 324 int inbound_address, | 323 int inbound_address, |
| 325 int outbound_address, | 324 int outbound_address, |
| 326 int zero_mask) | 325 int zero_mask, |
| 326 int interface_id) | |
| 327 : message_loop_(NULL), | 327 : message_loop_(NULL), |
| 328 rsa_key_(rsa_key->Copy()), | 328 rsa_key_(rsa_key->Copy()), |
| 329 usb_device_(usb_device), | 329 usb_device_(usb_device), |
| 330 serial_(serial), | 330 serial_(serial), |
| 331 inbound_address_(inbound_address), | 331 inbound_address_(inbound_address), |
| 332 outbound_address_(outbound_address), | 332 outbound_address_(outbound_address), |
| 333 zero_mask_(zero_mask), | 333 zero_mask_(zero_mask), |
| 334 interface_id_(interface_id), | |
| 334 is_connected_(false), | 335 is_connected_(false), |
| 335 signature_sent_(false), | 336 signature_sent_(false), |
| 336 last_socket_id_(256), | 337 last_socket_id_(256), |
| 337 terminated_(false) { | 338 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 (terminated_) | |
| 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() { |
| 370 Terminate(); | 375 Terminate(); |
| 371 usb_device_->AddRef(); | |
| 372 BrowserThread::ReleaseSoon(BrowserThread::FILE, FROM_HERE, | |
| 373 usb_device_.get()); | |
| 374 } | 376 } |
| 375 | 377 |
| 376 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) { | 378 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) { |
| 377 // Queue header. | 379 // Queue header. |
| 378 std::vector<uint32> header; | 380 std::vector<uint32> header; |
| 379 header.push_back(message->command); | 381 header.push_back(message->command); |
| 380 header.push_back(message->arg0); | 382 header.push_back(message->arg0); |
| 381 header.push_back(message->arg1); | 383 header.push_back(message->arg1); |
| 382 bool append_zero = true; | 384 bool append_zero = true; |
| 383 if (message->body.empty()) | 385 if (message->body.empty()) |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 413 | 415 |
| 414 void AndroidUsbDevice::ProcessOutgoing() { | 416 void AndroidUsbDevice::ProcessOutgoing() { |
| 415 if (outgoing_queue_.empty() || terminated_) | 417 if (outgoing_queue_.empty() || terminated_) |
| 416 return; | 418 return; |
| 417 | 419 |
| 418 BulkMessage message = outgoing_queue_.front(); | 420 BulkMessage message = outgoing_queue_.front(); |
| 419 outgoing_queue_.pop(); | 421 outgoing_queue_.pop(); |
| 420 DumpMessage(true, message.first->data(), message.second); | 422 DumpMessage(true, message.first->data(), message.second); |
| 421 usb_device_->BulkTransfer(USB_DIRECTION_OUTBOUND, outbound_address_, | 423 usb_device_->BulkTransfer(USB_DIRECTION_OUTBOUND, outbound_address_, |
| 422 message.first, message.second, kUsbTimeout, | 424 message.first, message.second, kUsbTimeout, |
| 423 base::Bind(&AndroidUsbDevice::OutgoingMessageSent, this)); | 425 base::Bind(&AndroidUsbDevice::OutgoingMessageSent, |
| 426 weak_factory_.GetWeakPtr())); | |
| 424 } | 427 } |
| 425 | 428 |
| 426 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status, | 429 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status, |
| 427 scoped_refptr<net::IOBuffer> buffer, | 430 scoped_refptr<net::IOBuffer> buffer, |
| 428 size_t result) { | 431 size_t result) { |
| 429 if (status != USB_TRANSFER_COMPLETED) | 432 if (status != USB_TRANSFER_COMPLETED) |
| 430 return; | 433 return; |
| 431 message_loop_->PostTask(FROM_HERE, | 434 message_loop_->PostTask(FROM_HERE, |
| 432 base::Bind(&AndroidUsbDevice::ProcessOutgoing, | 435 base::Bind(&AndroidUsbDevice::ProcessOutgoing, this)); |
| 433 this)); | |
| 434 } | 436 } |
| 435 | 437 |
| 436 void AndroidUsbDevice::ReadHeader(bool initial) { | 438 void AndroidUsbDevice::ReadHeader() { |
| 437 if (terminated_) | 439 if (terminated_) |
| 438 return; | 440 return; |
| 439 if (!initial && HasOneRef()) | |
| 440 return; // Stop polling. | |
| 441 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize); | 441 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize); |
| 442 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_, | 442 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_, |
| 443 buffer, kHeaderSize, kUsbTimeout, | 443 buffer, kHeaderSize, kUsbTimeout, |
| 444 base::Bind(&AndroidUsbDevice::ParseHeader, this)); | 444 base::Bind(&AndroidUsbDevice::ParseHeader, |
| 445 weak_factory_.GetWeakPtr())); | |
| 445 } | 446 } |
| 446 | 447 |
| 447 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status, | 448 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status, |
| 448 scoped_refptr<net::IOBuffer> buffer, | 449 scoped_refptr<net::IOBuffer> buffer, |
| 449 size_t result) { | 450 size_t result) { |
| 450 if (status == USB_TRANSFER_TIMEOUT) { | 451 if (status == USB_TRANSFER_TIMEOUT) { |
| 451 message_loop_->PostTask(FROM_HERE, | 452 message_loop_->PostTask(FROM_HERE, |
| 452 base::Bind(&AndroidUsbDevice::ReadHeader, this, | 453 base::Bind(&AndroidUsbDevice::ReadHeader, this)); |
| 453 false)); | |
| 454 return; | 454 return; |
| 455 } | 455 } |
| 456 | 456 |
| 457 if (status != USB_TRANSFER_COMPLETED || result != kHeaderSize) { | 457 if (status != USB_TRANSFER_COMPLETED || result != kHeaderSize) { |
| 458 TransferError(status); | 458 TransferError(status); |
| 459 return; | 459 return; |
| 460 } | 460 } |
| 461 | 461 |
| 462 DumpMessage(false, buffer->data(), result); | 462 DumpMessage(false, buffer->data(), result); |
| 463 std::vector<uint32> header(6); | 463 std::vector<uint32> header(6); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 480 } | 480 } |
| 481 | 481 |
| 482 message_loop_->PostTask(FROM_HERE, | 482 message_loop_->PostTask(FROM_HERE, |
| 483 base::Bind(&AndroidUsbDevice::ReadBody, this, | 483 base::Bind(&AndroidUsbDevice::ReadBody, this, |
| 484 message, data_length, data_check)); | 484 message, data_length, data_check)); |
| 485 } | 485 } |
| 486 | 486 |
| 487 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message, | 487 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message, |
| 488 uint32 data_length, | 488 uint32 data_length, |
| 489 uint32 data_check) { | 489 uint32 data_check) { |
| 490 if (terminated_) | |
| 491 return; | |
| 490 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length); | 492 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length); |
| 491 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_, | 493 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_, |
| 492 buffer, data_length, kUsbTimeout, | 494 buffer, data_length, kUsbTimeout, |
| 493 base::Bind(&AndroidUsbDevice::ParseBody, this, message, data_length, | 495 base::Bind(&AndroidUsbDevice::ParseBody, weak_factory_.GetWeakPtr(), |
| 494 data_check)); | 496 message, data_length, data_check)); |
| 495 } | 497 } |
| 496 | 498 |
| 497 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message, | 499 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message, |
| 498 uint32 data_length, | 500 uint32 data_length, |
| 499 uint32 data_check, | 501 uint32 data_check, |
| 500 UsbTransferStatus status, | 502 UsbTransferStatus status, |
| 501 scoped_refptr<net::IOBuffer> buffer, | 503 scoped_refptr<net::IOBuffer> buffer, |
| 502 size_t result) { | 504 size_t result) { |
| 503 if (status == USB_TRANSFER_TIMEOUT) { | 505 if (status == USB_TRANSFER_TIMEOUT) { |
| 504 message_loop_->PostTask(FROM_HERE, | 506 message_loop_->PostTask(FROM_HERE, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 565 case AdbMessage::kCommandCLSE: | 567 case AdbMessage::kCommandCLSE: |
| 566 { | 568 { |
| 567 AndroidUsbSockets::iterator it = sockets_.find(message->arg1); | 569 AndroidUsbSockets::iterator it = sockets_.find(message->arg1); |
| 568 if (it != sockets_.end()) | 570 if (it != sockets_.end()) |
| 569 it->second->HandleIncoming(message); | 571 it->second->HandleIncoming(message); |
| 570 } | 572 } |
| 571 break; | 573 break; |
| 572 default: | 574 default: |
| 573 break; | 575 break; |
| 574 } | 576 } |
| 575 ReadHeader(false); | 577 ReadHeader(); |
| 576 } | 578 } |
| 577 | 579 |
| 578 void AndroidUsbDevice::TransferError(UsbTransferStatus status) { | 580 void AndroidUsbDevice::TransferError(UsbTransferStatus status) { |
| 579 message_loop_->PostTask(FROM_HERE, | 581 message_loop_->PostTask(FROM_HERE, |
| 580 base::Bind(&AndroidUsbDevice::Terminate, | 582 base::Bind(&AndroidUsbDevice::Terminate, this)); |
| 581 this)); | 583 } |
| 584 | |
| 585 void AndroidUsbDevice::TerminateIfReleased() { | |
| 586 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 587 if (usb_device_->device()) | |
|
Vladislav Kaznacheev
2014/04/10 14:38:11
usb_device_ pointer can be set to NULL by a differ
pfeldman
2014/04/10 15:37:46
Done.
| |
| 588 return; | |
| 589 message_loop_->PostTask(FROM_HERE, | |
| 590 base::Bind(&AndroidUsbDevice::Terminate, this)); | |
| 582 } | 591 } |
| 583 | 592 |
| 584 void AndroidUsbDevice::Terminate() { | 593 void AndroidUsbDevice::Terminate() { |
| 594 std::vector<AndroidUsbDevice*>::iterator it = | |
| 595 std::find(g_devices.Get().begin(), g_devices.Get().end(), this); | |
| 596 if (it != g_devices.Get().end()) | |
| 597 g_devices.Get().erase(it); | |
| 598 | |
| 585 if (terminated_) | 599 if (terminated_) |
| 586 return; | 600 return; |
| 587 | 601 |
| 588 terminated_ = true; | 602 terminated_ = true; |
|
Vladislav Kaznacheev
2014/04/10 14:38:11
terminated_ is always in sync with !usb_device_. D
pfeldman
2014/04/10 15:37:46
Done.
| |
| 589 | 603 |
| 590 // Iterate over copy. | 604 // Iterate over copy. |
| 591 AndroidUsbSockets sockets(sockets_); | 605 AndroidUsbSockets sockets(sockets_); |
| 592 for (AndroidUsbSockets::iterator it = sockets.begin(); | 606 for (AndroidUsbSockets::iterator it = sockets.begin(); |
| 593 it != sockets.end(); ++it) { | 607 it != sockets.end(); ++it) { |
| 594 it->second->Terminated(); | 608 it->second->Terminated(); |
| 595 } | 609 } |
| 610 DCHECK(sockets_.empty()); | |
| 596 | 611 |
| 597 BrowserThread::PostTask( | 612 BrowserThread::PostTask( |
| 598 BrowserThread::FILE, FROM_HERE, | 613 BrowserThread::FILE, FROM_HERE, |
| 599 base::Bind(&ReleaseInterface, usb_device_)); | 614 base::Bind(&ReleaseInterface, usb_device_, interface_id_)); |
| 615 usb_device_ = NULL; | |
| 600 } | 616 } |
| 601 | 617 |
| 602 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { | 618 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { |
| 603 sockets_.erase(socket_id); | 619 sockets_.erase(socket_id); |
| 604 } | 620 } |
| OLD | NEW |