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

Unified Diff: chrome/browser/printing/print_preview_dialog_controller.cc

Issue 124673002: Remove notifications from PrintPreviewDialogController. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/printing/print_preview_dialog_controller.cc
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc
index 1f0769c9dc86554ddc0120d255eaa2a3d4085c10..e190f01be432ef9ea56a5327c3e6c14d5a1c2669 100644
--- a/chrome/browser/printing/print_preview_dialog_controller.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -6,7 +6,6 @@
#include <algorithm>
#include <string>
-#include <vector>
#include "base/auto_reset.h"
#include "base/path_service.h"
@@ -31,14 +30,14 @@
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/webplugininfo.h"
#include "ui/web_dialogs/web_dialog_delegate.h"
@@ -46,6 +45,7 @@
using content::NativeWebKeyboardEvent;
using content::NavigationController;
+using content::RenderProcessHost;
using content::WebContents;
using content::WebUIMessageHandler;
using ui::WebDialogDelegate;
@@ -209,6 +209,97 @@ void PrintPreviewWebContentDelegate::HandleKeyboardEvent(
namespace printing {
+struct PrintPreviewDialogController::Operation {
+ class Observer : public content::WebContentsObserver,
+ public content::RenderProcessHostObserver {
+ public:
+ Observer();
+ virtual ~Observer();
+
+ void StartObserving(PrintPreviewDialogController* owner,
+ WebContents* web_contents);
+ void StopObserving();
+
+ private:
+ // content::WebContentsObserver
+ virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+ virtual void NavigationEntryCommitted(
+ const content::LoadCommittedDetails& load_details) OVERRIDE;
+ // content::RenderProcessHostObserver
+ virtual void RenderProcessExited(RenderProcessHost* host,
+ base::ProcessHandle handle,
+ base::TerminationStatus status,
+ int exit_code) OVERRIDE;
+ virtual void RenderProcessHostDestroyed(RenderProcessHost* host) OVERRIDE;
+
+ PrintPreviewDialogController* owner_;
+ RenderProcessHost* host_;
+ };
+
+ Operation();
+
+ WebContents* preview_dialog;
+ WebContents* initiator;
+ Observer preview_dialog_observer;
+ Observer initiator_observer;
+
+ DISALLOW_COPY_AND_ASSIGN(Operation);
+};
+
+PrintPreviewDialogController::Operation::Operation() : preview_dialog(NULL),
+ initiator(NULL) {
+}
+
+PrintPreviewDialogController::Operation::Observer::Observer() : owner_(NULL),
+ host_(NULL) {
+}
+
+PrintPreviewDialogController::Operation::Observer::~Observer() {
+ StopObserving();
+}
+
+void PrintPreviewDialogController::Operation::Observer::StartObserving(
+ PrintPreviewDialogController* owner,
+ WebContents* web_contents) {
+ owner_ = owner;
+ Observe(web_contents);
+ host_ = web_contents->GetRenderProcessHost();
+ host_->AddObserver(this);
+}
+
+void PrintPreviewDialogController::Operation::Observer::StopObserving() {
+ Observe(NULL);
+ if (host_) {
+ host_->RemoveObserver(this);
+ host_ = NULL;
+ }
+}
+
+void PrintPreviewDialogController::Operation::Observer::WebContentsDestroyed(
+ WebContents* web_contents) {
+ owner_->OnWebContentsDestroyed(web_contents);
+}
+
+void
+PrintPreviewDialogController::Operation::Observer::NavigationEntryCommitted(
+ const content::LoadCommittedDetails& load_details) {
+ owner_->OnNavigationEntryCommitted(web_contents(), &load_details);
+}
+
+void PrintPreviewDialogController::Operation::Observer::RenderProcessExited(
+ RenderProcessHost* host,
+ base::ProcessHandle handle,
+ base::TerminationStatus status,
+ int exit_code) {
+ owner_->OnRenderProcessExited(host);
+}
+
+void
+PrintPreviewDialogController::Operation::Observer::RenderProcessHostDestroyed(
+ RenderProcessHost* host) {
+ host_ = NULL;
+}
+
PrintPreviewDialogController::PrintPreviewDialogController()
: waiting_for_new_preview_page_(false),
is_creating_print_preview_dialog_(false) {
@@ -249,19 +340,11 @@ WebContents* PrintPreviewDialogController::GetOrCreatePreviewDialog(
WebContents* PrintPreviewDialogController::GetPrintPreviewForContents(
WebContents* contents) const {
- // |preview_dialog_map_| is keyed by the preview dialog, so if find()
- // succeeds, then |contents| is the preview dialog.
- PrintPreviewDialogMap::const_iterator it = preview_dialog_map_.find(contents);
- if (it != preview_dialog_map_.end())
- return contents;
-
- for (it = preview_dialog_map_.begin();
- it != preview_dialog_map_.end();
- ++it) {
- // If |contents| is an initiator.
- if (contents == it->second) {
- // Return the associated preview dialog.
- return it->first;
+ for (size_t i = 0; i < preview_operations_.size(); ++i) {
+ Operation* operation = preview_operations_[i];
+ if (operation->preview_dialog == contents ||
+ operation->initiator == contents) {
+ return operation->preview_dialog;
}
}
return NULL;
@@ -269,27 +352,12 @@ WebContents* PrintPreviewDialogController::GetPrintPreviewForContents(
WebContents* PrintPreviewDialogController::GetInitiator(
WebContents* preview_dialog) {
- PrintPreviewDialogMap::iterator it = preview_dialog_map_.find(preview_dialog);
- return (it != preview_dialog_map_.end()) ? it->second : NULL;
-}
-
-void PrintPreviewDialogController::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- if (type == content::NOTIFICATION_RENDERER_PROCESS_CLOSED) {
- OnRendererProcessClosed(
- content::Source<content::RenderProcessHost>(source).ptr());
- } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) {
- OnWebContentsDestroyed(content::Source<WebContents>(source).ptr());
- } else {
- DCHECK_EQ(content::NOTIFICATION_NAV_ENTRY_COMMITTED, type);
- WebContents* contents =
- content::Source<NavigationController>(source)->GetWebContents();
- OnNavEntryCommitted(
- contents,
- content::Details<content::LoadCommittedDetails>(details).ptr());
+ for (size_t i = 0; i < preview_operations_.size(); ++i) {
+ Operation* operation = preview_operations_[i];
+ if (operation->preview_dialog == preview_dialog)
+ return operation->initiator;
}
+ return NULL;
}
// static
@@ -305,26 +373,30 @@ bool PrintPreviewDialogController::IsPrintPreviewURL(const GURL& url) {
void PrintPreviewDialogController::EraseInitiatorInfo(
WebContents* preview_dialog) {
- PrintPreviewDialogMap::iterator it = preview_dialog_map_.find(preview_dialog);
- if (it == preview_dialog_map_.end())
- return;
-
- RemoveObservers(it->second);
- preview_dialog_map_[preview_dialog] = NULL;
+ for (size_t i = 0; i < preview_operations_.size(); ++i) {
+ Operation* operation = preview_operations_[i];
+ if (operation->preview_dialog == preview_dialog) {
+ operation->initiator_observer.StopObserving();
+ operation->initiator = NULL;
+ return;
+ }
+ }
}
-PrintPreviewDialogController::~PrintPreviewDialogController() {}
+PrintPreviewDialogController::~PrintPreviewDialogController() {
+ DCHECK_EQ(0U, preview_operations_.size());
+}
-void PrintPreviewDialogController::OnRendererProcessClosed(
- content::RenderProcessHost* rph) {
+void PrintPreviewDialogController::OnRenderProcessExited(
+ RenderProcessHost* rph) {
// Store contents in a vector and deal with them after iterating through
- // |preview_dialog_map_| because RemoveFoo() can change |preview_dialog_map_|.
+ // |preview_operations_| because RemoveFoo() can change |preview_operations_|.
std::vector<WebContents*> closed_initiators;
std::vector<WebContents*> closed_preview_dialogs;
- for (PrintPreviewDialogMap::iterator iter = preview_dialog_map_.begin();
- iter != preview_dialog_map_.end(); ++iter) {
- WebContents* preview_dialog = iter->first;
- WebContents* initiator = iter->second;
+ for (size_t i = 0; i < preview_operations_.size(); ++i) {
+ Operation* operation = preview_operations_[i];
+ WebContents* preview_dialog = operation->preview_dialog;
+ WebContents* initiator = operation->initiator;
if (preview_dialog->GetRenderProcessHost() == rph) {
closed_preview_dialogs.push_back(preview_dialog);
} else if (initiator &&
@@ -359,8 +431,8 @@ void PrintPreviewDialogController::OnWebContentsDestroyed(
RemoveInitiator(contents);
}
-void PrintPreviewDialogController::OnNavEntryCommitted(
- WebContents* contents, content::LoadCommittedDetails* details) {
+void PrintPreviewDialogController::OnNavigationEntryCommitted(
+ WebContents* contents, const content::LoadCommittedDetails* details) {
WebContents* preview_dialog = GetPrintPreviewForContents(contents);
if (!preview_dialog) {
NOTREACHED();
@@ -420,12 +492,15 @@ WebContents* PrintPreviewDialogController::CreatePrintPreviewDialog(
EnableInternalPDFPluginForContents(preview_dialog);
PrintViewManager::CreateForWebContents(preview_dialog);
- // Add an entry to the map.
- preview_dialog_map_[preview_dialog] = initiator;
waiting_for_new_preview_page_ = true;
- AddObservers(initiator);
- AddObservers(preview_dialog);
+ // Add an entry to the map.
+ Operation* operation = new Operation;
+ operation->preview_dialog = preview_dialog;
+ operation->initiator = initiator;
+ operation->preview_dialog_observer.StartObserving(this, preview_dialog);
+ operation->initiator_observer.StartObserving(this, initiator);
+ preview_operations_.push_back(operation);
return preview_dialog;
}
@@ -441,49 +516,15 @@ void PrintPreviewDialogController::SaveInitiatorTitle(
}
}
-void PrintPreviewDialogController::AddObservers(WebContents* contents) {
- registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
- content::Source<WebContents>(contents));
- registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
- content::Source<NavigationController>(&contents->GetController()));
-
- // Multiple sites may share the same RenderProcessHost, so check if this
- // notification has already been added.
- content::Source<content::RenderProcessHost> rph_source(
- contents->GetRenderProcessHost());
- if (!registrar_.IsRegistered(this,
- content::NOTIFICATION_RENDERER_PROCESS_CLOSED, rph_source)) {
- registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
- rph_source);
- }
-}
-
-void PrintPreviewDialogController::RemoveObservers(WebContents* contents) {
- registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
- content::Source<WebContents>(contents));
- registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
- content::Source<NavigationController>(&contents->GetController()));
-
- // Multiple sites may share the same RenderProcessHost, so check if this
- // notification has already been added.
- content::Source<content::RenderProcessHost> rph_source(
- contents->GetRenderProcessHost());
- if (registrar_.IsRegistered(this,
- content::NOTIFICATION_RENDERER_PROCESS_CLOSED, rph_source)) {
- registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
- rph_source);
- }
-}
-
void PrintPreviewDialogController::RemoveInitiator(
WebContents* initiator) {
WebContents* preview_dialog = GetPrintPreviewForContents(initiator);
DCHECK(preview_dialog);
+
// Update the map entry first, so when the print preview dialog gets destroyed
// and reaches RemovePreviewDialog(), it does not attempt to also remove the
// initiator's observers.
- preview_dialog_map_[preview_dialog] = NULL;
- RemoveObservers(initiator);
+ EraseInitiatorInfo(preview_dialog);
PrintViewManager::FromWebContents(initiator)->PrintPreviewDone();
@@ -496,22 +537,30 @@ void PrintPreviewDialogController::RemoveInitiator(
void PrintPreviewDialogController::RemovePreviewDialog(
WebContents* preview_dialog) {
- // Remove the initiator's observers before erasing the mapping.
- WebContents* initiator = GetInitiator(preview_dialog);
- if (initiator) {
- RemoveObservers(initiator);
- PrintViewManager::FromWebContents(initiator)->PrintPreviewDone();
- }
+ for (size_t i = 0; i < preview_operations_.size(); ++i) {
+ Operation* operation = preview_operations_[i];
+ if (operation->preview_dialog == preview_dialog) {
+ // Remove the initiator's observers before erasing the mapping.
+ if (operation->initiator) {
+ operation->initiator_observer.StopObserving();
+ PrintViewManager::FromWebContents(operation->initiator)->
+ PrintPreviewDone();
+ }
- // Print preview WebContents is destroyed. Notify |PrintPreviewUI| to abort
- // the initiator preview request.
- PrintPreviewUI* print_preview_ui =
- static_cast<PrintPreviewUI*>(preview_dialog->GetWebUI()->GetController());
- if (print_preview_ui)
- print_preview_ui->OnPrintPreviewDialogDestroyed();
+ // Print preview WebContents is destroyed. Notify |PrintPreviewUI| to
+ // abort the initiator preview request.
+ PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
+ preview_dialog->GetWebUI()->GetController());
+ if (print_preview_ui)
+ print_preview_ui->OnPrintPreviewDialogDestroyed();
+
+ preview_operations_.erase(preview_operations_.begin() + i);
+ delete operation;
- preview_dialog_map_.erase(preview_dialog);
- RemoveObservers(preview_dialog);
+ return;
+ }
+ }
+ NOTREACHED();
}
} // namespace printing

Powered by Google App Engine
This is Rietveld 408576698