blob: ee59e8b5b415f57bc804a34e30c30bbb0b761453 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// 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 <vector>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/scoped_observer.h"
#include "base/threading/thread_checker.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_binding.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:
typedef base::Callback<void(std::unique_ptr<base::ListValue>)>
GetApiDevicesCallback;
using ConnectCallback = device::mojom::HidManager::ConnectCallback;
explicit HidDeviceManager(content::BrowserContext* context);
~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,
const GetApiDevicesCallback& callback);
// Converts a list of device::mojom::HidDeviceInfo objects into a value that
// can be returned through the API.
std::unique_ptr<base::ListValue> GetApiDevicesFromList(
std::vector<device::mojom::HidDeviceInfoPtr> devices);
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();
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;
static const bool kServiceIsNULLWhileTesting = 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;
// 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.
std::unique_ptr<base::ListValue> 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,
std::unique_ptr<base::ListValue> event_args,
const device::mojom::HidDeviceInfo& device_info);
base::ThreadChecker thread_checker_;
content::BrowserContext* browser_context_ = nullptr;
EventRouter* event_router_ = nullptr;
bool initialized_ = false;
device::mojom::HidManagerPtr hid_manager_;
mojo::AssociatedBinding<device::mojom::HidManagerClient> binding_;
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_;
DISALLOW_COPY_AND_ASSIGN(HidDeviceManager);
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_HID_HID_DEVICE_MANAGER_H_