From a92e5d5e3dd0099e7bae63266fd76419564cf4a1 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Wed, 16 Jun 2021 16:19:44 -0400 Subject: [PATCH] alloy: Fix link click navigation in PDF files (fixes issue #3143) This change adds a minimal implementation of the |tabs.update| extension API and modifies StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent to return a valid |streamInfo.tabId| value as required by the navigateInCurrentTab implementation in chrome/browser/resources/pdf/browser_api.js. --- BUILD.gn | 2 + .../extensions/alloy_extensions_util.cc | 20 ++ .../extensions/alloy_extensions_util.h | 21 ++ .../browser/extensions/api/tabs/tabs_api.cc | 264 ++++++++++++------ libcef/browser/extensions/api/tabs/tabs_api.h | 61 ++-- .../extensions/chrome_api_registration.cc | 2 + .../extensions/extension_function_details.cc | 17 +- patch/patches/extensions_1947.patch | 39 ++- 8 files changed, 308 insertions(+), 118 deletions(-) create mode 100644 libcef/browser/extensions/alloy_extensions_util.cc create mode 100644 libcef/browser/extensions/alloy_extensions_util.h diff --git a/BUILD.gn b/BUILD.gn index e27e88d60..1a5a0a93d 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -481,6 +481,8 @@ static_library("libcef_static") { "libcef/browser/extensions/api/storage/sync_value_store_cache.h", "libcef/browser/extensions/api/tabs/tabs_api.cc", "libcef/browser/extensions/api/tabs/tabs_api.h", + "libcef/browser/extensions/alloy_extensions_util.cc", + "libcef/browser/extensions/alloy_extensions_util.h", "libcef/browser/extensions/browser_extensions_util.cc", "libcef/browser/extensions/browser_extensions_util.h", "libcef/browser/extensions/browser_platform_delegate_background.cc", diff --git a/libcef/browser/extensions/alloy_extensions_util.cc b/libcef/browser/extensions/alloy_extensions_util.cc new file mode 100644 index 000000000..0dabb1b22 --- /dev/null +++ b/libcef/browser/extensions/alloy_extensions_util.cc @@ -0,0 +1,20 @@ +// Copyright 2021 The Chromium Embedded Framework 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 "libcef/browser/extensions/alloy_extensions_util.h" + +#include "libcef/browser/alloy/alloy_browser_host_impl.h" + +namespace extensions { +namespace alloy { + +int GetTabIdForWebContents(content::WebContents* web_contents) { + auto browser = AlloyBrowserHostImpl::GetBrowserForContents(web_contents); + if (!browser) + return -1; + return browser->GetIdentifier(); +} + +} // namespace alloy +} // namespace extensions diff --git a/libcef/browser/extensions/alloy_extensions_util.h b/libcef/browser/extensions/alloy_extensions_util.h new file mode 100644 index 000000000..e68c0c2e1 --- /dev/null +++ b/libcef/browser/extensions/alloy_extensions_util.h @@ -0,0 +1,21 @@ +// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. + +#ifndef CEF_LIBCEF_BROWSER_EXTENSIONS_ALLOY_EXTENSIONS_UTIL_H_ +#define CEF_LIBCEF_BROWSER_EXTENSIONS_ALLOY_EXTENSIONS_UTIL_H_ + +namespace content { +class WebContents; +} + +namespace extensions { +namespace alloy { + +// Returns the tabId for |web_contents|, or -1 if not found. +int GetTabIdForWebContents(content::WebContents* web_contents); + +} // namespace alloy +} // namespace extensions + +#endif // CEF_LIBCEF_BROWSER_EXTENSIONS_ALLOY_EXTENSIONS_UTIL_H_ diff --git a/libcef/browser/extensions/api/tabs/tabs_api.cc b/libcef/browser/extensions/api/tabs/tabs_api.cc index f5c779ee9..5197c3b85 100644 --- a/libcef/browser/extensions/api/tabs/tabs_api.cc +++ b/libcef/browser/extensions/api/tabs/tabs_api.cc @@ -6,10 +6,15 @@ #include "libcef/browser/extensions/extension_web_contents_observer.h" +#include "base/notreached.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/extensions/api/tabs/tabs_constants.h" +#include "chrome/browser/extensions/extension_tab_util.h" #include "components/zoom/zoom_controller.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/site_instance.h" #include "extensions/browser/extension_api_frame_id_map.h" #include "extensions/browser/extension_zoom_request_client.h" #include "extensions/common/error_utils.h" @@ -17,6 +22,8 @@ #include "extensions/common/permissions/permissions_data.h" #include "third_party/blink/public/common/page/page_zoom.h" +using zoom::ZoomController; + namespace extensions { namespace cef { @@ -97,6 +104,148 @@ ExtensionFunction::ResponseAction TabsCreateFunction::Run() { : NoArguments()); } +BaseAPIFunction::BaseAPIFunction() : cef_details_(this) {} + +content::WebContents* BaseAPIFunction::GetWebContents(int tab_id) { + // Find a browser that we can access, or set |error_| and return nullptr. + CefRefPtr browser = + cef_details_.GetBrowserForTabIdFirstTime(tab_id, &error_); + if (!browser) + return nullptr; + + return browser->web_contents(); +} + +ExtensionFunction::ResponseAction TabsUpdateFunction::Run() { + std::unique_ptr params( + tabs::Update::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + tab_id_ = params->tab_id ? *params->tab_id : -1; + content::WebContents* web_contents = GetWebContents(tab_id_); + if (!web_contents) + return RespondNow(Error(std::move(error_))); + + web_contents_ = web_contents; + + // TODO(rafaelw): handle setting remaining tab properties: + // -title + // -favIconUrl + + // Navigate the tab to a new location if the url is different. + if (params->update_properties.url.get()) { + std::string updated_url = *params->update_properties.url; + if (!UpdateURL(updated_url, tab_id_, &error_)) + return RespondNow(Error(std::move(error_))); + } + + bool active = false; + // TODO(rafaelw): Setting |active| from js doesn't make much sense. + // Move tab selection management up to window. + if (params->update_properties.selected.get()) + active = *params->update_properties.selected; + + // The 'active' property has replaced 'selected'. + if (params->update_properties.active.get()) + active = *params->update_properties.active; + + if (active) { + // TODO: Activate the tab at |tab_id_|. + NOTIMPLEMENTED(); + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + } + + if (params->update_properties.highlighted.get() && + *params->update_properties.highlighted) { + // TODO: Highlight the tab at |tab_id_|. + NOTIMPLEMENTED(); + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + } + + if (params->update_properties.pinned.get() && + *params->update_properties.pinned) { + // TODO: Pin the tab at |tab_id_|. + NOTIMPLEMENTED(); + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + } + + if (params->update_properties.muted.get()) { + // TODO: Mute/unmute the tab at |tab_id_|. + NOTIMPLEMENTED(); + return RespondNow(Error(ErrorUtils::FormatErrorMessage( + tabs_constants::kCannotUpdateMuteCaptured, + base::NumberToString(tab_id_)))); + } + + if (params->update_properties.opener_tab_id.get()) { + int opener_id = *params->update_properties.opener_tab_id; + if (opener_id == tab_id_) + return RespondNow(Error("Cannot set a tab's opener to itself.")); + + // TODO: Set the opener for the tab at |tab_id_|. + NOTIMPLEMENTED(); + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + } + + if (params->update_properties.auto_discardable.get()) { + // TODO: Set auto-discardable state for the tab at |tab_id_|. + NOTIMPLEMENTED(); + } + + return RespondNow(GetResult()); +} + +bool TabsUpdateFunction::UpdateURL(const std::string& url_string, + int tab_id, + std::string* error) { + GURL url; + if (!ExtensionTabUtil::PrepareURLForNavigation(url_string, extension(), &url, + error)) { + return false; + } + + const bool is_javascript_scheme = url.SchemeIs(url::kJavaScriptScheme); + // JavaScript URLs are forbidden in chrome.tabs.update(). + if (is_javascript_scheme) { + *error = tabs_constants::kJavaScriptUrlsNotAllowedInTabsUpdate; + return false; + } + + content::NavigationController::LoadURLParams load_params(url); + + // Treat extension-initiated navigations as renderer-initiated so that the URL + // does not show in the omnibox until it commits. This avoids URL spoofs + // since URLs can be opened on behalf of untrusted content. + load_params.is_renderer_initiated = true; + // All renderer-initiated navigations need to have an initiator origin. + load_params.initiator_origin = extension()->origin(); + // |source_site_instance| needs to be set so that a renderer process + // compatible with |initiator_origin| is picked by Site Isolation. + load_params.source_site_instance = content::SiteInstance::CreateForURL( + web_contents_->GetBrowserContext(), + load_params.initiator_origin->GetURL()); + + // Marking the navigation as initiated via an API means that the focus + // will stay in the omnibox - see https://crbug.com/1085779. + load_params.transition_type = ui::PAGE_TRANSITION_FROM_API; + + web_contents_->GetController().LoadURLWithParams(load_params); + + DCHECK_EQ(url, + web_contents_->GetController().GetPendingEntry()->GetVirtualURL()); + + return true; +} + +ExtensionFunction::ResponseValue TabsUpdateFunction::GetResult() { + if (!has_callback()) + return NoArguments(); + + return ArgumentList(tabs::Get::Results::Create(*cef_details_.CreateTabObject( + AlloyBrowserHostImpl::GetBrowserForContents(web_contents_), + /*opener_browser_id=*/-1, /*active=*/true, tab_id_))); +} + ExecuteCodeInTabFunction::ExecuteCodeInTabFunction() : cef_details_(this), execute_tab_id_(-1) {} @@ -244,165 +393,124 @@ bool TabsRemoveCSSFunction::ShouldRemoveCSS() const { return true; } -ZoomAPIFunction::ZoomAPIFunction() : cef_details_(this) {} - -content::WebContents* ZoomAPIFunction::GetWebContents(int tab_id) { - // Find a browser that we can access, or set |error_| and return nullptr. - CefRefPtr browser = - cef_details_.GetBrowserForTabIdFirstTime(tab_id, &error_); - if (!browser) - return nullptr; - - return browser->web_contents(); -} - -void ZoomAPIFunction::SendResponse(bool success) { - ResponseValue response; - if (success) { - response = ArgumentList(std::move(results_)); - } else { - response = results_ ? ErrorWithArguments(std::move(results_), error_) - : Error(error_); - } - Respond(std::move(response)); -} - -ExtensionFunction::ResponseAction ZoomAPIFunction::Run() { - if (RunAsync()) - return RespondLater(); - // TODO(devlin): Track these down and eliminate them if possible. We - // shouldn't return results and an error. - if (results_) - return RespondNow(ErrorWithArguments(std::move(results_), error_)); - return RespondNow(Error(error_)); -} - -bool TabsSetZoomFunction::RunAsync() { +ExtensionFunction::ResponseAction TabsSetZoomFunction::Run() { std::unique_ptr params( tabs::SetZoom::Params::Create(*args_)); - EXTENSION_FUNCTION_PRERUN_VALIDATE(params); + EXTENSION_FUNCTION_VALIDATE(params); int tab_id = params->tab_id ? *params->tab_id : -1; content::WebContents* web_contents = GetWebContents(tab_id); if (!web_contents) - return false; + return RespondNow(Error(std::move(error_))); GURL url(web_contents->GetVisibleURL()); if (extension()->permissions_data()->IsRestrictedUrl(url, &error_)) - return false; + return RespondNow(Error(std::move(error_))); - zoom::ZoomController* zoom_controller = - zoom::ZoomController::FromWebContents(web_contents); + ZoomController* zoom_controller = + ZoomController::FromWebContents(web_contents); double zoom_level = params->zoom_factor > 0 ? blink::PageZoomFactorToZoomLevel(params->zoom_factor) : zoom_controller->GetDefaultZoomLevel(); - scoped_refptr client( - new extensions::ExtensionZoomRequestClient(extension())); + auto client = base::MakeRefCounted(extension()); if (!zoom_controller->SetZoomLevelByClient(zoom_level, client)) { // Tried to zoom a tab in disabled mode. - error_ = keys::kCannotZoomDisabledTabError; - return false; + return RespondNow(Error(tabs_constants::kCannotZoomDisabledTabError)); } - SendResponse(true); - return true; + return RespondNow(NoArguments()); } -bool TabsGetZoomFunction::RunAsync() { +ExtensionFunction::ResponseAction TabsGetZoomFunction::Run() { std::unique_ptr params( tabs::GetZoom::Params::Create(*args_)); - EXTENSION_FUNCTION_PRERUN_VALIDATE(params); + EXTENSION_FUNCTION_VALIDATE(params); int tab_id = params->tab_id ? *params->tab_id : -1; content::WebContents* web_contents = GetWebContents(tab_id); if (!web_contents) - return false; + return RespondNow(Error(std::move(error_))); double zoom_level = zoom::ZoomController::FromWebContents(web_contents)->GetZoomLevel(); double zoom_factor = blink::PageZoomLevelToZoomFactor(zoom_level); - results_ = tabs::GetZoom::Results::Create(zoom_factor); - SendResponse(true); - return true; + + return RespondNow(ArgumentList(tabs::GetZoom::Results::Create(zoom_factor))); } -bool TabsSetZoomSettingsFunction::RunAsync() { +ExtensionFunction::ResponseAction TabsSetZoomSettingsFunction::Run() { using api::tabs::ZoomSettings; std::unique_ptr params( tabs::SetZoomSettings::Params::Create(*args_)); - EXTENSION_FUNCTION_PRERUN_VALIDATE(params); + EXTENSION_FUNCTION_VALIDATE(params); int tab_id = params->tab_id ? *params->tab_id : -1; content::WebContents* web_contents = GetWebContents(tab_id); if (!web_contents) - return false; + return RespondNow(Error(std::move(error_))); GURL url(web_contents->GetVisibleURL()); + std::string error; if (extension()->permissions_data()->IsRestrictedUrl(url, &error_)) - return false; + return RespondNow(Error(std::move(error_))); // "per-origin" scope is only available in "automatic" mode. if (params->zoom_settings.scope == tabs::ZOOM_SETTINGS_SCOPE_PER_ORIGIN && params->zoom_settings.mode != tabs::ZOOM_SETTINGS_MODE_AUTOMATIC && params->zoom_settings.mode != tabs::ZOOM_SETTINGS_MODE_NONE) { - error_ = keys::kPerOriginOnlyInAutomaticError; - return false; + return RespondNow(Error(tabs_constants::kPerOriginOnlyInAutomaticError)); } // Determine the correct internal zoom mode to set |web_contents| to from the // user-specified |zoom_settings|. - zoom::ZoomController::ZoomMode zoom_mode = - zoom::ZoomController::ZOOM_MODE_DEFAULT; + ZoomController::ZoomMode zoom_mode = ZoomController::ZOOM_MODE_DEFAULT; switch (params->zoom_settings.mode) { case tabs::ZOOM_SETTINGS_MODE_NONE: case tabs::ZOOM_SETTINGS_MODE_AUTOMATIC: switch (params->zoom_settings.scope) { case tabs::ZOOM_SETTINGS_SCOPE_NONE: case tabs::ZOOM_SETTINGS_SCOPE_PER_ORIGIN: - zoom_mode = zoom::ZoomController::ZOOM_MODE_DEFAULT; + zoom_mode = ZoomController::ZOOM_MODE_DEFAULT; break; case tabs::ZOOM_SETTINGS_SCOPE_PER_TAB: - zoom_mode = zoom::ZoomController::ZOOM_MODE_ISOLATED; + zoom_mode = ZoomController::ZOOM_MODE_ISOLATED; } break; case tabs::ZOOM_SETTINGS_MODE_MANUAL: - zoom_mode = zoom::ZoomController::ZOOM_MODE_MANUAL; + zoom_mode = ZoomController::ZOOM_MODE_MANUAL; break; case tabs::ZOOM_SETTINGS_MODE_DISABLED: - zoom_mode = zoom::ZoomController::ZOOM_MODE_DISABLED; + zoom_mode = ZoomController::ZOOM_MODE_DISABLED; } - zoom::ZoomController::FromWebContents(web_contents)->SetZoomMode(zoom_mode); + ZoomController::FromWebContents(web_contents)->SetZoomMode(zoom_mode); - SendResponse(true); - return true; + return RespondNow(NoArguments()); } -bool TabsGetZoomSettingsFunction::RunAsync() { +ExtensionFunction::ResponseAction TabsGetZoomSettingsFunction::Run() { std::unique_ptr params( tabs::GetZoomSettings::Params::Create(*args_)); - EXTENSION_FUNCTION_PRERUN_VALIDATE(params); + EXTENSION_FUNCTION_VALIDATE(params); int tab_id = params->tab_id ? *params->tab_id : -1; content::WebContents* web_contents = GetWebContents(tab_id); if (!web_contents) - return false; - zoom::ZoomController* zoom_controller = - zoom::ZoomController::FromWebContents(web_contents); + return RespondNow(Error(std::move(error_))); + ZoomController* zoom_controller = + ZoomController::FromWebContents(web_contents); - zoom::ZoomController::ZoomMode zoom_mode = zoom_controller->zoom_mode(); + ZoomController::ZoomMode zoom_mode = zoom_controller->zoom_mode(); api::tabs::ZoomSettings zoom_settings; ZoomModeToZoomSettings(zoom_mode, &zoom_settings); - zoom_settings.default_zoom_factor.reset( - new double(blink::PageZoomLevelToZoomFactor( - zoom_controller->GetDefaultZoomLevel()))); + zoom_settings.default_zoom_factor = std::make_unique( + blink::PageZoomLevelToZoomFactor(zoom_controller->GetDefaultZoomLevel())); - results_ = api::tabs::GetZoomSettings::Results::Create(zoom_settings); - SendResponse(true); - return true; + return RespondNow( + ArgumentList(api::tabs::GetZoomSettings::Results::Create(zoom_settings))); } } // namespace cef diff --git a/libcef/browser/extensions/api/tabs/tabs_api.h b/libcef/browser/extensions/api/tabs/tabs_api.h index 45bd70449..409d758db 100644 --- a/libcef/browser/extensions/api/tabs/tabs_api.h +++ b/libcef/browser/extensions/api/tabs/tabs_api.h @@ -42,6 +42,37 @@ class TabsCreateFunction : public ExtensionFunction { const CefExtensionFunctionDetails cef_details_; }; +class BaseAPIFunction : public ExtensionFunction { + public: + BaseAPIFunction(); + + protected: + ~BaseAPIFunction() override {} + + // Gets the WebContents for |tab_id| if it is specified. Otherwise get the + // WebContents for the active tab in the current window. Calling this function + // may set |error_|. + content::WebContents* GetWebContents(int tab_id); + + std::string error_; + const CefExtensionFunctionDetails cef_details_; +}; + +class TabsUpdateFunction : public BaseAPIFunction { + private: + ~TabsUpdateFunction() override {} + + ResponseAction Run() override; + + bool UpdateURL(const std::string& url, int tab_id, std::string* error); + ResponseValue GetResult(); + + DECLARE_EXTENSION_FUNCTION("tabs.update", TABS_UPDATE) + + int tab_id_ = -1; + content::WebContents* web_contents_ = nullptr; +}; + // Implement API calls tabs.executeScript, tabs.insertCSS, and tabs.removeCSS. class ExecuteCodeInTabFunction : public ExecuteCodeFunction { public: @@ -108,58 +139,44 @@ class ZoomAPIFunction : public ExtensionFunction { // may set |error_|. content::WebContents* GetWebContents(int tab_id); - virtual bool RunAsync() = 0; - - // Responds with success/failure. |results_| or |error_| should be set - // accordingly. - void SendResponse(bool success); - - // Exposed versions of ExtensionFunction::results_ and - // ExtensionFunction::error_ that are curried into the response. - // These need to keep the same name to avoid breaking existing - // implementations, but this should be temporary with crbug.com/648275 - // and crbug.com/634140. - std::unique_ptr results_; std::string error_; private: - ResponseAction Run() final; - const CefExtensionFunctionDetails cef_details_; }; -class TabsSetZoomFunction : public ZoomAPIFunction { +class TabsSetZoomFunction : public BaseAPIFunction { private: ~TabsSetZoomFunction() override {} - bool RunAsync() override; + ResponseAction Run() override; DECLARE_EXTENSION_FUNCTION("tabs.setZoom", TABS_SETZOOM) }; -class TabsGetZoomFunction : public ZoomAPIFunction { +class TabsGetZoomFunction : public BaseAPIFunction { private: ~TabsGetZoomFunction() override {} - bool RunAsync() override; + ResponseAction Run() override; DECLARE_EXTENSION_FUNCTION("tabs.getZoom", TABS_GETZOOM) }; -class TabsSetZoomSettingsFunction : public ZoomAPIFunction { +class TabsSetZoomSettingsFunction : public BaseAPIFunction { private: ~TabsSetZoomSettingsFunction() override {} - bool RunAsync() override; + ResponseAction Run() override; DECLARE_EXTENSION_FUNCTION("tabs.setZoomSettings", TABS_SETZOOMSETTINGS) }; -class TabsGetZoomSettingsFunction : public ZoomAPIFunction { +class TabsGetZoomSettingsFunction : public BaseAPIFunction { private: ~TabsGetZoomSettingsFunction() override {} - bool RunAsync() override; + ResponseAction Run() override; DECLARE_EXTENSION_FUNCTION("tabs.getZoomSettings", TABS_GETZOOMSETTINGS) }; diff --git a/libcef/browser/extensions/chrome_api_registration.cc b/libcef/browser/extensions/chrome_api_registration.cc index bf2e3006f..23d15c75a 100644 --- a/libcef/browser/extensions/chrome_api_registration.cc +++ b/libcef/browser/extensions/chrome_api_registration.cc @@ -51,6 +51,7 @@ const char* const kSupportedAPIs[] = { "tabs", EXTENSION_FUNCTION_NAME(cefimpl::TabsGetFunction), EXTENSION_FUNCTION_NAME(cefimpl::TabsCreateFunction), + EXTENSION_FUNCTION_NAME(cefimpl::TabsUpdateFunction), EXTENSION_FUNCTION_NAME(cefimpl::TabsExecuteScriptFunction), EXTENSION_FUNCTION_NAME(cefimpl::TabsInsertCSSFunction), EXTENSION_FUNCTION_NAME(cefimpl::TabsRemoveCSSFunction), @@ -95,6 +96,7 @@ void ChromeFunctionRegistry::RegisterAll(ExtensionFunctionRegistry* registry) { registry->RegisterFunction(); registry->RegisterFunction(); registry->RegisterFunction(); + registry->RegisterFunction(); registry->RegisterFunction(); registry->RegisterFunction(); registry->RegisterFunction(); diff --git a/libcef/browser/extensions/extension_function_details.cc b/libcef/browser/extensions/extension_function_details.cc index 79d0aafb2..c664bfffd 100644 --- a/libcef/browser/extensions/extension_function_details.cc +++ b/libcef/browser/extensions/extension_function_details.cc @@ -7,7 +7,6 @@ #include "libcef/browser/browser_context.h" #include "libcef/browser/extensions/browser_extensions_util.h" #include "libcef/browser/extensions/extension_system.h" -#include "libcef/browser/navigate_params.h" #include "libcef/browser/thread_util.h" #include "base/strings/utf_string_conversions.h" @@ -319,24 +318,12 @@ base::DictionaryValue* CefExtensionFunctionDetails::OpenTab( GURL url; if (params.url.get()) { std::string url_string = *params.url; - url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string, - function()->extension()); - if (!url.is_valid()) { - if (error_message) { - *error_message = - ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, url_string); - } + if (!ExtensionTabUtil::PrepareURLForNavigation( + url_string, function()->extension(), &url, error_message)) { return nullptr; } } - // Don't let extensions crash the browser or renderers. - if (ExtensionTabUtil::IsKillURL(url)) { - if (error_message) - *error_message = keys::kNoCrashBrowserError; - return nullptr; - } - // Default to foreground for the new tab. The presence of 'active' property // will override this default. bool active = true; diff --git a/patch/patches/extensions_1947.patch b/patch/patches/extensions_1947.patch index 5f194d54e..aab990ccd 100644 --- a/patch/patches/extensions_1947.patch +++ b/patch/patches/extensions_1947.patch @@ -1,5 +1,5 @@ diff --git chrome/browser/extensions/api/streams_private/streams_private_api.cc chrome/browser/extensions/api/streams_private/streams_private_api.cc -index 5c903a13a14e..d385c6c0c95c 100644 +index 5c903a13a14e..c85964a7bab1 100644 --- chrome/browser/extensions/api/streams_private/streams_private_api.cc +++ chrome/browser/extensions/api/streams_private/streams_private_api.cc @@ -6,6 +6,7 @@ @@ -10,7 +10,18 @@ index 5c903a13a14e..d385c6c0c95c 100644 #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/prefetch/no_state_prefetch/chrome_no_state_prefetch_contents_delegate.h" #include "components/no_state_prefetch/browser/no_state_prefetch_contents.h" -@@ -42,6 +43,7 @@ void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent( +@@ -18,6 +19,10 @@ + #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h" + #include "extensions/common/manifest_handlers/mime_types_handler.h" + ++#if BUILDFLAG(ENABLE_CEF) ++#include "cef/libcef/browser/extensions/alloy_extensions_util.h" ++#endif ++ + namespace extensions { + + void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent( +@@ -42,6 +47,7 @@ void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent( if (!web_contents) return; @@ -18,7 +29,7 @@ index 5c903a13a14e..d385c6c0c95c 100644 // If the request was for NoStatePrefetch, abort the prefetcher and do not // continue. This is because plugins cancel NoStatePrefetch, see // http://crbug.com/343590. -@@ -52,6 +54,7 @@ void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent( +@@ -52,6 +58,7 @@ void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent( no_state_prefetch_contents->Destroy(prerender::FINAL_STATUS_DOWNLOAD); return; } @@ -26,6 +37,28 @@ index 5c903a13a14e..d385c6c0c95c 100644 auto* browser_context = web_contents->GetBrowserContext(); +@@ -78,9 +85,18 @@ void StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent( + // forms of zooming won't work). + // TODO(1042323): Present a coherent representation of a tab id for portal + // contents. +- int tab_id = web_contents->GetOuterWebContents() +- ? SessionID::InvalidValue().id() +- : ExtensionTabUtil::GetTabId(web_contents); ++ int tab_id; ++ if (web_contents->GetOuterWebContents()) { ++ tab_id = SessionID::InvalidValue().id(); ++ } else ++#if BUILDFLAG(ENABLE_CEF) ++ if (cef::IsAlloyRuntimeEnabled()) { ++ tab_id = alloy::GetTabIdForWebContents(web_contents); ++ } else ++#endif // BUILDFLAG(ENABLE_CEF) ++ { ++ tab_id = ExtensionTabUtil::GetTabId(web_contents); ++ } + + std::unique_ptr stream_container( + new StreamContainer(tab_id, embedded, handler_url, extension_id, diff --git extensions/browser/extension_host.cc extensions/browser/extension_host.cc index 231a3b6c8ce1..14776d981f50 100644 --- extensions/browser/extension_host.cc