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

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. Now using weak pointer to GuestViewManager. 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(
37 base::WeakPtr<GuestViewManager> guest_view_manager,
38 int embedder_process_id)
39 : guest_view_manager_(guest_view_manager), id_(embedder_process_id) {
40 RenderProcessHost* rph = RenderProcessHost::FromID(id_);
41 rph->AddObserver(this);
42 }
43
44 ~EmbedderRenderProcessHostObserver() override {
45 RenderProcessHost* rph = RenderProcessHost::FromID(id_);
46 if (rph)
47 rph->RemoveObserver(this);
48 }
49
50 void RenderProcessHostDestroyed(RenderProcessHost* host) override {
51 if (guest_view_manager_.get())
52 guest_view_manager_->EmbedderProcessDestroyed(id_);
53 delete this;
54 }
55
56 private:
57 base::WeakPtr<GuestViewManager> guest_view_manager_;
58 int id_;
59 };
60
30 // static 61 // static
31 GuestViewManagerFactory* GuestViewManager::factory_ = nullptr; 62 GuestViewManagerFactory* GuestViewManager::factory_ = nullptr;
32 63
33 GuestViewManager::GuestViewManager( 64 GuestViewManager::GuestViewManager(
34 content::BrowserContext* context, 65 content::BrowserContext* context,
35 scoped_ptr<GuestViewManagerDelegate> delegate) 66 scoped_ptr<GuestViewManagerDelegate> delegate)
36 : current_instance_id_(0), 67 : current_instance_id_(0),
37 last_instance_id_removed_(0), 68 last_instance_id_removed_(0),
38 context_(context), 69 context_(context),
39 delegate_(delegate.Pass()) { 70 delegate_(delegate.Pass()),
71 weak_ptr_factory_(this) {
40 } 72 }
41 73
42 GuestViewManager::~GuestViewManager() {} 74 GuestViewManager::~GuestViewManager() {}
43 75
44 // static 76 // static
45 GuestViewManager* GuestViewManager::CreateWithDelegate( 77 GuestViewManager* GuestViewManager::CreateWithDelegate(
46 BrowserContext* context, 78 BrowserContext* context,
47 scoped_ptr<GuestViewManagerDelegate> delegate) { 79 scoped_ptr<GuestViewManagerDelegate> delegate) {
48 GuestViewManager* guest_manager = FromBrowserContext(context); 80 GuestViewManager* guest_manager = FromBrowserContext(context);
49 if (!guest_manager) { 81 if (!guest_manager) {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 if (instance_id != last_instance_id_removed_ + 1) 270 if (instance_id != last_instance_id_removed_ + 1)
239 break; 271 break;
240 ++last_instance_id_removed_; 272 ++last_instance_id_removed_;
241 removed_instance_ids_.erase(iter++); 273 removed_instance_ids_.erase(iter++);
242 } 274 }
243 } else { 275 } else {
244 removed_instance_ids_.insert(guest_instance_id); 276 removed_instance_ids_.insert(guest_instance_id);
245 } 277 }
246 } 278 }
247 279
248 void GuestViewManager::EmbedderWillBeDestroyed(int embedder_process_id) { 280 void GuestViewManager::EmbedderProcessDestroyed(int embedder_process_id) {
249 // Find and call any callbacks associated with the embedder that is being 281 embedders_observed_.erase(embedder_process_id);
250 // destroyed. 282 CallViewDestructionCallbacks(embedder_process_id);
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 } 283 }
263 284
264 void GuestViewManager::ViewCreated(int embedder_process_id, 285 void GuestViewManager::ViewCreated(int embedder_process_id,
265 int view_instance_id, 286 int view_instance_id,
266 const std::string& view_type) { 287 const std::string& view_type) {
267 if (guest_view_registry_.empty()) 288 if (guest_view_registry_.empty())
268 RegisterGuestViewTypes(); 289 RegisterGuestViewTypes();
269 auto view_it = guest_view_registry_.find(view_type); 290 auto view_it = guest_view_registry_.find(view_type);
270 CHECK(view_it != guest_view_registry_.end()) 291 CHECK(view_it != guest_view_registry_.end())
271 << "Invalid GuestView created of type \"" << view_type << "\""; 292 << "Invalid GuestView created of type \"" << view_type << "\"";
272 293
273 // Register the cleanup callback for when this view is destroyed. 294 // Register the cleanup callback for when this view is destroyed.
274 RegisterViewDestructionCallback(embedder_process_id, 295 RegisterViewDestructionCallback(embedder_process_id,
275 view_instance_id, 296 view_instance_id,
276 base::Bind(view_it->second.cleanup_function, 297 base::Bind(view_it->second.cleanup_function,
298 context_,
Fady Samuel 2015/07/14 17:56:59 Why does the cleanup function need the browser con
paulmeyer 2015/07/14 18:04:07 It always needed it to clean up some of the browse
277 embedder_process_id, 299 embedder_process_id,
278 view_instance_id)); 300 view_instance_id));
279 } 301 }
280 302
281 void GuestViewManager::ViewGarbageCollected(int embedder_process_id, 303 void GuestViewManager::ViewGarbageCollected(int embedder_process_id,
282 int view_instance_id) { 304 int view_instance_id) {
283 // Find and call any callbacks associated with the view that has been garbage 305 CallViewDestructionCallbacks(embedder_process_id, view_instance_id);
284 // collected. 306 }
307
308 void GuestViewManager::CallViewDestructionCallbacks(int embedder_process_id,
309 int view_instance_id) {
310 // Find the callbacks for the embedder with ID |embedder_process_id|.
285 auto embedder_it = view_destruction_callback_map_.find(embedder_process_id); 311 auto embedder_it = view_destruction_callback_map_.find(embedder_process_id);
286 if (embedder_it == view_destruction_callback_map_.end()) 312 if (embedder_it == view_destruction_callback_map_.end())
287 return; 313 return;
288 CallbacksForEachViewID& callbacks_for_embedder = embedder_it->second; 314 CallbacksForEachViewID& callbacks_for_embedder = embedder_it->second;
315
316 // If |view_instance_id| is guest_view::kInstanceIDNone, then all callbacks
317 // for this embedder should be called.
318 if (view_instance_id == guest_view::kInstanceIDNone) {
319 // Call all callbacks for the embedder with ID |embedder_process_id|.
320 for (auto& view_pair : callbacks_for_embedder) {
321 Callbacks& callbacks_for_view = view_pair.second;
322 for (auto& callback : callbacks_for_view)
323 callback.Run();
324 }
325 view_destruction_callback_map_.erase(embedder_it);
326 return;
327 }
328
329 // Otherwise, call the callbacks only for the specific view with ID
330 // |view_instance_id|.
289 auto view_it = callbacks_for_embedder.find(view_instance_id); 331 auto view_it = callbacks_for_embedder.find(view_instance_id);
290 if (view_it == callbacks_for_embedder.end()) 332 if (view_it == callbacks_for_embedder.end())
291 return; 333 return;
292 Callbacks& callbacks_for_view = view_it->second; 334 Callbacks& callbacks_for_view = view_it->second;
293 for (auto& callback : callbacks_for_view) 335 for (auto& callback : callbacks_for_view)
294 callback.Run(); 336 callback.Run();
295 callbacks_for_embedder.erase(view_it); 337 callbacks_for_embedder.erase(view_it);
296 } 338 }
297 339
340 void GuestViewManager::CallViewDestructionCallbacks(int embedder_process_id) {
341 CallViewDestructionCallbacks(embedder_process_id,
342 guest_view::kInstanceIDNone);
343 }
344
298 GuestViewBase* GuestViewManager::CreateGuestInternal( 345 GuestViewBase* GuestViewManager::CreateGuestInternal(
299 content::WebContents* owner_web_contents, 346 content::WebContents* owner_web_contents,
300 const std::string& view_type) { 347 const std::string& view_type) {
301 if (guest_view_registry_.empty()) 348 if (guest_view_registry_.empty())
302 RegisterGuestViewTypes(); 349 RegisterGuestViewTypes();
303 350
304 auto it = guest_view_registry_.find(view_type); 351 auto it = guest_view_registry_.find(view_type);
305 if (it == guest_view_registry_.end()) { 352 if (it == guest_view_registry_.end()) {
306 NOTREACHED(); 353 NOTREACHED();
307 return nullptr; 354 return nullptr;
308 } 355 }
309 356
310 return it->second.create_function.Run(owner_web_contents); 357 return it->second.create_function.Run(owner_web_contents);
311 } 358 }
312 359
313 void GuestViewManager::RegisterGuestViewTypes() { 360 void GuestViewManager::RegisterGuestViewTypes() {
314 delegate_->RegisterAdditionalGuestViewTypes(); 361 delegate_->RegisterAdditionalGuestViewTypes();
315 } 362 }
316 363
317 void GuestViewManager::RegisterViewDestructionCallback( 364 void GuestViewManager::RegisterViewDestructionCallback(
318 int embedder_process_id, 365 int embedder_process_id,
319 int view_instance_id, 366 int view_instance_id,
320 const base::Closure& callback) { 367 const base::Closure& callback) {
368 // When an embedder is registered for the first time, create an observer to
369 // watch for its destruction.
370 if (!embedders_observed_.count(embedder_process_id)) {
371 embedders_observed_.insert(embedder_process_id);
372 new EmbedderRenderProcessHostObserver(weak_ptr_factory_.GetWeakPtr(),
373 embedder_process_id);
374 }
375
321 view_destruction_callback_map_[embedder_process_id][view_instance_id] 376 view_destruction_callback_map_[embedder_process_id][view_instance_id]
322 .push_back(callback); 377 .push_back(callback);
323 } 378 }
324 379
325 bool GuestViewManager::IsGuestAvailableToContext(GuestViewBase* guest) { 380 bool GuestViewManager::IsGuestAvailableToContext(GuestViewBase* guest) {
326 return delegate_->IsGuestAvailableToContext(guest); 381 return delegate_->IsGuestAvailableToContext(guest);
327 } 382 }
328 383
329 void GuestViewManager::DispatchEvent(const std::string& event_name, 384 void GuestViewManager::DispatchEvent(const std::string& event_name,
330 scoped_ptr<base::DictionaryValue> args, 385 scoped_ptr<base::DictionaryValue> args,
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 } 487 }
433 488
434 GuestViewManager::GuestViewData::GuestViewData( 489 GuestViewManager::GuestViewData::GuestViewData(
435 const GuestViewCreateFunction& create_function, 490 const GuestViewCreateFunction& create_function,
436 const GuestViewCleanUpFunction& cleanup_function) 491 const GuestViewCleanUpFunction& cleanup_function)
437 : create_function(create_function), cleanup_function(cleanup_function) {} 492 : create_function(create_function), cleanup_function(cleanup_function) {}
438 493
439 GuestViewManager::GuestViewData::~GuestViewData() {} 494 GuestViewManager::GuestViewData::~GuestViewData() {}
440 495
441 } // namespace guest_view 496 } // 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