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