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

Side by Side Diff: chrome/browser/guest_view/guest_view_manager.cc

Issue 464533002: Move guest_view to extensions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Small changes are made in guest_view_manager_unittest.cc Created 6 years, 4 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/guest_view/guest_view_manager.h"
6
7 #include "base/strings/stringprintf.h"
8 #include "chrome/browser/guest_view/guest_view_base.h"
9 #include "chrome/browser/guest_view/guest_view_manager_factory.h"
10 #include "content/public/browser/browser_context.h"
11 #include "content/public/browser/render_process_host.h"
12 #include "content/public/browser/user_metrics.h"
13 #include "content/public/browser/web_contents_observer.h"
14 #include "content/public/common/result_codes.h"
15 #include "content/public/common/url_constants.h"
16 #include "extensions/browser/extension_system.h"
17 #include "extensions/browser/guest_view/guest_view_constants.h"
18 #include "net/base/escape.h"
19 #include "url/gurl.h"
20
21 using content::BrowserContext;
22 using content::SiteInstance;
23 using content::WebContents;
24
25 // static
26 GuestViewManagerFactory* GuestViewManager::factory_ = NULL;
27
28 GuestViewManager::GuestViewManager(content::BrowserContext* context)
29 : current_instance_id_(0), last_instance_id_removed_(0), context_(context) {
30 }
31
32 GuestViewManager::~GuestViewManager() {}
33
34 // static.
35 GuestViewManager* GuestViewManager::FromBrowserContext(
36 BrowserContext* context) {
37 GuestViewManager* guest_manager =
38 static_cast<GuestViewManager*>(context->GetUserData(
39 guestview::kGuestViewManagerKeyName));
40 if (!guest_manager) {
41 if (factory_) {
42 guest_manager = factory_->CreateGuestViewManager(context);
43 } else {
44 guest_manager = new GuestViewManager(context);
45 }
46 context->SetUserData(guestview::kGuestViewManagerKeyName, guest_manager);
47 }
48 return guest_manager;
49 }
50
51 content::WebContents* GuestViewManager::GetGuestByInstanceIDSafely(
52 int guest_instance_id,
53 int embedder_render_process_id) {
54 if (!CanEmbedderAccessInstanceIDMaybeKill(embedder_render_process_id,
55 guest_instance_id)) {
56 return NULL;
57 }
58 return GetGuestByInstanceID(guest_instance_id);
59 }
60
61 int GuestViewManager::GetNextInstanceID() {
62 return ++current_instance_id_;
63 }
64
65 void GuestViewManager::CreateGuest(const std::string& view_type,
66 const std::string& embedder_extension_id,
67 content::WebContents* embedder_web_contents,
68 const base::DictionaryValue& create_params,
69 const WebContentsCreatedCallback& callback) {
70 int guest_instance_id = GetNextInstanceID();
71 GuestViewBase* guest =
72 GuestViewBase::Create(context_, guest_instance_id, view_type);
73 if (!guest) {
74 callback.Run(NULL);
75 return;
76 }
77 guest->Init(
78 embedder_extension_id, embedder_web_contents, create_params, callback);
79 }
80
81 content::WebContents* GuestViewManager::CreateGuestWithWebContentsParams(
82 const std::string& view_type,
83 const std::string& embedder_extension_id,
84 int embedder_render_process_id,
85 const content::WebContents::CreateParams& create_params) {
86 int guest_instance_id = GetNextInstanceID();
87 GuestViewBase* guest =
88 GuestViewBase::Create(context_, guest_instance_id, view_type);
89 if (!guest)
90 return NULL;
91 content::WebContents::CreateParams guest_create_params(create_params);
92 guest_create_params.guest_delegate = guest;
93 content::WebContents* guest_web_contents =
94 WebContents::Create(guest_create_params);
95 guest->InitWithWebContents(embedder_extension_id,
96 embedder_render_process_id,
97 guest_web_contents);
98 return guest_web_contents;
99 }
100
101 void GuestViewManager::MaybeGetGuestByInstanceIDOrKill(
102 int guest_instance_id,
103 int embedder_render_process_id,
104 const GuestByInstanceIDCallback& callback) {
105 if (!CanEmbedderAccessInstanceIDMaybeKill(embedder_render_process_id,
106 guest_instance_id)) {
107 // If we kill the embedder, then don't bother calling back.
108 return;
109 }
110 content::WebContents* guest_web_contents =
111 GetGuestByInstanceID(guest_instance_id);
112 callback.Run(guest_web_contents);
113 }
114
115 SiteInstance* GuestViewManager::GetGuestSiteInstance(
116 const GURL& guest_site) {
117 for (GuestInstanceMap::const_iterator it =
118 guest_web_contents_by_instance_id_.begin();
119 it != guest_web_contents_by_instance_id_.end(); ++it) {
120 if (it->second->GetSiteInstance()->GetSiteURL() == guest_site)
121 return it->second->GetSiteInstance();
122 }
123 return NULL;
124 }
125
126 bool GuestViewManager::ForEachGuest(WebContents* embedder_web_contents,
127 const GuestCallback& callback) {
128 for (GuestInstanceMap::iterator it =
129 guest_web_contents_by_instance_id_.begin();
130 it != guest_web_contents_by_instance_id_.end(); ++it) {
131 WebContents* guest = it->second;
132 GuestViewBase* guest_view = GuestViewBase::FromWebContents(guest);
133 if (embedder_web_contents != guest_view->embedder_web_contents())
134 continue;
135
136 if (callback.Run(guest))
137 return true;
138 }
139 return false;
140 }
141
142 void GuestViewManager::AddGuest(int guest_instance_id,
143 WebContents* guest_web_contents) {
144 CHECK(!ContainsKey(guest_web_contents_by_instance_id_, guest_instance_id));
145 CHECK(CanUseGuestInstanceID(guest_instance_id));
146 guest_web_contents_by_instance_id_[guest_instance_id] = guest_web_contents;
147 }
148
149 void GuestViewManager::RemoveGuest(int guest_instance_id) {
150 GuestInstanceMap::iterator it =
151 guest_web_contents_by_instance_id_.find(guest_instance_id);
152 DCHECK(it != guest_web_contents_by_instance_id_.end());
153 guest_web_contents_by_instance_id_.erase(it);
154
155 // All the instance IDs that lie within [0, last_instance_id_removed_]
156 // are invalid.
157 // The remaining sparse invalid IDs are kept in |removed_instance_ids_| set.
158 // The following code compacts the set by incrementing
159 // |last_instance_id_removed_|.
160 if (guest_instance_id == last_instance_id_removed_ + 1) {
161 ++last_instance_id_removed_;
162 // Compact.
163 std::set<int>::iterator iter = removed_instance_ids_.begin();
164 while (iter != removed_instance_ids_.end()) {
165 int instance_id = *iter;
166 // The sparse invalid IDs must not lie within
167 // [0, last_instance_id_removed_]
168 DCHECK(instance_id > last_instance_id_removed_);
169 if (instance_id != last_instance_id_removed_ + 1)
170 break;
171 ++last_instance_id_removed_;
172 removed_instance_ids_.erase(iter++);
173 }
174 } else {
175 removed_instance_ids_.insert(guest_instance_id);
176 }
177 }
178
179 content::WebContents* GuestViewManager::GetGuestByInstanceID(
180 int guest_instance_id) {
181 GuestInstanceMap::const_iterator it =
182 guest_web_contents_by_instance_id_.find(guest_instance_id);
183 if (it == guest_web_contents_by_instance_id_.end())
184 return NULL;
185 return it->second;
186 }
187
188 bool GuestViewManager::CanEmbedderAccessInstanceIDMaybeKill(
189 int embedder_render_process_id,
190 int guest_instance_id) {
191 if (!CanEmbedderAccessInstanceID(embedder_render_process_id,
192 guest_instance_id)) {
193 // The embedder process is trying to access a guest it does not own.
194 content::RecordAction(
195 base::UserMetricsAction("BadMessageTerminate_BPGM"));
196 base::KillProcess(
197 content::RenderProcessHost::FromID(embedder_render_process_id)->
198 GetHandle(),
199 content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
200 return false;
201 }
202 return true;
203 }
204
205 bool GuestViewManager::CanUseGuestInstanceID(int guest_instance_id) {
206 if (guest_instance_id <= last_instance_id_removed_)
207 return false;
208 return !ContainsKey(removed_instance_ids_, guest_instance_id);
209 }
210
211 bool GuestViewManager::CanEmbedderAccessInstanceID(
212 int embedder_render_process_id,
213 int guest_instance_id) {
214 // The embedder is trying to access a guest with a negative or zero
215 // instance ID.
216 if (guest_instance_id <= guestview::kInstanceIDNone)
217 return false;
218
219 // The embedder is trying to access an instance ID that has not yet been
220 // allocated by GuestViewManager. This could cause instance ID
221 // collisions in the future, and potentially give one embedder access to a
222 // guest it does not own.
223 if (guest_instance_id > current_instance_id_)
224 return false;
225
226 // We might get some late arriving messages at tear down. Let's let the
227 // embedder tear down in peace.
228 GuestInstanceMap::const_iterator it =
229 guest_web_contents_by_instance_id_.find(guest_instance_id);
230 if (it == guest_web_contents_by_instance_id_.end())
231 return true;
232
233 GuestViewBase* guest_view = GuestViewBase::FromWebContents(it->second);
234 if (!guest_view)
235 return false;
236
237 return embedder_render_process_id == guest_view->embedder_render_process_id();
238 }
OLDNEW
« no previous file with comments | « chrome/browser/guest_view/guest_view_manager.h ('k') | chrome/browser/guest_view/guest_view_manager_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698