| 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 |