1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#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 {
// A BrowserContext-scoped object which is registered as an observer of the
// EventRouter and UsbDeviceManager in order to manage the connection to the
// Device Service and generate device add/remove events.
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);
// BrowserContextKeyedAPI implementation.
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);
// Returns an ID for this device GUID. If the GUID is unknown to the
// UsbGuidMap a new ID is generated for it.
int GetIdFromGuid(const std::string& guid);
// Looks up a device GUID for a given extensions USB device ID. If the ID is
// unknown (e.g., the corresponding device was unplugged), this returns
// `false`; otherwise it returns `true`.
bool GetGuidFromId(int id, std::string* guid);
// Populates an instance of the chrome.usb.Device object from the given
// device.
void GetApiDevice(const device::mojom::UsbDeviceInfo& device_in,
api::usb::Device* device_out);
// Forward UsbDeviceManager methods.
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 // BUILDFLAG(IS_CHROMEOS)
void EnsureConnectionWithDeviceManager();
void SetDeviceManagerForTesting(
mojo::PendingRemote<device::mojom::UsbDeviceManager> fake_device_manager);
private:
friend class BrowserContextKeyedAPIFactory<UsbDeviceManager>;
// BrowserContextKeyedAPI implementation.
static const char* service_name() { return "UsbDeviceManager"; }
static const bool kServiceHasOwnInstanceInIncognito = true;
// KeyedService implementation.
void Shutdown() override;
// EventRouter::Observer implementation.
void OnListenerAdded(const EventListenerInfo& details) override;
// UsbService::Observer implementation.
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();
// Broadcasts a device add or remove event for the given device.
void DispatchEvent(const std::string& event_name,
const device::mojom::UsbDeviceInfo& device_info);
const raw_ptr<content::BrowserContext> browser_context_;
// Legacy integer IDs are used in USB extensions API so we need to maps USB
// device GUIDs to integer IDs.
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_;
// Connection to `device_manager_instance_`.
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();
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_USB_USB_DEVICE_MANAGER_H_
|