1 // Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include "libcef/browser/extensions/browser_extensions_util.h"
6
7 #include "libcef/browser/alloy/alloy_browser_host_impl.h"
8 #include "libcef/browser/browser_context.h"
9 #include "libcef/browser/browser_host_base.h"
10 #include "libcef/browser/browser_info_manager.h"
11 #include "libcef/browser/thread_util.h"
12 #include "libcef/common/extensions/extensions_util.h"
13 #include "libcef/common/frame_util.h"
14 #include "libcef/features/runtime_checks.h"
15
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/printing/print_preview_dialog_controller.h"
18 #include "content/browser/browser_plugin/browser_plugin_guest.h"
19 #include "content/browser/web_contents/web_contents_impl.h"
20 #include "content/public/browser/browser_context.h"
21 #include "content/public/browser/browser_plugin_guest_manager.h"
22 #include "content/public/browser/render_frame_host.h"
23 #include "content/public/browser/render_view_host.h"
24 #include "extensions/browser/extension_registry.h"
25
26 namespace extensions {
27
28 namespace {
29
InsertWebContents(std::vector<content::WebContents * > * vector,content::WebContents * web_contents)30 bool InsertWebContents(std::vector<content::WebContents*>* vector,
31 content::WebContents* web_contents) {
32 vector->push_back(web_contents);
33 return false; // Continue iterating.
34 }
35
36 } // namespace
37
GetAllGuestsForOwnerContents(content::WebContents * owner,std::vector<content::WebContents * > * guests)38 void GetAllGuestsForOwnerContents(content::WebContents* owner,
39 std::vector<content::WebContents*>* guests) {
40 content::BrowserPluginGuestManager* plugin_guest_manager =
41 owner->GetBrowserContext()->GetGuestManager();
42 plugin_guest_manager->ForEachGuest(
43 owner, base::BindRepeating(InsertWebContents, guests));
44 }
45
GetOwnerForGuestContents(content::WebContents * guest)46 content::WebContents* GetOwnerForGuestContents(content::WebContents* guest) {
47 content::WebContentsImpl* guest_impl =
48 static_cast<content::WebContentsImpl*>(guest);
49 content::BrowserPluginGuest* plugin_guest =
50 guest_impl->GetBrowserPluginGuest();
51 if (plugin_guest) {
52 return plugin_guest->owner_web_contents();
53 }
54
55 // Maybe it's a print preview dialog.
56 auto print_preview_controller =
57 g_browser_process->print_preview_dialog_controller();
58 return print_preview_controller->GetInitiator(guest);
59 }
60
GetOwnerBrowserForGlobalId(const content::GlobalRenderFrameHostId & global_id,bool * is_guest_view)61 CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForGlobalId(
62 const content::GlobalRenderFrameHostId& global_id,
63 bool* is_guest_view) {
64 if (CEF_CURRENTLY_ON_UIT()) {
65 // Use the non-thread-safe but potentially faster approach.
66 content::RenderFrameHost* host =
67 content::RenderFrameHost::FromID(global_id);
68 if (host)
69 return GetOwnerBrowserForHost(host, is_guest_view);
70 return nullptr;
71 } else {
72 // Use the thread-safe approach.
73 scoped_refptr<CefBrowserInfo> info =
74 CefBrowserInfoManager::GetInstance()->GetBrowserInfo(global_id,
75 is_guest_view);
76 if (info.get()) {
77 CefRefPtr<CefBrowserHostBase> browser = info->browser();
78 if (!browser.get()) {
79 LOG(WARNING) << "Found browser id " << info->browser_id()
80 << " but no browser object matching frame "
81 << frame_util::GetFrameDebugString(global_id);
82 }
83 return browser;
84 }
85 return nullptr;
86 }
87 }
88
GetOwnerBrowserForHost(content::RenderViewHost * host,bool * is_guest_view)89 CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForHost(
90 content::RenderViewHost* host,
91 bool* is_guest_view) {
92 if (is_guest_view)
93 *is_guest_view = false;
94
95 CefRefPtr<CefBrowserHostBase> browser =
96 CefBrowserHostBase::GetBrowserForHost(host);
97 if (!browser.get() && ExtensionsEnabled()) {
98 // Retrieve the owner browser, if any.
99 content::WebContents* owner = GetOwnerForGuestContents(
100 content::WebContents::FromRenderViewHost(host));
101 if (owner) {
102 browser = CefBrowserHostBase::GetBrowserForContents(owner);
103 if (browser.get() && is_guest_view)
104 *is_guest_view = true;
105 }
106 }
107 return browser;
108 }
109
GetOwnerBrowserForHost(content::RenderFrameHost * host,bool * is_guest_view)110 CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForHost(
111 content::RenderFrameHost* host,
112 bool* is_guest_view) {
113 if (is_guest_view)
114 *is_guest_view = false;
115
116 CefRefPtr<CefBrowserHostBase> browser =
117 CefBrowserHostBase::GetBrowserForHost(host);
118 if (!browser.get() && ExtensionsEnabled()) {
119 // Retrieve the owner browser, if any.
120 content::WebContents* owner = GetOwnerForGuestContents(
121 content::WebContents::FromRenderFrameHost(host));
122 if (owner) {
123 browser = CefBrowserHostBase::GetBrowserForContents(owner);
124 if (browser.get() && is_guest_view)
125 *is_guest_view = true;
126 }
127 }
128 return browser;
129 }
130
GetBrowserForTabId(int tab_id,content::BrowserContext * browser_context)131 CefRefPtr<AlloyBrowserHostImpl> GetBrowserForTabId(
132 int tab_id,
133 content::BrowserContext* browser_context) {
134 REQUIRE_ALLOY_RUNTIME();
135 CEF_REQUIRE_UIT();
136 DCHECK(browser_context);
137 if (tab_id < 0 || !browser_context)
138 return nullptr;
139
140 auto cef_browser_context =
141 CefBrowserContext::FromBrowserContext(browser_context);
142
143 for (const auto& browser_info :
144 CefBrowserInfoManager::GetInstance()->GetBrowserInfoList()) {
145 CefRefPtr<AlloyBrowserHostImpl> current_browser =
146 static_cast<AlloyBrowserHostImpl*>(browser_info->browser().get());
147 if (current_browser && current_browser->GetIdentifier() == tab_id) {
148 // Make sure we're operating in the same CefBrowserContext.
149 if (CefBrowserContext::FromBrowserContext(
150 current_browser->GetBrowserContext()) == cef_browser_context) {
151 return current_browser;
152 } else {
153 LOG(WARNING) << "Browser with tabId " << tab_id
154 << " cannot be accessed because is uses a different "
155 "CefRequestContext";
156 break;
157 }
158 }
159 }
160
161 return nullptr;
162 }
163
GetExtensionForUrl(content::BrowserContext * browser_context,const GURL & url)164 const Extension* GetExtensionForUrl(content::BrowserContext* browser_context,
165 const GURL& url) {
166 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context);
167 if (!registry)
168 return nullptr;
169 std::string extension_id = url.host();
170 return registry->enabled_extensions().GetByID(extension_id);
171 }
172
173 } // namespace extensions
174