Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / devtools / device / usb / android_usb_browsertest.cc
blobbd98e9acde79e261bf5cd0eda54f04b48c421007
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.
5 #include <algorithm>
7 #include "base/containers/scoped_ptr_hash_map.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "chrome/browser/devtools/device/adb/mock_adb_server.h"
13 #include "chrome/browser/devtools/device/devtools_android_bridge.h"
14 #include "chrome/browser/devtools/device/usb/android_usb_device.h"
15 #include "chrome/browser/devtools/device/usb/usb_device_provider.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/test/base/in_process_browser_test.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/test/test_utils.h"
20 #include "device/core/device_client.h"
21 #include "device/usb/usb_descriptors.h"
22 #include "device/usb/usb_device.h"
23 #include "device/usb/usb_device_handle.h"
24 #include "device/usb/usb_service.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 using content::BrowserThread;
28 using device::DeviceClient;
29 using device::UsbConfigDescriptor;
30 using device::UsbDevice;
31 using device::UsbDeviceHandle;
32 using device::UsbEndpointDescriptor;
33 using device::UsbEndpointDirection;
34 using device::UsbInterfaceDescriptor;
35 using device::UsbService;
36 using device::UsbSynchronizationType;
37 using device::UsbTransferType;
38 using device::UsbUsageType;
40 namespace {
42 struct NoConfigTraits {
43 static const int kClass = 0xff;
44 static const int kSubclass = 0x42;
45 static const int kProtocol = 0x1;
46 static const bool kBreaks = false;
47 static const bool kConfigured = false;
50 struct AndroidTraits {
51 static const int kClass = 0xff;
52 static const int kSubclass = 0x42;
53 static const int kProtocol = 0x1;
54 static const bool kBreaks = false;
55 static const bool kConfigured = true;
58 struct NonAndroidTraits {
59 static const int kClass = 0xf0;
60 static const int kSubclass = 0x42;
61 static const int kProtocol = 0x2;
62 static const bool kBreaks = false;
63 static const bool kConfigured = true;
66 struct BreakingAndroidTraits {
67 static const int kClass = 0xff;
68 static const int kSubclass = 0x42;
69 static const int kProtocol = 0x1;
70 static const bool kBreaks = true;
71 static const bool kConfigured = true;
74 const uint32 kMaxPayload = 4096;
75 const uint32 kVersion = 0x01000000;
77 const char kDeviceManufacturer[] = "Test Manufacturer";
78 const char kDeviceModel[] = "Nexus 6";
79 const char kDeviceSerial[] = "01498B321301A00A";
81 template <class T>
82 class MockUsbDevice;
84 class MockLocalSocket : public MockAndroidConnection::Delegate {
85 public:
86 using Callback = base::Callback<void(int command,
87 const std::string& message)>;
89 MockLocalSocket(const Callback& callback,
90 const std::string& serial,
91 const std::string& command)
92 : callback_(callback),
93 connection_(new MockAndroidConnection(this, serial, command)) {
96 void Receive(const std::string& data) {
97 connection_->Receive(data);
100 private:
101 void SendSuccess(const std::string& message) override {
102 if (!message.empty())
103 callback_.Run(AdbMessage::kCommandWRTE, message);
106 void SendRaw(const std::string& message) override {
107 callback_.Run(AdbMessage::kCommandWRTE, message);
110 void Close() override {
111 callback_.Run(AdbMessage::kCommandCLSE, std::string());
114 Callback callback_;
115 scoped_ptr<MockAndroidConnection> connection_;
118 template <class T>
119 class MockUsbDeviceHandle : public UsbDeviceHandle {
120 public:
121 explicit MockUsbDeviceHandle(MockUsbDevice<T>* device)
122 : device_(device),
123 remaining_body_length_(0),
124 last_local_socket_(0),
125 broken_(false) {
128 scoped_refptr<UsbDevice> GetDevice() const override {
129 return device_;
132 void Close() override { device_ = nullptr; }
134 void SetConfiguration(int configuration_value,
135 const ResultCallback& callback) override {
136 NOTIMPLEMENTED();
139 void ClaimInterface(int interface_number,
140 const ResultCallback& callback) override {
141 bool success = false;
142 if (device_->claimed_interfaces_.find(interface_number) ==
143 device_->claimed_interfaces_.end()) {
144 device_->claimed_interfaces_.insert(interface_number);
145 success = true;
148 base::ThreadTaskRunnerHandle::Get()->PostTask(
149 FROM_HERE, base::Bind(callback, success));
152 bool ReleaseInterface(int interface_number) override {
153 if (device_->claimed_interfaces_.find(interface_number) ==
154 device_->claimed_interfaces_.end())
155 return false;
157 device_->claimed_interfaces_.erase(interface_number);
158 return true;
161 void SetInterfaceAlternateSetting(int interface_number,
162 int alternate_setting,
163 const ResultCallback& callback) override {
164 NOTIMPLEMENTED();
167 void ResetDevice(const ResultCallback& callback) override {
168 NOTIMPLEMENTED();
171 void ClearHalt(uint8 endpoint, const ResultCallback& callback) override {
172 NOTIMPLEMENTED();
175 // Async IO. Can be called on any thread.
176 void ControlTransfer(UsbEndpointDirection direction,
177 TransferRequestType request_type,
178 TransferRecipient recipient,
179 uint8 request,
180 uint16 value,
181 uint16 index,
182 scoped_refptr<net::IOBuffer> buffer,
183 size_t length,
184 unsigned int timeout,
185 const TransferCallback& callback) override {}
187 void GenericTransfer(UsbEndpointDirection direction,
188 uint8 endpoint,
189 scoped_refptr<net::IOBuffer> buffer,
190 size_t length,
191 unsigned int timeout,
192 const TransferCallback& callback) override {
193 if (direction == device::USB_DIRECTION_OUTBOUND) {
194 if (remaining_body_length_ == 0) {
195 std::vector<uint32> header(6);
196 memcpy(&header[0], buffer->data(), length);
197 current_message_.reset(
198 new AdbMessage(header[0], header[1], header[2], std::string()));
199 remaining_body_length_ = header[3];
200 uint32 magic = header[5];
201 if ((current_message_->command ^ 0xffffffff) != magic) {
202 DCHECK(false) << "Header checksum error";
203 return;
205 } else {
206 DCHECK(current_message_.get());
207 current_message_->body += std::string(buffer->data(), length);
208 remaining_body_length_ -= length;
211 if (remaining_body_length_ == 0) {
212 ProcessIncoming();
215 device::UsbTransferStatus status =
216 broken_ ? device::USB_TRANSFER_ERROR : device::USB_TRANSFER_COMPLETED;
217 base::ThreadTaskRunnerHandle::Get()->PostTask(
218 FROM_HERE, base::Bind(callback, status, nullptr, 0));
219 ProcessQueries();
220 } else if (direction == device::USB_DIRECTION_INBOUND) {
221 queries_.push(Query(callback, buffer, length));
222 ProcessQueries();
226 template <class D>
227 void append(D data) {
228 std::copy(reinterpret_cast<char*>(&data),
229 (reinterpret_cast<char*>(&data)) + sizeof(D),
230 std::back_inserter(output_buffer_));
233 // Copied from AndroidUsbDevice::Checksum
234 uint32 Checksum(const std::string& data) {
235 unsigned char* x = (unsigned char*)data.data();
236 int count = data.length();
237 uint32 sum = 0;
238 while (count-- > 0)
239 sum += *x++;
240 return sum;
243 void ProcessIncoming() {
244 DCHECK(current_message_.get());
245 switch (current_message_->command) {
246 case AdbMessage::kCommandCNXN: {
247 WriteResponse(kVersion,
248 kMaxPayload,
249 AdbMessage::kCommandCNXN,
250 "device::ro.product.name=SampleProduct;ro.product.model="
251 "SampleModel;ro.product.device=SampleDevice;");
252 break;
254 case AdbMessage::kCommandCLSE: {
255 WriteResponse(0,
256 current_message_->arg0,
257 AdbMessage::kCommandCLSE,
258 std::string());
259 local_sockets_.erase(current_message_->arg0);
260 break;
262 case AdbMessage::kCommandWRTE: {
263 if (T::kBreaks) {
264 broken_ = true;
265 return;
267 auto it = local_sockets_.find(current_message_->arg0);
268 if (it == local_sockets_.end())
269 return;
271 DCHECK(current_message_->arg1 != 0);
272 WriteResponse(current_message_->arg1,
273 current_message_->arg0,
274 AdbMessage::kCommandOKAY,
275 std::string());
276 it->second->Receive(current_message_->body);
277 break;
279 case AdbMessage::kCommandOPEN: {
280 DCHECK(current_message_->arg1 == 0);
281 DCHECK(current_message_->arg0 != 0);
282 std::string response;
283 WriteResponse(++last_local_socket_,
284 current_message_->arg0,
285 AdbMessage::kCommandOKAY,
286 std::string());
287 local_sockets_.set(
288 current_message_->arg0,
289 make_scoped_ptr(new MockLocalSocket(
290 base::Bind(&MockUsbDeviceHandle::WriteResponse,
291 base::Unretained(this),
292 last_local_socket_,
293 current_message_->arg0),
294 kDeviceSerial,
295 current_message_->body.substr(
296 0, current_message_->body.size() - 1))));
297 return;
299 default: {
300 return;
303 ProcessQueries();
306 void WriteResponse(int arg0, int arg1, int command, const std::string& body) {
307 append(command);
308 append(arg0);
309 append(arg1);
310 bool add_zero = !body.empty() && (command != AdbMessage::kCommandWRTE);
311 append(static_cast<uint32>(body.size() + (add_zero ? 1 : 0)));
312 append(Checksum(body));
313 append(command ^ 0xffffffff);
314 std::copy(body.begin(), body.end(), std::back_inserter(output_buffer_));
315 if (add_zero) {
316 output_buffer_.push_back(0);
318 ProcessQueries();
321 void ProcessQueries() {
322 if (!queries_.size())
323 return;
324 Query query = queries_.front();
325 if (broken_) {
326 base::ThreadTaskRunnerHandle::Get()->PostTask(
327 FROM_HERE,
328 base::Bind(query.callback, device::USB_TRANSFER_ERROR, nullptr, 0));
331 if (query.size > output_buffer_.size())
332 return;
334 queries_.pop();
335 std::copy(output_buffer_.begin(),
336 output_buffer_.begin() + query.size,
337 query.buffer->data());
338 output_buffer_.erase(output_buffer_.begin(),
339 output_buffer_.begin() + query.size);
340 base::ThreadTaskRunnerHandle::Get()->PostTask(
341 FROM_HERE, base::Bind(query.callback, device::USB_TRANSFER_COMPLETED,
342 query.buffer, query.size));
345 void IsochronousTransfer(UsbEndpointDirection direction,
346 uint8 endpoint,
347 scoped_refptr<net::IOBuffer> buffer,
348 size_t length,
349 unsigned int packets,
350 unsigned int packet_length,
351 unsigned int timeout,
352 const TransferCallback& callback) override {}
354 protected:
355 virtual ~MockUsbDeviceHandle() {}
357 struct Query {
358 TransferCallback callback;
359 scoped_refptr<net::IOBuffer> buffer;
360 size_t size;
362 Query(TransferCallback callback,
363 scoped_refptr<net::IOBuffer> buffer,
364 int size)
365 : callback(callback), buffer(buffer), size(size) {}
368 scoped_refptr<MockUsbDevice<T> > device_;
369 uint32 remaining_body_length_;
370 scoped_ptr<AdbMessage> current_message_;
371 std::vector<char> output_buffer_;
372 std::queue<Query> queries_;
373 base::ScopedPtrHashMap<int, scoped_ptr<MockLocalSocket>> local_sockets_;
374 int last_local_socket_;
375 bool broken_;
378 template <class T>
379 class MockUsbDevice : public UsbDevice {
380 public:
381 MockUsbDevice()
382 : UsbDevice(0,
384 base::UTF8ToUTF16(kDeviceManufacturer),
385 base::UTF8ToUTF16(kDeviceModel),
386 base::UTF8ToUTF16(kDeviceSerial)) {
387 UsbEndpointDescriptor bulk_in;
388 bulk_in.address = 0x81;
389 bulk_in.direction = device::USB_DIRECTION_INBOUND;
390 bulk_in.maximum_packet_size = 512;
391 bulk_in.transfer_type = device::USB_TRANSFER_BULK;
393 UsbEndpointDescriptor bulk_out;
394 bulk_out.address = 0x01;
395 bulk_out.direction = device::USB_DIRECTION_OUTBOUND;
396 bulk_out.maximum_packet_size = 512;
397 bulk_out.transfer_type = device::USB_TRANSFER_BULK;
399 UsbInterfaceDescriptor interface_desc;
400 interface_desc.interface_number = 0;
401 interface_desc.alternate_setting = 0;
402 interface_desc.interface_class = T::kClass;
403 interface_desc.interface_subclass = T::kSubclass;
404 interface_desc.interface_protocol = T::kProtocol;
405 interface_desc.endpoints.push_back(bulk_in);
406 interface_desc.endpoints.push_back(bulk_out);
408 config_desc_.interfaces.push_back(interface_desc);
411 void Open(const OpenCallback& callback) override {
412 base::ThreadTaskRunnerHandle::Get()->PostTask(
413 FROM_HERE, base::Bind(callback, make_scoped_refptr(
414 new MockUsbDeviceHandle<T>(this))));
417 const UsbConfigDescriptor* GetActiveConfiguration() override {
418 return T::kConfigured ? &config_desc_ : nullptr;
421 bool Close(scoped_refptr<UsbDeviceHandle> handle) override {
422 return true;
425 std::set<int> claimed_interfaces_;
427 protected:
428 virtual ~MockUsbDevice() {}
430 private:
431 UsbConfigDescriptor config_desc_;
434 class MockUsbService : public UsbService {
435 public:
436 MockUsbService() {
437 devices_.push_back(new MockUsbDevice<AndroidTraits>());
440 scoped_refptr<UsbDevice> GetDevice(const std::string& guid) override {
441 NOTIMPLEMENTED();
442 return nullptr;
445 void GetDevices(const GetDevicesCallback& callback) override {
446 callback.Run(devices_);
449 std::vector<scoped_refptr<UsbDevice> > devices_;
452 class MockBreakingUsbService : public MockUsbService {
453 public:
454 MockBreakingUsbService() {
455 devices_.clear();
456 devices_.push_back(new MockUsbDevice<BreakingAndroidTraits>());
460 class MockNoConfigUsbService : public MockUsbService {
461 public:
462 MockNoConfigUsbService() {
463 devices_.push_back(new MockUsbDevice<NoConfigTraits>());
467 class MockUsbServiceForCheckingTraits : public MockUsbService {
468 public:
469 MockUsbServiceForCheckingTraits() : step_(0) {}
471 void GetDevices(const GetDevicesCallback& callback) override {
472 std::vector<scoped_refptr<UsbDevice>> devices;
473 // This switch should be kept in sync with
474 // AndroidUsbBrowserTest::DeviceCountChanged.
475 switch (step_) {
476 case 0:
477 // No devices.
478 break;
479 case 1:
480 // Android device.
481 devices.push_back(new MockUsbDevice<AndroidTraits>());
482 break;
483 case 2:
484 // Android and non-android device.
485 devices.push_back(new MockUsbDevice<AndroidTraits>());
486 devices.push_back(new MockUsbDevice<NonAndroidTraits>());
487 break;
488 case 3:
489 // Non-android device.
490 devices.push_back(new MockUsbDevice<NonAndroidTraits>());
491 break;
493 step_++;
494 callback.Run(devices);
497 private:
498 int step_;
501 class TestDeviceClient : public DeviceClient {
502 public:
503 explicit TestDeviceClient(scoped_ptr<UsbService> service)
504 : DeviceClient(), usb_service_(service.Pass()) {}
505 ~TestDeviceClient() override {}
507 private:
508 UsbService* GetUsbService() override { return usb_service_.get(); }
510 scoped_ptr<UsbService> usb_service_;
513 class DevToolsAndroidBridgeWarmUp
514 : public DevToolsAndroidBridge::DeviceCountListener {
515 public:
516 DevToolsAndroidBridgeWarmUp(base::Closure closure,
517 DevToolsAndroidBridge* adb_bridge)
518 : closure_(closure), adb_bridge_(adb_bridge) {}
520 void DeviceCountChanged(int count) override {
521 adb_bridge_->RemoveDeviceCountListener(this);
522 closure_.Run();
525 base::Closure closure_;
526 DevToolsAndroidBridge* adb_bridge_;
529 class AndroidUsbDiscoveryTest : public InProcessBrowserTest {
530 protected:
531 AndroidUsbDiscoveryTest()
532 : scheduler_invoked_(0) {
535 void SetUpOnMainThread() override {
536 device_client_.reset(new TestDeviceClient(CreateMockService()));
537 adb_bridge_ =
538 DevToolsAndroidBridge::Factory::GetForProfile(browser()->profile());
539 DCHECK(adb_bridge_);
540 adb_bridge_->set_task_scheduler_for_test(base::Bind(
541 &AndroidUsbDiscoveryTest::ScheduleDeviceCountRequest, this));
543 scoped_refptr<UsbDeviceProvider> provider =
544 new UsbDeviceProvider(browser()->profile());
546 AndroidDeviceManager::DeviceProviders providers;
547 providers.push_back(provider);
548 adb_bridge_->set_device_providers_for_test(providers);
549 runner_ = new content::MessageLoopRunner;
552 void ScheduleDeviceCountRequest(const base::Closure& request) {
553 DCHECK_CURRENTLY_ON(BrowserThread::UI);
554 scheduler_invoked_++;
555 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, request);
558 virtual scoped_ptr<MockUsbService> CreateMockService() {
559 return make_scoped_ptr(new MockUsbService());
562 scoped_refptr<content::MessageLoopRunner> runner_;
563 scoped_ptr<TestDeviceClient> device_client_;
564 DevToolsAndroidBridge* adb_bridge_;
565 int scheduler_invoked_;
568 class AndroidUsbCountTest : public AndroidUsbDiscoveryTest {
569 protected:
570 void SetUpOnMainThread() override {
571 AndroidUsbDiscoveryTest::SetUpOnMainThread();
572 DevToolsAndroidBridgeWarmUp warmup(runner_->QuitClosure(), adb_bridge_);
573 adb_bridge_->AddDeviceCountListener(&warmup);
574 runner_->Run();
575 runner_ = new content::MessageLoopRunner;
579 class AndroidUsbTraitsTest : public AndroidUsbDiscoveryTest {
580 protected:
581 scoped_ptr<MockUsbService> CreateMockService() override {
582 return make_scoped_ptr(new MockUsbServiceForCheckingTraits());
586 class AndroidBreakingUsbTest : public AndroidUsbDiscoveryTest {
587 protected:
588 scoped_ptr<MockUsbService> CreateMockService() override {
589 return make_scoped_ptr(new MockBreakingUsbService());
593 class AndroidNoConfigUsbTest : public AndroidUsbDiscoveryTest {
594 protected:
595 scoped_ptr<MockUsbService> CreateMockService() override {
596 return make_scoped_ptr(new MockNoConfigUsbService());
600 class MockListListener : public DevToolsAndroidBridge::DeviceListListener {
601 public:
602 MockListListener(DevToolsAndroidBridge* adb_bridge,
603 const base::Closure& callback)
604 : adb_bridge_(adb_bridge),
605 callback_(callback) {
608 void DeviceListChanged(
609 const DevToolsAndroidBridge::RemoteDevices& devices) override {
610 if (devices.size() > 0) {
611 for (const auto& device : devices) {
612 if (device->is_connected()) {
613 ASSERT_EQ(kDeviceModel, device->model());
614 ASSERT_EQ(kDeviceSerial, device->serial());
615 adb_bridge_->RemoveDeviceListListener(this);
616 callback_.Run();
617 break;
623 DevToolsAndroidBridge* adb_bridge_;
624 base::Closure callback_;
627 class MockCountListener : public DevToolsAndroidBridge::DeviceCountListener {
628 public:
629 explicit MockCountListener(DevToolsAndroidBridge* adb_bridge)
630 : adb_bridge_(adb_bridge), invoked_(0) {}
632 void DeviceCountChanged(int count) override {
633 ++invoked_;
634 adb_bridge_->RemoveDeviceCountListener(this);
635 Shutdown();
638 void Shutdown() { base::MessageLoop::current()->Quit(); }
640 DevToolsAndroidBridge* adb_bridge_;
641 int invoked_;
644 class MockCountListenerWithReAdd : public MockCountListener {
645 public:
646 explicit MockCountListenerWithReAdd(
647 DevToolsAndroidBridge* adb_bridge)
648 : MockCountListener(adb_bridge),
649 readd_count_(2) {
652 void DeviceCountChanged(int count) override {
653 ++invoked_;
654 adb_bridge_->RemoveDeviceCountListener(this);
655 if (readd_count_ > 0) {
656 readd_count_--;
657 adb_bridge_->AddDeviceCountListener(this);
658 adb_bridge_->RemoveDeviceCountListener(this);
659 adb_bridge_->AddDeviceCountListener(this);
660 } else {
661 Shutdown();
665 int readd_count_;
668 class MockCountListenerWithReAddWhileQueued : public MockCountListener {
669 public:
670 MockCountListenerWithReAddWhileQueued(
671 DevToolsAndroidBridge* adb_bridge)
672 : MockCountListener(adb_bridge),
673 readded_(false) {
676 void DeviceCountChanged(int count) override {
677 ++invoked_;
678 if (!readded_) {
679 readded_ = true;
680 base::ThreadTaskRunnerHandle::Get()->PostTask(
681 FROM_HERE, base::Bind(&MockCountListenerWithReAddWhileQueued::ReAdd,
682 base::Unretained(this)));
683 } else {
684 adb_bridge_->RemoveDeviceCountListener(this);
685 Shutdown();
689 void ReAdd() {
690 adb_bridge_->RemoveDeviceCountListener(this);
691 adb_bridge_->AddDeviceCountListener(this);
694 bool readded_;
697 class MockCountListenerForCheckingTraits : public MockCountListener {
698 public:
699 MockCountListenerForCheckingTraits(
700 DevToolsAndroidBridge* adb_bridge)
701 : MockCountListener(adb_bridge),
702 step_(0) {
704 void DeviceCountChanged(int count) override {
705 switch (step_) {
706 case 0:
707 // Check for 0 devices when no devices present.
708 EXPECT_EQ(0, count);
709 break;
710 case 1:
711 // Check for 1 device when only android device present.
712 EXPECT_EQ(1, count);
713 break;
714 case 2:
715 // Check for 1 device when android and non-android devices present.
716 EXPECT_EQ(1, count);
717 break;
718 case 3:
719 // Check for 0 devices when only non-android devices present.
720 EXPECT_EQ(0, count);
721 adb_bridge_->RemoveDeviceCountListener(this);
722 Shutdown();
723 break;
724 default:
725 EXPECT_TRUE(false) << "Unknown step " << step_;
727 step_++;
730 int step_;
733 } // namespace
735 IN_PROC_BROWSER_TEST_F(AndroidUsbDiscoveryTest, TestDeviceDiscovery) {
736 MockListListener listener(adb_bridge_, runner_->QuitClosure());
737 adb_bridge_->AddDeviceListListener(&listener);
738 runner_->Run();
741 IN_PROC_BROWSER_TEST_F(AndroidBreakingUsbTest, TestDeviceBreaking) {
742 MockListListener listener(adb_bridge_, runner_->QuitClosure());
743 adb_bridge_->AddDeviceListListener(&listener);
744 runner_->Run();
747 IN_PROC_BROWSER_TEST_F(AndroidNoConfigUsbTest, TestDeviceNoConfig) {
748 MockListListener listener(adb_bridge_, runner_->QuitClosure());
749 adb_bridge_->AddDeviceListListener(&listener);
750 runner_->Run();
753 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest,
754 TestNoMultipleCallsRemoveInCallback) {
755 MockCountListener listener(adb_bridge_);
756 adb_bridge_->AddDeviceCountListener(&listener);
757 runner_->Run();
758 EXPECT_EQ(1, listener.invoked_);
759 EXPECT_EQ(listener.invoked_ - 1, scheduler_invoked_);
760 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
763 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest,
764 TestNoMultipleCallsRemoveAddInCallback) {
765 MockCountListenerWithReAdd listener(adb_bridge_);
766 adb_bridge_->AddDeviceCountListener(&listener);
767 runner_->Run();
768 EXPECT_EQ(3, listener.invoked_);
769 EXPECT_EQ(listener.invoked_ - 1, scheduler_invoked_);
770 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
773 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest,
774 TestNoMultipleCallsRemoveAddOnStart) {
775 MockCountListener listener(adb_bridge_);
776 adb_bridge_->AddDeviceCountListener(&listener);
777 adb_bridge_->RemoveDeviceCountListener(&listener);
778 adb_bridge_->AddDeviceCountListener(&listener);
779 runner_->Run();
780 EXPECT_EQ(1, listener.invoked_);
781 EXPECT_EQ(listener.invoked_ - 1, scheduler_invoked_);
782 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
785 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest,
786 TestNoMultipleCallsRemoveAddWhileQueued) {
787 MockCountListenerWithReAddWhileQueued listener(adb_bridge_);
788 adb_bridge_->AddDeviceCountListener(&listener);
789 runner_->Run();
790 EXPECT_EQ(2, listener.invoked_);
791 EXPECT_EQ(listener.invoked_ - 1, scheduler_invoked_);
792 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
795 IN_PROC_BROWSER_TEST_F(AndroidUsbTraitsTest, TestDeviceCounting) {
796 MockCountListenerForCheckingTraits listener(adb_bridge_);
797 adb_bridge_->AddDeviceCountListener(&listener);
798 runner_->Run();