File: hid_chooser_context.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (198 lines) | stat: -rw-r--r-- 8,182 bytes parent folder | download | duplicates (6)
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// 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 CHROME_BROWSER_HID_HID_CHOOSER_CONTEXT_H_
#define CHROME_BROWSER_HID_HID_CHOOSER_CONTEXT_H_

#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>

#include "base/containers/queue.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation_traits.h"
#include "chrome/browser/hid/web_view_chooser_context.h"
#include "components/permissions/object_permission_context_base.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"
#include "url/origin.h"

class Profile;

namespace base {
class Value;
}

// Manages the internal state and connection to the device service for the
// Human Interface Device (HID) chooser UI.
class HidChooserContext : public permissions::ObjectPermissionContextBase,
                          public device::mojom::HidManagerClient {
 public:
  // This observer can be used to be notified when HID devices are connected or
  // disconnected.
  class DeviceObserver : public base::CheckedObserver {
   public:
    virtual void OnDeviceAdded(const device::mojom::HidDeviceInfo&);
    virtual void OnDeviceRemoved(const device::mojom::HidDeviceInfo&);
    virtual void OnDeviceChanged(const device::mojom::HidDeviceInfo&);
    virtual void OnHidManagerConnectionError();

    // Called when the HidChooserContext is shutting down. Observers must remove
    // themselves before returning.
    virtual void OnHidChooserContextShutdown() = 0;
  };

  explicit HidChooserContext(Profile* profile);
  HidChooserContext(const HidChooserContext&) = delete;
  HidChooserContext& operator=(const HidChooserContext&) = delete;
  ~HidChooserContext() override;

  static base::Value::Dict DeviceInfoToValue(
      const device::mojom::HidDeviceInfo& device);

  // Returns a human-readable string identifier for |device|.
  static std::u16string DisplayNameFromDeviceInfo(
      const device::mojom::HidDeviceInfo& device);

  // Returns true if a persistent permission can be granted for |device|.
  static bool CanStorePersistentEntry(
      const device::mojom::HidDeviceInfo& device);

  // permissions::ObjectPermissionContextBase implementation:
  std::string GetKeyForObject(const base::Value::Dict& object) override;
  bool IsValidObject(const base::Value::Dict& object) override;
  // In addition these methods from ObjectPermissionContextBase are overridden
  // in order to expose ephemeral devices through the public interface.
  std::vector<std::unique_ptr<Object>> GetGrantedObjects(
      const url::Origin& origin) override;
  std::vector<std::unique_ptr<Object>> GetAllGrantedObjects() override;
  void RevokeObjectPermission(const url::Origin& origin,
                              const base::Value::Dict& object) override;
  std::u16string GetObjectDisplayName(const base::Value::Dict& object) override;

  // HID-specific interface for granting, revoking and checking permissions.
  void GrantDevicePermission(const url::Origin& origin,
                             const device::mojom::HidDeviceInfo& device,
                             const std::optional<url::Origin>&
                                 embedding_origin_of_web_view = std::nullopt);
  void RevokeDevicePermission(const url::Origin& origin,
                              const device::mojom::HidDeviceInfo& device,
                              const std::optional<url::Origin>&
                                  embedding_origin_of_web_view = std::nullopt);
  bool HasDevicePermission(const url::Origin& origin,
                           const device::mojom::HidDeviceInfo& device,
                           const std::optional<url::Origin>&
                               embedding_origin_of_web_view = std::nullopt);

  // Returns true if `origin` is allowed to access FIDO reports.
  bool IsFidoAllowedForOrigin(const url::Origin& origin);

  // Returns true if `device` is a known FIDO U2F security key. Origins allowed
  // to access FIDO reports are also allowed to access the non-FIDO collections
  // of known security keys.
  bool IsKnownSecurityKey(const device::mojom::HidDeviceInfo& device);

  // For ScopedObservation, see ScopedObservationTraits below.
  void AddDeviceObserver(DeviceObserver* observer);
  void RemoveDeviceObserver(DeviceObserver* observer);

  // Forward HidManager::GetDevices.
  void GetDevices(device::mojom::HidManager::GetDevicesCallback callback);

  // Only call this if you're sure |devices_| has been initialized before-hand.
  // The returned raw pointer is owned by |devices_| and will be destroyed when
  // the device is removed.
  const device::mojom::HidDeviceInfo* GetDeviceInfo(const std::string& guid);

  device::mojom::HidManager* GetHidManager();

  // Sets |manager| as the HidManager and registers this context as a
  // HidManagerClient. Calls |callback| with the set of enumerated devices once
  // the client is registered and the initial enumeration is complete.
  void SetHidManagerForTesting(
      mojo::PendingRemote<device::mojom::HidManager> manager,
      device::mojom::HidManager::GetDevicesCallback callback);

  void PermissionForWebViewChanged();
  void PermissionForWebViewRevoked(const url::Origin& web_view_origin);

  base::WeakPtr<HidChooserContext> AsWeakPtr();

  // KeyedService:
  void Shutdown() override;

 private:
  // device::mojom::HidManagerClient implementation:
  void DeviceAdded(device::mojom::HidDeviceInfoPtr device_info) override;
  void DeviceRemoved(device::mojom::HidDeviceInfoPtr device_info) override;
  void DeviceChanged(device::mojom::HidDeviceInfoPtr device_info) override;

  void EnsureHidManagerConnection();
  void SetUpHidManagerConnection(
      mojo::PendingRemote<device::mojom::HidManager> manager);
  void InitDeviceList(std::vector<device::mojom::HidDeviceInfoPtr> devices);
  void OnHidManagerInitializedForTesting(
      device::mojom::HidManager::GetDevicesCallback callback,
      std::vector<device::mojom::HidDeviceInfoPtr> devices);
  void OnHidManagerConnectionError();
  bool CanApplyPolicy();

  // HID-specific interface for revoking device permissions.
  void RevokePersistentDevicePermission(
      const url::Origin& origin,
      const device::mojom::HidDeviceInfo& device);
  void RevokeEphemeralDevicePermission(
      const url::Origin& origin,
      const device::mojom::HidDeviceInfo& device);

  // This raw pointer is safe because instances of this class are created by
  // HidChooserContextFactory as KeyedServices that will be destroyed when the
  // Profile object is destroyed.
  const raw_ptr<Profile> profile_;

  bool is_initialized_ = false;
  base::queue<device::mojom::HidManager::GetDevicesCallback>
      pending_get_devices_requests_;

  // Tracks the set of devices to which an origin has access to.
  std::map<url::Origin, std::set<std::string>> ephemeral_devices_;

  // Map from device GUID to device info.
  std::map<std::string, device::mojom::HidDeviceInfoPtr> devices_;

  WebViewChooserContext web_view_chooser_context_{this};

  mojo::Remote<device::mojom::HidManager> hid_manager_;
  mojo::AssociatedReceiver<device::mojom::HidManagerClient> client_receiver_{
      this};
  base::ObserverList<DeviceObserver> device_observer_list_;

  base::WeakPtrFactory<HidChooserContext> weak_factory_{this};
};

namespace base {

template <>
struct ScopedObservationTraits<HidChooserContext,
                               HidChooserContext::DeviceObserver> {
  static void AddObserver(HidChooserContext* source,
                          HidChooserContext::DeviceObserver* observer) {
    source->AddDeviceObserver(observer);
  }
  static void RemoveObserver(HidChooserContext* source,
                             HidChooserContext::DeviceObserver* observer) {
    source->RemoveDeviceObserver(observer);
  }
};

}  // namespace base

#endif  // CHROME_BROWSER_HID_HID_CHOOSER_CONTEXT_H_