| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/web_applications/web_app_protocol_handler_manager.h" |
| |
| #include "base/containers/contains.h" |
| #include "chrome/browser/custom_handlers/protocol_handler_registry.h" |
| #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/web_applications/web_app.h" |
| #include "chrome/browser/web_applications/web_app_protocol_handler_registration.h" |
| #include "chrome/browser/web_applications/web_app_registrar.h" |
| #include "third_party/blink/public/common/security/protocol_handler_security_level.h" |
| |
| namespace web_app { |
| |
| WebAppProtocolHandlerManager::WebAppProtocolHandlerManager(Profile* profile) |
| : app_registrar_(nullptr), profile_(profile) {} |
| |
| WebAppProtocolHandlerManager::~WebAppProtocolHandlerManager() = default; |
| |
| void WebAppProtocolHandlerManager::SetSubsystems(WebAppRegistrar* registrar) { |
| app_registrar_ = registrar; |
| } |
| |
| void WebAppProtocolHandlerManager::Start() { |
| DCHECK(app_registrar_); |
| } |
| |
| absl::optional<GURL> WebAppProtocolHandlerManager::TranslateProtocolUrl( |
| const AppId& app_id, |
| const GURL& protocol_url) const { |
| std::vector<ProtocolHandler> handlers = GetAppProtocolHandlers(app_id); |
| |
| for (const auto& handler : handlers) { |
| if (handler.protocol() == protocol_url.scheme()) { |
| return handler.TranslateUrl(protocol_url); |
| } |
| } |
| |
| return absl::nullopt; |
| } |
| |
| std::vector<ProtocolHandler> WebAppProtocolHandlerManager::GetHandlersFor( |
| const std::string& protocol) const { |
| std::vector<ProtocolHandler> protocol_handlers; |
| |
| for (const auto& app_id : app_registrar_->GetAppIds()) { |
| const std::vector<ProtocolHandler> handlers = |
| GetAppProtocolHandlers(app_id); |
| for (const auto& handler : handlers) { |
| if (handler.protocol() == protocol) |
| protocol_handlers.push_back(handler); |
| } |
| } |
| |
| return protocol_handlers; |
| } |
| |
| std::vector<apps::ProtocolHandlerInfo> |
| WebAppProtocolHandlerManager::GetAppProtocolHandlerInfos( |
| const std::string& app_id) const { |
| const WebApp* web_app = app_registrar_->GetAppById(app_id); |
| |
| if (!web_app) |
| return {}; |
| |
| std::vector<apps::ProtocolHandlerInfo> protocol_handlers_infos; |
| for (const auto& handler_info : web_app->protocol_handlers()) { |
| if (!base::Contains(web_app->disallowed_launch_protocols(), |
| handler_info.protocol)) { |
| protocol_handlers_infos.push_back(handler_info); |
| } |
| } |
| |
| return protocol_handlers_infos; |
| } |
| |
| std::vector<ProtocolHandler> |
| WebAppProtocolHandlerManager::GetAppProtocolHandlers( |
| const AppId& app_id) const { |
| std::vector<apps::ProtocolHandlerInfo> infos = |
| GetAppProtocolHandlerInfos(app_id); |
| |
| std::vector<ProtocolHandler> protocol_handlers; |
| for (const auto& info : infos) { |
| ProtocolHandler handler = ProtocolHandler::CreateWebAppProtocolHandler( |
| info.protocol, GURL(info.url), app_id); |
| protocol_handlers.push_back(handler); |
| } |
| |
| return protocol_handlers; |
| } |
| |
| std::vector<ProtocolHandler> |
| WebAppProtocolHandlerManager::GetAllowedHandlersForProtocol( |
| const std::string& protocol) const { |
| std::vector<ProtocolHandler> protocol_handlers; |
| |
| for (const WebApp& web_app : app_registrar_->GetApps()) { |
| web_app::AppId app_id = web_app.app_id(); |
| |
| if (!app_registrar_->IsAllowedLaunchProtocol(app_id, protocol)) |
| continue; |
| |
| for (const auto& info : web_app.protocol_handlers()) { |
| if (info.protocol != protocol) |
| continue; |
| |
| ProtocolHandler handler = ProtocolHandler::CreateWebAppProtocolHandler( |
| info.protocol, GURL(info.url), app_id); |
| protocol_handlers.push_back(handler); |
| } |
| } |
| |
| return protocol_handlers; |
| } |
| |
| std::vector<ProtocolHandler> |
| WebAppProtocolHandlerManager::GetDisallowedHandlersForProtocol( |
| const std::string& protocol) const { |
| std::vector<ProtocolHandler> protocol_handlers; |
| |
| for (const WebApp& web_app : app_registrar_->GetApps()) { |
| web_app::AppId app_id = web_app.app_id(); |
| |
| if (!app_registrar_->IsDisallowedLaunchProtocol(app_id, protocol)) |
| continue; |
| |
| for (const auto& info : web_app.protocol_handlers()) { |
| if (info.protocol != protocol) |
| continue; |
| |
| ProtocolHandler handler = ProtocolHandler::CreateWebAppProtocolHandler( |
| info.protocol, GURL(info.url), app_id); |
| protocol_handlers.push_back(handler); |
| } |
| } |
| |
| return protocol_handlers; |
| } |
| |
| void WebAppProtocolHandlerManager::RegisterOsProtocolHandlers( |
| const AppId& app_id, |
| base::OnceCallback<void(bool)> callback) { |
| if (!app_registrar_->IsLocallyInstalled(app_id)) { |
| std::move(callback).Run(true); |
| return; |
| } |
| const std::vector<apps::ProtocolHandlerInfo> handlers = |
| GetAppProtocolHandlerInfos(app_id); |
| if (handlers.empty()) { |
| std::move(callback).Run(true); |
| return; |
| } |
| RegisterProtocolHandlersWithOs(app_id, |
| app_registrar_->GetAppShortName(app_id), |
| profile_, handlers, std::move(callback)); |
| } |
| |
| void WebAppProtocolHandlerManager::UnregisterOsProtocolHandlers( |
| const AppId& app_id, |
| base::OnceCallback<void(bool)> callback) { |
| UnregisterProtocolHandlersWithOs(app_id, profile_, std::move(callback)); |
| } |
| |
| } // namespace web_app |