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 2014 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_HID_HID_DEVICE_MANAGER_H_
#define EXTENSIONS_BROWSER_API_HID_HID_DEVICE_MANAGER_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/values.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_event_histogram_value.h"
#include "extensions/common/api/hid.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/hid.mojom.h"
namespace device {
class HidDeviceFilter;
}
namespace extensions {
class Extension;
// This class maps devices enumerated by device::HidManager to resource IDs
// returned by the chrome.hid API.
class HidDeviceManager : public BrowserContextKeyedAPI,
public device::mojom::HidManagerClient,
public EventRouter::Observer {
public:
using GetApiDevicesCallback = base::OnceCallback<void(base::Value::List)>;
using ConnectCallback = device::mojom::HidManager::ConnectCallback;
explicit HidDeviceManager(content::BrowserContext* context);
HidDeviceManager(const HidDeviceManager&) = delete;
HidDeviceManager& operator=(const HidDeviceManager&) = delete;
~HidDeviceManager() override;
// BrowserContextKeyedAPI implementation.
static BrowserContextKeyedAPIFactory<HidDeviceManager>* GetFactoryInstance();
// Convenience method to get the HidDeviceManager for a profile.
static HidDeviceManager* Get(content::BrowserContext* context) {
return BrowserContextKeyedAPIFactory<HidDeviceManager>::Get(context);
}
// Enumerates available devices, taking into account the permissions held by
// the given extension and the filters provided. The provided callback will
// be posted to the calling thread's task runner with a list of device info
// objects.
void GetApiDevices(const Extension* extension,
const std::vector<device::HidDeviceFilter>& filters,
GetApiDevicesCallback callback);
const device::mojom::HidDeviceInfo* GetDeviceInfo(int resource_id);
void Connect(const std::string& device_guid, ConnectCallback callback);
// Checks if `extension` has permission to open `device_info`. Set
// `update_last_used` to update the timestamp in the DevicePermissionsManager.
bool HasPermission(const Extension* extension,
const device::mojom::HidDeviceInfo& device_info,
bool update_last_used);
// Lazily perform an initial enumeration and set client to HidManager when
// the first API customer makes a request or registers an event listener.
virtual void LazyInitialize();
// Allows tests to override where this class binds a HidManager receiver.
using HidManagerBinder = base::RepeatingCallback<void(
mojo::PendingReceiver<device::mojom::HidManager>)>;
static void OverrideHidManagerBinderForTesting(HidManagerBinder binder);
private:
friend class BrowserContextKeyedAPIFactory<HidDeviceManager>;
typedef std::map<int, device::mojom::HidDeviceInfoPtr>
ResourceIdToDeviceInfoMap;
typedef std::map<std::string, int> DeviceIdToResourceIdMap;
struct GetApiDevicesParams;
// KeyedService:
void Shutdown() override;
// BrowserContextKeyedAPI:
static const char* service_name() { return "HidDeviceManager"; }
static const bool kServiceHasOwnInstanceInIncognito = true;
// EventRouter::Observer:
void OnListenerAdded(const EventListenerInfo& details) override;
// device::mojom::HidManagerClient implementation:
void DeviceAdded(device::mojom::HidDeviceInfoPtr device) override;
void DeviceRemoved(device::mojom::HidDeviceInfoPtr device) override;
void DeviceChanged(device::mojom::HidDeviceInfoPtr device) override;
// Builds a list of device info objects representing the currently enumerated
// devices, taking into account the permissions held by the given extension
// and the filters provided.
base::Value::List CreateApiDeviceList(
const Extension* extension,
const std::vector<device::HidDeviceFilter>& filters);
void OnEnumerationComplete(
std::vector<device::mojom::HidDeviceInfoPtr> devices);
void DispatchEvent(events::HistogramValue histogram_value,
const std::string& event_name,
base::Value::List event_args,
const device::mojom::HidDeviceInfo& device_info);
base::ThreadChecker thread_checker_;
raw_ptr<content::BrowserContext> browser_context_ = nullptr;
raw_ptr<EventRouter> event_router_ = nullptr;
bool initialized_ = false;
mojo::Remote<device::mojom::HidManager> hid_manager_;
mojo::AssociatedReceiver<device::mojom::HidManagerClient> receiver_{this};
bool enumeration_ready_ = false;
std::vector<std::unique_ptr<GetApiDevicesParams>> pending_enumerations_;
int next_resource_id_ = 0;
ResourceIdToDeviceInfoMap devices_;
DeviceIdToResourceIdMap resource_ids_;
base::WeakPtrFactory<HidDeviceManager> weak_factory_{this};
};
template <>
void BrowserContextKeyedAPIFactory<
HidDeviceManager>::DeclareFactoryDependencies();
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_HID_HID_DEVICE_MANAGER_H_
|