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

Side by Side Diff: chrome/browser/guestview/guestview_manager.cc

Issue 258373002: Towards moving guest management to chrome: Introduce GuestViewManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 months 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
(Empty)
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 "chrome/browser/guestview/guestview_manager.h"
6
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/guestview/guestview.h"
9 #include "chrome/browser/guestview/guestview_constants.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "content/public/browser/browser_context.h"
12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/browser/user_metrics.h"
14 #include "content/public/browser/web_contents_observer.h"
15 #include "content/public/common/result_codes.h"
16 #include "extensions/browser/extension_system.h"
17 #include "url/gurl.h"
18
19 using content::BrowserContext;
20 using content::SiteInstance;
21 using content::WebContents;
22
23 class GuestWebContentsObserver
24 : public content::WebContentsObserver {
25 public:
26 explicit GuestWebContentsObserver(WebContents* guest)
lazyboy 2014/04/30 08:40:15 s/guest/guest_web_contents
27 : WebContentsObserver(guest) {
28 }
29
30 virtual ~GuestWebContentsObserver() {
31 }
32
33 // WebContentsObserver:
34 virtual void DidStartProvisionalLoadForFrame(
35 int64 frame_id,
36 int64 parent_frame_id,
37 bool is_main_frame,
38 const GURL& validated_url,
39 bool is_error_page,
40 bool is_iframe_srcdoc,
41 content::RenderViewHost* render_view_host) OVERRIDE {
42 GuestViewManager::FromBrowserContext(web_contents()->GetBrowserContext())->
43 AddRenderProcessHostID(web_contents()->GetRenderProcessHost()->GetID());
44 delete this;
45 }
46
47 private:
48 DISALLOW_COPY_AND_ASSIGN(GuestWebContentsObserver);
49 };
50
51 GuestViewManager::GuestViewManager(content::BrowserContext* context)
52 : next_instance_id_(0),
53 context_(context) {}
54
55 GuestViewManager::~GuestViewManager() {}
56
57 // static.
58 GuestViewManager* GuestViewManager::FromBrowserContext(
59 BrowserContext* context) {
60 GuestViewManager* guest_manager =
61 static_cast<GuestViewManager*>(context->GetUserData(
62 guestview::kGuestViewManagerKeyName));
63 if (!guest_manager) {
64 guest_manager = new GuestViewManager(context);
65 context->SetUserData(guestview::kGuestViewManagerKeyName, guest_manager);
66 }
67 return guest_manager;
68 }
69
70 int GuestViewManager::GetNextInstanceID() {
71 return ++next_instance_id_;
72 }
73
74 void GuestViewManager::AddGuest(int guest_instance_id,
75 WebContents* guest_web_contents) {
76 DCHECK(guest_web_contents_by_instance_id_.find(guest_instance_id) ==
77 guest_web_contents_by_instance_id_.end());
78 guest_web_contents_by_instance_id_[guest_instance_id] = guest_web_contents;
79 // Add the RenderProcessHost ID when we get one.
80 new GuestWebContentsObserver(guest_web_contents);
81 }
82
83 void GuestViewManager::RemoveGuest(int guest_instance_id) {
84 GuestInstanceMap::iterator it =
85 guest_web_contents_by_instance_id_.find(guest_instance_id);
86 DCHECK(it != guest_web_contents_by_instance_id_.end());
87 render_process_host_id_set_.erase(
88 it->second->GetRenderProcessHost()->GetID());
89 guest_web_contents_by_instance_id_.erase(it);
90 }
91
92 content::WebContents* GuestViewManager::GetGuestByInstanceID(
93 int guest_instance_id,
94 int embedder_render_process_id) {
95 if (!CanEmbedderAccessInstanceIDMaybeKill(embedder_render_process_id,
96 guest_instance_id)) {
97 return NULL;
98 }
99 GuestInstanceMap::const_iterator it =
100 guest_web_contents_by_instance_id_.find(guest_instance_id);
101 if (it == guest_web_contents_by_instance_id_.end())
102 return NULL;
103 return it->second;
104 }
105
106 bool GuestViewManager::CanEmbedderAccessInstanceIDMaybeKill(
107 int embedder_render_process_id,
108 int guest_instance_id) {
109 if (!CanEmbedderAccessInstanceID(embedder_render_process_id,
110 guest_instance_id)) {
111 // The embedder process is trying to access a guest it does not own.
112 content::RecordAction(
113 base::UserMetricsAction("BadMessageTerminate_BPGM"));
114 base::KillProcess(
115 content::RenderProcessHost::FromID(embedder_render_process_id)->
116 GetHandle(),
117 content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
118 return false;
119 }
120 return true;
121 }
122
123 bool GuestViewManager::CanEmbedderAccessInstanceID(
124 int embedder_render_process_id,
125 int guest_instance_id) {
126 // The embedder is trying to access a guest with a negative or zero
127 // instance ID.
128 if (guest_instance_id <= guestview::kInstanceIDNone)
129 return false;
130
131 // The embedder is trying to access an instance ID that has not yet been
132 // allocated by GuestViewManager. This could cause instance ID
133 // collisions in the future, and potentially give one embedder access to a
134 // guest it does not own.
135 if (guest_instance_id > next_instance_id_)
136 return false;
137
138 GuestInstanceMap::const_iterator it =
139 guest_web_contents_by_instance_id_.find(guest_instance_id);
140 if (it == guest_web_contents_by_instance_id_.end())
141 return true;
142
143 GuestView* guest_view = GuestView::FromWebContents(it->second);
144 if (!guest_view)
145 return false;
146
147 return CanEmbedderAccessGuest(embedder_render_process_id, guest_view);
148 }
149
150 SiteInstance* GuestViewManager::GetGuestSiteInstance(
151 const GURL& guest_site) {
152 for (GuestInstanceMap::const_iterator it =
153 guest_web_contents_by_instance_id_.begin();
154 it != guest_web_contents_by_instance_id_.end(); ++it) {
155 if (it->second->GetSiteInstance()->GetSiteURL() == guest_site)
156 return it->second->GetSiteInstance();
157 }
158 return NULL;
159 }
160
161 bool GuestViewManager::ForEachGuest(WebContents* embedder_web_contents,
162 const GuestCallback& callback) {
163 for (GuestInstanceMap::iterator it =
164 guest_web_contents_by_instance_id_.begin();
165 it != guest_web_contents_by_instance_id_.end(); ++it) {
166 WebContents* guest = it->second;
167 if (embedder_web_contents != guest->GetEmbedderWebContents())
168 continue;
169
170 if (callback.Run(guest))
171 return true;
172 }
173 return false;
174 }
175
176 void GuestViewManager::RequestInstanceID(
177 const std::string& src,
178 const InstanceIDResponseCallback& callback) {
179 GURL url(src);
180 if (!url.is_valid() || !url.SchemeIs("chrome-extension")) {
181 callback.Run(GetNextInstanceID());
182 return;
183 }
184 const std::string& extension_id = url.host();
185 Profile* profile = Profile::FromBrowserContext(context_);
186 ExtensionService* service =
187 extensions::ExtensionSystem::Get(profile)->extension_service();
188 if (!service) {
189 callback.Run(GetNextInstanceID());
190 return;
191 }
192 const extensions::Extension* extension =
193 service->GetExtensionById(extension_id, false);
194 if (!extension || !extension->is_platform_app()) {
195 callback.Run(GetNextInstanceID());
196 return;
197 }
198 callback.Run(GetNextInstanceID());
199 }
200
201 void GuestViewManager::AddRenderProcessHostID(int render_process_host_id) {
202 render_process_host_id_set_.insert(render_process_host_id);
203 }
204
205 bool GuestViewManager::CanEmbedderAccessGuest(int embedder_render_process_id,
206 GuestView* guest) {
207 // The embedder can access the guest if it has not been attached and its
208 // opener's embedder lives in the same process as the given embedder.
209 if (!guest->attached()) {
210 if (!guest->GetOpener())
211 return false;
212
213 return embedder_render_process_id ==
214 guest->GetOpener()->GetEmbedderWebContents()->GetRenderProcessHost()->
215 GetID();
216 }
217
218 return embedder_render_process_id ==
219 guest->embedder_web_contents()->GetRenderProcessHost()->GetID();
220 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698