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.
7 #include "base/containers/scoped_ptr_hash_map.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/devtools/device/adb/mock_adb_server.h"
10 #include "chrome/browser/devtools/device/devtools_android_bridge.h"
11 #include "chrome/browser/devtools/device/usb/android_usb_device.h"
12 #include "chrome/browser/devtools/device/usb/usb_device_provider.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/test/base/in_process_browser_test.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/test/test_utils.h"
17 #include "device/usb/usb_descriptors.h"
18 #include "device/usb/usb_device.h"
19 #include "device/usb/usb_device_handle.h"
20 #include "device/usb/usb_service.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 using content::BrowserThread
;
24 using device::UsbConfigDescriptor
;
25 using device::UsbDevice
;
26 using device::UsbDeviceHandle
;
27 using device::UsbEndpointDescriptor
;
28 using device::UsbEndpointDirection
;
29 using device::UsbInterfaceDescriptor
;
30 using device::UsbService
;
31 using device::UsbSynchronizationType
;
32 using device::UsbTransferCallback
;
33 using device::UsbTransferType
;
34 using device::UsbUsageType
;
38 struct NoConfigTraits
{
39 static const int kClass
= 0xff;
40 static const int kSubclass
= 0x42;
41 static const int kProtocol
= 0x1;
42 static const bool kBreaks
= false;
43 static const bool kConfigured
= false;
46 struct AndroidTraits
{
47 static const int kClass
= 0xff;
48 static const int kSubclass
= 0x42;
49 static const int kProtocol
= 0x1;
50 static const bool kBreaks
= false;
51 static const bool kConfigured
= true;
54 struct NonAndroidTraits
{
55 static const int kClass
= 0xf0;
56 static const int kSubclass
= 0x42;
57 static const int kProtocol
= 0x2;
58 static const bool kBreaks
= false;
59 static const bool kConfigured
= true;
62 struct BreakingAndroidTraits
{
63 static const int kClass
= 0xff;
64 static const int kSubclass
= 0x42;
65 static const int kProtocol
= 0x1;
66 static const bool kBreaks
= true;
67 static const bool kConfigured
= true;
70 const uint32 kMaxPayload
= 4096;
71 const uint32 kVersion
= 0x01000000;
73 const char kDeviceManufacturer
[] = "Test Manufacturer";
74 const char kDeviceModel
[] = "Nexus 6";
75 const char kDeviceSerial
[] = "01498B321301A00A";
80 class MockLocalSocket
: public MockAndroidConnection::Delegate
{
82 using Callback
= base::Callback
<void(int command
,
83 const std::string
& message
)>;
85 MockLocalSocket(const Callback
& callback
,
86 const std::string
& serial
,
87 const std::string
& command
)
88 : callback_(callback
),
89 connection_(new MockAndroidConnection(this, serial
, command
)) {
92 void Receive(const std::string
& data
) {
93 connection_
->Receive(data
);
97 void SendSuccess(const std::string
& message
) override
{
99 callback_
.Run(AdbMessage::kCommandWRTE
, message
);
102 void SendRaw(const std::string
& message
) override
{
103 callback_
.Run(AdbMessage::kCommandWRTE
, message
);
106 void Close() override
{
107 callback_
.Run(AdbMessage::kCommandCLSE
, std::string());
111 scoped_ptr
<MockAndroidConnection
> connection_
;
115 class MockUsbDeviceHandle
: public UsbDeviceHandle
{
117 explicit MockUsbDeviceHandle(MockUsbDevice
<T
>* device
)
119 remaining_body_length_(0),
120 last_local_socket_(0),
124 virtual scoped_refptr
<UsbDevice
> GetDevice() const override
{
128 virtual void Close() override
{ device_
= nullptr; }
130 bool SetConfiguration(int configuration_value
) override
{ return true; }
132 bool ClaimInterface(int interface_number
) override
{
133 if (device_
->claimed_interfaces_
.find(interface_number
) !=
134 device_
->claimed_interfaces_
.end())
137 device_
->claimed_interfaces_
.insert(interface_number
);
141 bool ReleaseInterface(int interface_number
) override
{
142 if (device_
->claimed_interfaces_
.find(interface_number
) ==
143 device_
->claimed_interfaces_
.end())
146 device_
->claimed_interfaces_
.erase(interface_number
);
150 virtual bool SetInterfaceAlternateSetting(int interface_number
,
151 int alternate_setting
) override
{
155 virtual bool ResetDevice() override
{ return true; }
156 bool GetStringDescriptor(uint8_t string_id
,
157 base::string16
* content
) override
{
161 // Async IO. Can be called on any thread.
162 virtual void ControlTransfer(UsbEndpointDirection direction
,
163 TransferRequestType request_type
,
164 TransferRecipient recipient
,
168 net::IOBuffer
* buffer
,
170 unsigned int timeout
,
171 const UsbTransferCallback
& callback
) override
{}
173 virtual void BulkTransfer(UsbEndpointDirection direction
,
175 net::IOBuffer
* buffer
,
177 unsigned int timeout
,
178 const UsbTransferCallback
& callback
) override
{
179 if (direction
== device::USB_DIRECTION_OUTBOUND
) {
180 if (remaining_body_length_
== 0) {
181 std::vector
<uint32
> header(6);
182 memcpy(&header
[0], buffer
->data(), length
);
183 current_message_
.reset(
184 new AdbMessage(header
[0], header
[1], header
[2], std::string()));
185 remaining_body_length_
= header
[3];
186 uint32 magic
= header
[5];
187 if ((current_message_
->command
^ 0xffffffff) != magic
) {
188 DCHECK(false) << "Header checksum error";
192 DCHECK(current_message_
.get());
193 current_message_
->body
+= std::string(buffer
->data(), length
);
194 remaining_body_length_
-= length
;
197 if (remaining_body_length_
== 0) {
201 device::UsbTransferStatus status
=
202 broken_
? device::USB_TRANSFER_ERROR
: device::USB_TRANSFER_COMPLETED
;
203 base::MessageLoop::current()->PostTask(
205 base::Bind(callback
, status
, scoped_refptr
<net::IOBuffer
>(), 0));
207 } else if (direction
== device::USB_DIRECTION_INBOUND
) {
208 queries_
.push(Query(callback
, make_scoped_refptr(buffer
), length
));
214 void append(D data
) {
215 std::copy(reinterpret_cast<char*>(&data
),
216 (reinterpret_cast<char*>(&data
)) + sizeof(D
),
217 std::back_inserter(output_buffer_
));
220 // Copied from AndroidUsbDevice::Checksum
221 uint32
Checksum(const std::string
& data
) {
222 unsigned char* x
= (unsigned char*)data
.data();
223 int count
= data
.length();
230 void ProcessIncoming() {
231 DCHECK(current_message_
.get());
232 switch (current_message_
->command
) {
233 case AdbMessage::kCommandCNXN
: {
234 WriteResponse(kVersion
,
236 AdbMessage::kCommandCNXN
,
237 "device::ro.product.name=SampleProduct;ro.product.model="
238 "SampleModel;ro.product.device=SampleDevice;");
241 case AdbMessage::kCommandCLSE
: {
243 current_message_
->arg0
,
244 AdbMessage::kCommandCLSE
,
246 local_sockets_
.erase(current_message_
->arg0
);
249 case AdbMessage::kCommandWRTE
: {
254 auto it
= local_sockets_
.find(current_message_
->arg0
);
255 if (it
== local_sockets_
.end())
258 DCHECK(current_message_
->arg1
!= 0);
259 WriteResponse(current_message_
->arg1
,
260 current_message_
->arg0
,
261 AdbMessage::kCommandOKAY
,
263 it
->second
->Receive(current_message_
->body
);
266 case AdbMessage::kCommandOPEN
: {
267 DCHECK(current_message_
->arg1
== 0);
268 DCHECK(current_message_
->arg0
!= 0);
269 std::string response
;
270 WriteResponse(++last_local_socket_
,
271 current_message_
->arg0
,
272 AdbMessage::kCommandOKAY
,
275 current_message_
->arg0
,
276 make_scoped_ptr(new MockLocalSocket(
277 base::Bind(&MockUsbDeviceHandle::WriteResponse
,
278 base::Unretained(this),
280 current_message_
->arg0
),
282 current_message_
->body
.substr(
283 0, current_message_
->body
.size() - 1))));
293 void WriteResponse(int arg0
, int arg1
, int command
, const std::string
& body
) {
297 bool add_zero
= !body
.empty() && (command
!= AdbMessage::kCommandWRTE
);
298 append(static_cast<uint32
>(body
.size() + (add_zero
? 1 : 0)));
299 append(Checksum(body
));
300 append(command
^ 0xffffffff);
301 std::copy(body
.begin(), body
.end(), std::back_inserter(output_buffer_
));
303 output_buffer_
.push_back(0);
308 void ProcessQueries() {
309 if (!queries_
.size())
311 Query query
= queries_
.front();
313 base::MessageLoop::current()->PostTask(
315 base::Bind(query
.callback
,
316 device::USB_TRANSFER_ERROR
,
321 if (query
.size
> output_buffer_
.size())
325 std::copy(output_buffer_
.begin(),
326 output_buffer_
.begin() + query
.size
,
327 query
.buffer
->data());
328 output_buffer_
.erase(output_buffer_
.begin(),
329 output_buffer_
.begin() + query
.size
);
330 base::MessageLoop::current()->PostTask(
332 base::Bind(query
.callback
,
333 device::USB_TRANSFER_COMPLETED
,
339 virtual void InterruptTransfer(UsbEndpointDirection direction
,
341 net::IOBuffer
* buffer
,
343 unsigned int timeout
,
344 const UsbTransferCallback
& callback
) override
{
347 virtual void IsochronousTransfer(
348 UsbEndpointDirection direction
,
350 net::IOBuffer
* buffer
,
352 unsigned int packets
,
353 unsigned int packet_length
,
354 unsigned int timeout
,
355 const UsbTransferCallback
& callback
) override
{}
358 virtual ~MockUsbDeviceHandle() {}
361 UsbTransferCallback callback
;
362 scoped_refptr
<net::IOBuffer
> buffer
;
365 Query(UsbTransferCallback callback
,
366 scoped_refptr
<net::IOBuffer
> buffer
,
368 : callback(callback
), buffer(buffer
), size(size
) {};
371 scoped_refptr
<MockUsbDevice
<T
> > device_
;
372 uint32 remaining_body_length_
;
373 scoped_ptr
<AdbMessage
> current_message_
;
374 std::vector
<char> output_buffer_
;
375 std::queue
<Query
> queries_
;
376 base::ScopedPtrHashMap
<int, MockLocalSocket
> local_sockets_
;
377 int last_local_socket_
;
382 class MockUsbDevice
: public UsbDevice
{
384 MockUsbDevice() : UsbDevice(0, 0, 0) {
385 UsbEndpointDescriptor bulk_in
;
386 bulk_in
.address
= 0x81;
387 bulk_in
.direction
= device::USB_DIRECTION_INBOUND
;
388 bulk_in
.maximum_packet_size
= 512;
389 bulk_in
.transfer_type
= device::USB_TRANSFER_BULK
;
391 UsbEndpointDescriptor bulk_out
;
392 bulk_out
.address
= 0x01;
393 bulk_out
.direction
= device::USB_DIRECTION_OUTBOUND
;
394 bulk_out
.maximum_packet_size
= 512;
395 bulk_out
.transfer_type
= device::USB_TRANSFER_BULK
;
397 UsbInterfaceDescriptor interface_desc
;
398 interface_desc
.interface_number
= 0;
399 interface_desc
.alternate_setting
= 0;
400 interface_desc
.interface_class
= T::kClass
;
401 interface_desc
.interface_subclass
= T::kSubclass
;
402 interface_desc
.interface_protocol
= T::kProtocol
;
403 interface_desc
.endpoints
.push_back(bulk_in
);
404 interface_desc
.endpoints
.push_back(bulk_out
);
406 config_desc_
.interfaces
.push_back(interface_desc
);
409 virtual scoped_refptr
<UsbDeviceHandle
> Open() override
{
410 return new MockUsbDeviceHandle
<T
>(this);
413 virtual const UsbConfigDescriptor
* GetConfiguration() override
{
414 return T::kConfigured
? &config_desc_
: nullptr;
417 virtual bool GetManufacturer(base::string16
* manufacturer
) override
{
418 *manufacturer
= base::UTF8ToUTF16(kDeviceManufacturer
);
422 virtual bool GetProduct(base::string16
* product
) override
{
423 *product
= base::UTF8ToUTF16(kDeviceModel
);
427 virtual bool GetSerialNumber(base::string16
* serial
) override
{
428 *serial
= base::UTF8ToUTF16(kDeviceSerial
);
432 virtual bool Close(scoped_refptr
<UsbDeviceHandle
> handle
) override
{
436 #if defined(OS_CHROMEOS)
437 // On ChromeOS, if an interface of a claimed device is not claimed, the
438 // permission broker can change the owner of the device so that the unclaimed
439 // interfaces can be used. If this argument is missing, permission broker will
440 // not be used and this method fails if the device is claimed.
441 virtual void RequestUsbAccess(
443 const base::Callback
<void(bool success
)>& callback
) override
{
446 #endif // OS_CHROMEOS
448 std::set
<int> claimed_interfaces_
;
451 virtual ~MockUsbDevice() {}
454 UsbConfigDescriptor config_desc_
;
457 class MockUsbService
: public UsbService
{
460 devices_
.push_back(new MockUsbDevice
<AndroidTraits
>());
463 scoped_refptr
<UsbDevice
> GetDeviceById(uint32 unique_id
) override
{
468 void GetDevices(std::vector
<scoped_refptr
<UsbDevice
>>* devices
) override
{
469 STLClearObject(devices
);
470 std::copy(devices_
.begin(), devices_
.end(), back_inserter(*devices
));
473 std::vector
<scoped_refptr
<UsbDevice
> > devices_
;
476 class MockBreakingUsbService
: public UsbService
{
478 scoped_refptr
<UsbDevice
> GetDeviceById(uint32 unique_id
) override
{
483 void GetDevices(std::vector
<scoped_refptr
<UsbDevice
>>* devices
) override
{
484 STLClearObject(devices
);
485 devices
->push_back(new MockUsbDevice
<BreakingAndroidTraits
>());
489 class MockNoConfigUsbService
: public UsbService
{
491 scoped_refptr
<UsbDevice
> GetDeviceById(uint32 unique_id
) override
{
496 void GetDevices(std::vector
<scoped_refptr
<UsbDevice
>>* devices
) override
{
497 STLClearObject(devices
);
498 devices
->push_back(new MockUsbDevice
<AndroidTraits
>());
499 devices
->push_back(new MockUsbDevice
<NoConfigTraits
>());
503 class MockUsbServiceForCheckingTraits
: public UsbService
{
505 MockUsbServiceForCheckingTraits() : step_(0) {}
507 scoped_refptr
<UsbDevice
> GetDeviceById(uint32 unique_id
) override
{
512 void GetDevices(std::vector
<scoped_refptr
<UsbDevice
>>* devices
) override
{
513 STLClearObject(devices
);
514 // This switch should be kept in sync with
515 // AndroidUsbBrowserTest::DeviceCountChanged.
522 devices
->push_back(new MockUsbDevice
<AndroidTraits
>());
525 // Android and non-android device.
526 devices
->push_back(new MockUsbDevice
<AndroidTraits
>());
527 devices
->push_back(new MockUsbDevice
<NonAndroidTraits
>());
530 // Non-android device.
531 devices
->push_back(new MockUsbDevice
<NonAndroidTraits
>());
541 class DevToolsAndroidBridgeWarmUp
542 : public DevToolsAndroidBridge::DeviceCountListener
{
544 DevToolsAndroidBridgeWarmUp(base::Closure closure
,
545 DevToolsAndroidBridge
* adb_bridge
)
546 : closure_(closure
), adb_bridge_(adb_bridge
) {}
548 void DeviceCountChanged(int count
) override
{
549 adb_bridge_
->RemoveDeviceCountListener(this);
553 base::Closure closure_
;
554 DevToolsAndroidBridge
* adb_bridge_
;
557 class AndroidUsbDiscoveryTest
: public InProcessBrowserTest
{
559 AndroidUsbDiscoveryTest()
560 : scheduler_invoked_(0) {
562 void SetUpOnMainThread() override
{
563 scoped_refptr
<content::MessageLoopRunner
> runner
=
564 new content::MessageLoopRunner
;
566 BrowserThread::PostTaskAndReply(
569 base::Bind(&AndroidUsbDiscoveryTest::SetUpService
, this),
570 runner
->QuitClosure());
574 DevToolsAndroidBridge::Factory::GetForProfile(browser()->profile());
576 adb_bridge_
->set_task_scheduler_for_test(base::Bind(
577 &AndroidUsbDiscoveryTest::ScheduleDeviceCountRequest
, this));
579 scoped_refptr
<UsbDeviceProvider
> provider
=
580 new UsbDeviceProvider(browser()->profile());
582 AndroidDeviceManager::DeviceProviders providers
;
583 providers
.push_back(provider
);
584 adb_bridge_
->set_device_providers_for_test(providers
);
585 runner_
= new content::MessageLoopRunner
;
588 void ScheduleDeviceCountRequest(const base::Closure
& request
) {
589 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
590 scheduler_invoked_
++;
591 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, request
);
594 virtual void SetUpService() {
595 UsbService::SetInstanceForTest(new MockUsbService());
598 void TearDownOnMainThread() override
{
599 scoped_refptr
<content::MessageLoopRunner
> runner
=
600 new content::MessageLoopRunner
;
601 UsbService
* service
= nullptr;
602 BrowserThread::PostTaskAndReply(
605 base::Bind(&UsbService::SetInstanceForTest
, service
),
606 runner
->QuitClosure());
610 scoped_refptr
<content::MessageLoopRunner
> runner_
;
611 DevToolsAndroidBridge
* adb_bridge_
;
612 int scheduler_invoked_
;
615 class AndroidUsbCountTest
: public AndroidUsbDiscoveryTest
{
617 void SetUpOnMainThread() override
{
618 AndroidUsbDiscoveryTest::SetUpOnMainThread();
619 DevToolsAndroidBridgeWarmUp
warmup(runner_
->QuitClosure(), adb_bridge_
);
620 adb_bridge_
->AddDeviceCountListener(&warmup
);
622 runner_
= new content::MessageLoopRunner
;
626 class AndroidUsbTraitsTest
: public AndroidUsbDiscoveryTest
{
628 void SetUpService() override
{
629 UsbService::SetInstanceForTest(new MockUsbServiceForCheckingTraits());
633 class AndroidBreakingUsbTest
: public AndroidUsbDiscoveryTest
{
635 void SetUpService() override
{
636 UsbService::SetInstanceForTest(new MockBreakingUsbService());
640 class AndroidNoConfigUsbTest
: public AndroidUsbDiscoveryTest
{
642 void SetUpService() override
{
643 UsbService::SetInstanceForTest(new MockNoConfigUsbService());
647 class MockListListener
: public DevToolsAndroidBridge::DeviceListListener
{
649 MockListListener(DevToolsAndroidBridge
* adb_bridge
,
650 const base::Closure
& callback
)
651 : adb_bridge_(adb_bridge
),
652 callback_(callback
) {
655 void DeviceListChanged(
656 const DevToolsAndroidBridge::RemoteDevices
& devices
) override
{
657 if (devices
.size() > 0) {
658 for (const auto& device
: devices
) {
659 if (device
->is_connected()) {
660 ASSERT_EQ(kDeviceModel
, device
->model());
661 ASSERT_EQ(kDeviceSerial
, device
->serial());
662 adb_bridge_
->RemoveDeviceListListener(this);
670 DevToolsAndroidBridge
* adb_bridge_
;
671 base::Closure callback_
;
674 class MockCountListener
: public DevToolsAndroidBridge::DeviceCountListener
{
676 explicit MockCountListener(DevToolsAndroidBridge
* adb_bridge
)
677 : adb_bridge_(adb_bridge
),
682 void DeviceCountChanged(int count
) override
{
684 adb_bridge_
->RemoveDeviceCountListener(this);
689 ShutdownOnUIThread();
692 void ShutdownOnUIThread() {
693 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
694 if (reposts_left_
-- == 0) {
695 base::MessageLoop::current()->Quit();
697 BrowserThread::PostTask(
700 base::Bind(&MockCountListener::ShutdownOnFileThread
,
701 base::Unretained(this)));
705 void ShutdownOnFileThread() {
706 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
707 BrowserThread::PostTask(BrowserThread::UI
,
709 base::Bind(&MockCountListener::ShutdownOnUIThread
,
710 base::Unretained(this)));
713 DevToolsAndroidBridge
* adb_bridge_
;
718 class MockCountListenerWithReAdd
: public MockCountListener
{
720 explicit MockCountListenerWithReAdd(
721 DevToolsAndroidBridge
* adb_bridge
)
722 : MockCountListener(adb_bridge
),
726 void DeviceCountChanged(int count
) override
{
728 adb_bridge_
->RemoveDeviceCountListener(this);
729 if (readd_count_
> 0) {
731 adb_bridge_
->AddDeviceCountListener(this);
732 adb_bridge_
->RemoveDeviceCountListener(this);
733 adb_bridge_
->AddDeviceCountListener(this);
742 class MockCountListenerWithReAddWhileQueued
: public MockCountListener
{
744 MockCountListenerWithReAddWhileQueued(
745 DevToolsAndroidBridge
* adb_bridge
)
746 : MockCountListener(adb_bridge
),
750 void DeviceCountChanged(int count
) override
{
754 base::MessageLoop::current()->PostTask(
756 base::Bind(&MockCountListenerWithReAddWhileQueued::ReAdd
,
757 base::Unretained(this)));
759 adb_bridge_
->RemoveDeviceCountListener(this);
765 adb_bridge_
->RemoveDeviceCountListener(this);
766 adb_bridge_
->AddDeviceCountListener(this);
772 class MockCountListenerForCheckingTraits
: public MockCountListener
{
774 MockCountListenerForCheckingTraits(
775 DevToolsAndroidBridge
* adb_bridge
)
776 : MockCountListener(adb_bridge
),
779 void DeviceCountChanged(int count
) override
{
782 // Check for 0 devices when no devices present.
786 // Check for 1 device when only android device present.
790 // Check for 1 device when android and non-android devices present.
794 // Check for 0 devices when only non-android devices present.
796 adb_bridge_
->RemoveDeviceCountListener(this);
800 EXPECT_TRUE(false) << "Unknown step " << step_
;
810 IN_PROC_BROWSER_TEST_F(AndroidUsbDiscoveryTest
, TestDeviceDiscovery
) {
811 MockListListener
listener(adb_bridge_
, runner_
->QuitClosure());
812 adb_bridge_
->AddDeviceListListener(&listener
);
816 IN_PROC_BROWSER_TEST_F(AndroidBreakingUsbTest
, TestDeviceBreaking
) {
817 MockListListener
listener(adb_bridge_
, runner_
->QuitClosure());
818 adb_bridge_
->AddDeviceListListener(&listener
);
822 IN_PROC_BROWSER_TEST_F(AndroidNoConfigUsbTest
, TestDeviceNoConfig
) {
823 MockListListener
listener(adb_bridge_
, runner_
->QuitClosure());
824 adb_bridge_
->AddDeviceListListener(&listener
);
828 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest
,
829 TestNoMultipleCallsRemoveInCallback
) {
830 MockCountListener
listener(adb_bridge_
);
831 adb_bridge_
->AddDeviceCountListener(&listener
);
833 EXPECT_EQ(1, listener
.invoked_
);
834 EXPECT_EQ(listener
.invoked_
- 1, scheduler_invoked_
);
837 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest
,
838 TestNoMultipleCallsRemoveAddInCallback
) {
839 MockCountListenerWithReAdd
listener(adb_bridge_
);
840 adb_bridge_
->AddDeviceCountListener(&listener
);
842 EXPECT_EQ(3, listener
.invoked_
);
843 EXPECT_EQ(listener
.invoked_
- 1, scheduler_invoked_
);
846 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest
,
847 TestNoMultipleCallsRemoveAddOnStart
) {
848 MockCountListener
listener(adb_bridge_
);
849 adb_bridge_
->AddDeviceCountListener(&listener
);
850 adb_bridge_
->RemoveDeviceCountListener(&listener
);
851 adb_bridge_
->AddDeviceCountListener(&listener
);
853 EXPECT_EQ(1, listener
.invoked_
);
854 EXPECT_EQ(listener
.invoked_
- 1, scheduler_invoked_
);
857 IN_PROC_BROWSER_TEST_F(AndroidUsbCountTest
,
858 TestNoMultipleCallsRemoveAddWhileQueued
) {
859 MockCountListenerWithReAddWhileQueued
listener(adb_bridge_
);
860 adb_bridge_
->AddDeviceCountListener(&listener
);
862 EXPECT_EQ(2, listener
.invoked_
);
863 EXPECT_EQ(listener
.invoked_
- 1, scheduler_invoked_
);
866 IN_PROC_BROWSER_TEST_F(AndroidUsbTraitsTest
, TestDeviceCounting
) {
867 MockCountListenerForCheckingTraits
listener(adb_bridge_
);
868 adb_bridge_
->AddDeviceCountListener(&listener
);