cef/libcef/browser/extensions/browser_extensions_util.cc
Marshall Greenblatt 48fc0bd220 Make CefBrowserContext an abstract base class (see issue #2969)
Existing CefBrowserContext functionality is now split between
CefBrowserContext and AlloyBrowserContext. Runtime implementations of
CefBrowserContext will provide access to the content::BrowserContext and
Profile types via different inheritance paths. For example, the Alloy
runtime uses ChromeProfileAlloy and the Chrome runtime uses ProfileImpl.

This change also renames CefResourceContext to CefIOThreadState to more
accurately represent its purpose as it no longer needs to extend
content::ResourceContext.
2020-07-01 15:35:07 -04:00

185 lines
6.3 KiB
C++

// Copyright (c) 2015 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/browser_extensions_util.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/extensions/extensions_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/printing/print_preview_dialog_controller.h"
#include "content/browser/browser_plugin/browser_plugin_embedder.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
#include "extensions/browser/extension_registry.h"
namespace extensions {
namespace {
bool InsertWebContents(std::vector<content::WebContents*>* vector,
content::WebContents* web_contents) {
vector->push_back(web_contents);
return false; // Continue iterating.
}
} // namespace
content::WebContents* GetFullPageGuestForOwnerContents(
content::WebContents* owner) {
content::WebContentsImpl* owner_impl =
static_cast<content::WebContentsImpl*>(owner);
content::BrowserPluginEmbedder* plugin_embedder =
owner_impl->GetBrowserPluginEmbedder();
if (plugin_embedder) {
content::BrowserPluginGuest* plugin_guest =
plugin_embedder->GetFullPageGuest();
if (plugin_guest)
return plugin_guest->web_contents();
}
return nullptr;
}
void GetAllGuestsForOwnerContents(content::WebContents* owner,
std::vector<content::WebContents*>* guests) {
content::BrowserPluginGuestManager* plugin_guest_manager =
owner->GetBrowserContext()->GetGuestManager();
plugin_guest_manager->ForEachGuest(owner,
base::Bind(InsertWebContents, guests));
}
content::WebContents* GetOwnerForGuestContents(content::WebContents* guest) {
content::WebContentsImpl* guest_impl =
static_cast<content::WebContentsImpl*>(guest);
content::BrowserPluginGuest* plugin_guest =
guest_impl->GetBrowserPluginGuest();
if (plugin_guest) {
return content::WebContents::FromRenderFrameHost(
plugin_guest->GetEmbedderFrame());
}
// Maybe it's a print preview dialog.
auto print_preview_controller =
g_browser_process->print_preview_dialog_controller();
return print_preview_controller->GetInitiator(guest);
}
CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForFrameRoute(
int render_process_id,
int render_routing_id,
bool* is_guest_view) {
if (CEF_CURRENTLY_ON_UIT()) {
// Use the non-thread-safe but potentially faster approach.
content::RenderFrameHost* host =
content::RenderFrameHost::FromID(render_process_id, render_routing_id);
if (host)
return GetOwnerBrowserForHost(host, is_guest_view);
return nullptr;
} else {
// Use the thread-safe approach.
scoped_refptr<CefBrowserInfo> info =
CefBrowserInfoManager::GetInstance()->GetBrowserInfoForFrameRoute(
render_process_id, render_routing_id, is_guest_view);
if (info.get()) {
CefRefPtr<CefBrowserHostImpl> browser = info->browser();
if (!browser.get()) {
LOG(WARNING) << "Found browser id " << info->browser_id()
<< " but no browser object matching view process id "
<< render_process_id << " and frame routing id "
<< render_routing_id;
}
return browser;
}
return nullptr;
}
}
CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForHost(
content::RenderViewHost* host,
bool* is_guest_view) {
if (is_guest_view)
*is_guest_view = false;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForHost(host);
if (!browser.get() && ExtensionsEnabled()) {
// Retrieve the owner browser, if any.
content::WebContents* owner = GetOwnerForGuestContents(
content::WebContents::FromRenderViewHost(host));
if (owner) {
browser = CefBrowserHostImpl::GetBrowserForContents(owner);
if (browser.get() && is_guest_view)
*is_guest_view = true;
}
}
return browser;
}
CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForHost(
content::RenderFrameHost* host,
bool* is_guest_view) {
if (is_guest_view)
*is_guest_view = false;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForHost(host);
if (!browser.get() && ExtensionsEnabled()) {
// Retrieve the owner browser, if any.
content::WebContents* owner = GetOwnerForGuestContents(
content::WebContents::FromRenderFrameHost(host));
if (owner) {
browser = CefBrowserHostImpl::GetBrowserForContents(owner);
if (browser.get() && is_guest_view)
*is_guest_view = true;
}
}
return browser;
}
CefRefPtr<CefBrowserHostImpl> GetBrowserForTabId(
int tab_id,
content::BrowserContext* browser_context) {
CEF_REQUIRE_UIT();
DCHECK(browser_context);
if (tab_id < 0 || !browser_context)
return nullptr;
auto cef_browser_context =
CefBrowserContext::FromBrowserContext(browser_context);
for (const auto& browser_info :
CefBrowserInfoManager::GetInstance()->GetBrowserInfoList()) {
CefRefPtr<CefBrowserHostImpl> current_browser = browser_info->browser();
if (current_browser && current_browser->GetIdentifier() == tab_id) {
// Make sure we're operating in the same CefBrowserContext.
if (CefBrowserContext::FromBrowserContext(
current_browser->GetBrowserContext()) == cef_browser_context) {
return current_browser;
} else {
LOG(WARNING) << "Browser with tabId " << tab_id
<< " cannot be accessed because is uses a different "
"CefRequestContext";
break;
}
}
}
return nullptr;
}
const Extension* GetExtensionForUrl(content::BrowserContext* browser_context,
const GURL& url) {
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context);
if (!registry)
return nullptr;
std::string extension_id = url.host();
return registry->enabled_extensions().GetByID(extension_id);
}
} // namespace extensions