Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: extensions/browser/extension_web_contents_observer.cc

Issue 1413853005: Track all extension frames in ProcessManager, inspect extensionoptions (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nits, git cl format, fix error in ExtensionWebContentsObserver::GetExtensionFromFrame, exclude kGue… Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/extension_web_contents_observer.h" 5 #include "extensions/browser/extension_web_contents_observer.h"
6 6
7 #include "base/command_line.h"
8 #include "components/guest_view/browser/guest_view_base.h"
7 #include "content/public/browser/child_process_security_policy.h" 9 #include "content/public/browser/child_process_security_policy.h"
10 #include "content/public/browser/navigation_details.h"
8 #include "content/public/browser/render_frame_host.h" 11 #include "content/public/browser/render_frame_host.h"
9 #include "content/public/browser/render_process_host.h" 12 #include "content/public/browser/render_process_host.h"
10 #include "content/public/browser/render_view_host.h" 13 #include "content/public/browser/render_view_host.h"
11 #include "content/public/browser/site_instance.h" 14 #include "content/public/browser/site_instance.h"
12 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
16 #include "content/public/common/content_switches.h"
13 #include "content/public/common/url_constants.h" 17 #include "content/public/common/url_constants.h"
14 #include "extensions/browser/extension_prefs.h" 18 #include "extensions/browser/extension_prefs.h"
15 #include "extensions/browser/extension_registry.h" 19 #include "extensions/browser/extension_registry.h"
16 #include "extensions/browser/extensions_browser_client.h" 20 #include "extensions/browser/extensions_browser_client.h"
17 #include "extensions/browser/mojo/service_registration.h" 21 #include "extensions/browser/mojo/service_registration.h"
18 #include "extensions/browser/process_manager.h" 22 #include "extensions/browser/process_manager.h"
19 #include "extensions/browser/view_type_utils.h" 23 #include "extensions/browser/view_type_utils.h"
20 #include "extensions/common/constants.h" 24 #include "extensions/common/constants.h"
21 #include "extensions/common/extension.h" 25 #include "extensions/common/extension.h"
22 #include "extensions/common/extension_messages.h" 26 #include "extensions/common/extension_messages.h"
(...skipping 20 matching lines...) Expand all
43 } 47 }
44 48
45 ExtensionWebContentsObserver::~ExtensionWebContentsObserver() { 49 ExtensionWebContentsObserver::~ExtensionWebContentsObserver() {
46 } 50 }
47 51
48 void ExtensionWebContentsObserver::InitializeRenderFrame( 52 void ExtensionWebContentsObserver::InitializeRenderFrame(
49 content::RenderFrameHost* render_frame_host) { 53 content::RenderFrameHost* render_frame_host) {
50 DCHECK(render_frame_host); 54 DCHECK(render_frame_host);
51 DCHECK(render_frame_host->IsRenderFrameLive()); 55 DCHECK(render_frame_host->IsRenderFrameLive());
52 56
57 ViewType view_type = GetViewType(web_contents());
58 if (view_type == VIEW_TYPE_INVALID) {
59 // This is expected to happen only for non-extension pages (e.g. devtools)
60 // and GuestViews.
61 DCHECK(guest_view::GuestViewBase::FromWebContents(web_contents()) ||
62 !render_frame_host->GetSiteInstance()->GetSiteURL().SchemeIs(
63 kExtensionScheme));
64 return;
65 }
66
67 // At the initialization of the render frame, the last committed URL is not
68 // reliable, so do not take it into account in determining whether it is an
69 // extension frame.
70 const Extension* frame_extension =
71 GetExtensionFromFrame(render_frame_host, false);
72 // Only extension frames should be reported if site isolation is enabled, so
73 // |frame_extension| should exist at this point.
74 DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
75 switches::kSitePerProcess) ||
76 frame_extension);
77 if (!frame_extension)
78 return;
79
53 // Notify the render frame of the view type. 80 // Notify the render frame of the view type.
54 render_frame_host->Send(new ExtensionMsg_NotifyRenderViewType( 81 render_frame_host->Send(new ExtensionMsg_NotifyRenderViewType(
55 render_frame_host->GetRoutingID(), GetViewType(web_contents()))); 82 render_frame_host->GetRoutingID(), view_type));
56 83
57 const Extension* frame_extension = GetExtensionFromFrame(render_frame_host); 84 ExtensionsBrowserClient::Get()->RegisterMojoServices(render_frame_host,
58 if (frame_extension) { 85 frame_extension);
59 ExtensionsBrowserClient::Get()->RegisterMojoServices(render_frame_host, 86 ProcessManager::Get(browser_context_)
60 frame_extension); 87 ->RegisterRenderFrameHost(web_contents(), render_frame_host,
61 ProcessManager::Get(browser_context_) 88 frame_extension);
62 ->RegisterRenderFrameHost(web_contents(), render_frame_host,
63 frame_extension);
64 }
65 } 89 }
66 90
67 content::WebContents* ExtensionWebContentsObserver::GetAssociatedWebContents() 91 content::WebContents* ExtensionWebContentsObserver::GetAssociatedWebContents()
68 const { 92 const {
69 return web_contents(); 93 return web_contents();
70 } 94 }
71 95
72 void ExtensionWebContentsObserver::RenderViewCreated( 96 void ExtensionWebContentsObserver::RenderViewCreated(
73 content::RenderViewHost* render_view_host) { 97 content::RenderViewHost* render_view_host) {
74 // TODO(devlin): Most/all of this should move to RenderFrameCreated. 98 // TODO(devlin): Most/all of this should move to RenderFrameCreated.
(...skipping 28 matching lines...) Expand all
103 content::RenderFrameHost* render_frame_host) { 127 content::RenderFrameHost* render_frame_host) {
104 InitializeRenderFrame(render_frame_host); 128 InitializeRenderFrame(render_frame_host);
105 } 129 }
106 130
107 void ExtensionWebContentsObserver::RenderFrameDeleted( 131 void ExtensionWebContentsObserver::RenderFrameDeleted(
108 content::RenderFrameHost* render_frame_host) { 132 content::RenderFrameHost* render_frame_host) {
109 ProcessManager::Get(browser_context_) 133 ProcessManager::Get(browser_context_)
110 ->UnregisterRenderFrameHost(render_frame_host); 134 ->UnregisterRenderFrameHost(render_frame_host);
111 } 135 }
112 136
137 void ExtensionWebContentsObserver::DidCommitProvisionalLoadForFrame(
138 content::RenderFrameHost* render_frame_host,
139 const GURL& url,
140 ui::PageTransition transition_type) {
141 ProcessManager* pm = ProcessManager::Get(browser_context_);
142
143 if (pm->IsRenderFrameHostRegistered(render_frame_host)) {
144 const Extension* frame_extension =
145 GetExtensionFromFrame(render_frame_host, true);
146
147 if (!frame_extension)
148 pm->UnregisterRenderFrameHost(render_frame_host);
149 }
150 }
151
152 void ExtensionWebContentsObserver::DidNavigateAnyFrame(
153 content::RenderFrameHost* render_frame_host,
154 const content::LoadCommittedDetails& details,
155 const content::FrameNavigateParams& params) {
156 if (details.is_in_page)
157 return;
158
159 const Extension* frame_extension =
160 GetExtensionFromFrame(render_frame_host, true);
161 ProcessManager* pm = ProcessManager::Get(browser_context_);
162
163 if (!frame_extension) {
164 // Should have been unregistered by DidCommitProvisionalLoadForFrame.
165 DCHECK(!pm->IsRenderFrameHostRegistered(render_frame_host));
166 return;
167 }
168
169 if (pm->IsRenderFrameHostRegistered(render_frame_host)) {
170 // Notify ProcessManager, because some clients do not just want to know
171 // whether the frame is in an extension process, but also whether the frame
172 // was navigated.
173 pm->DidNavigateRenderFrameHost(render_frame_host);
174 } else {
175 pm->RegisterRenderFrameHost(web_contents(), render_frame_host,
176 frame_extension);
177 }
178 }
179
113 bool ExtensionWebContentsObserver::OnMessageReceived( 180 bool ExtensionWebContentsObserver::OnMessageReceived(
114 const IPC::Message& message, 181 const IPC::Message& message,
115 content::RenderFrameHost* render_frame_host) { 182 content::RenderFrameHost* render_frame_host) {
116 bool handled = true; 183 bool handled = true;
117 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM( 184 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(
118 ExtensionWebContentsObserver, message, render_frame_host) 185 ExtensionWebContentsObserver, message, render_frame_host)
119 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) 186 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
120 IPC_MESSAGE_UNHANDLED(handled = false) 187 IPC_MESSAGE_UNHANDLED(handled = false)
121 IPC_END_MESSAGE_MAP() 188 IPC_END_MESSAGE_MAP()
122 return handled; 189 return handled;
(...skipping 16 matching lines...) Expand all
139 ProcessManager::Get(browser_context_); 206 ProcessManager::Get(browser_context_);
140 const Extension* const extension = 207 const Extension* const extension =
141 process_manager->GetExtensionForWebContents(web_contents()); 208 process_manager->GetExtensionForWebContents(web_contents());
142 if (extension) 209 if (extension)
143 process_manager->DecrementLazyKeepaliveCount(extension); 210 process_manager->DecrementLazyKeepaliveCount(extension);
144 } 211 }
145 } 212 }
146 213
147 std::string ExtensionWebContentsObserver::GetExtensionIdFromFrame( 214 std::string ExtensionWebContentsObserver::GetExtensionIdFromFrame(
148 content::RenderFrameHost* render_frame_host) const { 215 content::RenderFrameHost* render_frame_host) const {
149 content::SiteInstance* site_instance = render_frame_host->GetSiteInstance(); 216 const Extension* extension = GetExtensionFromFrame(render_frame_host, true);
150 GURL url = render_frame_host->GetLastCommittedURL(); 217 return extension ? extension->id() : std::string();
151 if (!url.is_empty()) {
152 if (site_instance->GetSiteURL().GetOrigin() != url.GetOrigin())
153 return std::string();
154 } else {
155 url = site_instance->GetSiteURL();
156 }
157
158 return url.SchemeIs(kExtensionScheme) ? url.host() : std::string();
159 } 218 }
160 219
161 const Extension* ExtensionWebContentsObserver::GetExtensionFromFrame( 220 const Extension* ExtensionWebContentsObserver::GetExtensionFromFrame(
162 content::RenderFrameHost* render_frame_host) const { 221 content::RenderFrameHost* render_frame_host,
163 return ExtensionRegistry::Get( 222 bool verify_url) const {
164 render_frame_host->GetProcess()->GetBrowserContext()) 223 const GURL site_url(render_frame_host->GetSiteInstance()->GetSiteURL());
165 ->enabled_extensions() 224 if (!site_url.SchemeIs(kExtensionScheme))
166 .GetByID(GetExtensionIdFromFrame(render_frame_host)); 225 return nullptr;
226
227 const std::string& extension_id = site_url.host();
228 const Extension* extension =
229 ExtensionRegistry::Get(
230 render_frame_host->GetProcess()->GetBrowserContext())
231 ->enabled_extensions()
232 .GetByID(extension_id);
233 if (!extension)
234 return nullptr;
235
236 if (verify_url) {
237 // Without site isolation, this check is needed to eliminate non-extension
238 // schemes. With site isolation, this is still needed to exclude sandboxed
239 // extension frames with a unique origin.
240 if (!render_frame_host->GetLastCommittedOrigin().IsSameOriginWith(
241 url::Origin(site_url)) &&
ncarter (slow) 2015/12/01 17:51:42 I think this works only because extension urls don
robwu 2015/12/01 23:19:58 Done.
242 (!extension->is_hosted_app() ||
243 !extension->web_extent().MatchesURL(
244 render_frame_host->GetLastCommittedURL())))
ncarter (slow) 2015/12/01 17:51:42 Does this MatchesURL logic work properly for the a
robwu 2015/12/01 23:19:58 No.
245 return nullptr;
246 }
247
248 return extension;
167 } 249 }
168 250
169 const Extension* ExtensionWebContentsObserver::GetExtension( 251 const Extension* ExtensionWebContentsObserver::GetExtension(
170 content::RenderViewHost* render_view_host) { 252 content::RenderViewHost* render_view_host) {
171 std::string extension_id = GetExtensionId(render_view_host); 253 std::string extension_id = GetExtensionId(render_view_host);
172 if (extension_id.empty()) 254 if (extension_id.empty())
173 return NULL; 255 return NULL;
174 256
175 // May be null if the extension doesn't exist, for example if somebody typos 257 // May be null if the extension doesn't exist, for example if somebody typos
176 // a chrome-extension:// URL. 258 // a chrome-extension:// URL.
(...skipping 26 matching lines...) Expand all
203 // Since this is called for all existing RenderFrameHosts during the 285 // Since this is called for all existing RenderFrameHosts during the
204 // ExtensionWebContentsObserver's creation, it's possible that not all hosts 286 // ExtensionWebContentsObserver's creation, it's possible that not all hosts
205 // are ready. 287 // are ready.
206 // We only initialize the frame if the renderer counterpart is live; otherwise 288 // We only initialize the frame if the renderer counterpart is live; otherwise
207 // we wait for the RenderFrameCreated notification. 289 // we wait for the RenderFrameCreated notification.
208 if (render_frame_host->IsRenderFrameLive()) 290 if (render_frame_host->IsRenderFrameLive())
209 InitializeRenderFrame(render_frame_host); 291 InitializeRenderFrame(render_frame_host);
210 } 292 }
211 293
212 } // namespace extensions 294 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698