OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/background_printing_manager.h" | 5 #include "chrome/browser/printing/background_printing_manager.h" |
6 | 6 |
7 #include "chrome/browser/printing/print_job.h" | 7 #include "chrome/browser/printing/print_job.h" |
8 #include "chrome/browser/printing/print_preview_tab_controller.h" | 8 #include "chrome/browser/printing/print_preview_tab_controller.h" |
9 #include "chrome/browser/sessions/restore_tab_helper.h" | 9 #include "chrome/browser/sessions/restore_tab_helper.h" |
10 #include "chrome/browser/ui/browser_list.h" | 10 #include "chrome/browser/ui/browser_list.h" |
11 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 11 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
12 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 12 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
13 #include "chrome/common/chrome_notification_types.h" | 13 #include "chrome/common/chrome_notification_types.h" |
14 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/browser/notification_details.h" | 15 #include "content/public/browser/notification_details.h" |
16 #include "content/public/browser/notification_source.h" | 16 #include "content/public/browser/notification_source.h" |
17 #include "content/public/browser/render_view_host.h" | 17 #include "content/public/browser/render_view_host.h" |
18 #include "content/public/browser/web_contents.h" | 18 #include "content/public/browser/web_contents.h" |
19 #include "content/public/browser/web_contents_delegate.h" | 19 #include "content/public/browser/web_contents_delegate.h" |
20 | 20 |
21 using content::BrowserThread; | 21 using content::BrowserThread; |
22 using content::WebContents; | 22 using content::WebContents; |
23 | 23 |
24 namespace printing { | 24 namespace printing { |
25 | 25 |
26 BackgroundPrintingManager::BackgroundPrintingManager() { | 26 BackgroundPrintingManager::BackgroundPrintingManager() { |
27 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 27 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
28 } | 28 } |
29 | 29 |
30 BackgroundPrintingManager::~BackgroundPrintingManager() { | 30 BackgroundPrintingManager::~BackgroundPrintingManager() { |
31 DCHECK(CalledOnValidThread()); | 31 DCHECK(CalledOnValidThread()); |
32 // The might be some TabContentsWrappers still in |printing_tabs_| at | 32 // The might be some TabContents still in |printing_tabs_| at |
33 // this point. E.g. when the last remaining tab is a print preview tab and | 33 // this point. E.g. when the last remaining tab is a print preview tab and |
34 // tries to print. In which case it will fail to print. | 34 // tries to print. In which case it will fail to print. |
35 // TODO(thestig) handle this case better. | 35 // TODO(thestig) handle this case better. |
36 } | 36 } |
37 | 37 |
38 void BackgroundPrintingManager::OwnPrintPreviewTab( | 38 void BackgroundPrintingManager::OwnPrintPreviewTab(TabContents* preview_tab) { |
39 TabContentsWrapper* preview_tab) { | |
40 DCHECK(CalledOnValidThread()); | 39 DCHECK(CalledOnValidThread()); |
41 DCHECK(PrintPreviewTabController::IsPrintPreviewTab(preview_tab)); | 40 DCHECK(PrintPreviewTabController::IsPrintPreviewTab(preview_tab)); |
42 CHECK(!HasPrintPreviewTab(preview_tab)); | 41 CHECK(!HasPrintPreviewTab(preview_tab)); |
43 | 42 |
44 printing_tabs_.insert(preview_tab); | 43 printing_tabs_.insert(preview_tab); |
45 | 44 |
46 content::Source<TabContentsWrapper> preview_source(preview_tab); | 45 content::Source<TabContents> preview_source(preview_tab); |
47 registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_RELEASED, preview_source); | 46 registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_RELEASED, preview_source); |
48 | 47 |
49 // OwnInitiatorTabContents() may have already added this notification. | 48 // OwnInitiatorTabContents() may have already added this notification. |
50 if (!registrar_.IsRegistered(this, | 49 if (!registrar_.IsRegistered(this, |
51 chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, preview_source)) { | 50 chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, preview_source)) { |
52 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, | 51 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, |
53 preview_source); | 52 preview_source); |
54 } | 53 } |
55 | 54 |
56 // If a tab that is printing crashes, the user cannot destroy it since it is | 55 // If a tab that is printing crashes, the user cannot destroy it since it is |
57 // not in any tab strip. Thus listen for crashes here and delete the tab. | 56 // not in any tab strip. Thus listen for crashes here and delete the tab. |
58 // | 57 // |
59 // Multiple sites may share the same RenderProcessHost, so check if this | 58 // Multiple sites may share the same RenderProcessHost, so check if this |
60 // notification has already been added. | 59 // notification has already been added. |
61 content::RenderProcessHost* rph = | 60 content::RenderProcessHost* rph = |
62 preview_tab->web_contents()->GetRenderProcessHost(); | 61 preview_tab->web_contents()->GetRenderProcessHost(); |
63 if (!registrar_.IsRegistered(this, | 62 if (!registrar_.IsRegistered(this, |
64 content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 63 content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
65 content::Source<content::RenderProcessHost>( | 64 content::Source<content::RenderProcessHost>( |
66 rph))) { | 65 rph))) { |
67 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 66 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
68 content::Source<content::RenderProcessHost>(rph)); | 67 content::Source<content::RenderProcessHost>(rph)); |
69 } | 68 } |
70 | 69 |
71 // Activate the initiator tab. | 70 // Activate the initiator tab. |
72 PrintPreviewTabController* tab_controller = | 71 PrintPreviewTabController* tab_controller = |
73 PrintPreviewTabController::GetInstance(); | 72 PrintPreviewTabController::GetInstance(); |
74 if (!tab_controller) | 73 if (!tab_controller) |
75 return; | 74 return; |
76 TabContentsWrapper* initiator_tab = | 75 TabContents* initiator_tab = tab_controller->GetInitiatorTab(preview_tab); |
77 tab_controller->GetInitiatorTab(preview_tab); | |
78 if (!initiator_tab) | 76 if (!initiator_tab) |
79 return; | 77 return; |
80 WebContents* web_contents = initiator_tab->web_contents(); | 78 WebContents* web_contents = initiator_tab->web_contents(); |
81 web_contents->GetDelegate()->ActivateContents(web_contents); | 79 web_contents->GetDelegate()->ActivateContents(web_contents); |
82 } | 80 } |
83 | 81 |
84 void BackgroundPrintingManager::Observe( | 82 void BackgroundPrintingManager::Observe( |
85 int type, | 83 int type, |
86 const content::NotificationSource& source, | 84 const content::NotificationSource& source, |
87 const content::NotificationDetails& details) { | 85 const content::NotificationDetails& details) { |
88 switch (type) { | 86 switch (type) { |
89 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | 87 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
90 OnRendererProcessClosed( | 88 OnRendererProcessClosed( |
91 content::Source<content::RenderProcessHost>(source).ptr()); | 89 content::Source<content::RenderProcessHost>(source).ptr()); |
92 break; | 90 break; |
93 } | 91 } |
94 case chrome::NOTIFICATION_PRINT_JOB_RELEASED: { | 92 case chrome::NOTIFICATION_PRINT_JOB_RELEASED: { |
95 OnPrintJobReleased(content::Source<TabContentsWrapper>(source).ptr()); | 93 OnPrintJobReleased(content::Source<TabContents>(source).ptr()); |
96 break; | 94 break; |
97 } | 95 } |
98 case chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED: { | 96 case chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED: { |
99 OnTabContentsDestroyed(content::Source<TabContentsWrapper>(source).ptr()); | 97 OnTabContentsDestroyed(content::Source<TabContents>(source).ptr()); |
100 break; | 98 break; |
101 } | 99 } |
102 default: { | 100 default: { |
103 NOTREACHED(); | 101 NOTREACHED(); |
104 break; | 102 break; |
105 } | 103 } |
106 } | 104 } |
107 } | 105 } |
108 | 106 |
109 void BackgroundPrintingManager::OnRendererProcessClosed( | 107 void BackgroundPrintingManager::OnRendererProcessClosed( |
110 content::RenderProcessHost* rph) { | 108 content::RenderProcessHost* rph) { |
111 TabContentsWrapperSet preview_tabs_pending_deletion; | 109 TabContentsSet preview_tabs_pending_deletion; |
112 TabContentsWrapperSet::const_iterator it; | 110 TabContentsSet::const_iterator it; |
113 for (it = begin(); it != end(); ++it) { | 111 for (it = begin(); it != end(); ++it) { |
114 TabContentsWrapper* preview_tab = *it; | 112 TabContents* preview_tab = *it; |
115 if (preview_tab->web_contents()->GetRenderProcessHost() == rph) { | 113 if (preview_tab->web_contents()->GetRenderProcessHost() == rph) { |
116 preview_tabs_pending_deletion.insert(preview_tab); | 114 preview_tabs_pending_deletion.insert(preview_tab); |
117 } | 115 } |
118 } | 116 } |
119 for (it = preview_tabs_pending_deletion.begin(); | 117 for (it = preview_tabs_pending_deletion.begin(); |
120 it != preview_tabs_pending_deletion.end(); | 118 it != preview_tabs_pending_deletion.end(); |
121 ++it) { | 119 ++it) { |
122 DeletePreviewTab(*it); | 120 DeletePreviewTab(*it); |
123 } | 121 } |
124 } | 122 } |
125 | 123 |
126 void BackgroundPrintingManager::OnPrintJobReleased( | 124 void BackgroundPrintingManager::OnPrintJobReleased(TabContents* preview_tab) { |
127 TabContentsWrapper* preview_tab) { | |
128 DeletePreviewTab(preview_tab); | 125 DeletePreviewTab(preview_tab); |
129 } | 126 } |
130 | 127 |
131 void BackgroundPrintingManager::OnTabContentsDestroyed( | 128 void BackgroundPrintingManager::OnTabContentsDestroyed( |
132 TabContentsWrapper* preview_tab) { | 129 TabContents* preview_tab) { |
133 // Always need to remove this notification since the tab is gone. | 130 // Always need to remove this notification since the tab is gone. |
134 content::Source<TabContentsWrapper> preview_source(preview_tab); | 131 content::Source<TabContents> preview_source(preview_tab); |
135 registrar_.Remove(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, | 132 registrar_.Remove(this, chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, |
136 preview_source); | 133 preview_source); |
137 | 134 |
138 if (!HasPrintPreviewTab(preview_tab)) { | 135 if (!HasPrintPreviewTab(preview_tab)) { |
139 NOTREACHED(); | 136 NOTREACHED(); |
140 return; | 137 return; |
141 } | 138 } |
142 | 139 |
143 // Remove NOTIFICATION_RENDERER_PROCESS_CLOSED if |preview_tab| is the last | 140 // Remove NOTIFICATION_RENDERER_PROCESS_CLOSED if |preview_tab| is the last |
144 // WebContents associated with |rph|. | 141 // WebContents associated with |rph|. |
145 bool shared_rph = HasSharedRenderProcessHost(printing_tabs_, preview_tab) || | 142 bool shared_rph = HasSharedRenderProcessHost(printing_tabs_, preview_tab) || |
146 HasSharedRenderProcessHost(printing_tabs_pending_deletion_, preview_tab); | 143 HasSharedRenderProcessHost(printing_tabs_pending_deletion_, preview_tab); |
147 if (!shared_rph) { | 144 if (!shared_rph) { |
148 content::RenderProcessHost* rph = | 145 content::RenderProcessHost* rph = |
149 preview_tab->web_contents()->GetRenderProcessHost(); | 146 preview_tab->web_contents()->GetRenderProcessHost(); |
150 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 147 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
151 content::Source<content::RenderProcessHost>(rph)); | 148 content::Source<content::RenderProcessHost>(rph)); |
152 } | 149 } |
153 | 150 |
154 // Remove other notifications and remove the tab from its | 151 // Remove other notifications and remove the tab from its TabContentsSet. |
155 // TabContentsWrapperSet. | |
156 if (printing_tabs_.find(preview_tab) != printing_tabs_.end()) { | 152 if (printing_tabs_.find(preview_tab) != printing_tabs_.end()) { |
157 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_RELEASED, | 153 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_RELEASED, |
158 preview_source); | 154 preview_source); |
159 printing_tabs_.erase(preview_tab); | 155 printing_tabs_.erase(preview_tab); |
160 } else { | 156 } else { |
161 // DeletePreviewTab already deleted the notification. | 157 // DeletePreviewTab already deleted the notification. |
162 printing_tabs_pending_deletion_.erase(preview_tab); | 158 printing_tabs_pending_deletion_.erase(preview_tab); |
163 } | 159 } |
164 } | 160 } |
165 | 161 |
166 void BackgroundPrintingManager::DeletePreviewTab(TabContentsWrapper* tab) { | 162 void BackgroundPrintingManager::DeletePreviewTab(TabContents* tab) { |
167 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_RELEASED, | 163 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_RELEASED, |
168 content::Source<TabContentsWrapper>(tab)); | 164 content::Source<TabContents>(tab)); |
169 printing_tabs_.erase(tab); | 165 printing_tabs_.erase(tab); |
170 printing_tabs_pending_deletion_.insert(tab); | 166 printing_tabs_pending_deletion_.insert(tab); |
171 MessageLoop::current()->DeleteSoon(FROM_HERE, tab); | 167 MessageLoop::current()->DeleteSoon(FROM_HERE, tab); |
172 } | 168 } |
173 | 169 |
174 bool BackgroundPrintingManager::HasSharedRenderProcessHost( | 170 bool BackgroundPrintingManager::HasSharedRenderProcessHost( |
175 const TabContentsWrapperSet& set, | 171 const TabContentsSet& set, |
176 TabContentsWrapper* tab) { | 172 TabContents* tab) { |
177 content::RenderProcessHost* rph = tab->web_contents()->GetRenderProcessHost(); | 173 content::RenderProcessHost* rph = tab->web_contents()->GetRenderProcessHost(); |
178 for (TabContentsWrapperSet::const_iterator it = set.begin(); | 174 for (TabContentsSet::const_iterator it = set.begin(); it != set.end(); ++it) { |
179 it != set.end(); | 175 TabContents* iter_tab = *it; |
180 ++it) { | |
181 TabContentsWrapper* iter_tab = *it; | |
182 if ((iter_tab != tab) && | 176 if ((iter_tab != tab) && |
183 (iter_tab->web_contents()->GetRenderProcessHost() == rph)) { | 177 (iter_tab->web_contents()->GetRenderProcessHost() == rph)) { |
184 return true; | 178 return true; |
185 } | 179 } |
186 } | 180 } |
187 return false; | 181 return false; |
188 } | 182 } |
189 | 183 |
190 BackgroundPrintingManager::TabContentsWrapperSet::const_iterator | 184 BackgroundPrintingManager::TabContentsSet::const_iterator |
191 BackgroundPrintingManager::begin() { | 185 BackgroundPrintingManager::begin() { |
192 return printing_tabs_.begin(); | 186 return printing_tabs_.begin(); |
193 } | 187 } |
194 | 188 |
195 BackgroundPrintingManager::TabContentsWrapperSet::const_iterator | 189 BackgroundPrintingManager::TabContentsSet::const_iterator |
196 BackgroundPrintingManager::end() { | 190 BackgroundPrintingManager::end() { |
197 return printing_tabs_.end(); | 191 return printing_tabs_.end(); |
198 } | 192 } |
199 | 193 |
200 bool BackgroundPrintingManager::HasPrintPreviewTab( | 194 bool BackgroundPrintingManager::HasPrintPreviewTab( |
201 TabContentsWrapper* preview_tab) { | 195 TabContents* preview_tab) { |
202 if (printing_tabs_.find(preview_tab) != printing_tabs_.end()) | 196 if (printing_tabs_.find(preview_tab) != printing_tabs_.end()) |
203 return true; | 197 return true; |
204 return printing_tabs_pending_deletion_.find(preview_tab) != | 198 return printing_tabs_pending_deletion_.find(preview_tab) != |
205 printing_tabs_pending_deletion_.end(); | 199 printing_tabs_pending_deletion_.end(); |
206 } | 200 } |
207 | 201 |
208 } // namespace printing | 202 } // namespace printing |
OLD | NEW |