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
content / browser / generic_sensor / web_contents_sensor_provider_proxy.h [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_GENERIC_SENSOR_WEB_CONTENTS_SENSOR_PROVIDER_PROXY_H_
#define CONTENT_BROWSER_GENERIC_SENSOR_WEB_CONTENTS_SENSOR_PROVIDER_PROXY_H_
#include <memory>
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "content/common/content_export.h"
#include "content/public/browser/web_contents_user_data.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/cpp/generic_sensor/sensor_reading.h"
#include "services/device/public/mojom/sensor.mojom-shared.h"
#include "services/device/public/mojom/sensor_provider.mojom.h"
namespace content {
class ScopedVirtualSensorForDevTools;
// This proxy acts as a gatekeeper to the real sensor provider so that this
// proxy can intercept sensor requests and allow or deny them based on
// the permission statuses retrieved from a permission controller.
//
// Its mojo::ReceiverSet references FrameSensorProviderProxy to retrieve
// RenderHostInformation used in the checks
class CONTENT_EXPORT WebContentsSensorProviderProxy final
: public WebContentsUserData<WebContentsSensorProviderProxy> {
public:
class Observer : public base::CheckedObserver {
public:
virtual void OnMojoConnectionError() = 0;
};
WebContentsSensorProviderProxy(const WebContentsSensorProviderProxy&) =
delete;
WebContentsSensorProviderProxy& operator=(
const WebContentsSensorProviderProxy&) = delete;
~WebContentsSensorProviderProxy() override;
static WebContentsSensorProviderProxy* GetOrCreate(WebContents*);
void GetSensor(device::mojom::SensorType type,
device::mojom::SensorProvider::GetSensorCallback callback);
// Attempts to create and return a ScopedVirtualSensorForDevTools instance of
// a given |type| if one does not exist (and therefore a |type| virtual
// sensor has not been created), otherwise returns nullptr.
std::unique_ptr<ScopedVirtualSensorForDevTools>
CreateVirtualSensorForDevTools(
device::mojom::SensorType type,
device::mojom::VirtualSensorMetadataPtr metadata);
// Allows tests to override how this class binds its backing SensorProvider
// endpoint.
using SensorProviderBinder = base::RepeatingCallback<void(
mojo::PendingReceiver<device::mojom::SensorProvider>)>;
static void OverrideSensorProviderBinderForTesting(
SensorProviderBinder binder);
void AddObserver(Observer*);
void RemoveObserver(Observer*);
private:
friend class ScopedVirtualSensorForDevTools;
explicit WebContentsSensorProviderProxy(content::WebContents* web_contents);
// These functions as wrappers around their Mojo counterparts. They are
// supposed to be called via ScopedVirtualSensorForDevTools.
void CreateVirtualSensor(
device::mojom::SensorType type,
device::mojom::VirtualSensorMetadataPtr metadata,
device::mojom::SensorProvider::CreateVirtualSensorCallback callback);
void UpdateVirtualSensor(
device::mojom::SensorType type,
const device::SensorReading& reading,
device::mojom::SensorProvider::UpdateVirtualSensorCallback callback);
void RemoveVirtualSensor(
device::mojom::SensorType type,
device::mojom::SensorProvider::RemoveVirtualSensorCallback callback);
void GetVirtualSensorInformation(
device::mojom::SensorType type,
device::mojom::SensorProvider::GetVirtualSensorInformationCallback
callback);
void OnConnectionError();
void EnsureDeviceServiceConnection();
mojo::Remote<device::mojom::SensorProvider> sensor_provider_;
base::ObserverList<Observer, /*check_empty=*/true> observers_;
base::flat_set<device::mojom::SensorType> virtual_sensor_types_for_devtools_;
friend WebContentsUserData;
WEB_CONTENTS_USER_DATA_KEY_DECL();
};
// This class is the public interface to the virtual-sensor related Mojo calls.
// Instances are created by
// WebContentsSensorProviderProxy::CreateVirtualSensorForDevTools().
//
// RemoveVirtualSensor() is invoked automatically on destruction, and
// CreateVirtualSensor() is invoked automatically on creation.
class CONTENT_EXPORT ScopedVirtualSensorForDevTools {
public:
~ScopedVirtualSensorForDevTools();
void GetVirtualSensorInformation(
device::mojom::SensorProvider::GetVirtualSensorInformationCallback
callback);
void UpdateVirtualSensor(
const device::SensorReading& reading,
device::mojom::SensorProvider::UpdateVirtualSensorCallback callback);
private:
friend class WebContentsSensorProviderProxy;
ScopedVirtualSensorForDevTools(
device::mojom::SensorType type,
device::mojom::VirtualSensorMetadataPtr metadata,
WebContentsSensorProviderProxy*);
device::mojom::SensorType type_;
// From https://crrev.com/c/4770864: WebContentsSensorProviderProxy is
// associated to a WebContents and will not get destroyed before the WC, and
// on the DevTools side the contract is the
// DevToolsAgentHost::DisconnectWebContents() will be called before the WC is
// destroyed.
raw_ptr<WebContentsSensorProviderProxy> web_contents_sensor_provider_;
};
} // namespace content
#endif // CONTENT_BROWSER_GENERIC_SENSOR_WEB_CONTENTS_SENSOR_PROVIDER_PROXY_H_