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

Side by Side Diff: chrome/browser/devtools/device/usb/android_usb_browsertest.cc

Issue 315923003: DevTools: Tests for DevToolsAndroidBridge device polling (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added test for non-Android devices Created 6 years, 6 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
« no previous file with comments | « no previous file | chrome/browser/devtools/device/usb/devtools_android_bridge_browsertest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <algorithm>
6
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/devtools/device/devtools_android_bridge.h"
9 #include "chrome/browser/devtools/device/usb/android_usb_device.h"
10 #include "chrome/browser/devtools/device/usb/usb_device_provider.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/test/base/in_process_browser_test.h"
13 #include "components/usb_service/usb_device.h"
14 #include "components/usb_service/usb_device_handle.h"
15 #include "components/usb_service/usb_interface.h"
16 #include "components/usb_service/usb_service.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/test/test_utils.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 using content::BrowserThread;
22 using namespace usb_service;
23
24 namespace {
25
26 struct AndroidTraits {
27 static const int kClass = 0xff;
28 static const int kSubclass = 0x42;
29 static const int kProtocol = 0x1;
30 };
31
32 struct NonAndroidTraits {
33 static const int kClass = 0xf0;
34 static const int kSubclass = 0x42;
35 static const int kProtocol = 0x2;
36 };
37
38 const uint32 kMaxPayload = 4096;
39 const uint32 kVersion = 0x01000000;
40
41 const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix";
42 const char kDeviceModelCommand[] = "shell:getprop ro.product.model";
43 const char kDumpsysCommand[] = "shell:dumpsys window policy";
44 const char kListProcessesCommand[] = "shell:ps";
45 const char kInstalledChromePackagesCommand[] = "shell:pm list packages";
46 const char kDeviceModel[] = "Nexus 5";
47 const char kDeviceSerial[] = "Sample serial";
48
49 const char kSampleOpenedUnixSockets[] =
50 "Num RefCount Protocol Flags Type St Inode Path\n"
51 "00000000: 00000004 00000000"
52 " 00000000 0002 01 3328 /dev/socket/wpa_wlan0\n"
53 "00000000: 00000002 00000000"
54 " 00010000 0001 01 5394 /dev/socket/vold\n";
55
56 const char kSampleListProcesses[] =
57 "USER PID PPID VSIZE RSS WCHAN PC NAME\n"
58 "root 1 0 688 508 ffffffff 00000000 S /init\r\n"
59 "u0_a75 2425 123 933736 193024 ffffffff 00000000 S com.sample.feed\r\n"
60 "nfc 741 123 706448 26316 ffffffff 00000000 S com.android.nfc\r\n"
61 "u0_a76 1001 124 111111 222222 ffffffff 00000000 S com.android.chrome\r\n"
62 "u0_a78 1003 126 111111 222222 ffffffff 00000000 S com.noprocess.app\r\n";
63
64 const char kSampleListPackages[] =
65 "package:com.sample.feed\r\n"
66 "package:com.android.nfc\r\n"
67 "package:com.android.chrome\r\n"
68 "package:com.chrome.beta\r\n"
69 "package:com.google.android.apps.chrome\r\n";
70
71 const char kSampleDumpsys[] =
72 "WINDOW MANAGER POLICY STATE (dumpsys window policy)\r\n"
73 " mSafeMode=false mSystemReady=true mSystemBooted=true\r\n"
74 " mStable=(0,50)-(720,1184)\r\n" // Only mStable parameter is parsed
75 " mForceStatusBar=false mForceStatusBarFromKeyguard=false\r\n";
76
77 const char* GetMockShellResponse(std::string command) {
78 if (command == kDeviceModelCommand) {
79 return kDeviceModel;
80 } else if (command == kOpenedUnixSocketsCommand) {
81 return kSampleOpenedUnixSockets;
82 } else if (command == kDumpsysCommand) {
83 return kSampleDumpsys;
84 } else if (command == kListProcessesCommand) {
85 return kSampleListProcesses;
86 } else if (command == kInstalledChromePackagesCommand) {
87 return kSampleListPackages;
88 }
89
90 DCHECK(false) << "Should not be reached";
91
92 return "";
93 }
94
95 class MockUsbEndpointDescriptor : public UsbEndpointDescriptor {
96 public:
97 virtual int GetAddress() const OVERRIDE { return address_; }
98
99 virtual UsbEndpointDirection GetDirection() const OVERRIDE {
100 return direction_;
101 }
102
103 virtual int GetMaximumPacketSize() const OVERRIDE {
104 return maximum_packet_size_;
105 }
106
107 virtual UsbSynchronizationType GetSynchronizationType() const OVERRIDE {
108 return usb_synchronization_type_;
109 }
110
111 virtual UsbTransferType GetTransferType() const OVERRIDE {
112 return usb_transfer_type_;
113 }
114 virtual UsbUsageType GetUsageType() const OVERRIDE { return usb_usage_type_; }
115
116 virtual int GetPollingInterval() const OVERRIDE { return polling_interval_; }
117
118 int address_;
119 UsbEndpointDirection direction_;
120 int maximum_packet_size_;
121 UsbSynchronizationType usb_synchronization_type_;
122 UsbTransferType usb_transfer_type_;
123 UsbUsageType usb_usage_type_;
124 int polling_interval_;
125
126 private:
127 virtual ~MockUsbEndpointDescriptor() {}
128 };
129
130 template <class T>
131 class MockUsbInterfaceAltSettingDescriptor
132 : public UsbInterfaceAltSettingDescriptor {
133 public:
134 MockUsbInterfaceAltSettingDescriptor(int interface_number,
135 int alternate_setting)
136 : interface_number_(interface_number),
137 alternate_setting_(alternate_setting) {}
138
139 virtual size_t GetNumEndpoints() const OVERRIDE {
140 // See IsAndroidInterface function in android_usb_device.cc
141 return 2;
142 }
143
144 virtual scoped_refptr<const UsbEndpointDescriptor> GetEndpoint(
145 size_t index) const OVERRIDE {
146 EXPECT_GT(static_cast<size_t>(2), index);
147 MockUsbEndpointDescriptor* result = new MockUsbEndpointDescriptor();
148 result->address_ = index + 1;
149 result->usb_transfer_type_ = USB_TRANSFER_BULK;
150 result->direction_ =
151 ((index == 0) ? USB_DIRECTION_INBOUND : USB_DIRECTION_OUTBOUND);
152 result->maximum_packet_size_ = 1 << 20; // 1Mb maximum packet size
153 return result;
154 }
155
156 virtual int GetInterfaceNumber() const OVERRIDE { return interface_number_; }
157
158 virtual int GetAlternateSetting() const OVERRIDE {
159 return alternate_setting_;
160 }
161
162 virtual int GetInterfaceClass() const OVERRIDE { return T::kClass; }
163
164 virtual int GetInterfaceSubclass() const OVERRIDE { return T::kSubclass; }
165
166 virtual int GetInterfaceProtocol() const OVERRIDE { return T::kProtocol; }
167
168 protected:
169 virtual ~MockUsbInterfaceAltSettingDescriptor() {};
170
171 private:
172 const int interface_number_;
173 const int alternate_setting_;
174 };
175
176 template <class T>
177 class MockUsbInterfaceDescriptor : public UsbInterfaceDescriptor {
178 public:
179 explicit MockUsbInterfaceDescriptor(int interface_number)
180 : interface_number_(interface_number) {}
181
182 virtual size_t GetNumAltSettings() const OVERRIDE {
183 // See IsAndroidInterface function in android_usb_device.cc
184 return 1;
185 }
186 virtual scoped_refptr<const UsbInterfaceAltSettingDescriptor> GetAltSetting(
187 size_t index) const OVERRIDE {
188 EXPECT_EQ(static_cast<size_t>(0), index);
189 return new MockUsbInterfaceAltSettingDescriptor<T>(interface_number_, 0);
190 }
191
192 protected:
193 const int interface_number_;
194 virtual ~MockUsbInterfaceDescriptor() {}
195 };
196
197 template <class T>
198 class MockUsbConfigDescriptor : public UsbConfigDescriptor {
199 public:
200 MockUsbConfigDescriptor() {}
201
202 virtual size_t GetNumInterfaces() const OVERRIDE { return 1; }
203
204 virtual scoped_refptr<const UsbInterfaceDescriptor> GetInterface(
205 size_t index) const OVERRIDE {
206 EXPECT_EQ(static_cast<size_t>(0), index);
207 return new MockUsbInterfaceDescriptor<T>(index);
208 }
209
210 protected:
211 virtual ~MockUsbConfigDescriptor() {};
212 };
213
214 template <class T>
215 class MockUsbDevice;
216
217 template <class T>
218 class MockUsbDeviceHandle : public UsbDeviceHandle {
219 public:
220 explicit MockUsbDeviceHandle(MockUsbDevice<T>* device)
221 : device_(device),
222 remaining_body_length_(0),
223 next_local_socket_(0) {}
224
225 virtual scoped_refptr<UsbDevice> GetDevice() const OVERRIDE {
226 return device_;
227 }
228
229 virtual void Close() OVERRIDE { device_ = NULL; }
230
231 bool ClaimInterface(const int interface_number) {
232 if (device_->claimed_interfaces_.find(interface_number) !=
233 device_->claimed_interfaces_.end())
234 return false;
235
236 device_->claimed_interfaces_.insert(interface_number);
237 return true;
238 }
239
240 bool ReleaseInterface(const int interface_number) {
241 if (device_->claimed_interfaces_.find(interface_number) ==
242 device_->claimed_interfaces_.end())
243 return false;
244
245 device_->claimed_interfaces_.erase(interface_number);
246 return true;
247 }
248
249 virtual bool SetInterfaceAlternateSetting(
250 const int interface_number,
251 const int alternate_setting) OVERRIDE {
252 return true;
253 }
254
255 virtual bool ResetDevice() OVERRIDE { return true; }
256
257 virtual bool GetSerial(base::string16* serial) OVERRIDE {
258 *serial = base::UTF8ToUTF16(kDeviceSerial);
259 return true;
260 }
261
262 // Async IO. Can be called on any thread.
263 virtual void ControlTransfer(const UsbEndpointDirection direction,
264 const TransferRequestType request_type,
265 const TransferRecipient recipient,
266 const uint8 request,
267 const uint16 value,
268 const uint16 index,
269 net::IOBuffer* buffer,
270 const size_t length,
271 const unsigned int timeout,
272 const UsbTransferCallback& callback) OVERRIDE {}
273
274 virtual void BulkTransfer(const UsbEndpointDirection direction,
275 const uint8 endpoint,
276 net::IOBuffer* buffer,
277 const size_t length,
278 const unsigned int timeout,
279 const UsbTransferCallback& callback) OVERRIDE {
280 if (direction == USB_DIRECTION_OUTBOUND) {
281 if (remaining_body_length_ == 0) {
282 std::vector<uint32> header(6);
283 memcpy(&header[0], buffer->data(), length);
284 current_message_ = new AdbMessage(header[0], header[1], header[2], "");
285 remaining_body_length_ = header[3];
286 uint32 magic = header[5];
287 if ((current_message_->command ^ 0xffffffff) != magic) {
288 DCHECK(false) << "Header checksum error";
289 return;
290 }
291 } else {
292 DCHECK(current_message_);
293 current_message_->body += std::string(buffer->data(), length);
294 remaining_body_length_ -= length;
295 }
296
297 if (remaining_body_length_ == 0) {
298 ProcessIncoming();
299 }
300
301 base::MessageLoop::current()->PostTask(
302 FROM_HERE,
303 base::Bind(callback,
304 usb_service::USB_TRANSFER_COMPLETED,
305 scoped_refptr<net::IOBuffer>(),
306 0));
307
308 } else if (direction == USB_DIRECTION_INBOUND) {
309 queries_.push(Query(callback, make_scoped_refptr(buffer), length));
310 ProcessQueries();
311 }
312 }
313
314 template <class D>
315 void append(D data) {
316 std::copy(reinterpret_cast<char*>(&data),
317 (reinterpret_cast<char*>(&data)) + sizeof(D),
318 std::back_inserter(output_buffer_));
319 }
320
321 // Copied from AndroidUsbDevice::Checksum
322 uint32 Checksum(const std::string& data) {
323 unsigned char* x = (unsigned char*)data.data();
324 int count = data.length();
325 uint32 sum = 0;
326 while (count-- > 0)
327 sum += *x++;
328 return sum;
329 }
330
331 void ProcessIncoming() {
332 DCHECK(current_message_);
333 switch (current_message_->command) {
334 case AdbMessage::kCommandCNXN:
335 WriteResponse(new AdbMessage(AdbMessage::kCommandCNXN,
336 kVersion,
337 kMaxPayload,
338 "device::ro.product.name=SampleProduct;ro."
339 "product.model=SampleModel;ro.product."
340 "device=SampleDevice;"));
341 break;
342 case AdbMessage::kCommandOPEN:
343 DCHECK(current_message_->arg1 == 0);
344 DCHECK(current_message_->arg0 != 0);
345 if (current_message_->body.find("shell:") != std::string::npos) {
346 WriteResponse(new AdbMessage(AdbMessage::kCommandOKAY,
347 ++next_local_socket_,
348 current_message_->arg0,
349 ""));
350 WriteResponse(
351 new AdbMessage(AdbMessage::kCommandWRTE,
352 next_local_socket_,
353 current_message_->arg0,
354 GetMockShellResponse(current_message_->body.substr(
355 0, current_message_->body.size() - 1))));
356 WriteResponse(new AdbMessage(
357 AdbMessage::kCommandCLSE, 0, current_message_->arg0, ""));
358 }
359 default:
360 return;
361 }
362 ProcessQueries();
363 }
364
365 void WriteResponse(scoped_refptr<AdbMessage> response) {
366 append(response->command);
367 append(response->arg0);
368 append(response->arg1);
369 bool add_zero = response->body.length() &&
370 (response->command != AdbMessage::kCommandWRTE);
371 append(static_cast<uint32>(response->body.length() + (add_zero ? 1 : 0)));
372 append(Checksum(response->body));
373 append(response->command ^ 0xffffffff);
374 std::copy(response->body.begin(),
375 response->body.end(),
376 std::back_inserter(output_buffer_));
377 if (add_zero) {
378 output_buffer_.push_back(0);
379 }
380 ProcessQueries();
381 }
382
383 void ProcessQueries() {
384 if (!queries_.size())
385 return;
386 Query query = queries_.front();
387
388 if (query.size > output_buffer_.size())
389 return;
390
391 queries_.pop();
392 std::copy(output_buffer_.begin(),
393 output_buffer_.begin() + query.size,
394 query.buffer->data());
395 output_buffer_.erase(output_buffer_.begin(),
396 output_buffer_.begin() + query.size);
397 base::MessageLoop::current()->PostTask(
398 FROM_HERE,
399 base::Bind(query.callback,
400 usb_service::USB_TRANSFER_COMPLETED,
401 query.buffer,
402 query.size));
403 }
404
405 virtual void InterruptTransfer(const UsbEndpointDirection direction,
406 const uint8 endpoint,
407 net::IOBuffer* buffer,
408 const size_t length,
409 const unsigned int timeout,
410 const UsbTransferCallback& callback) OVERRIDE {
411 }
412
413 virtual void IsochronousTransfer(
414 const UsbEndpointDirection direction,
415 const uint8 endpoint,
416 net::IOBuffer* buffer,
417 const size_t length,
418 const unsigned int packets,
419 const unsigned int packet_length,
420 const unsigned int timeout,
421 const UsbTransferCallback& callback) OVERRIDE {}
422
423 protected:
424 virtual ~MockUsbDeviceHandle() {}
425
426 struct Query {
427 UsbTransferCallback callback;
428 scoped_refptr<net::IOBuffer> buffer;
429 size_t size;
430
431 Query(UsbTransferCallback callback,
432 scoped_refptr<net::IOBuffer> buffer,
433 int size)
434 : callback(callback), buffer(buffer), size(size) {};
435 };
436
437 scoped_refptr<MockUsbDevice<T> > device_;
438 uint32 remaining_body_length_;
439 scoped_refptr<AdbMessage> current_message_;
440 std::vector<char> output_buffer_;
441 std::queue<Query> queries_;
442 int next_local_socket_;
443 };
444
445 template <class T>
446 class MockUsbDevice : public UsbDevice {
447 public:
448 MockUsbDevice() : UsbDevice(0, 0, 0) {}
449
450 virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE {
451 return new MockUsbDeviceHandle<T>(this);
452 }
453
454 virtual scoped_refptr<UsbConfigDescriptor> ListInterfaces() OVERRIDE {
455 return new MockUsbConfigDescriptor<T>();
456 }
457
458 virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE {
459 return true;
460 }
461
462 #if defined(OS_CHROMEOS)
463 // On ChromeOS, if an interface of a claimed device is not claimed, the
464 // permission broker can change the owner of the device so that the unclaimed
465 // interfaces can be used. If this argument is missing, permission broker will
466 // not be used and this method fails if the device is claimed.
467 virtual void RequestUsbAcess(
468 int interface_id,
469 const base::Callback<void(bool success)>& callback) OVERRIDE {
470 callback.Run(true);
471 }
472 #endif // OS_CHROMEOS
473
474 std::set<int> claimed_interfaces_;
475
476 protected:
477 virtual ~MockUsbDevice() {}
478 };
479
480 class MockUsbService : public UsbService {
481 public:
482 MockUsbService() {
483 devices_.push_back(new MockUsbDevice<AndroidTraits>());
484 }
485
486 virtual ~MockUsbService() {}
487
488 virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) OVERRIDE {
489 NOTIMPLEMENTED();
490 return NULL;
491 }
492
493 virtual void GetDevices(
494 std::vector<scoped_refptr<UsbDevice> >* devices) OVERRIDE {
495 STLClearObject(devices);
496 std::copy(devices_.begin(), devices_.end(), back_inserter(*devices));
497 }
498
499 std::vector<scoped_refptr<UsbDevice> > devices_;
500 };
501
502 class MockUsbServiceForCheckingTraits : public UsbService {
503 public:
504 MockUsbServiceForCheckingTraits() : step_(0) {}
505
506 virtual ~MockUsbServiceForCheckingTraits() {}
507
508 virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) OVERRIDE {
509 NOTIMPLEMENTED();
510 return NULL;
511 }
512
513 virtual void GetDevices(
514 std::vector<scoped_refptr<UsbDevice> >* devices) OVERRIDE {
515 STLClearObject(devices);
516 // This switch should be kept in sync with
517 // AndroidUsbBrowserTest::DeviceCountChanged.
518 switch (step_) {
519 case 0:
520 // No devices.
521 break;
522 case 1:
523 // Android device.
524 devices->push_back(new MockUsbDevice<AndroidTraits>());
525 break;
526 case 2:
527 // Android and non-android device.
528 devices->push_back(new MockUsbDevice<AndroidTraits>());
529 devices->push_back(new MockUsbDevice<NonAndroidTraits>());
530 break;
531 case 3:
532 // Non-android device.
533 devices->push_back(new MockUsbDevice<NonAndroidTraits>());
534 break;
535 }
536 step_++;
537 }
538
539 private:
540 int step_;
541 };
542
543 class DevToolsAndroidBridgeWarmUp
544 : public DevToolsAndroidBridge::DeviceCountListener {
545 public:
546 DevToolsAndroidBridgeWarmUp(base::Closure closure,
547 scoped_refptr<DevToolsAndroidBridge> adb_bridge)
548 : closure_(closure), adb_bridge_(adb_bridge) {}
549
550 virtual void DeviceCountChanged(int count) OVERRIDE {
551 adb_bridge_->RemoveDeviceCountListener(this);
552 closure_.Run();
553 }
554
555 base::Closure closure_;
556 scoped_refptr<DevToolsAndroidBridge> adb_bridge_;
557 };
558
559 class AndroidUsbDiscoveryTest : public InProcessBrowserTest {
560 protected:
561 AndroidUsbDiscoveryTest()
562 : scheduler_invoked_(0) {
563 }
564 virtual void SetUpOnMainThread() OVERRIDE {
565 scoped_refptr<content::MessageLoopRunner> runner =
566 new content::MessageLoopRunner;
567
568 BrowserThread::PostTaskAndReply(
569 BrowserThread::FILE,
570 FROM_HERE,
571 base::Bind(&AndroidUsbDiscoveryTest::SetUpService, this),
572 runner->QuitClosure());
573 runner->Run();
574
575 adb_bridge_ =
576 DevToolsAndroidBridge::Factory::GetForProfile(browser()->profile());
577 DCHECK(adb_bridge_);
578 adb_bridge_->set_task_scheduler_for_test(base::Bind(
579 &AndroidUsbDiscoveryTest::ScheduleDeviceCountRequest, this));
580
581 scoped_refptr<UsbDeviceProvider> provider =
582 new UsbDeviceProvider(browser()->profile());
583
584 AndroidDeviceManager::DeviceProviders providers;
585 providers.push_back(provider);
586 adb_bridge_->set_device_providers_for_test(providers);
587 runner_ = new content::MessageLoopRunner;
588 }
589
590 void ScheduleDeviceCountRequest(const base::Closure& request) {
591 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
592 scheduler_invoked_++;
593 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, request);
594 }
595
596 virtual void SetUpService() {
597 UsbService::SetInstanceForTest(new MockUsbService());
598 }
599
600 virtual void CleanUpOnMainThread() OVERRIDE {
601 scoped_refptr<content::MessageLoopRunner> runner =
602 new content::MessageLoopRunner;
603 UsbService* service = NULL;
604 BrowserThread::PostTaskAndReply(
605 BrowserThread::FILE,
606 FROM_HERE,
607 base::Bind(&UsbService::SetInstanceForTest, service),
608 runner->QuitClosure());
609 runner->Run();
610 }
611
612 scoped_refptr<content::MessageLoopRunner> runner_;
613 scoped_refptr<DevToolsAndroidBridge> adb_bridge_;
614 int scheduler_invoked_;
615 };
616
617 class AndroidUsbCountTest : public AndroidUsbDiscoveryTest {
618 protected:
619 virtual void SetUpOnMainThread() OVERRIDE {
620 AndroidUsbDiscoveryTest::SetUpOnMainThread();
621 DevToolsAndroidBridgeWarmUp warmup(runner_->QuitClosure(), adb_bridge_);
622 adb_bridge_->AddDeviceCountListener(&warmup);
623 runner_->Run();
624 runner_ = new content::MessageLoopRunner;
625 }
626 };
627
628 class AndroidUsbTraitsTest : public AndroidUsbDiscoveryTest {
629 protected:
630 virtual void SetUpService() {
631 UsbService::SetInstanceForTest(new MockUsbServiceForCheckingTraits());
632 }
633 };
634
635 class MockListListener : public DevToolsAndroidBridge::DeviceListListener {
636 public:
637 MockListListener(scoped_refptr<DevToolsAndroidBridge> adb_bridge,
638 const base::Closure& callback)
639 : adb_bridge_(adb_bridge),
640 callback_(callback) {
641 }
642 virtual void DeviceListChanged(
643 const DevToolsAndroidBridge::RemoteDevices& devices) OVERRIDE {
644 if (devices.size() > 0) {
645 if (devices[0]->is_connected()) {
646 ASSERT_EQ(kDeviceModel, devices[0]->model());
647 ASSERT_EQ(kDeviceSerial, devices[0]->serial());
648 adb_bridge_->RemoveDeviceListListener(this);
649 callback_.Run();
650 }
651 }
652 }
653
654 scoped_refptr<DevToolsAndroidBridge> adb_bridge_;
655 base::Closure callback_;
656 };
657
658 class MockCountListener : public DevToolsAndroidBridge::DeviceCountListener {
659 public:
660 explicit MockCountListener(scoped_refptr<DevToolsAndroidBridge> adb_bridge)
661 : adb_bridge_(adb_bridge),
662 reposts_left_(10),
663 invoked_(0) {
664 }
665
666 virtual void DeviceCountChanged(int count) OVERRIDE {
667 ++invoked_;
668 adb_bridge_->RemoveDeviceCountListener(this);
669 Shutdown();
670 }
671
672 void Shutdown() {
673 ShutdownOnUIThread();
674 };
675
676 void ShutdownOnUIThread() {
677 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
678 if (reposts_left_-- == 0) {
679 base::MessageLoop::current()->Quit();
680 } else {
681 BrowserThread::PostTask(
682 BrowserThread::FILE,
683 FROM_HERE,
684 base::Bind(&MockCountListener::ShutdownOnFileThread,
685 base::Unretained(this)));
686 }
687 }
688
689 void ShutdownOnFileThread() {
690 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
691 BrowserThread::PostTask(BrowserThread::UI,
692 FROM_HERE,
693 base::Bind(&MockCountListener::ShutdownOnUIThread,
694 base::Unretained(this)));
695 }
696
697 scoped_refptr<DevToolsAndroidBridge> adb_bridge_;
698 int reposts_left_;
699 int invoked_;
700 };
701
702 class MockCountListenerWithReAdd : public MockCountListener {
703 public:
704 explicit MockCountListenerWithReAdd(
705 scoped_refptr<DevToolsAndroidBridge> adb_bridge)
706 : MockCountListener(adb_bridge),
707 readd_count_(2) {
708 }
709
710 virtual void DeviceCountChanged(int count) OVERRIDE {
711 ++invoked_;
712 adb_bridge_->RemoveDeviceCountListener(this);
713 if (readd_count_ > 0) {
714 readd_count_--;
715 adb_bridge_->AddDeviceCountListener(this);
716 adb_bridge_->RemoveDeviceCountListener(this);
717 adb_bridge_->AddDeviceCountListener(this);
718 } else {
719 Shutdown();
720 }
721 }
722
723 int readd_count_;
724 };
725
726 class MockCountListenerWithReAddWhileQueued : public MockCountListener {
727 public:
728 MockCountListenerWithReAddWhileQueued(
729 scoped_refptr<DevToolsAndroidBridge> adb_bridge)
730 : MockCountListener(adb_bridge),
731 readded_(false) {
732 }
733
734 virtual void DeviceCountChanged(int count) OVERRIDE {
735 ++invoked_;
736 if (!readded_) {
737 readded_ = true;
738 base::MessageLoop::current()->PostTask(
739 FROM_HERE,
740 base::Bind(&MockCountListenerWithReAddWhileQueued::ReAdd,
741 base::Unretained(this)));
742 } else {
743 adb_bridge_->RemoveDeviceCountListener(this);
744 Shutdown();
745 }
746 }
747
748 void ReAdd() {
749 adb_bridge_->RemoveDeviceCountListener(this);
750 adb_bridge_->AddDeviceCountListener(this);
751 }
752
753 bool readded_;
754 };
755
756 class MockCountListenerForCheckingTraits : public MockCountListener {
757 public:
758 MockCountListenerForCheckingTraits(
759 scoped_refptr<DevToolsAndroidBridge> adb_bridge)
760 : MockCountListener(adb_bridge),
761 step_(0) {
762 }
763 virtual void DeviceCountChanged(int count) OVERRIDE {
764 switch (step_) {
765 case 0:
766 // Check for 0 devices when no devices present.
767 EXPECT_EQ(0, count);
768 break;
769 case 1:
770 // Check for 1 device when only android device present.
771 EXPECT_EQ(1, count);
772 break;
773 case 2:
774 // Check for 1 device when android and non-android devices present.
775 EXPECT_EQ(1, count);
776 break;
777 case 3:
778 // Check for 0 devices when only non-android devices present.
779 EXPECT_EQ(0, count);
780 adb_bridge_->RemoveDeviceCountListener(this);
781 Shutdown();
782 break;
783 default:
784 EXPECT_TRUE(false) << "Unknown step " << step_;
785 }
786 step_++;
787 }
788
789 int step_;
790 };
791
792 } // namespace
793
794 IN_PROC_BROWSER_TEST_F(AndroidUsbDiscoveryTest, TestDeviceDiscovery) {
795 scoped_ptr<MockListListener> listener(
796 new MockListListener(adb_bridge_, runner_->QuitClosure()));
797 adb_bridge_->AddDeviceListListener(listener.get());
798 runner_->Run();
799 }
800
801 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest,
802 TestNoMultipleCallsRemoveInCallback) {
803 scoped_ptr<MockCountListener> listener(new MockCountListener(adb_bridge_));
Vladislav Kaznacheev 2014/06/17 10:27:16 Is there a reason you are using scoped_ptr instead
vkuzkokov 2014/06/17 13:01:44 No reason. Moved to stack.
804
805 adb_bridge_->AddDeviceCountListener(listener.get());
806
807 runner_->Run();
808 EXPECT_EQ(1, listener->invoked_);
809 EXPECT_EQ(listener->invoked_ - 1, scheduler_invoked_);
810 }
811
812 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest,
813 TestNoMultipleCallsRemoveAddInCallback) {
814 scoped_ptr<MockCountListener> listener(
815 new MockCountListenerWithReAdd(adb_bridge_));
816
817 adb_bridge_->AddDeviceCountListener(listener.get());
818
819 runner_->Run();
820 EXPECT_EQ(3, listener->invoked_);
821 EXPECT_EQ(listener->invoked_ - 1, scheduler_invoked_);
822 }
823
824 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest,
825 TestNoMultipleCallsRemoveAddOnStart) {
826 scoped_ptr<MockCountListener> listener(new MockCountListener(adb_bridge_));
827
828 adb_bridge_->AddDeviceCountListener(listener.get());
829 adb_bridge_->RemoveDeviceCountListener(listener.get());
830 adb_bridge_->AddDeviceCountListener(listener.get());
831
832 runner_->Run();
833 EXPECT_EQ(1, listener->invoked_);
834 EXPECT_EQ(listener->invoked_ - 1, scheduler_invoked_);
835 }
836
837 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest,
838 TestNoMultipleCallsRemoveAddWhileQueued) {
839 scoped_ptr<MockCountListener> listener(
840 new MockCountListenerWithReAddWhileQueued(adb_bridge_));
841
842 adb_bridge_->AddDeviceCountListener(listener.get());
843
844 runner_->Run();
845 EXPECT_EQ(2, listener->invoked_);
846 EXPECT_EQ(listener->invoked_ - 1, scheduler_invoked_);
847 }
848
849 IN_PROC_BROWSER_TEST_F(AndroidUsbTraitsTest, TestDeviceCounting) {
850 scoped_ptr<MockCountListener> listener(
851 new MockCountListenerForCheckingTraits(adb_bridge_));
852
853 adb_bridge_->AddDeviceCountListener(listener.get());
854 runner_->Run();
855 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/devtools/device/usb/devtools_android_bridge_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698