1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "libcef/renderer/extensions/extensions_renderer_client.h"
6
7 #include "libcef/renderer/alloy/alloy_render_thread_observer.h"
8 #include "libcef/renderer/extensions/extensions_dispatcher_delegate.h"
9
10 #include "base/stl_util.h"
11 #include "chrome/common/url_constants.h"
12 #include "chrome/renderer/extensions/resource_request_policy.h"
13 #include "components/guest_view/renderer/guest_view_container_dispatcher.h"
14 #include "content/public/common/content_constants.h"
15 #include "content/public/renderer/render_frame.h"
16 #include "content/public/renderer/render_thread.h"
17 #include "extensions/common/constants.h"
18 #include "extensions/common/permissions/permissions_data.h"
19 #include "extensions/renderer/dispatcher.h"
20 #include "extensions/renderer/extension_frame_helper.h"
21 #include "extensions/renderer/extensions_render_frame_observer.h"
22 #include "extensions/renderer/renderer_extension_registry.h"
23 #include "extensions/renderer/script_context.h"
24 #include "third_party/blink/public/web/web_document.h"
25 #include "third_party/blink/public/web/web_local_frame.h"
26 #include "third_party/blink/public/web/web_plugin_params.h"
27
28 namespace extensions {
29
30 namespace {
31
IsGuestViewApiAvailableToScriptContext(bool * api_is_available,extensions::ScriptContext * context)32 void IsGuestViewApiAvailableToScriptContext(
33 bool* api_is_available,
34 extensions::ScriptContext* context) {
35 if (context->GetAvailability("guestViewInternal").is_available()) {
36 *api_is_available = true;
37 }
38 }
39
40 } // namespace
41
CefExtensionsRendererClient()42 CefExtensionsRendererClient::CefExtensionsRendererClient() {}
43
~CefExtensionsRendererClient()44 CefExtensionsRendererClient::~CefExtensionsRendererClient() {}
45
IsIncognitoProcess() const46 bool CefExtensionsRendererClient::IsIncognitoProcess() const {
47 return AlloyRenderThreadObserver::is_incognito_process();
48 }
49
GetLowestIsolatedWorldId() const50 int CefExtensionsRendererClient::GetLowestIsolatedWorldId() const {
51 // CEF doesn't need to reserve world IDs for anything other than extensions,
52 // so we always return 1. Note that 0 is reserved for the global world.
53 return 1;
54 }
55
GetDispatcher()56 extensions::Dispatcher* CefExtensionsRendererClient::GetDispatcher() {
57 return extension_dispatcher_.get();
58 }
59
OnExtensionLoaded(const extensions::Extension & extension)60 void CefExtensionsRendererClient::OnExtensionLoaded(
61 const extensions::Extension& extension) {
62 resource_request_policy_->OnExtensionLoaded(extension);
63 }
64
OnExtensionUnloaded(const extensions::ExtensionId & extension_id)65 void CefExtensionsRendererClient::OnExtensionUnloaded(
66 const extensions::ExtensionId& extension_id) {
67 resource_request_policy_->OnExtensionUnloaded(extension_id);
68 }
69
ExtensionAPIEnabledForServiceWorkerScript(const GURL & scope,const GURL & script_url) const70 bool CefExtensionsRendererClient::ExtensionAPIEnabledForServiceWorkerScript(
71 const GURL& scope,
72 const GURL& script_url) const {
73 // TODO(extensions): Implement to support background sevice worker scripts
74 // in extensions
75 return false;
76 }
77
RenderThreadStarted()78 void CefExtensionsRendererClient::RenderThreadStarted() {
79 content::RenderThread* thread = content::RenderThread::Get();
80
81 extension_dispatcher_ = std::make_unique<extensions::Dispatcher>(
82 std::make_unique<extensions::CefExtensionsDispatcherDelegate>());
83 extension_dispatcher_->OnRenderThreadStarted(thread);
84 resource_request_policy_ =
85 std::make_unique<extensions::ResourceRequestPolicy>(
86 extension_dispatcher_.get());
87 guest_view_container_dispatcher_ =
88 std::make_unique<guest_view::GuestViewContainerDispatcher>();
89
90 thread->AddObserver(extension_dispatcher_.get());
91 thread->AddObserver(guest_view_container_dispatcher_.get());
92 }
93
RenderFrameCreated(content::RenderFrame * render_frame,service_manager::BinderRegistry * registry)94 void CefExtensionsRendererClient::RenderFrameCreated(
95 content::RenderFrame* render_frame,
96 service_manager::BinderRegistry* registry) {
97 new extensions::ExtensionsRenderFrameObserver(render_frame, registry);
98 new extensions::ExtensionFrameHelper(render_frame,
99 extension_dispatcher_.get());
100 extension_dispatcher_->OnRenderFrameCreated(render_frame);
101 }
102
OverrideCreatePlugin(content::RenderFrame * render_frame,const blink::WebPluginParams & params)103 bool CefExtensionsRendererClient::OverrideCreatePlugin(
104 content::RenderFrame* render_frame,
105 const blink::WebPluginParams& params) {
106 if (params.mime_type.Utf8() != content::kBrowserPluginMimeType)
107 return true;
108
109 bool guest_view_api_available = false;
110 extension_dispatcher_->script_context_set_iterator()->ForEach(
111 render_frame, base::BindRepeating(&IsGuestViewApiAvailableToScriptContext,
112 &guest_view_api_available));
113 return !guest_view_api_available;
114 }
115
WillSendRequest(blink::WebLocalFrame * frame,ui::PageTransition transition_type,const blink::WebURL & url,const net::SiteForCookies & site_for_cookies,const url::Origin * initiator_origin,GURL * new_url)116 void CefExtensionsRendererClient::WillSendRequest(
117 blink::WebLocalFrame* frame,
118 ui::PageTransition transition_type,
119 const blink::WebURL& url,
120 const net::SiteForCookies& site_for_cookies,
121 const url::Origin* initiator_origin,
122 GURL* new_url) {
123 // Check whether the request should be allowed. If not allowed, we reset the
124 // URL to something invalid to prevent the request and cause an error.
125 if (url.ProtocolIs(extensions::kExtensionScheme) &&
126 !resource_request_policy_->CanRequestResource(
127 GURL(url), frame, transition_type,
128 base::OptionalFromPtr(initiator_origin))) {
129 *new_url = GURL(chrome::kExtensionInvalidRequestURL);
130 }
131 }
132
RunScriptsAtDocumentStart(content::RenderFrame * render_frame)133 void CefExtensionsRendererClient::RunScriptsAtDocumentStart(
134 content::RenderFrame* render_frame) {
135 extension_dispatcher_->RunScriptsAtDocumentStart(render_frame);
136 }
137
RunScriptsAtDocumentEnd(content::RenderFrame * render_frame)138 void CefExtensionsRendererClient::RunScriptsAtDocumentEnd(
139 content::RenderFrame* render_frame) {
140 extension_dispatcher_->RunScriptsAtDocumentEnd(render_frame);
141 }
142
RunScriptsAtDocumentIdle(content::RenderFrame * render_frame)143 void CefExtensionsRendererClient::RunScriptsAtDocumentIdle(
144 content::RenderFrame* render_frame) {
145 extension_dispatcher_->RunScriptsAtDocumentIdle(render_frame);
146 }
147
148 } // namespace extensions
149