0

[MPArch guest view] Fix loading extension resources inside a guest view

- Ensure that the view type is correct for guest views, this previously
was computed from the WebContents but we should use the RenderFrameHost
for this.
- Provide an API to get the owner RenderFrameHost before attachment.

Bug: 40202416
Change-Id: I351313f06cd7a221e9c9bae0e3c155e827b3be51
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6053978
Reviewed-by: Greg Thompson <grt@chromium.org>
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: David Bertoni <dbertoni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1390990}
This commit is contained in:
Dave Tapuska
2024-12-03 15:02:16 +00:00
committed by Chromium LUCI CQ
parent af40a0bbde
commit cd4c24d550
13 changed files with 67 additions and 52 deletions

@ -1432,14 +1432,10 @@ IN_PROC_BROWSER_TEST_P(WebViewTest, SelectShowHide) {
#endif
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestChromeExtensionURL) {
SKIP_FOR_MPARCH(); // TODO(crbug.com/40202416): Enable test for MPArch.
TestHelper("testChromeExtensionURL", "web_view/shim", NO_TEST_SERVER);
}
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestChromeExtensionRelativePath) {
SKIP_FOR_MPARCH(); // TODO(crbug.com/40202416): Enable test for MPArch.
TestHelper("testChromeExtensionRelativePath",
"web_view/shim",
NO_TEST_SERVER);

@ -213,9 +213,8 @@ void ChromeSpeechRecognitionManagerDelegate::CheckRenderFrameType(
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
WebContents* web_contents =
WebContents::FromRenderFrameHost(render_frame_host);
extensions::mojom::ViewType view_type = extensions::GetViewType(web_contents);
extensions::mojom::ViewType view_type =
extensions::GetViewType(render_frame_host);
if (view_type == extensions::mojom::ViewType::kTabContents ||
view_type == extensions::mojom::ViewType::kAppWindow ||

@ -125,8 +125,11 @@ FrameTreeNodeId GuestPageHolderImpl::GetOuterDelegateFrameTreeNodeId() {
}
RenderFrameHostImpl* GuestPageHolderImpl::GetProspectiveOuterDocument() {
NOTIMPLEMENTED();
return nullptr;
if (!delegate_) {
return nullptr;
}
return static_cast<RenderFrameHostImpl*>(
delegate_->GetProspectiveOuterDocument());
}
FrameTree* GuestPageHolderImpl::LoadingTree() {

@ -68,6 +68,10 @@ class GuestPageHolder : public base::SupportsUserData {
// The guest was resized.
virtual void GuestResizeDueToAutoResize(const gfx::Size& new_size) = 0;
// Return the prospective outer document. Should only be called when
// unattached.
virtual RenderFrameHost* GetProspectiveOuterDocument() = 0;
// TODO(40202416): Guest implementations need to be informed of several
// other events that they currently get through primary main frame specific
// WebContentsObserver methods (e.g.

@ -960,9 +960,7 @@ int RuntimeGetContextsFunction::GetTabId(content::WebContents& web_contents) {
}
int RuntimeGetContextsFunction::GetFrameId(content::RenderFrameHost& host) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(&host);
mojom::ViewType view_type = extensions::GetViewType(web_contents);
mojom::ViewType view_type = extensions::GetViewType(&host);
if (view_type == extensions::mojom::ViewType::kDeveloperTools) {
return -1;

@ -58,30 +58,9 @@ namespace {
bool ShouldBlockNavigationToPlatformAppResource(
const Extension* platform_app,
content::NavigationHandle& navigation_handle) {
content::WebContents* web_contents = navigation_handle.GetWebContents();
mojom::ViewType view_type = GetViewType(web_contents);
DCHECK_NE(mojom::ViewType::kInvalid, view_type);
// Navigation to platform app's background page.
if (view_type == mojom::ViewType::kExtensionBackgroundPage)
return false;
#if BUILDFLAG(ENABLE_PLATFORM_APPS)
// Navigation within an app window. The app window must belong to the
// |platform_app|.
if (view_type == mojom::ViewType::kAppWindow) {
AppWindowRegistry* registry =
AppWindowRegistry::Get(web_contents->GetBrowserContext());
DCHECK(registry);
AppWindow* app_window = registry->GetAppWindowForWebContents(web_contents);
DCHECK(app_window);
return app_window->extension_id() != platform_app->id();
}
#endif
#if BUILDFLAG(ENABLE_GUEST_VIEW)
// Navigation within a guest web contents.
if (view_type == mojom::ViewType::kExtensionGuest) {
if (auto* guest =
guest_view::GuestViewBase::FromNavigationHandle(&navigation_handle)) {
// Navigating within a PDF viewer extension (see crbug.com/1252154). This
// exemption is only for the PDF resource. The initial navigation to the PDF
// loads the PDF viewer extension, which would have already passed the
@ -96,15 +75,14 @@ bool ShouldBlockNavigationToPlatformAppResource(
// Platform apps can be embedded by other platform apps using an <appview>
// tag.
auto* app_view = AppViewGuest::FromNavigationHandle(&navigation_handle);
auto* app_view = AppViewGuest::FromGuestViewBase(guest);
if (app_view) {
return false;
}
// Webviews owned by the platform app can embed platform app resources via
// "accessible_resources".
auto* web_view_guest =
WebViewGuest::FromNavigationHandle(&navigation_handle);
auto* web_view_guest = WebViewGuest::FromGuestViewBase(guest);
if (web_view_guest) {
return web_view_guest->owner_host() != platform_app->id();
}
@ -115,6 +93,28 @@ bool ShouldBlockNavigationToPlatformAppResource(
}
#endif
content::WebContents* web_contents = navigation_handle.GetWebContents();
mojom::ViewType view_type = GetViewType(web_contents);
DCHECK_NE(mojom::ViewType::kInvalid, view_type);
// Navigation to platform app's background page.
if (view_type == mojom::ViewType::kExtensionBackgroundPage) {
return false;
}
#if BUILDFLAG(ENABLE_PLATFORM_APPS)
// Navigation within an app window. The app window must belong to the
// |platform_app|.
if (view_type == mojom::ViewType::kAppWindow) {
AppWindowRegistry* registry =
AppWindowRegistry::Get(web_contents->GetBrowserContext());
DCHECK(registry);
AppWindow* app_window = registry->GetAppWindowForWebContents(web_contents);
DCHECK(app_window);
return app_window->extension_id() != platform_app->id();
}
#endif
DCHECK(view_type == mojom::ViewType::kBackgroundContents ||
view_type == mojom::ViewType::kComponent ||
view_type == mojom::ViewType::kExtensionPopup ||
@ -406,8 +406,9 @@ ExtensionNavigationThrottle::WillProcessResponse() {
#if BUILDFLAG(ENABLE_GUEST_VIEW)
auto* mime_handler_view_embedder =
MimeHandlerViewEmbedder::Get(navigation_handle()->GetFrameTreeNodeId());
if (!mime_handler_view_embedder)
if (!mime_handler_view_embedder) {
return PROCEED;
}
// If we have a MimeHandlerViewEmbedder, the frame might embed a resource. If
// the frame is sandboxed, however, we shouldn't show the embedded resource.

@ -149,11 +149,10 @@ void ExtensionWebContentsObserver::InitializeRenderFrame(
// Notify the render frame of the view type.
GetLocalFrameChecked(render_frame_host)
.NotifyRenderViewType(GetViewType(web_contents()));
.NotifyRenderViewType(GetViewType(render_frame_host));
ProcessManager::Get(browser_context_)
->RegisterRenderFrameHost(web_contents(), render_frame_host,
frame_extension);
->RegisterRenderFrameHost(render_frame_host, frame_extension);
}
void ExtensionWebContentsObserver::SetUpRenderFrameHost(
@ -284,8 +283,7 @@ void ExtensionWebContentsObserver::DidFinishNavigation(
if (!frame_extension)
pm->UnregisterRenderFrameHost(render_frame_host);
} else if (frame_extension && render_frame_host->IsRenderFrameLive()) {
pm->RegisterRenderFrameHost(web_contents(), render_frame_host,
frame_extension);
pm->RegisterRenderFrameHost(render_frame_host, frame_extension);
}
ScriptInjectionTracker::DidFinishNavigation(PassKey(), navigation_handle);

@ -15,6 +15,7 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/content_features.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "extensions/browser/browser_frame_context_data.h"
#include "extensions/browser/event_router.h"
@ -99,6 +100,7 @@ ExtensionsGuestViewManagerDelegate::~ExtensionsGuestViewManagerDelegate() =
void ExtensionsGuestViewManagerDelegate::OnGuestAdded(
content::WebContents* guest_web_contents) const {
CHECK(!base::FeatureList::IsEnabled(features::kGuestViewMPArch));
// Set the view type so extensions sees the guest view as a foreground page.
SetViewType(guest_web_contents, mojom::ViewType::kExtensionGuest);
}

@ -244,12 +244,11 @@ void ProcessManager::Shutdown() {
}
void ProcessManager::RegisterRenderFrameHost(
content::WebContents* web_contents,
content::RenderFrameHost* render_frame_host,
const Extension* extension) {
DCHECK(render_frame_host->IsRenderFrameLive());
ExtensionRenderFrameData* data = &all_extension_frames_[render_frame_host];
data->view_type = GetViewType(web_contents);
data->view_type = GetViewType(render_frame_host);
// Keep the lazy background page alive as long as any non-background-page
// extension views are visible. Keepalive count balanced in

@ -100,8 +100,7 @@ class ProcessManager : public KeyedService,
// KeyedService support:
void Shutdown() override;
void RegisterRenderFrameHost(content::WebContents* web_contents,
content::RenderFrameHost* render_frame_host,
void RegisterRenderFrameHost(content::RenderFrameHost* render_frame_host,
const Extension* extension);
void UnregisterRenderFrameHost(content::RenderFrameHost* render_frame_host);

@ -5,6 +5,7 @@
#include "extensions/browser/view_type_utils.h"
#include "base/lazy_instance.h"
#include "components/guest_view/browser/guest_view_base.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_web_contents_observer.h"
#include "extensions/browser/extensions_browser_client.h"
@ -40,6 +41,13 @@ mojom::ViewType GetViewType(WebContents* tab) {
return user_data ? user_data->type() : mojom::ViewType::kInvalid;
}
mojom::ViewType GetViewType(content::RenderFrameHost* frame_host) {
return guest_view::GuestViewBase::IsGuest(frame_host)
? mojom::ViewType::kExtensionGuest
: GetViewType(
content::WebContents::FromRenderFrameHost(frame_host));
}
void SetViewType(WebContents* tab, mojom::ViewType type) {
tab->SetUserData(&kViewTypeUserDataKey,
std::make_unique<ViewTypeUserData>(type));

@ -8,15 +8,25 @@
#include "extensions/common/mojom/view_type.mojom.h"
namespace content {
class RenderFrameHost;
class WebContents;
}
namespace extensions {
// Get/Set the type of a WebContents.
// Get the type of a WebContents.
// Use GetViewType(RenderFrameHost) where applicable.
// GetViewType handles a NULL |tab| for convenience by returning
// mojom::ViewType::kInvalid.
mojom::ViewType GetViewType(content::WebContents* tab);
// Return the closest view type of the associated frame tree. If `frame_host` is
// contained in a guest frame tree this will return
// mojom::ViewType::kExtensionGuest, otherwise it will return the type set
// for the associated WebContents.
mojom::ViewType GetViewType(content::RenderFrameHost* frame_host);
// Set the type of a WebContents.
void SetViewType(content::WebContents* tab, mojom::ViewType type);
} // namespace extensions

@ -101,10 +101,8 @@ void ShellSpeechRecognitionManagerDelegate::CheckRenderFrameType(
bool check_permission = false;
if (render_frame_host) {
WebContents* web_contents =
WebContents::FromRenderFrameHost(render_frame_host);
extensions::mojom::ViewType view_type =
extensions::GetViewType(web_contents);
extensions::GetViewType(render_frame_host);
if (view_type == extensions::mojom::ViewType::kAppWindow ||
view_type == extensions::mojom::ViewType::kExtensionBackgroundPage) {