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

Side by Side 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: fix a style issue 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/printing/print_preview_tab_controller.h" 5 #include "chrome/browser/printing/print_preview_tab_controller.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "chrome/browser/browser_process.h" 8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/sessions/restore_tab_helper.h" 10 #include "chrome/browser/sessions/restore_tab_helper.h"
11 #include "chrome/browser/tabs/tab_strip_model.h" 11 #include "chrome/browser/tabs/tab_strip_model.h"
12 #include "chrome/browser/ui/browser.h" 12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_list.h" 13 #include "chrome/browser/ui/browser_list.h"
14 #include "chrome/browser/ui/browser_navigator.h" 14 #include "chrome/browser/ui/browser_navigator.h"
15 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 15 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
16 #include "chrome/browser/ui/webui/print_preview_ui.h" 16 #include "chrome/browser/ui/webui/print_preview_ui.h"
17 #include "chrome/common/chrome_switches.h" 17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/url_constants.h" 18 #include "chrome/common/url_constants.h"
19 #include "content/browser/renderer_host/render_view_host.h"
19 #include "content/browser/tab_contents/navigation_details.h" 20 #include "content/browser/tab_contents/navigation_details.h"
20 #include "content/browser/tab_contents/tab_contents.h" 21 #include "content/browser/tab_contents/tab_contents.h"
22 #include "content/common/content_notification_types.h"
21 #include "content/common/notification_details.h" 23 #include "content/common/notification_details.h"
22 #include "content/common/notification_source.h" 24 #include "content/common/notification_source.h"
23 25
24 namespace printing { 26 namespace printing {
25 27
26 PrintPreviewTabController::PrintPreviewTabController() 28 PrintPreviewTabController::PrintPreviewTabController()
27 : waiting_for_new_preview_page_(false) { 29 : waiting_for_new_preview_page_(false) {
28 } 30 }
29 31
30 PrintPreviewTabController::~PrintPreviewTabController() {} 32 PrintPreviewTabController::~PrintPreviewTabController() {}
31 33
32 // static 34 // static
33 PrintPreviewTabController* PrintPreviewTabController::GetInstance() { 35 PrintPreviewTabController* PrintPreviewTabController::GetInstance() {
34 if (!g_browser_process) 36 if (!g_browser_process)
35 return NULL; 37 return NULL;
36 return g_browser_process->print_preview_tab_controller(); 38 return g_browser_process->print_preview_tab_controller();
37 } 39 }
38 40
39 // static 41 // static
40 void PrintPreviewTabController::PrintPreview(TabContents* tab) { 42 void PrintPreviewTabController::PrintPreview(TabContents* tab) {
41 if (tab->showing_interstitial_page()) 43 if (tab->showing_interstitial_page())
42 return; 44 return;
43 45
44 printing::PrintPreviewTabController* tab_controller = 46 printing::PrintPreviewTabController* tab_controller =
45 printing::PrintPreviewTabController::GetInstance(); 47 printing::PrintPreviewTabController::GetInstance();
46 if (!tab_controller) 48 if (!tab_controller)
47 return; 49 return;
50
Lei Zhang 2011/08/16 00:59:23 nit: do we need all these extra blank lines?
kmadhusu 2011/08/16 01:31:37 Removed.
48 tab_controller->GetOrCreatePreviewTab(tab); 51 tab_controller->GetOrCreatePreviewTab(tab);
49 } 52 }
50 53
51 TabContents* PrintPreviewTabController::GetOrCreatePreviewTab( 54 TabContents* PrintPreviewTabController::GetOrCreatePreviewTab(
52 TabContents* initiator_tab) { 55 TabContents* initiator_tab) {
53 DCHECK(initiator_tab); 56 DCHECK(initiator_tab);
54 57
55 // Get the print preview tab for |initiator_tab|. 58 // Get the print preview tab for |initiator_tab|.
56 TabContents* preview_tab = GetPrintPreviewForTab(initiator_tab); 59 TabContents* preview_tab = GetPrintPreviewForTab(initiator_tab);
57 if (preview_tab) { 60 if (preview_tab) {
58 // Show current preview tab. 61 // Show current preview tab.
59 static_cast<RenderViewHostDelegate*>(preview_tab)->Activate(); 62 static_cast<RenderViewHostDelegate*>(preview_tab)->Activate();
60 return preview_tab; 63 return preview_tab;
61 } 64 }
65
62 return CreatePrintPreviewTab(initiator_tab); 66 return CreatePrintPreviewTab(initiator_tab);
63 } 67 }
64 68
65 TabContents* PrintPreviewTabController::GetPrintPreviewForTab( 69 TabContents* PrintPreviewTabController::GetPrintPreviewForTab(
66 TabContents* tab) const { 70 TabContents* tab) const {
71 // |preview_tab_map_| is keyed by the preview tab, so if find() succeeds, then
72 // |tab| is the preview tab.
67 PrintPreviewTabMap::const_iterator it = preview_tab_map_.find(tab); 73 PrintPreviewTabMap::const_iterator it = preview_tab_map_.find(tab);
68 if (it != preview_tab_map_.end()) 74 if (it != preview_tab_map_.end())
69 return tab; 75 return tab;
70 76
71 for (it = preview_tab_map_.begin(); it != preview_tab_map_.end(); ++it) { 77 for (it = preview_tab_map_.begin(); it != preview_tab_map_.end(); ++it) {
72 // If |tab| is an initiator tab. 78 // If |tab| is an initiator tab.
73 if (tab == it->second) { 79 if (tab == it->second) {
74 // Return the associated preview tab. 80 // Return the associated preview tab.
75 return it->first; 81 return it->first;
76 } 82 }
77 } 83 }
84
78 return NULL; 85 return NULL;
79 } 86 }
80 87
81 void PrintPreviewTabController::Observe(int type, 88 void PrintPreviewTabController::Observe(int type,
82 const NotificationSource& source, 89 const NotificationSource& source,
83 const NotificationDetails& details) { 90 const NotificationDetails& details) {
84 TabContents* source_tab = NULL;
85 content::LoadCommittedDetails* detail_info = NULL;
86
87 switch (type) { 91 switch (type) {
92 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
93 OnRendererProcessClosed(Source<RenderProcessHost>(source).ptr());
94 break;
95 }
88 case content::NOTIFICATION_TAB_CONTENTS_DESTROYED: { 96 case content::NOTIFICATION_TAB_CONTENTS_DESTROYED: {
89 source_tab = Source<TabContents>(source).ptr(); 97 OnTabContentsDestroyed(Source<TabContents>(source).ptr());
90 break; 98 break;
91 } 99 }
92 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { 100 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
93 NavigationController* controller = 101 NavigationController* controller =
94 Source<NavigationController>(source).ptr(); 102 Source<NavigationController>(source).ptr();
95 source_tab = controller->tab_contents(); 103 content::LoadCommittedDetails* load_details =
96 detail_info = Details<content::LoadCommittedDetails>(details).ptr(); 104 Details<content::LoadCommittedDetails>(details).ptr();
105 OnNavEntryCommitted(controller->tab_contents(), load_details);
97 break; 106 break;
98 } 107 }
99 default: { 108 default: {
100 NOTREACHED(); 109 NOTREACHED();
101 break; 110 break;
102 } 111 }
103 } 112 }
113 }
104 114
105 DCHECK(source_tab); 115 void PrintPreviewTabController::OnRendererProcessClosed(
116 RenderProcessHost* rph) {
117 for (PrintPreviewTabMap::iterator iter = preview_tab_map_.begin();
118 iter != preview_tab_map_.end(); ++iter) {
119 if (iter->second != NULL &&
120 iter->second->render_view_host()->process() == rph) {
121 TabContents* preview_tab = GetPrintPreviewForTab(iter->second);
122 PrintPreviewUI* print_preview_ui =
123 static_cast<PrintPreviewUI*>(preview_tab->web_ui());
124 print_preview_ui->OnInitiatorTabCrashed();
125 }
126 }
127 }
106 128
107 TabContents* preview_tab = GetPrintPreviewForTab(source_tab); 129 void PrintPreviewTabController::OnTabContentsDestroyed(TabContents* tab) {
108 bool source_tab_is_preview_tab = (source_tab == preview_tab); 130 TabContents* preview_tab = GetPrintPreviewForTab(tab);
131 if (!preview_tab)
132 return;
109 133
110 if (detail_info) { 134 if (tab == preview_tab) {
111 PageTransition::Type transition_type = 135 // Remove the initiator tab's observers before erasing the mapping.
112 detail_info->entry->transition_type(); 136 TabContents* initiator_tab = GetInitiatorTab(tab);
113 NavigationType::Type nav_type = detail_info->type; 137 if (initiator_tab)
138 RemoveObservers(initiator_tab);
139
140 // Print preview tab contents are destroyed. Notify |PrintPreviewUI| to
141 // abort the initiator tab preview request.
142 if (IsPrintPreviewTab(tab) && tab->web_ui()) {
143 PrintPreviewUI* print_preview_ui =
144 static_cast<PrintPreviewUI*>(tab->web_ui());
145 print_preview_ui->OnTabDestroyed();
146 }
147
148 // Erase the map entry.
149 preview_tab_map_.erase(tab);
150 } else {
151 // Initiator tab is closed. Disable the controls in preview tab.
152 if (preview_tab->web_ui()) {
153 PrintPreviewUI* print_preview_ui =
154 static_cast<PrintPreviewUI*>(preview_tab->web_ui());
155 print_preview_ui->OnInitiatorTabClosed();
156 }
157
158 // |tab| is an initiator tab, update the map entry and remove observers.
159 preview_tab_map_[preview_tab] = NULL;
160 }
161
162 RemoveObservers(tab);
163 }
164
165 void PrintPreviewTabController::OnNavEntryCommitted(
166 TabContents* tab, content::LoadCommittedDetails* details) {
167 TabContents* preview_tab = GetPrintPreviewForTab(tab);
168 bool source_tab_is_preview_tab = (tab == preview_tab);
169 if (details) {
170 PageTransition::Type transition_type = details->entry->transition_type();
171 NavigationType::Type nav_type = details->type;
114 172
115 // Don't update/erase the map entry if the page has not changed. 173 // Don't update/erase the map entry if the page has not changed.
116 if (transition_type == PageTransition::RELOAD || 174 if (transition_type == PageTransition::RELOAD ||
117 nav_type == NavigationType::SAME_PAGE) { 175 nav_type == NavigationType::SAME_PAGE) {
118 return; 176 return;
119 } 177 }
120 178
121 // New |preview_tab| is created. Don't update/erase map entry. 179 // New |preview_tab| is created. Don't update/erase map entry.
122 if (waiting_for_new_preview_page_ && 180 if (waiting_for_new_preview_page_ &&
123 transition_type == PageTransition::LINK && 181 transition_type == PageTransition::LINK &&
124 nav_type == NavigationType::NEW_PAGE && 182 nav_type == NavigationType::NEW_PAGE &&
125 source_tab_is_preview_tab) { 183 source_tab_is_preview_tab) {
126 waiting_for_new_preview_page_ = false; 184 waiting_for_new_preview_page_ = false;
185 // Set the initiator tab url.
186 TabContents* initiator_tab = GetInitiatorTab(tab);
187 if (initiator_tab && preview_tab->web_ui()) {
188 PrintPreviewUI* print_preview_ui =
189 static_cast<PrintPreviewUI*>(preview_tab->web_ui());
190 print_preview_ui->SetInitiatorTabURL(initiator_tab->GetURL().spec());
191 }
127 return; 192 return;
128 } 193 }
129 194
130 // User navigated to a preview tab using forward/back button. 195 // User navigated to a preview tab using forward/back button.
131 if (source_tab_is_preview_tab && 196 if (source_tab_is_preview_tab &&
132 transition_type == PageTransition::FORWARD_BACK && 197 transition_type == PageTransition::FORWARD_BACK &&
133 nav_type == NavigationType::EXISTING_PAGE) { 198 nav_type == NavigationType::EXISTING_PAGE) {
134 return; 199 return;
135 } 200 }
136 } 201 }
137 202
203 RemoveObservers(tab);
138 if (source_tab_is_preview_tab) { 204 if (source_tab_is_preview_tab) {
139 // Remove the initiator tab's observers before erasing the mapping. 205 // Remove the initiator tab's observers before erasing the mapping.
140 TabContents* initiator_tab = GetInitiatorTab(source_tab); 206 TabContents* initiator_tab = GetInitiatorTab(tab);
141 if (initiator_tab) 207 if (initiator_tab)
142 RemoveObservers(initiator_tab); 208 RemoveObservers(initiator_tab);
209 preview_tab_map_.erase(tab);
210 } else {
211 preview_tab_map_[preview_tab] = NULL;
143 212
144 // |source_tab_is_preview_tab| is misleading in the case where the user 213 // Initiator tab is closed. Disable the controls in preview tab.
145 // chooses to re-open the initiator tab after closing it, as |source_tab| 214 if (preview_tab->web_ui()) {
146 // has navigated to the URL of the initiator tab at this point. Make sure to
147 // verify that |source_tab| really is a print preview tab.
148 if (IsPrintPreviewTab(source_tab) && source_tab->web_ui()) {
149 PrintPreviewUI* print_preview_ui = 215 PrintPreviewUI* print_preview_ui =
150 static_cast<PrintPreviewUI*>(source_tab->web_ui()); 216 static_cast<PrintPreviewUI*>(preview_tab->web_ui());
151 print_preview_ui->OnNavigation(); 217 print_preview_ui->OnInitiatorTabClosed();
152 } 218 }
153
154 // Erase the map entry.
155 preview_tab_map_.erase(source_tab);
156 } else {
157 // Initiator tab is closed. Disable the controls in preview tab.
158 PrintPreviewUI* print_preview_ui =
159 static_cast<PrintPreviewUI*>(preview_tab->web_ui());
160 print_preview_ui->OnInitiatorTabClosed(source_tab->GetURL().spec());
161
162 // |source_tab| is an initiator tab, update the map entry.
163 preview_tab_map_[preview_tab] = NULL;
164 } 219 }
165 RemoveObservers(source_tab);
166 } 220 }
167 221
168 // static 222 // static
169 bool PrintPreviewTabController::IsPrintPreviewTab(TabContents* tab) { 223 bool PrintPreviewTabController::IsPrintPreviewTab(TabContents* tab) {
170 const GURL& url = tab->GetURL(); 224 const GURL& url = tab->GetURL();
171 return (url.SchemeIs(chrome::kChromeUIScheme) && 225 return (url.SchemeIs(chrome::kChromeUIScheme) &&
172 url.host() == chrome::kChromeUIPrintHost); 226 url.host() == chrome::kChromeUIPrintHost);
173 } 227 }
174 228
175 void PrintPreviewTabController::EraseInitiatorTabInfo( 229 void PrintPreviewTabController::EraseInitiatorTabInfo(
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 AddObservers(preview_tab->tab_contents()); 287 AddObservers(preview_tab->tab_contents());
234 288
235 return preview_tab->tab_contents(); 289 return preview_tab->tab_contents();
236 } 290 }
237 291
238 void PrintPreviewTabController::AddObservers(TabContents* tab) { 292 void PrintPreviewTabController::AddObservers(TabContents* tab) {
239 registrar_.Add(this, content::NOTIFICATION_TAB_CONTENTS_DESTROYED, 293 registrar_.Add(this, content::NOTIFICATION_TAB_CONTENTS_DESTROYED,
240 Source<TabContents>(tab)); 294 Source<TabContents>(tab));
241 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 295 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
242 Source<NavigationController>(&tab->controller())); 296 Source<NavigationController>(&tab->controller()));
297
298 // Multiple sites may share the same RenderProcessHost, so check if this
299 // notification has already been added.
300 RenderProcessHost* rph = tab->render_view_host()->process();
301 if (!registrar_.IsRegistered(this,
302 content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
303 Source<RenderProcessHost>(rph))) {
304 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
305 Source<RenderProcessHost>(rph));
306 }
243 } 307 }
244 308
245 void PrintPreviewTabController::RemoveObservers(TabContents* tab) { 309 void PrintPreviewTabController::RemoveObservers(TabContents* tab) {
246 registrar_.Remove(this, content::NOTIFICATION_TAB_CONTENTS_DESTROYED, 310 registrar_.Remove(this, content::NOTIFICATION_TAB_CONTENTS_DESTROYED,
247 Source<TabContents>(tab)); 311 Source<TabContents>(tab));
248 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 312 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
249 Source<NavigationController>(&tab->controller())); 313 Source<NavigationController>(&tab->controller()));
314
315 // Multiple sites may share the same RenderProcessHost, so check if this
316 // notification has already been added.
317 RenderProcessHost* rph = tab->render_view_host()->process();
318 if (registrar_.IsRegistered(this,
319 content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
320 Source<RenderProcessHost>(rph))) {
321 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
322 Source<RenderProcessHost>(rph));
323 }
250 } 324 }
251 325
252 } // namespace printing 326 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698