New list in SchemeRegistry to manage schemes with predefined handlers
In the ProtocolHandlerRegistry class we install some predefined default
handlers for 'mailto' and 'webcal" schemes. This is done only if the
CHROMEOS_ASH buildflag is activated, since only ChromeOS has predefined
handlers for now.
As part of this CL, we are going to enable in Lacros too the use of the pre-defined handlers for the mentioned schemes.
I'm planning to add predefined handlers for other protocols (eg, IPFS)
so this CL adds a generic logic to allow embedders define them in an
extensible way. I think the best approach is to allow the
SchemeRegistry to manage this and offer the chrome embedders the
possibility of specifying schemes with predefined handlers with the
implementation of the AddAdditionalSchemes method of the ContentClient
interface.
Bug: 1341949
Change-Id: I5167a15827ef3b64491e03cffd3eeec5ddc1b113
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3652049
Commit-Queue: Javier Fernandez <jfernandez@igalia.com>
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Reviewed-by: Dominick Ng <dominickn@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1026024}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
afb2aa0bf0
commit
d97a124d4f
chrome
components/custom_handlers
content
url
@ -307,6 +307,13 @@ void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
||||
schemes->csp_bypassing_schemes.push_back(extensions::kExtensionScheme);
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
schemes->predefined_handler_schemes.emplace_back(
|
||||
url::kMailToScheme, chrome::kChromeOSDefaultMailtoHandler);
|
||||
schemes->predefined_handler_schemes.emplace_back(
|
||||
url::kWebcalScheme, chrome::kChromeOSDefaultWebcalHandler);
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
schemes->local_schemes.push_back(content::kExternalFileScheme);
|
||||
#endif
|
||||
|
@ -308,6 +308,13 @@ const char kEnhancedPlaybackNotificationLearnMoreURL[] =
|
||||
"https://support.google.com/chrome/?p=mobile_protected_content";
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
const char kChromeOSDefaultMailtoHandler[] =
|
||||
"https://mail.google.com/mail/?extsrc=mailto&url=%s";
|
||||
const char kChromeOSDefaultWebcalHandler[] =
|
||||
"https://www.google.com/calendar/render?cid=%s";
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
const char kAccountManagerLearnMoreURL[] =
|
||||
"https://support.google.com/chromebook/?p=google_accounts";
|
||||
|
@ -277,6 +277,12 @@ extern const char kCwsEnhancedSafeBrowsingLearnMoreURL[];
|
||||
extern const char kEnhancedPlaybackNotificationLearnMoreURL[];
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
// Chrome OS default pre-defined custom handlers
|
||||
extern const char kChromeOSDefaultMailtoHandler[];
|
||||
extern const char kChromeOSDefaultWebcalHandler[];
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
// Help center URL for Chrome OS Account Manager.
|
||||
extern const char kAccountManagerLearnMoreURL[];
|
||||
|
@ -2624,12 +2624,14 @@ if (!is_android) {
|
||||
sources += [
|
||||
"../browser/chrome_multiprofile_startup_browsertest.cc",
|
||||
"../browser/enterprise/reporting/cloud_profile_reporting_browsertest.cc",
|
||||
"../browser/external_protocol/external_protocol_handler_browsertest.cc",
|
||||
"../browser/profiles/avatar_menu_browsertest.cc",
|
||||
"../browser/profiles/profile_window_browsertest.cc",
|
||||
"../browser/ui/views/accessibility/accessibility_focus_highlight_browsertest.cc",
|
||||
"../browser/ui/views/profiles/signin_view_controller_delegate_views_browsertest.cc",
|
||||
]
|
||||
if (!is_chromeos_lacros) {
|
||||
sources += [ "../browser/external_protocol/external_protocol_handler_browsertest.cc" ]
|
||||
}
|
||||
sources -= [
|
||||
"../browser/invalidation/profile_invalidation_provider_factory_browsertest.cc",
|
||||
"../browser/net/nss_context_chromeos_browsertest.cc",
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "components/user_prefs/user_prefs.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "url/url_util.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::ChildProcessSecurityPolicy;
|
||||
@ -68,11 +69,9 @@ std::unique_ptr<ProtocolHandlerRegistry> ProtocolHandlerRegistry::Create(
|
||||
auto registry =
|
||||
std::make_unique<ProtocolHandlerRegistry>(prefs, std::move(delegate));
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
// If installing defaults, they must be installed prior calling
|
||||
// InitProtocolSettings.
|
||||
registry->InstallDefaultsForChromeOS();
|
||||
#endif
|
||||
registry->InstallPredefinedHandlers();
|
||||
|
||||
registry->InitProtocolSettings();
|
||||
|
||||
@ -178,17 +177,11 @@ bool ProtocolHandlerRegistry::IsDefault(const ProtocolHandler& handler) const {
|
||||
return GetHandlerFor(handler.protocol()) == handler;
|
||||
}
|
||||
|
||||
void ProtocolHandlerRegistry::InstallDefaultsForChromeOS() {
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
// Only chromeos has default protocol handlers at this point.
|
||||
AddPredefinedHandler(ProtocolHandler::CreateProtocolHandler(
|
||||
"mailto",
|
||||
GURL("https://mail.google.com/mail/?extsrc=mailto&url=%s")));
|
||||
AddPredefinedHandler(ProtocolHandler::CreateProtocolHandler(
|
||||
"webcal", GURL("https://www.google.com/calendar/render?cid=%s")));
|
||||
#else
|
||||
NOTREACHED(); // this method should only ever be called in chromeos.
|
||||
#endif
|
||||
void ProtocolHandlerRegistry::InstallPredefinedHandlers() {
|
||||
for (const auto& [scheme, handler] : url::GetPredefinedHandlerSchemes()) {
|
||||
AddPredefinedHandler(
|
||||
ProtocolHandler::CreateProtocolHandler(scheme, GURL(handler)));
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolHandlerRegistry::InitProtocolSettings() {
|
||||
|
@ -227,7 +227,7 @@ class ProtocolHandlerRegistry : public KeyedService {
|
||||
|
||||
// Install default protocol handlers for chromeos which must be done
|
||||
// prior to calling InitProtocolSettings.
|
||||
void InstallDefaultsForChromeOS();
|
||||
void InstallPredefinedHandlers();
|
||||
|
||||
// Puts the given handler at the top of the list of handlers for its
|
||||
// protocol.
|
||||
|
@ -107,6 +107,9 @@ void RegisterContentSchemes(bool should_lock_registry) {
|
||||
url::EnableNonStandardSchemesForAndroidWebView();
|
||||
#endif
|
||||
|
||||
for (auto& [scheme, handler] : schemes.predefined_handler_schemes)
|
||||
url::AddPredefinedHandlerScheme(scheme.c_str(), handler.c_str());
|
||||
|
||||
schemes.service_worker_schemes.push_back(kIsolatedAppScheme);
|
||||
// This should only be registered if the
|
||||
// kEnableServiceWorkerForChromeUntrusted feature is enabled but checking
|
||||
|
@ -143,6 +143,11 @@ class CONTENT_EXPORT ContentClient {
|
||||
std::vector<std::string> empty_document_schemes;
|
||||
// Registers a URL scheme as extension scheme.
|
||||
std::vector<std::string> extension_schemes;
|
||||
// Registers a URL scheme with a predefined default custom handler.
|
||||
// This pair of strings must be normalized protocol handler parameters as
|
||||
// described in the Custom Handler specification.
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#normalize-protocol-handler-parameters
|
||||
std::vector<std::pair<std::string, std::string>> predefined_handler_schemes;
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
// Normally, non-standard schemes canonicalize to opaque origins. However,
|
||||
// Android WebView requires non-standard schemes to still be preserved.
|
||||
|
@ -50,6 +50,8 @@ const char kUrnScheme[] = "urn";
|
||||
const char16_t kUrnScheme16[] = u"urn";
|
||||
const char kUuidInPackageScheme[] = "uuid-in-package";
|
||||
const char16_t kUuidInPackageScheme16[] = u"uuid-in-package";
|
||||
const char kWebcalScheme[] = "webcal";
|
||||
const char16_t kWebcalScheme16[] = u"webcal";
|
||||
const char kWsScheme[] = "ws";
|
||||
const char16_t kWsScheme16[] = u"ws";
|
||||
const char kWssScheme[] = "wss";
|
||||
|
@ -54,6 +54,8 @@ COMPONENT_EXPORT(URL) extern const char kUrnScheme[];
|
||||
COMPONENT_EXPORT(URL) extern const char16_t kUrnScheme16[];
|
||||
COMPONENT_EXPORT(URL) extern const char kUuidInPackageScheme[];
|
||||
COMPONENT_EXPORT(URL) extern const char16_t kUuidInPackageScheme16[];
|
||||
COMPONENT_EXPORT(URL) extern const char kWebcalScheme[];
|
||||
COMPONENT_EXPORT(URL) extern const char16_t kWebcalScheme16[];
|
||||
COMPONENT_EXPORT(URL) extern const char kWsScheme[];
|
||||
COMPONENT_EXPORT(URL) extern const char16_t kWsScheme16[];
|
||||
COMPONENT_EXPORT(URL) extern const char kWssScheme[];
|
||||
|
@ -29,6 +29,16 @@ struct SchemeWithType {
|
||||
SchemeType type;
|
||||
};
|
||||
|
||||
// A pair for representing a scheme and a custom protocol handler for it.
|
||||
//
|
||||
// This pair of strings must be normalized protocol handler parameters as
|
||||
// described in the Custom Handler specification.
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#normalize-protocol-handler-parameters
|
||||
struct SchemeWithHandler {
|
||||
std::string scheme;
|
||||
std::string handler;
|
||||
};
|
||||
|
||||
// List of currently registered schemes and associated properties.
|
||||
struct SchemeRegistry {
|
||||
// Standard format schemes (see header for details).
|
||||
@ -101,6 +111,9 @@ struct SchemeRegistry {
|
||||
kAboutScheme,
|
||||
};
|
||||
|
||||
// Schemes with a predefined default custom handler.
|
||||
std::vector<SchemeWithHandler> predefined_handler_schemes;
|
||||
|
||||
bool allow_non_standard_schemes = false;
|
||||
};
|
||||
|
||||
@ -501,6 +514,21 @@ void DoSchemeModificationPreamble() {
|
||||
<< "Trying to add a scheme after the lists have been locked.";
|
||||
}
|
||||
|
||||
void DoAddSchemeWithHandler(const char* new_scheme,
|
||||
const char* handler,
|
||||
std::vector<SchemeWithHandler>* schemes) {
|
||||
DoSchemeModificationPreamble();
|
||||
DCHECK(schemes);
|
||||
DCHECK(strlen(new_scheme) > 0);
|
||||
DCHECK(strlen(handler) > 0);
|
||||
DCHECK_EQ(base::ToLowerASCII(new_scheme), new_scheme);
|
||||
DCHECK(std::find_if(schemes->begin(), schemes->end(),
|
||||
[&new_scheme](const SchemeWithHandler& scheme) {
|
||||
return scheme.scheme == new_scheme;
|
||||
}) == schemes->end());
|
||||
schemes->push_back({new_scheme, handler});
|
||||
}
|
||||
|
||||
void DoAddScheme(const char* new_scheme, std::vector<std::string>* schemes) {
|
||||
DoSchemeModificationPreamble();
|
||||
DCHECK(schemes);
|
||||
@ -649,6 +677,22 @@ const std::vector<std::string>& GetEmptyDocumentSchemes() {
|
||||
return GetSchemeRegistry().empty_document_schemes;
|
||||
}
|
||||
|
||||
void AddPredefinedHandlerScheme(const char* new_scheme, const char* handler) {
|
||||
DoAddSchemeWithHandler(
|
||||
new_scheme, handler,
|
||||
&GetSchemeRegistryWithoutLocking()->predefined_handler_schemes);
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> GetPredefinedHandlerSchemes() {
|
||||
std::vector<std::pair<std::string, std::string>> result;
|
||||
result.reserve(GetSchemeRegistry().predefined_handler_schemes.size());
|
||||
for (const SchemeWithHandler& entry :
|
||||
GetSchemeRegistry().predefined_handler_schemes) {
|
||||
result.emplace_back(entry.scheme, entry.handler);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LockSchemeRegistries() {
|
||||
scheme_registries_locked = true;
|
||||
}
|
||||
|
@ -115,6 +115,16 @@ COMPONENT_EXPORT(URL) const std::vector<std::string>& GetCSPBypassingSchemes();
|
||||
COMPONENT_EXPORT(URL) void AddEmptyDocumentScheme(const char* new_scheme);
|
||||
COMPONENT_EXPORT(URL) const std::vector<std::string>& GetEmptyDocumentSchemes();
|
||||
|
||||
// Adds a scheme with a predefined default handler.
|
||||
//
|
||||
// This pair of strings must be normalized protocol handler parameters as
|
||||
// described in the Custom Handler specification.
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#normalize-protocol-handler-parameters
|
||||
COMPONENT_EXPORT(URL)
|
||||
void AddPredefinedHandlerScheme(const char* new_scheme, const char* handler);
|
||||
COMPONENT_EXPORT(URL)
|
||||
std::vector<std::pair<std::string, std::string>> GetPredefinedHandlerSchemes();
|
||||
|
||||
// Sets a flag to prevent future calls to Add*Scheme from succeeding.
|
||||
//
|
||||
// This is designed to help prevent errors for multithreaded applications.
|
||||
|
Reference in New Issue
Block a user