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
|
// 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.
#include "content/browser/generic_sensor/web_contents_sensor_provider_proxy.h"
#include <algorithm>
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "content/browser/generic_sensor/frame_sensor_provider_proxy.h"
#include "content/public/browser/device_service.h"
using device::mojom::SensorCreationResult;
using device::mojom::SensorType;
namespace content {
namespace {
WebContentsSensorProviderProxy::SensorProviderBinder& GetBinderOverride() {
static base::NoDestructor<
WebContentsSensorProviderProxy::SensorProviderBinder>
binder;
return *binder;
}
} // namespace
ScopedVirtualSensorForDevTools::ScopedVirtualSensorForDevTools(
SensorType type,
device::mojom::VirtualSensorMetadataPtr metadata,
WebContentsSensorProviderProxy* web_contents_sensor_provider)
: type_(type), web_contents_sensor_provider_(web_contents_sensor_provider) {
web_contents_sensor_provider_->CreateVirtualSensor(
type_, std::move(metadata),
base::BindOnce([](device::mojom::CreateVirtualSensorResult result) {
switch (result) {
case device::mojom::CreateVirtualSensorResult::
kSensorTypeAlreadyOverridden:
NOTREACHED() << "WebContentsSensorProviderProxy::"
"CreateVirtualSensorForDevTools() should have "
"prevented this result";
case device::mojom::CreateVirtualSensorResult::kSuccess:
break;
}
}));
}
ScopedVirtualSensorForDevTools::~ScopedVirtualSensorForDevTools() {
web_contents_sensor_provider_->RemoveVirtualSensor(type_,
base::NullCallback());
}
void ScopedVirtualSensorForDevTools::GetVirtualSensorInformation(
device::mojom::SensorProvider::GetVirtualSensorInformationCallback
callback) {
web_contents_sensor_provider_->GetVirtualSensorInformation(
type_, std::move(callback));
}
void ScopedVirtualSensorForDevTools::UpdateVirtualSensor(
const device::SensorReading& reading,
device::mojom::SensorProvider::UpdateVirtualSensorCallback callback) {
web_contents_sensor_provider_->UpdateVirtualSensor(type_, reading,
std::move(callback));
}
WebContentsSensorProviderProxy::WebContentsSensorProviderProxy(
WebContents* web_contents)
: WebContentsUserData<WebContentsSensorProviderProxy>(*web_contents) {}
WebContentsSensorProviderProxy::~WebContentsSensorProviderProxy() = default;
// static
WebContentsSensorProviderProxy* WebContentsSensorProviderProxy::GetOrCreate(
WebContents* web_contents) {
WebContentsUserData<WebContentsSensorProviderProxy>::CreateForWebContents(
web_contents);
return WebContentsUserData<WebContentsSensorProviderProxy>::FromWebContents(
web_contents);
}
std::unique_ptr<ScopedVirtualSensorForDevTools>
WebContentsSensorProviderProxy::CreateVirtualSensorForDevTools(
SensorType type,
device::mojom::VirtualSensorMetadataPtr metadata) {
auto did_insert = virtual_sensor_types_for_devtools_.insert(type).second;
if (!did_insert) {
return nullptr;
}
return base::WrapUnique(
new ScopedVirtualSensorForDevTools(type, std::move(metadata), this));
}
// static
void WebContentsSensorProviderProxy::OverrideSensorProviderBinderForTesting(
SensorProviderBinder binder) {
GetBinderOverride() = std::move(binder);
}
void WebContentsSensorProviderProxy::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void WebContentsSensorProviderProxy::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
void WebContentsSensorProviderProxy::GetSensor(
SensorType type,
device::mojom::SensorProvider::GetSensorCallback callback) {
EnsureDeviceServiceConnection();
sensor_provider_->GetSensor(type, std::move(callback));
}
void WebContentsSensorProviderProxy::CreateVirtualSensor(
SensorType type,
device::mojom::VirtualSensorMetadataPtr metadata,
device::mojom::SensorProvider::CreateVirtualSensorCallback callback) {
// CHECK that this was called via CreateVirtualSensorForDevTools().
CHECK(base::Contains(virtual_sensor_types_for_devtools_, type));
EnsureDeviceServiceConnection();
sensor_provider_->CreateVirtualSensor(type, std::move(metadata),
std::move(callback));
}
void WebContentsSensorProviderProxy::UpdateVirtualSensor(
SensorType type,
const device::SensorReading& reading,
device::mojom::SensorProvider::UpdateVirtualSensorCallback callback) {
EnsureDeviceServiceConnection();
sensor_provider_->UpdateVirtualSensor(type, reading, std::move(callback));
}
void WebContentsSensorProviderProxy::RemoveVirtualSensor(
SensorType type,
device::mojom::SensorProvider::RemoveVirtualSensorCallback callback) {
virtual_sensor_types_for_devtools_.erase(type);
EnsureDeviceServiceConnection();
sensor_provider_->RemoveVirtualSensor(type, std::move(callback));
}
void WebContentsSensorProviderProxy::GetVirtualSensorInformation(
SensorType type,
device::mojom::SensorProvider::GetVirtualSensorInformationCallback
callback) {
EnsureDeviceServiceConnection();
sensor_provider_->GetVirtualSensorInformation(type, std::move(callback));
}
void WebContentsSensorProviderProxy::OnConnectionError() {
// FrameSensorProviderProxy instances need to be notified first so that the
// corresponding mojo::Receivers are cleared before the mojo::Remotes below.
for (auto& observer : observers_) {
observer.OnMojoConnectionError();
}
sensor_provider_.reset();
}
void WebContentsSensorProviderProxy::EnsureDeviceServiceConnection() {
if (sensor_provider_) {
return;
}
auto receiver = sensor_provider_.BindNewPipeAndPassReceiver();
sensor_provider_.set_disconnect_handler(
base::BindOnce(&WebContentsSensorProviderProxy::OnConnectionError,
base::Unretained(this)));
const auto& binder = GetBinderOverride();
if (binder) {
binder.Run(std::move(receiver));
} else {
GetDeviceService().BindSensorProvider(std::move(receiver));
}
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(WebContentsSensorProviderProxy);
} // namespace content
|