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

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

Issue 7550063: Print Preview: Handle a crashed initiator tab by showing a message in PP. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: '' Created 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/printing/print_preview_tab_controller.cc
diff --git a/chrome/browser/printing/print_preview_tab_controller.cc b/chrome/browser/printing/print_preview_tab_controller.cc
index c552adac813b0a084e0d570ae2e3605ecef297ad..8037c0fea4bbd1099e0b733c5d438841851136a7 100644
--- a/chrome/browser/printing/print_preview_tab_controller.cc
+++ b/chrome/browser/printing/print_preview_tab_controller.cc
@@ -16,8 +16,10 @@
#include "chrome/browser/ui/webui/print_preview_ui.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
+#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/navigation_details.h"
#include "content/browser/tab_contents/tab_contents.h"
+#include "content/common/content_notification_types.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"
@@ -45,6 +47,7 @@ void PrintPreviewTabController::PrintPreview(TabContents* tab) {
printing::PrintPreviewTabController::GetInstance();
if (!tab_controller)
return;
+
tab_controller->GetOrCreatePreviewTab(tab);
}
@@ -59,11 +62,14 @@ TabContents* PrintPreviewTabController::GetOrCreatePreviewTab(
static_cast<RenderViewHostDelegate*>(preview_tab)->Activate();
return preview_tab;
}
+
return CreatePrintPreviewTab(initiator_tab);
}
TabContents* PrintPreviewTabController::GetPrintPreviewForTab(
TabContents* tab) const {
+ // |preview_tab_map_| is keyed by the preview tab, so if find() succeeds, then
+ // |tab| is the preview tab.
PrintPreviewTabMap::const_iterator it = preview_tab_map_.find(tab);
if (it != preview_tab_map_.end())
return tab;
@@ -75,25 +81,28 @@ TabContents* PrintPreviewTabController::GetPrintPreviewForTab(
return it->first;
}
}
+
return NULL;
}
void PrintPreviewTabController::Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) {
- TabContents* source_tab = NULL;
- content::LoadCommittedDetails* detail_info = NULL;
-
switch (type) {
+ case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
Lei Zhang 2011/08/09 20:51:19 If we just close a tab, do we get this notificatio
kmadhusu 2011/08/10 16:46:59 When a tab is closed, we do not get this notificat
+ OnRendererProcessClosed(Source<RenderProcessHost>(source).ptr());
+ break;
+ }
case content::NOTIFICATION_TAB_CONTENTS_DESTROYED: {
- source_tab = Source<TabContents>(source).ptr();
+ OnTabContentsDestroyed(Source<TabContents>(source).ptr());
break;
}
case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
NavigationController* controller =
Source<NavigationController>(source).ptr();
- source_tab = controller->tab_contents();
- detail_info = Details<content::LoadCommittedDetails>(details).ptr();
+ content::LoadCommittedDetails* load_details =
+ Details<content::LoadCommittedDetails>(details).ptr();
+ OnNavEntryCommitted(controller->tab_contents(), load_details);
break;
}
default: {
@@ -101,16 +110,73 @@ void PrintPreviewTabController::Observe(int type,
break;
}
}
+}
+
+void PrintPreviewTabController::OnRendererProcessClosed(
+ RenderProcessHost* rph) {
+ TabContents* initiator_tab = NULL;
+ for (PrintPreviewTabMap::iterator iter = preview_tab_map_.begin();
+ iter != preview_tab_map_.end(); ++iter) {
+ if (iter->second->render_view_host()->process() == rph) {
+ initiator_tab = iter->second;
+ break;
+ }
+ }
+
+ // The Print Preview renderer crashed.
+ if (!initiator_tab)
Lei Zhang 2011/08/09 20:51:19 In this case, do you need to call RemoveObservers(
kmadhusu 2011/08/10 16:46:59 We should not remove the observers for the preview
+ return;
- DCHECK(source_tab);
+ TabContents* preview_tab = GetPrintPreviewForTab(initiator_tab);
+ PrintPreviewUI* print_preview_ui =
+ static_cast<PrintPreviewUI*>(preview_tab->web_ui());
+ print_preview_ui->OnInitiatorTabCrashed();
Lei Zhang 2011/08/09 20:51:19 Do you need to check |preview_tab| or |print_previ
kmadhusu 2011/08/10 16:46:59 They will be valid. If you want I can add a DCHECK
+}
- TabContents* preview_tab = GetPrintPreviewForTab(source_tab);
- bool source_tab_is_preview_tab = (source_tab == preview_tab);
+void PrintPreviewTabController::OnTabContentsDestroyed(TabContents* tab) {
+ TabContents* preview_tab = GetPrintPreviewForTab(tab);
+ if (!preview_tab)
+ return;
- if (detail_info) {
- PageTransition::Type transition_type =
- detail_info->entry->transition_type();
- NavigationType::Type nav_type = detail_info->type;
+ if (tab == preview_tab) {
+ // Remove the initiator tab's observers before erasing the mapping.
+ TabContents* initiator_tab = GetInitiatorTab(tab);
+ if (initiator_tab)
+ RemoveObservers(initiator_tab);
+
+ // In the case where the user chooses to re-open the initiator tab after
+ // closing it, |tab| has navigated to the URL of the initiator tab at this
+ // point. Verify that |tab| really is a print preview tab.
+ if (IsPrintPreviewTab(tab) && tab->web_ui()) {
Lei Zhang 2011/08/09 20:51:19 If the print preview tab is navigating to its init
kmadhusu 2011/08/10 16:46:59 The comment is misleading. Here, the preview tab i
+ PrintPreviewUI* print_preview_ui =
+ static_cast<PrintPreviewUI*>(tab->web_ui());
+ print_preview_ui->OnNavigation();
+ }
+
+ // Erase the map entry.
+ preview_tab_map_.erase(tab);
+ } else {
+ // Initiator tab is closed. Disable the controls in preview tab.
+ if (preview_tab->web_ui()) {
+ PrintPreviewUI* print_preview_ui =
+ static_cast<PrintPreviewUI*>(preview_tab->web_ui());
+ print_preview_ui->OnInitiatorTabClosed();
+ }
+
+ // |tab| is an initiator tab, update the map entry and remove observers.
+ preview_tab_map_[preview_tab] = NULL;
+ }
+
+ RemoveObservers(tab);
+}
+
+void PrintPreviewTabController::OnNavEntryCommitted(
+ TabContents* tab, content::LoadCommittedDetails* details) {
+ TabContents* preview_tab = GetPrintPreviewForTab(tab);
+ bool source_tab_is_preview_tab = (tab == preview_tab);
+ if (details) {
+ PageTransition::Type transition_type = details->entry->transition_type();
+ NavigationType::Type nav_type = details->type;
// Don't update/erase the map entry if the page has not changed.
if (transition_type == PageTransition::RELOAD ||
@@ -124,6 +190,15 @@ void PrintPreviewTabController::Observe(int type,
nav_type == NavigationType::NEW_PAGE &&
source_tab_is_preview_tab) {
waiting_for_new_preview_page_ = false;
+ // Set the initiator tab url.
+ TabContents* initiator_tab = GetInitiatorTab(tab);
+ if (initiator_tab) {
+ if (preview_tab->web_ui()) {
Lei Zhang 2011/08/09 20:51:19 nit: combine with the if statement above.
kmadhusu 2011/08/10 16:46:59 Done.
+ PrintPreviewUI* print_preview_ui =
+ static_cast<PrintPreviewUI*>(preview_tab->web_ui());
+ print_preview_ui->SetInitiatorTabURL(initiator_tab->GetURL().spec());
+ }
+ }
return;
}
@@ -135,34 +210,23 @@ void PrintPreviewTabController::Observe(int type,
}
}
+ RemoveObservers(tab);
if (source_tab_is_preview_tab) {
// Remove the initiator tab's observers before erasing the mapping.
- TabContents* initiator_tab = GetInitiatorTab(source_tab);
+ TabContents* initiator_tab = GetInitiatorTab(tab);
if (initiator_tab)
RemoveObservers(initiator_tab);
+ preview_tab_map_.erase(tab);
+ } else {
+ preview_tab_map_[preview_tab] = NULL;
- // |source_tab_is_preview_tab| is misleading in the case where the user
- // chooses to re-open the initiator tab after closing it, as |source_tab|
- // has navigated to the URL of the initiator tab at this point. Make sure to
- // verify that |source_tab| really is a print preview tab.
- if (IsPrintPreviewTab(source_tab) && source_tab->web_ui()) {
+ // Initiator tab is closed. Disable the controls in preview tab.
+ if (preview_tab->web_ui()) {
PrintPreviewUI* print_preview_ui =
- static_cast<PrintPreviewUI*>(source_tab->web_ui());
- print_preview_ui->OnNavigation();
+ static_cast<PrintPreviewUI*>(preview_tab->web_ui());
+ print_preview_ui->OnInitiatorTabClosed();
}
-
- // Erase the map entry.
- preview_tab_map_.erase(source_tab);
- } else {
- // Initiator tab is closed. Disable the controls in preview tab.
- PrintPreviewUI* print_preview_ui =
- static_cast<PrintPreviewUI*>(preview_tab->web_ui());
- print_preview_ui->OnInitiatorTabClosed(source_tab->GetURL().spec());
-
- // |source_tab| is an initiator tab, update the map entry.
- preview_tab_map_[preview_tab] = NULL;
}
- RemoveObservers(source_tab);
}
// static
@@ -187,6 +251,7 @@ TabContents* PrintPreviewTabController::GetInitiatorTab(
PrintPreviewTabMap::iterator it = preview_tab_map_.find(preview_tab);
if (it != preview_tab_map_.end())
return preview_tab_map_[preview_tab];
+
return NULL;
}
@@ -240,6 +305,16 @@ void PrintPreviewTabController::AddObservers(TabContents* tab) {
Source<TabContents>(tab));
registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
Source<NavigationController>(&tab->controller()));
+
+ // Multiple sites may share the same RenderProcessHost, so check if this
+ // notification has already been added.
+ RenderProcessHost* rph = tab->render_view_host()->process();
+ if (!registrar_.IsRegistered(this,
+ content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
+ Source<RenderProcessHost>(rph))) {
+ registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
+ Source<RenderProcessHost>(rph));
+ }
}
void PrintPreviewTabController::RemoveObservers(TabContents* tab) {
@@ -247,6 +322,16 @@ void PrintPreviewTabController::RemoveObservers(TabContents* tab) {
Source<TabContents>(tab));
registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
Source<NavigationController>(&tab->controller()));
+
+ // Multiple sites may share the same RenderProcessHost, so check if this
+ // notification has already been added.
+ RenderProcessHost* rph = tab->render_view_host()->process();
+ if (registrar_.IsRegistered(this,
+ content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
+ Source<RenderProcessHost>(rph))) {
+ registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
+ Source<RenderProcessHost>(rph));
+ }
}
} // namespace printing

Powered by Google App Engine
This is Rietveld 408576698