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

Side by Side Diff: chrome/browser/browser_list.cc

Issue 2866034: Refactor shutdown code to allow win/linux to run after last browser closes. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Uploaded patch that resolves merge issue Created 10 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
« no previous file with comments | « chrome/browser/browser_list.h ('k') | chrome/browser/browser_list_gtk.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/browser_list.h" 5 #include "chrome/browser/browser_list.h"
6 6
7 #include "base/histogram.h" 7 #include "base/histogram.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 165 }
166 166
167 // static 167 // static
168 void BrowserList::RemoveBrowser(Browser* browser) { 168 void BrowserList::RemoveBrowser(Browser* browser) {
169 RemoveBrowserFrom(browser, &last_active_browsers_); 169 RemoveBrowserFrom(browser, &last_active_browsers_);
170 170
171 // Closing all windows does not indicate quitting the application on the Mac, 171 // Closing all windows does not indicate quitting the application on the Mac,
172 // however, many UI tests rely on this behavior so leave it be for now and 172 // however, many UI tests rely on this behavior so leave it be for now and
173 // simply ignore the behavior on the Mac outside of unit tests. 173 // simply ignore the behavior on the Mac outside of unit tests.
174 // TODO(andybons): Fix the UI tests to Do The Right Thing. 174 // TODO(andybons): Fix the UI tests to Do The Right Thing.
175 bool close_app_non_mac = (browsers_.size() == 1); 175 bool closing_last_browser = (browsers_.size() == 1);
176 NotificationService::current()->Notify( 176 NotificationService::current()->Notify(
177 NotificationType::BROWSER_CLOSED, 177 NotificationType::BROWSER_CLOSED,
178 Source<Browser>(browser), Details<bool>(&close_app_non_mac)); 178 Source<Browser>(browser), Details<bool>(&closing_last_browser));
179 179
180 // Send out notifications before anything changes. Do some basic checking to 180 // Send out notifications before anything changes. Do some basic checking to
181 // try to catch evil observers that change the list from under us. 181 // try to catch evil observers that change the list from under us.
182 size_t original_count = observers_.size(); 182 size_t original_count = observers_.size();
183 FOR_EACH_OBSERVER(Observer, observers_, OnBrowserRemoving(browser)); 183 FOR_EACH_OBSERVER(Observer, observers_, OnBrowserRemoving(browser));
184 DCHECK_EQ(original_count, observers_.size()) 184 DCHECK_EQ(original_count, observers_.size())
185 << "observer list modified during notification"; 185 << "observer list modified during notification";
186 186
187 RemoveBrowserFrom(browser, &browsers_); 187 RemoveBrowserFrom(browser, &browsers_);
188 188
189 // If the last Browser object was destroyed, make sure we try to close any 189 // If the last Browser object was destroyed, make sure we try to close any
190 // remaining dependent windows too. 190 // remaining dependent windows too.
191 if (browsers_.empty()) { 191 if (browsers_.empty()) {
192 AllBrowsersClosed();
193
194 delete activity_observer; 192 delete activity_observer;
195 activity_observer = NULL; 193 activity_observer = NULL;
196 } 194 }
197 195
198 g_browser_process->ReleaseModule(); 196 g_browser_process->ReleaseModule();
197
198 // If we're exiting, send out the APP_TERMINATING notification to allow other
199 // modules to shut themselves down.
200 if (browsers_.empty() &&
201 (browser_shutdown::IsTryingToQuit() ||
202 g_browser_process->IsShuttingDown())) {
203 // Last browser has just closed, and this is a user-initiated quit or there
204 // is no module keeping the app alive, so send out our notification.
205 NotificationService::current()->Notify(NotificationType::APP_TERMINATING,
206 NotificationService::AllSources(),
207 NotificationService::NoDetails());
208 AllBrowsersClosedAndAppExiting();
209 }
199 } 210 }
200 211
201 // static 212 // static
202 void BrowserList::AddObserver(BrowserList::Observer* observer) { 213 void BrowserList::AddObserver(BrowserList::Observer* observer) {
203 observers_.AddObserver(observer); 214 observers_.AddObserver(observer);
204 } 215 }
205 216
206 // static 217 // static
207 void BrowserList::RemoveObserver(BrowserList::Observer* observer) { 218 void BrowserList::RemoveObserver(BrowserList::Observer* observer) {
208 observers_.RemoveObserver(observer); 219 observers_.RemoveObserver(observer);
209 } 220 }
210 221
211 // static 222 // static
212 void BrowserList::CloseAllBrowsers(bool use_post) { 223 void BrowserList::CloseAllBrowsers(bool use_post) {
224 // Tell everyone that we are shutting down.
225 browser_shutdown::SetTryingToQuit(true);
226
213 // Before we close the browsers shutdown all session services. That way an 227 // Before we close the browsers shutdown all session services. That way an
214 // exit can restore all browsers open before exiting. 228 // exit can restore all browsers open before exiting.
215 ProfileManager::ShutdownSessionServices(); 229 ProfileManager::ShutdownSessionServices();
216 230
231 // If there are no browsers, send the APP_TERMINATING action here. Otherwise,
232 // it will be sent by RemoveBrowser() when the last browser has closed.
233 if (browsers_.empty()) {
234 NotificationService::current()->Notify(NotificationType::APP_TERMINATING,
235 NotificationService::AllSources(),
236 NotificationService::NoDetails());
237 AllBrowsersClosedAndAppExiting();
238 return;
239 }
217 for (BrowserList::const_iterator i = BrowserList::begin(); 240 for (BrowserList::const_iterator i = BrowserList::begin();
218 i != BrowserList::end();) { 241 i != BrowserList::end();) {
219 if (use_post) { 242 if (use_post) {
220 (*i)->window()->Close(); 243 (*i)->window()->Close();
221 ++i; 244 ++i;
222 } else { 245 } else {
223 // This path is hit during logoff/power-down. In this case we won't get 246 // This path is hit during logoff/power-down. In this case we won't get
224 // a final message and so we force the browser to be deleted. 247 // a final message and so we force the browser to be deleted.
225 Browser* browser = *i; 248 Browser* browser = *i;
226 browser->window()->Close(); 249 browser->window()->Close();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 // static 325 // static
303 bool BrowserList::HasBrowserWithProfile(Profile* profile) { 326 bool BrowserList::HasBrowserWithProfile(Profile* profile) {
304 return FindBrowserMatching(BrowserList::begin(), 327 return FindBrowserMatching(BrowserList::begin(),
305 BrowserList::end(), 328 BrowserList::end(),
306 profile, Browser::TYPE_ANY, 329 profile, Browser::TYPE_ANY,
307 Browser::FEATURE_NONE, 330 Browser::FEATURE_NONE,
308 kMatchNothing) != NULL; 331 kMatchNothing) != NULL;
309 } 332 }
310 333
311 // static 334 // static
312 bool BrowserList::IsInPersistentMode() { 335 int BrowserList::keep_alive_count_ = 0;
313 // TODO(atwilson): check the boolean state variable that you will set for 336
314 // persisent instances. 337 // static
315 return false; 338 void BrowserList::StartKeepAlive() {
339 // Increment the browser process refcount as long as we're keeping the
340 // application alive.
341 if (!WillKeepAlive())
342 g_browser_process->AddRefModule();
343 keep_alive_count_++;
316 } 344 }
317 345
318 // static 346 // static
347 void BrowserList::EndKeepAlive() {
348 DCHECK(keep_alive_count_ > 0);
349 keep_alive_count_--;
350 // Allow the app to shutdown again.
351 if (!WillKeepAlive()) {
352 g_browser_process->ReleaseModule();
353 // If there are no browsers open and we aren't already shutting down,
354 // initiate a shutdown. Also skips shutdown if this is a unit test
355 // (MessageLoop::current() == null).
356 if (browsers_.empty() && !browser_shutdown::IsTryingToQuit() &&
357 MessageLoop::current())
358 CloseAllBrowsers(true);
359 }
360 }
361
362 // static
363 bool BrowserList::WillKeepAlive() {
364 return keep_alive_count_ > 0;
365 }
366
367 // static
319 BrowserList::BrowserVector BrowserList::last_active_browsers_; 368 BrowserList::BrowserVector BrowserList::last_active_browsers_;
320 369
321 // static 370 // static
322 void BrowserList::SetLastActive(Browser* browser) { 371 void BrowserList::SetLastActive(Browser* browser) {
323 RemoveBrowserFrom(browser, &last_active_browsers_); 372 RemoveBrowserFrom(browser, &last_active_browsers_);
324 last_active_browsers_.push_back(browser); 373 last_active_browsers_.push_back(browser);
325 374
326 FOR_EACH_OBSERVER(Observer, observers_, OnBrowserSetLastActive(browser)); 375 FOR_EACH_OBSERVER(Observer, observers_, OnBrowserSetLastActive(browser));
327 } 376 }
328 377
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 } 504 }
456 505
457 TabContents* next_tab = 506 TabContents* next_tab =
458 (*browser_iterator_)->GetTabContentsAt(web_view_index_); 507 (*browser_iterator_)->GetTabContentsAt(web_view_index_);
459 if (next_tab) { 508 if (next_tab) {
460 cur_ = next_tab; 509 cur_ = next_tab;
461 return; 510 return;
462 } 511 }
463 } 512 }
464 } 513 }
OLDNEW
« no previous file with comments | « chrome/browser/browser_list.h ('k') | chrome/browser/browser_list_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698