#ifndef EXTENSIONS_BROWSER_API_USB_USB_DEVICE_MANAGER_H_
#define EXTENSIONS_BROWSER_API_USB_USB_DEVICE_MANAGER_H_
#include <map>
#include <string>
#include <vector>
#include "base/containers/queue.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "build/build_config.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/event_router.h"
#include "extensions/common/api/usb.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 "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/usb_manager.mojom.h"
#include "services/device/public/mojom/usb_manager_client.mojom.h"
namespace extensions {
class UsbDeviceManager : public BrowserContextKeyedAPI,
public EventRouter::Observer,
public device::mojom::UsbDeviceManagerClient {
public:
explicit UsbDeviceManager(content::BrowserContext* context);
~UsbDeviceManager() override;
UsbDeviceManager(const UsbDeviceManager&) = delete;
UsbDeviceManager& operator=(const UsbDeviceManager&) = delete;
static UsbDeviceManager* Get(content::BrowserContext* browser_context);
static BrowserContextKeyedAPIFactory<UsbDeviceManager>* GetFactoryInstance();
class Observer : public base::CheckedObserver {
public:
virtual void OnDeviceAdded(const device::mojom::UsbDeviceInfo&);
virtual void OnDeviceRemoved(const device::mojom::UsbDeviceInfo&);
virtual void OnDeviceManagerConnectionError();
};
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
int GetIdFromGuid(const std::string& guid);
bool GetGuidFromId(int id, std::string* guid);
void GetApiDevice(const device::mojom::UsbDeviceInfo& device_in,
api::usb::Device* device_out);
void GetDevices(device::mojom::UsbDeviceManager::GetDevicesCallback callback);
void GetDevice(
const std::string& guid,
mojo::PendingReceiver<device::mojom::UsbDevice> device_receiver);
const device::mojom::UsbDeviceInfo* GetDeviceInfo(const std::string& guid);
bool UpdateActiveConfig(const std::string& guid, uint8_t config_value);
#if BUILDFLAG(IS_CHROMEOS)
void CheckAccess(
const std::string& guid,
device::mojom::UsbDeviceManager::CheckAccessCallback callback);
#endif
void EnsureConnectionWithDeviceManager();
void SetDeviceManagerForTesting(
mojo::PendingRemote<device::mojom::UsbDeviceManager> fake_device_manager);
private:
friend class BrowserContextKeyedAPIFactory<UsbDeviceManager>;
static const char* service_name() { return "UsbDeviceManager"; }
static const bool kServiceHasOwnInstanceInIncognito = true;
void Shutdown() override;
void OnListenerAdded(const EventListenerInfo& details) override;
void OnDeviceAdded(device::mojom::UsbDeviceInfoPtr device_info) override;
void OnDeviceRemoved(device::mojom::UsbDeviceInfoPtr device_info) override;
void SetUpDeviceManagerConnection();
void InitDeviceList(std::vector<device::mojom::UsbDeviceInfoPtr> devices);
void OnDeviceManagerConnectionError();
void DispatchEvent(const std::string& event_name,
const device::mojom::UsbDeviceInfo& device_info);
const raw_ptr<content::BrowserContext> browser_context_;
int next_id_ = 0;
std::map<std::string, int> guid_to_id_map_;
std::map<int, std::string> id_to_guid_map_;
bool is_initialized_ = false;
base::queue<device::mojom::UsbDeviceManager::GetDevicesCallback>
pending_get_devices_requests_;
std::map<std::string, device::mojom::UsbDeviceInfoPtr> devices_;
mojo::Remote<device::mojom::UsbDeviceManager> device_manager_;
mojo::AssociatedReceiver<device::mojom::UsbDeviceManagerClient>
client_receiver_{this};
base::ObserverList<Observer> observer_list_;
base::WeakPtrFactory<UsbDeviceManager> weak_factory_{this};
};
template <>
void BrowserContextKeyedAPIFactory<
UsbDeviceManager>::DeclareFactoryDependencies();
}
#endif