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

Side by Side Diff: chrome/browser/devtools/adb/android_usb_device.cc

Issue 230773003: DevTools: do not retain android_usb_devices in their manager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698