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

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

Issue 1232603002: This patch improves the way that GuestViewManager tracks the destruction of GuestView embedders. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comment by fsamuel@. Created 5 years, 5 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
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 "components/guest_view/browser/guest_view_manager.h" 5 #include "components/guest_view/browser/guest_view_manager.h"
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "components/guest_view/browser/guest_view_base.h" 9 #include "components/guest_view/browser/guest_view_base.h"
10 #include "components/guest_view/browser/guest_view_manager_delegate.h" 10 #include "components/guest_view/browser/guest_view_manager_delegate.h"
11 #include "components/guest_view/browser/guest_view_manager_factory.h" 11 #include "components/guest_view/browser/guest_view_manager_factory.h"
12 #include "components/guest_view/common/guest_view_constants.h" 12 #include "components/guest_view/common/guest_view_constants.h"
13 #include "content/public/browser/browser_context.h" 13 #include "content/public/browser/browser_context.h"
14 #include "content/public/browser/render_frame_host.h" 14 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/browser/render_process_host.h" 15 #include "content/public/browser/render_process_host.h"
16 #include "content/public/browser/render_view_host.h" 16 #include "content/public/browser/render_view_host.h"
17 #include "content/public/browser/user_metrics.h" 17 #include "content/public/browser/user_metrics.h"
18 #include "content/public/browser/web_contents_observer.h" 18 #include "content/public/browser/web_contents_observer.h"
19 #include "content/public/common/child_process_host.h" 19 #include "content/public/common/child_process_host.h"
20 #include "content/public/common/result_codes.h" 20 #include "content/public/common/result_codes.h"
21 #include "content/public/common/url_constants.h" 21 #include "content/public/common/url_constants.h"
22 #include "url/gurl.h" 22 #include "url/gurl.h"
23 23
24 using content::BrowserContext; 24 using content::BrowserContext;
25 using content::RenderProcessHost;
25 using content::SiteInstance; 26 using content::SiteInstance;
26 using content::WebContents; 27 using content::WebContents;
27 28
28 namespace guest_view { 29 namespace guest_view {
29 30
31 // This observer observes the RenderProcessHosts of GuestView embedders, and
32 // notifies the GuestViewManager when they are destroyed.
33 class GuestViewManager::EmbedderRenderProcessHostObserver
34 : public content::RenderProcessHostObserver {
35 public:
36 EmbedderRenderProcessHostObserver(GuestViewManager* guest_view_manager,
37 int embedder_process_id)
38 : guest_view_manager_(guest_view_manager), id_(embedder_process_id) {
39 RenderProcessHost* rph = RenderProcessHost::FromID(id_);
40 rph->AddObserver(this);
41 }
42
43 ~EmbedderRenderProcessHostObserver() override {
44 RenderProcessHost* rph = RenderProcessHost::FromID(id_);
45 if (rph)
46 rph->RemoveObserver(this);
47 }
48
49 void RenderProcessHostDestroyed(RenderProcessHost* host) override {
50 guest_view_manager_->EmbedderProcessDestroyed(id_);
51 delete this;
52 }
53
54 private:
55 GuestViewManager* guest_view_manager_;
56 int id_;
57 };
58
30 // static 59 // static
31 GuestViewManagerFactory* GuestViewManager::factory_ = nullptr; 60 GuestViewManagerFactory* GuestViewManager::factory_ = nullptr;
32 61
33 GuestViewManager::GuestViewManager( 62 GuestViewManager::GuestViewManager(
34 content::BrowserContext* context, 63 content::BrowserContext* context,
35 scoped_ptr<GuestViewManagerDelegate> delegate) 64 scoped_ptr<GuestViewManagerDelegate> delegate)
36 : current_instance_id_(0), 65 : current_instance_id_(0),
37 last_instance_id_removed_(0), 66 last_instance_id_removed_(0),
38 context_(context), 67 context_(context),
39 delegate_(delegate.Pass()) { 68 delegate_(delegate.Pass()) {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 if (instance_id != last_instance_id_removed_ + 1) 267 if (instance_id != last_instance_id_removed_ + 1)
239 break; 268 break;
240 ++last_instance_id_removed_; 269 ++last_instance_id_removed_;
241 removed_instance_ids_.erase(iter++); 270 removed_instance_ids_.erase(iter++);
242 } 271 }
243 } else { 272 } else {
244 removed_instance_ids_.insert(guest_instance_id); 273 removed_instance_ids_.insert(guest_instance_id);
245 } 274 }
246 } 275 }
247 276
248 void GuestViewManager::EmbedderWillBeDestroyed(int embedder_process_id) { 277 void GuestViewManager::EmbedderProcessDestroyed(int embedder_process_id) {
249 // Find and call any callbacks associated with the embedder that is being 278 CallViewDestructionCallbacks(embedder_process_id);
250 // destroyed.
251 auto embedder_it = view_destruction_callback_map_.find(embedder_process_id);
252 if (embedder_it == view_destruction_callback_map_.end())
253 return;
254 CallbacksForEachViewID& callbacks_for_embedder = embedder_it->second;
255 for (auto& view_pair : callbacks_for_embedder) {
256 Callbacks& callbacks_for_view = view_pair.second;
257 for (auto& callback : callbacks_for_view) {
258 callback.Run();
259 }
260 }
261 view_destruction_callback_map_.erase(embedder_it);
262 } 279 }
263 280
264 void GuestViewManager::ViewCreated(int embedder_process_id, 281 void GuestViewManager::ViewCreated(int embedder_process_id,
265 int view_instance_id, 282 int view_instance_id,
266 const std::string& view_type) { 283 const std::string& view_type) {
267 if (guest_view_registry_.empty()) 284 if (guest_view_registry_.empty())
268 RegisterGuestViewTypes(); 285 RegisterGuestViewTypes();
269 auto view_it = guest_view_registry_.find(view_type); 286 auto view_it = guest_view_registry_.find(view_type);
270 CHECK(view_it != guest_view_registry_.end()) 287 CHECK(view_it != guest_view_registry_.end())
271 << "Invalid GuestView created of type \"" << view_type << "\""; 288 << "Invalid GuestView created of type \"" << view_type << "\"";
272 289
273 // Register the cleanup callback for when this view is destroyed. 290 // Register the cleanup callback for when this view is destroyed.
274 RegisterViewDestructionCallback(embedder_process_id, 291 RegisterViewDestructionCallback(embedder_process_id,
275 view_instance_id, 292 view_instance_id,
276 base::Bind(view_it->second.cleanup_function, 293 base::Bind(view_it->second.cleanup_function,
294 context_,
277 embedder_process_id, 295 embedder_process_id,
278 view_instance_id)); 296 view_instance_id));
279 } 297 }
280 298
281 void GuestViewManager::ViewGarbageCollected(int embedder_process_id, 299 void GuestViewManager::ViewGarbageCollected(int embedder_process_id,
282 int view_instance_id) { 300 int view_instance_id) {
283 // Find and call any callbacks associated with the view that has been garbage 301 CallViewDestructionCallbacks(embedder_process_id, view_instance_id);
284 // collected. 302 }
303
304 void GuestViewManager::CallViewDestructionCallbacks(int embedder_process_id,
305 int view_instance_id) {
306 // Find the callbacks for the embedder with ID |embedder_process_id|.
285 auto embedder_it = view_destruction_callback_map_.find(embedder_process_id); 307 auto embedder_it = view_destruction_callback_map_.find(embedder_process_id);
286 if (embedder_it == view_destruction_callback_map_.end()) 308 if (embedder_it == view_destruction_callback_map_.end())
287 return; 309 return;
288 CallbacksForEachViewID& callbacks_for_embedder = embedder_it->second; 310 CallbacksForEachViewID& callbacks_for_embedder = embedder_it->second;
311
312 // If |view_instance_id| is guest_view::kInstanceIDNone, then all callbacks
313 // for this embedder should be called.
314 if (view_instance_id == guest_view::kInstanceIDNone) {
315 // Call all callbacks for the embedder with ID |embedder_process_id|.
316 for (auto& view_pair : callbacks_for_embedder) {
317 Callbacks& callbacks_for_view = view_pair.second;
318 for (auto& callback : callbacks_for_view)
319 callback.Run();
320 }
321 view_destruction_callback_map_.erase(embedder_it);
322 return;
323 }
324
325 // Otherwise, call the callbacks only for the specific view with ID
326 // |view_instance_id|.
289 auto view_it = callbacks_for_embedder.find(view_instance_id); 327 auto view_it = callbacks_for_embedder.find(view_instance_id);
290 if (view_it == callbacks_for_embedder.end()) 328 if (view_it == callbacks_for_embedder.end())
291 return; 329 return;
292 Callbacks& callbacks_for_view = view_it->second; 330 Callbacks& callbacks_for_view = view_it->second;
293 for (auto& callback : callbacks_for_view) 331 for (auto& callback : callbacks_for_view)
294 callback.Run(); 332 callback.Run();
295 callbacks_for_embedder.erase(view_it); 333 callbacks_for_embedder.erase(view_it);
296 } 334 }
297 335
336 void GuestViewManager::CallViewDestructionCallbacks(int embedder_process_id) {
337 CallViewDestructionCallbacks(embedder_process_id,
338 guest_view::kInstanceIDNone);
339 }
340
298 GuestViewBase* GuestViewManager::CreateGuestInternal( 341 GuestViewBase* GuestViewManager::CreateGuestInternal(
299 content::WebContents* owner_web_contents, 342 content::WebContents* owner_web_contents,
300 const std::string& view_type) { 343 const std::string& view_type) {
301 if (guest_view_registry_.empty()) 344 if (guest_view_registry_.empty())
302 RegisterGuestViewTypes(); 345 RegisterGuestViewTypes();
303 346
304 auto it = guest_view_registry_.find(view_type); 347 auto it = guest_view_registry_.find(view_type);
305 if (it == guest_view_registry_.end()) { 348 if (it == guest_view_registry_.end()) {
306 NOTREACHED(); 349 NOTREACHED();
307 return nullptr; 350 return nullptr;
308 } 351 }
309 352
310 return it->second.create_function.Run(owner_web_contents); 353 return it->second.create_function.Run(owner_web_contents);
311 } 354 }
312 355
313 void GuestViewManager::RegisterGuestViewTypes() { 356 void GuestViewManager::RegisterGuestViewTypes() {
314 delegate_->RegisterAdditionalGuestViewTypes(); 357 delegate_->RegisterAdditionalGuestViewTypes();
315 } 358 }
316 359
317 void GuestViewManager::RegisterViewDestructionCallback( 360 void GuestViewManager::RegisterViewDestructionCallback(
318 int embedder_process_id, 361 int embedder_process_id,
319 int view_instance_id, 362 int view_instance_id,
320 const base::Closure& callback) { 363 const base::Closure& callback) {
364 // When an embedder is registered for the first time, create an observer to
365 // watch for its destruction.
366 if (!view_destruction_callback_map_.count(embedder_process_id))
367 new EmbedderRenderProcessHostObserver(this, embedder_process_id);
Fady Samuel 2015/07/10 15:36:59 Hmm, what if you add a webview, remove it, and the
paulmeyer 2015/07/10 20:05:25 You're right, that could happen. I'll use somethin
368
321 view_destruction_callback_map_[embedder_process_id][view_instance_id] 369 view_destruction_callback_map_[embedder_process_id][view_instance_id]
322 .push_back(callback); 370 .push_back(callback);
323 } 371 }
324 372
325 bool GuestViewManager::IsGuestAvailableToContext(GuestViewBase* guest) { 373 bool GuestViewManager::IsGuestAvailableToContext(GuestViewBase* guest) {
326 return delegate_->IsGuestAvailableToContext(guest); 374 return delegate_->IsGuestAvailableToContext(guest);
327 } 375 }
328 376
329 void GuestViewManager::DispatchEvent(const std::string& event_name, 377 void GuestViewManager::DispatchEvent(const std::string& event_name,
330 scoped_ptr<base::DictionaryValue> args, 378 scoped_ptr<base::DictionaryValue> args,
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 } 480 }
433 481
434 GuestViewManager::GuestViewData::GuestViewData( 482 GuestViewManager::GuestViewData::GuestViewData(
435 const GuestViewCreateFunction& create_function, 483 const GuestViewCreateFunction& create_function,
436 const GuestViewCleanUpFunction& cleanup_function) 484 const GuestViewCleanUpFunction& cleanup_function)
437 : create_function(create_function), cleanup_function(cleanup_function) {} 485 : create_function(create_function), cleanup_function(cleanup_function) {}
438 486
439 GuestViewManager::GuestViewData::~GuestViewData() {} 487 GuestViewManager::GuestViewData::~GuestViewData() {}
440 488
441 } // namespace guest_view 489 } // namespace guest_view
OLDNEW
« no previous file with comments | « components/guest_view/browser/guest_view_manager.h ('k') | components/guest_view/browser/test_guest_view_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698