blob: 41cdb64694d44c8ac8d1c9f17aeb03d2af64294b [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_USB_USB_TEST_UTILS_H_
#define CONTENT_BROWSER_USB_USB_TEST_UTILS_H_
#include <memory>
#include <vector>
#include "base/containers/span.h"
#include "base/observer_list.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/usb_chooser.h"
#include "content/public/browser/usb_delegate.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/device/public/mojom/usb_device.mojom-forward.h"
#include "services/device/public/mojom/usb_enumeration_options.mojom-forward.h"
#include "services/device/public/mojom/usb_manager.mojom-forward.h"
#include "services/device/public/mojom/usb_manager_client.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/mojom/usb/web_usb_service.mojom.h"
#include "url/origin.h"
namespace content {
class RenderFrameHost;
// A mock UsbDeviceManagerClient implementation that can be used to listen for
// USB device connection events.
class MockDeviceManagerClient : public device::mojom::UsbDeviceManagerClient {
public:
MockDeviceManagerClient();
MockDeviceManagerClient(MockDeviceManagerClient&) = delete;
MockDeviceManagerClient& operator=(MockDeviceManagerClient&) = delete;
~MockDeviceManagerClient() override;
void Bind(
mojo::PendingAssociatedReceiver<device::mojom::UsbDeviceManagerClient>
receiver) {
receiver_.Bind(std::move(receiver));
}
mojo::PendingAssociatedRemote<device::mojom::UsbDeviceManagerClient>
CreateInterfacePtrAndBind() {
auto client = receiver_.BindNewEndpointAndPassRemote();
receiver_.set_disconnect_handler(base::BindOnce(
&MockDeviceManagerClient::OnConnectionError, base::Unretained(this)));
return client;
}
MOCK_METHOD(void, OnDeviceAdded, (device::mojom::UsbDeviceInfoPtr));
MOCK_METHOD(void, OnDeviceRemoved, (device::mojom::UsbDeviceInfoPtr));
MOCK_METHOD(void, ConnectionError, ());
void OnConnectionError() {
receiver_.reset();
ConnectionError();
}
private:
mojo::AssociatedReceiver<device::mojom::UsbDeviceManagerClient> receiver_{
this};
};
// A UsbDelegate implementation that can be mocked for tests.
class MockUsbDelegate : public UsbDelegate {
public:
MockUsbDelegate();
MockUsbDelegate(MockUsbDelegate&) = delete;
MockUsbDelegate& operator=(MockUsbDelegate&) = delete;
~MockUsbDelegate() override;
// Simulates opening the USB device chooser dialog and selecting an item. The
// chooser automatically selects the item returned by RunChooserInternal,
// which may be mocked. Returns `nullptr`. `options` is ignored.
std::unique_ptr<UsbChooser> RunChooser(
RenderFrameHost& frame,
blink::mojom::WebUsbRequestDeviceOptionsPtr options,
blink::mojom::WebUsbService::GetPermissionCallback callback) override;
void AddObserver(BrowserContext* browser_context,
Observer* observer) override;
void RemoveObserver(BrowserContext* browser_context,
Observer* observer) override;
// Simulate events from tests.
void OnDeviceAdded(const device::mojom::UsbDeviceInfo& device);
void OnDeviceRemoved(const device::mojom::UsbDeviceInfo& device);
void OnPermissionRevoked(const url::Origin& origin);
void OnDeviceManagerConnectionError();
MOCK_METHOD0(RunChooserInternal, device::mojom::UsbDeviceInfoPtr());
MOCK_METHOD4(AdjustProtectedInterfaceClasses,
void(BrowserContext*,
const url::Origin&,
RenderFrameHost*,
std::vector<uint8_t>&));
MOCK_METHOD1(PageMayUseUsb, bool(Page&));
MOCK_METHOD2(CanRequestDevicePermission,
bool(BrowserContext*, const url::Origin&));
MOCK_METHOD3(RevokeDevicePermissionWebInitiated,
void(BrowserContext*,
const url::Origin&,
const device::mojom::UsbDeviceInfo&));
MOCK_METHOD2(GetDeviceInfo,
const device::mojom::UsbDeviceInfo*(BrowserContext*,
const std::string& guid));
MOCK_METHOD4(HasDevicePermission,
bool(BrowserContext*,
RenderFrameHost*,
const url::Origin&,
const device::mojom::UsbDeviceInfo&));
MOCK_METHOD2(GetDevices,
void(BrowserContext*,
blink::mojom::WebUsbService::GetDevicesCallback));
MOCK_METHOD5(GetDevice,
void(BrowserContext*,
const std::string&,
base::span<const uint8_t>,
mojo::PendingReceiver<device::mojom::UsbDevice>,
mojo::PendingRemote<device::mojom::UsbDeviceClient>));
MOCK_METHOD2(SetDeviceManagerForTesting,
void(RenderFrameHost&,
mojo::PendingRemote<device::mojom::UsbDeviceManager>
device_manager));
MOCK_METHOD1(IsServiceWorkerAllowedForOrigin, bool(const url::Origin&));
MOCK_METHOD2(IncrementConnectionCount,
void(BrowserContext*, const url::Origin&));
MOCK_METHOD2(DecrementConnectionCount,
void(BrowserContext*, const url::Origin&));
const base::ObserverList<Observer>& observer_list() { return observer_list_; }
void SetAssertBrowserContext(bool assert_browser_context);
private:
base::ObserverList<UsbDelegate::Observer> observer_list_;
bool assert_browser_context_ = false;
};
template <typename SuperClass>
class UsbTestContentBrowserClientBase : public SuperClass {
public:
MockUsbDelegate& delegate() { return delegate_; }
// ContentBrowserClient:
UsbDelegate* GetUsbDelegate() override { return &delegate_; }
private:
testing::NiceMock<MockUsbDelegate> delegate_;
};
using UsbTestContentBrowserClient =
UsbTestContentBrowserClientBase<ContentBrowserClient>;
} // namespace content
#endif // CONTENT_BROWSER_USB_USB_TEST_UTILS_H_