blob: 6ce8c665bb764c2e6494d1719c13f6966d66ba05 [file] [log] [blame]
// Copyright 2021 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/device_posture/device_posture_provider_impl.h"
#include "base/functional/bind.h"
#include "content/browser/device_posture/device_posture_platform_provider.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "mojo/public/cpp/bindings/remote_set.h"
namespace content {
// static
DevicePostureProviderImpl* DevicePostureProviderImpl::GetOrCreate(
WebContents* web_contents) {
CHECK(web_contents);
WebContentsUserData<DevicePostureProviderImpl>::CreateForWebContents(
web_contents);
return WebContentsUserData<DevicePostureProviderImpl>::FromWebContents(
web_contents);
}
DevicePostureProviderImpl::DevicePostureProviderImpl(WebContents* web_contents)
: WebContentsUserData<DevicePostureProviderImpl>(*web_contents) {
platform_provider_ = DevicePosturePlatformProvider::Create(web_contents);
// We need to listen to disconnections so that if there is nobody interested
// in posture changes we can shutdown the native backends.
posture_clients_.set_disconnect_handler(base::BindRepeating(
&DevicePostureProviderImpl::OnRemoteDisconnect, base::Unretained(this)));
}
DevicePostureProviderImpl::~DevicePostureProviderImpl() = default;
void DevicePostureProviderImpl::Bind(
mojo::PendingReceiver<blink::mojom::DevicePostureProvider> receiver) {
receivers_.Add(this, std::move(receiver));
}
DevicePosturePlatformProvider* DevicePostureProviderImpl::platform_provider()
const {
return platform_provider_.get();
}
void DevicePostureProviderImpl::AddListenerAndGetCurrentPosture(
mojo::PendingRemote<blink::mojom::DevicePostureClient> client,
AddListenerAndGetCurrentPostureCallback callback) {
if (posture_clients_.empty()) {
platform_provider_->AddObserver(this);
}
posture_clients_.Add(std::move(client));
blink::mojom::DevicePostureType posture =
platform_provider_->GetDevicePosture();
std::move(callback).Run(posture);
}
void DevicePostureProviderImpl::OverrideDevicePostureForEmulation(
blink::mojom::DevicePostureType emulated_posture) {
// Notify the related clients about the new posture.
is_posture_emulated_ = true;
for (auto& client : posture_clients_) {
client->OnPostureChanged(emulated_posture);
}
}
void DevicePostureProviderImpl::DisableDevicePostureOverrideForEmulation() {
// If the posture is not being overridden, bail out earlier to avoid
// needlessly calling OnPostureChanged().
if (!is_posture_emulated_) {
return;
}
// Restore the original posture from the platform.
is_posture_emulated_ = false;
for (auto& client : posture_clients_) {
client->OnPostureChanged(platform_provider_->GetDevicePosture());
}
}
void DevicePostureProviderImpl::OnDevicePostureChanged(
const blink::mojom::DevicePostureType& posture) {
// If we receive a posture change from the platform but we're emulating it we
// shouldn't notify the clients.
if (is_posture_emulated_) {
return;
}
for (auto& client : posture_clients_) {
client->OnPostureChanged(posture);
}
}
void DevicePostureProviderImpl::OnRemoteDisconnect(
mojo::RemoteSetElementId id) {
if (posture_clients_.empty()) {
// We're not interested in receiving posture changes.
platform_provider_->RemoveObserver(this);
}
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(DevicePostureProviderImpl);
} // namespace content