blob: 3f5cd759a02ecaef49d29be25f273d60eb7117b8 [file]
// 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.
#include "chrome/browser/sharing/sharing_handler_registry_impl.h"
#include "base/feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/glic/public/glic_keyed_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sharing/browser_actuator/browser_actuator_message_handler.h"
#include "chrome/browser/sharing/glic_experimental_triggering/glic_experimental_triggering_message_handler.h"
#include "chrome/browser/sharing/one_time_tokens/one_time_token_sharing_handler.h"
#include "chrome/browser/sharing/optimization_guide/optimization_guide_message_handler.h"
#include "chrome/common/chrome_features.h"
#include "components/browser_actuator/public/features.h"
#include "components/one_time_tokens/core/browser/gmail_otp_backend.h"
#include "components/optimization_guide/core/optimization_guide_features.h"
#include "components/sharing_message/ack_message_handler.h"
#include "components/sharing_message/ping_message_handler.h"
#include "components/sharing_message/sharing_device_registration.h"
#include "components/sharing_message/sharing_message_handler.h"
#include "components/sharing_message/sharing_message_sender.h"
#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/sharing/sms/sms_fetch_request_handler.h"
#endif // BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.h"
#endif
namespace {
bool IsBrowserActuatorForGlicEnabled() {
return base::FeatureList::IsEnabled(browser_actuator::kBrowserActuator) &&
base::FeatureList::IsEnabled(
browser_actuator::
kEnableBrowserActuatorForGlicExperimentalTriggering);
}
std::set<components_sharing_message::SharingMessage::PayloadCase>
GetBrowserActuatorPayloads(Profile* profile) {
std::set<components_sharing_message::SharingMessage::PayloadCase> payloads;
if (!base::FeatureList::IsEnabled(browser_actuator::kBrowserActuator)) {
return payloads;
}
// Generic transport messages always go to BrowserActuatorMessageHandler.
payloads.insert(
components_sharing_message::SharingMessage::kActuatorDownstreamMessage);
// Route kGlicExperimentalTriggering based on whether BrowserActuator is
// taking over handling for it.
if (IsBrowserActuatorForGlicEnabled() &&
glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile,
/*create=*/true)) {
payloads.insert(components_sharing_message::SharingMessage::
kGlicExperimentalTriggering);
}
return payloads;
}
} // namespace
SharingHandlerRegistryImpl::SharingHandlerRegistryImpl(
Profile* profile,
SharingDeviceRegistration* sharing_device_registration,
SharingMessageSender* message_sender,
SharingDeviceSource* device_source,
content::SmsFetcher* sms_fetcher,
one_time_tokens::GmailOtpBackend* gmail_otp_backend) {
AddSharingHandler(std::make_unique<PingMessageHandler>(),
{components_sharing_message::SharingMessage::kPingMessage});
AddSharingHandler(std::make_unique<AckMessageHandler>(message_sender),
{components_sharing_message::SharingMessage::kAckMessage});
#if BUILDFLAG(IS_ANDROID)
if (sharing_device_registration->IsSmsFetcherSupported()) {
AddSharingHandler(
std::make_unique<SmsFetchRequestHandler>(device_source, sms_fetcher),
{components_sharing_message::SharingMessage::kSmsFetchRequest});
}
#endif // BUILDFLAG(IS_ANDROID)
// Profile can be null in tests.
if (optimization_guide::features::IsPushNotificationsEnabled() &&
optimization_guide::features::IsOptimizationHintsEnabled() && profile) {
AddSharingHandler(OptimizationGuideMessageHandler::Create(profile),
{components_sharing_message::SharingMessage::
kOptimizationGuidePushNotification});
}
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
BUILDFLAG(IS_CHROMEOS)
if (sharing_device_registration->IsRemoteCopySupported()) {
AddSharingHandler(
std::make_unique<RemoteCopyMessageHandler>(profile),
{components_sharing_message::SharingMessage::kRemoteCopyMessage});
}
#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) ||
// BUILDFLAG(IS_CHROMEOS)
#if !BUILDFLAG(IS_ANDROID)
if (sharing_device_registration
->IsOneTimeTokenBackendNotificationSupported()) {
AddSharingHandler(
std::make_unique<OneTimeTokenSharingHandler>(gmail_otp_backend),
{components_sharing_message::SharingMessage::
kOneTimeTokenBackendNotification});
}
#endif // !BUILDFLAG(IS_ANDROID)
// Route kGlicExperimentalTriggering to legacy handler if BrowserActuator is
// not taking over handling for it.
if (!IsBrowserActuatorForGlicEnabled() &&
base::FeatureList::IsEnabled(features::kGlicExperimentalTriggering) &&
glic::GlicKeyedServiceFactory::GetGlicKeyedService(profile,
/*create=*/true)) {
AddSharingHandler(
std::make_unique<GlicExperimentalTriggeringMessageHandler>(
profile, message_sender),
{components_sharing_message::SharingMessage::
kGlicExperimentalTriggering});
}
std::set<components_sharing_message::SharingMessage::PayloadCase>
browser_actuator_payloads = GetBrowserActuatorPayloads(profile);
if (!browser_actuator_payloads.empty()) {
AddSharingHandler(std::make_unique<BrowserActuatorMessageHandler>(profile),
browser_actuator_payloads);
}
}
SharingHandlerRegistryImpl::~SharingHandlerRegistryImpl() = default;
SharingMessageHandler* SharingHandlerRegistryImpl::GetSharingHandler(
components_sharing_message::SharingMessage::PayloadCase payload_case) {
auto it = handler_map_.find(payload_case);
if (it != handler_map_.end()) {
return it->second;
}
auto extra_it = extra_handler_map_.find(payload_case);
if (extra_it != extra_handler_map_.end()) {
return extra_it->second.get();
}
return nullptr;
}
void SharingHandlerRegistryImpl::AddSharingHandler(
std::unique_ptr<SharingMessageHandler> handler,
std::set<components_sharing_message::SharingMessage::PayloadCase>
payload_cases) {
DCHECK(handler) << "Received request to add null handler";
for (const auto& payload_case : payload_cases) {
DCHECK(payload_case !=
components_sharing_message::SharingMessage::PAYLOAD_NOT_SET)
<< "Incorrect payload type specified for handler";
DCHECK(!handler_map_.count(payload_case)) << "Handler already exists";
handler_map_[payload_case] = handler.get();
}
handlers_.push_back(std::move(handler));
}
void SharingHandlerRegistryImpl::RegisterSharingHandler(
std::unique_ptr<SharingMessageHandler> handler,
components_sharing_message::SharingMessage::PayloadCase payload_case) {
DCHECK(handler) << "Received request to add null handler";
DCHECK(!GetSharingHandler(payload_case));
DCHECK(payload_case !=
components_sharing_message::SharingMessage::PAYLOAD_NOT_SET)
<< "Incorrect payload type specified for handler";
extra_handler_map_[payload_case] = std::move(handler);
}
void SharingHandlerRegistryImpl::UnregisterSharingHandler(
components_sharing_message::SharingMessage::PayloadCase payload_case) {
extra_handler_map_.erase(payload_case);
}