| // 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); | |
| } |