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/features/runtime_checks.h"
14
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/printing/print_preview_dialog_controller.h"
17 #include "content/browser/browser_plugin/browser_plugin_embedder.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
GetFullPageGuestForOwnerContents(content::WebContents * owner)38 content::WebContents* GetFullPageGuestForOwnerContents(
39 content::WebContents* owner) {
40 content::WebContentsImpl* owner_impl =
41 static_cast<content::WebContentsImpl*>(owner);
42 content::BrowserPluginEmbedder* plugin_embedder =
43 owner_impl->GetBrowserPluginEmbedder();
44 if (plugin_embedder) {
45 content::BrowserPluginGuest* plugin_guest =
46 plugin_embedder->GetFullPageGuest();
47 if (plugin_guest)
48 return plugin_guest->web_contents();
49 }
50 return nullptr;
51 }
52
GetAllGuestsForOwnerContents(content::WebContents * owner,std::vector<content::WebContents * > * guests)53 void GetAllGuestsForOwnerContents(content::WebContents* owner,
54 std::vector<content::WebContents*>* guests) {
55 content::BrowserPluginGuestManager* plugin_guest_manager =
56 owner->GetBrowserContext()->GetGuestManager();
57 plugin_guest_manager->ForEachGuest(owner,
58 base::Bind(InsertWebContents, guests));
59 }
60
GetOwnerForGuestContents(content::WebContents * guest)61 content::WebContents* GetOwnerForGuestContents(content::WebContents* guest) {
62 content::WebContentsImpl* guest_impl =
63 static_cast<content::WebContentsImpl*>(guest);
64 content::BrowserPluginGuest* plugin_guest =
65 guest_impl->GetBrowserPluginGuest();
66 if (plugin_guest) {
67 return plugin_guest->owner_web_contents();
68 }
69
70 // Maybe it's a print preview dialog.
71 auto print_preview_controller =
72 g_browser_process->print_preview_dialog_controller();
73 return print_preview_controller->GetInitiator(guest);
74 }
75
GetOwnerBrowserForFrameRoute(int render_process_id,int render_routing_id,bool * is_guest_view)76 CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForFrameRoute(
77 int render_process_id,
78 int render_routing_id,
79 bool* is_guest_view) {
80 if (CEF_CURRENTLY_ON_UIT()) {
81 // Use the non-thread-safe but potentially faster approach.
82 content::RenderFrameHost* host =
83 content::RenderFrameHost::FromID(render_process_id, render_routing_id);
84 if (host)
85 return GetOwnerBrowserForHost(host, is_guest_view);
86 return nullptr;
87 } else {
88 // Use the thread-safe approach.
89 scoped_refptr<CefBrowserInfo> info =
90 CefBrowserInfoManager::GetInstance()->GetBrowserInfoForFrameRoute(
91 render_process_id, render_routing_id, is_guest_view);
92 if (info.get()) {
93 CefRefPtr<CefBrowserHostBase> browser = info->browser();
94 if (!browser.get()) {
95 LOG(WARNING) << "Found browser id " << info->browser_id()
96 << " but no browser object matching view process id "
97 << render_process_id << " and frame routing id "
98 << render_routing_id;
99 }
100 return browser;
101 }
102 return nullptr;
103 }
104 }
105
GetOwnerBrowserForHost(content::RenderViewHost * host,bool * is_guest_view)106 CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForHost(
107 content::RenderViewHost* host,
108 bool* is_guest_view) {
109 if (is_guest_view)
110 *is_guest_view = false;
111
112 CefRefPtr<CefBrowserHostBase> browser =
113 CefBrowserHostBase::GetBrowserForHost(host);
114 if (!browser.get() && ExtensionsEnabled()) {
115 // Retrieve the owner browser, if any.
116 content::WebContents* owner = GetOwnerForGuestContents(
117 content::WebContents::FromRenderViewHost(host));
118 if (owner) {
119 browser = CefBrowserHostBase::GetBrowserForContents(owner);
120 if (browser.get() && is_guest_view)
121 *is_guest_view = true;
122 }
123 }
124 return browser;
125 }
126
GetOwnerBrowserForHost(content::RenderFrameHost * host,bool * is_guest_view)127 CefRefPtr<CefBrowserHostBase> GetOwnerBrowserForHost(
128 content::RenderFrameHost* host,
129 bool* is_guest_view) {
130 if (is_guest_view)
131 *is_guest_view = false;
132
133 CefRefPtr<CefBrowserHostBase> browser =
134 CefBrowserHostBase::GetBrowserForHost(host);
135 if (!browser.get() && ExtensionsEnabled()) {
136 // Retrieve the owner browser, if any.
137 content::WebContents* owner = GetOwnerForGuestContents(
138 content::WebContents::FromRenderFrameHost(host));
139 if (owner) {
140 browser = CefBrowserHostBase::GetBrowserForContents(owner);
141 if (browser.get() && is_guest_view)
142 *is_guest_view = true;
143 }
144 }
145 return browser;
146 }
147
GetBrowserForTabId(int tab_id,content::BrowserContext * browser_context)148 CefRefPtr<AlloyBrowserHostImpl> GetBrowserForTabId(
149 int tab_id,
150 content::BrowserContext* browser_context) {
151 REQUIRE_ALLOY_RUNTIME();
152 CEF_REQUIRE_UIT();
153 DCHECK(browser_context);
154 if (tab_id < 0 || !browser_context)
155 return nullptr;
156
157 auto cef_browser_context =
158 CefBrowserContext::FromBrowserContext(browser_context);
159
160 for (const auto& browser_info :
161 CefBrowserInfoManager::GetInstance()->GetBrowserInfoList()) {
162 CefRefPtr<AlloyBrowserHostImpl> current_browser =
163 static_cast<AlloyBrowserHostImpl*>(browser_info->browser().get());
164 if (current_browser && current_browser->GetIdentifier() == tab_id) {
165 // Make sure we're operating in the same CefBrowserContext.
166 if (CefBrowserContext::FromBrowserContext(
167 current_browser->GetBrowserContext()) == cef_browser_context) {
168 return current_browser;
169 } else {
170 LOG(WARNING) << "Browser with tabId " << tab_id
171 << " cannot be accessed because is uses a different "
172 "CefRequestContext";
173 break;
174 }
175 }
176 }
177
178 return nullptr;
179 }
180
GetExtensionForUrl(content::BrowserContext * browser_context,const GURL & url)181 const Extension* GetExtensionForUrl(content::BrowserContext* browser_context,
182 const GURL& url) {
183 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context);
184 if (!registry)
185 return nullptr;
186 std::string extension_id = url.host();
187 return registry->enabled_extensions().GetByID(extension_id);
188 }
189
190 } // namespace extensions
191