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

Side by Side Diff: chrome/browser/background/background_mode_manager.cc

Issue 25603004: Leave apps running on Windows and Linux when quitting Chrome from the wrench menu. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 2 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
OLDNEW
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 <algorithm> 5 #include <algorithm>
6 #include <string> 6 #include <string>
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/base_paths.h" 9 #include "base/base_paths.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 12 matching lines...) Expand all
23 #include "chrome/browser/extensions/extension_system.h" 23 #include "chrome/browser/extensions/extension_system.h"
24 #include "chrome/browser/lifetime/application_lifetime.h" 24 #include "chrome/browser/lifetime/application_lifetime.h"
25 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/profiles/profile_info_cache.h" 26 #include "chrome/browser/profiles/profile_info_cache.h"
27 #include "chrome/browser/profiles/profile_manager.h" 27 #include "chrome/browser/profiles/profile_manager.h"
28 #include "chrome/browser/status_icons/status_icon.h" 28 #include "chrome/browser/status_icons/status_icon.h"
29 #include "chrome/browser/status_icons/status_tray.h" 29 #include "chrome/browser/status_icons/status_tray.h"
30 #include "chrome/browser/ui/browser.h" 30 #include "chrome/browser/ui/browser.h"
31 #include "chrome/browser/ui/browser_commands.h" 31 #include "chrome/browser/ui/browser_commands.h"
32 #include "chrome/browser/ui/browser_finder.h" 32 #include "chrome/browser/ui/browser_finder.h"
33 #include "chrome/browser/ui/browser_list.h"
33 #include "chrome/browser/ui/chrome_pages.h" 34 #include "chrome/browser/ui/chrome_pages.h"
34 #include "chrome/browser/ui/extensions/application_launch.h" 35 #include "chrome/browser/ui/extensions/application_launch.h"
35 #include "chrome/browser/ui/host_desktop.h" 36 #include "chrome/browser/ui/host_desktop.h"
36 #include "chrome/common/chrome_constants.h" 37 #include "chrome/common/chrome_constants.h"
37 #include "chrome/common/chrome_switches.h" 38 #include "chrome/common/chrome_switches.h"
38 #include "chrome/common/extensions/extension.h" 39 #include "chrome/common/extensions/extension.h"
39 #include "chrome/common/extensions/extension_constants.h" 40 #include "chrome/common/extensions/extension_constants.h"
40 #include "chrome/common/extensions/permissions/permission_set.h" 41 #include "chrome/common/extensions/permissions/permission_set.h"
41 #include "chrome/common/pref_names.h" 42 #include "chrome/common/pref_names.h"
42 #include "content/public/browser/notification_service.h" 43 #include "content/public/browser/notification_service.h"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 BackgroundModeManager::BackgroundModeManager( 142 BackgroundModeManager::BackgroundModeManager(
142 CommandLine* command_line, 143 CommandLine* command_line,
143 ProfileInfoCache* profile_cache) 144 ProfileInfoCache* profile_cache)
144 : profile_cache_(profile_cache), 145 : profile_cache_(profile_cache),
145 status_tray_(NULL), 146 status_tray_(NULL),
146 status_icon_(NULL), 147 status_icon_(NULL),
147 context_menu_(NULL), 148 context_menu_(NULL),
148 in_background_mode_(false), 149 in_background_mode_(false),
149 keep_alive_for_startup_(false), 150 keep_alive_for_startup_(false),
150 keep_alive_for_test_(false), 151 keep_alive_for_test_(false),
152 background_mode_suspended_(false),
151 current_command_id_(0) { 153 current_command_id_(0) {
152 // We should never start up if there is no browser process or if we are 154 // We should never start up if there is no browser process or if we are
153 // currently quitting. 155 // currently quitting.
154 CHECK(g_browser_process != NULL); 156 CHECK(g_browser_process != NULL);
155 CHECK(!browser_shutdown::IsTryingToQuit()); 157 CHECK(!browser_shutdown::IsTryingToQuit());
156 158
157 // Add self as an observer for the profile info cache so we know when profiles 159 // Add self as an observer for the profile info cache so we know when profiles
158 // are deleted and their names change. 160 // are deleted and their names change.
159 profile_cache_->AddObserver(this); 161 profile_cache_->AddObserver(this);
160 162
(...skipping 20 matching lines...) Expand all
181 if (command_line->HasSwitch(switches::kKeepAliveForTest)) 183 if (command_line->HasSwitch(switches::kKeepAliveForTest))
182 keep_alive_for_test_ = true; 184 keep_alive_for_test_ = true;
183 185
184 if (ShouldBeInBackgroundMode()) 186 if (ShouldBeInBackgroundMode())
185 StartBackgroundMode(); 187 StartBackgroundMode();
186 188
187 // Listen for the application shutting down so we can decrement our KeepAlive 189 // Listen for the application shutting down so we can decrement our KeepAlive
188 // count. 190 // count.
189 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, 191 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
190 content::NotificationService::AllSources()); 192 content::NotificationService::AllSources());
193 BrowserList::AddObserver(this);
191 } 194 }
192 195
193 BackgroundModeManager::~BackgroundModeManager() { 196 BackgroundModeManager::~BackgroundModeManager() {
194 // Remove ourselves from the application observer list (only needed by unit 197 // Remove ourselves from the application observer list (only needed by unit
195 // tests since APP_TERMINATING is what does this in a real running system). 198 // tests since APP_TERMINATING is what does this in a real running system).
196 for (BackgroundModeInfoMap::iterator it = 199 for (BackgroundModeInfoMap::iterator it =
197 background_mode_data_.begin(); 200 background_mode_data_.begin();
198 it != background_mode_data_.end(); 201 it != background_mode_data_.end();
199 ++it) { 202 ++it) {
200 it->second->applications_->RemoveObserver(this); 203 it->second->applications_->RemoveObserver(this);
201 } 204 }
205 BrowserList::RemoveObserver(this);
202 206
203 // We're going away, so exit background mode (does nothing if we aren't in 207 // We're going away, so exit background mode (does nothing if we aren't in
204 // background mode currently). This is primarily needed for unit tests, 208 // background mode currently). This is primarily needed for unit tests,
205 // because in an actual running system we'd get an APP_TERMINATING 209 // because in an actual running system we'd get an APP_TERMINATING
206 // notification before being destroyed. 210 // notification before being destroyed.
207 EndBackgroundMode(); 211 EndBackgroundMode();
208 } 212 }
209 213
210 // static 214 // static
211 void BackgroundModeManager::RegisterPrefs(PrefRegistrySimple* registry) { 215 void BackgroundModeManager::RegisterPrefs(PrefRegistrySimple* registry) {
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 BackgroundModeData* bmd = background_mode_data_.begin()->second.get(); 454 BackgroundModeData* bmd = background_mode_data_.begin()->second.get();
451 switch (command_id) { 455 switch (command_id) {
452 case IDC_ABOUT: 456 case IDC_ABOUT:
453 chrome::ShowAboutChrome(bmd->GetBrowserWindow()); 457 chrome::ShowAboutChrome(bmd->GetBrowserWindow());
454 break; 458 break;
455 case IDC_TASK_MANAGER: 459 case IDC_TASK_MANAGER:
456 chrome::OpenTaskManager(bmd->GetBrowserWindow()); 460 chrome::OpenTaskManager(bmd->GetBrowserWindow());
457 break; 461 break;
458 case IDC_EXIT: 462 case IDC_EXIT:
459 content::RecordAction(UserMetricsAction("Exit")); 463 content::RecordAction(UserMetricsAction("Exit"));
460 chrome::AttemptExit(); 464 chrome::CloseAllBrowsers();
461 break; 465 break;
462 case IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND: { 466 case IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND: {
463 // Background mode must already be enabled (as otherwise this menu would 467 // Background mode must already be enabled (as otherwise this menu would
464 // not be visible). 468 // not be visible).
465 DCHECK(IsBackgroundModePrefEnabled()); 469 DCHECK(IsBackgroundModePrefEnabled());
466 DCHECK(chrome::WillKeepAlive()); 470 DCHECK(chrome::WillKeepAlive());
467 471
468 // Set the background mode pref to "disabled" - the resulting notification 472 // Set the background mode pref to "disabled" - the resulting notification
469 // will result in a call to DisableBackgroundMode(). 473 // will result in a call to DisableBackgroundMode().
470 PrefService* service = g_browser_process->local_state(); 474 PrefService* service = g_browser_process->local_state();
(...skipping 24 matching lines...) Expand all
495 void BackgroundModeManager::StartBackgroundMode() { 499 void BackgroundModeManager::StartBackgroundMode() {
496 DCHECK(ShouldBeInBackgroundMode()); 500 DCHECK(ShouldBeInBackgroundMode());
497 // Don't bother putting ourselves in background mode if we're already there 501 // Don't bother putting ourselves in background mode if we're already there
498 // or if background mode is disabled. 502 // or if background mode is disabled.
499 if (in_background_mode_) 503 if (in_background_mode_)
500 return; 504 return;
501 505
502 // Mark ourselves as running in background mode. 506 // Mark ourselves as running in background mode.
503 in_background_mode_ = true; 507 in_background_mode_ = true;
504 508
505 // Put ourselves in KeepAlive mode and create a status tray icon. 509 if (!background_mode_suspended_) {
506 chrome::StartKeepAlive(); 510 // Put ourselves in KeepAlive mode and create a status tray icon.
511 chrome::StartKeepAlive();
507 512
508 // Display a status icon to exit Chrome. 513 // Display a status icon to exit Chrome.
509 InitStatusTrayIcon(); 514 InitStatusTrayIcon();
515 }
510 516
511 content::NotificationService::current()->Notify( 517 content::NotificationService::current()->Notify(
512 chrome::NOTIFICATION_BACKGROUND_MODE_CHANGED, 518 chrome::NOTIFICATION_BACKGROUND_MODE_CHANGED,
513 content::Source<BackgroundModeManager>(this), 519 content::Source<BackgroundModeManager>(this),
514 content::Details<bool>(&in_background_mode_)); 520 content::Details<bool>(&in_background_mode_));
515 } 521 }
516 522
517 void BackgroundModeManager::InitStatusTrayIcon() { 523 void BackgroundModeManager::InitStatusTrayIcon() {
524 DCHECK(!background_mode_suspended_);
518 // Only initialize status tray icons for those profiles which actually 525 // Only initialize status tray icons for those profiles which actually
519 // have a background app running. 526 // have a background app running.
520 if (ShouldBeInBackgroundMode()) 527 if (ShouldBeInBackgroundMode())
521 CreateStatusTrayIcon(); 528 CreateStatusTrayIcon();
522 } 529 }
523 530
524 void BackgroundModeManager::EndBackgroundMode() { 531 void BackgroundModeManager::EndBackgroundMode() {
525 if (!in_background_mode_) 532 if (!in_background_mode_)
526 return; 533 return;
527 in_background_mode_ = false; 534 in_background_mode_ = false;
528 535
529 // End KeepAlive mode and blow away our status tray icon. 536 if (!background_mode_suspended_) {
530 chrome::EndKeepAlive(); 537 // End KeepAlive mode and blow away our status tray icon.
538 chrome::EndKeepAlive();
531 539
532 RemoveStatusTrayIcon(); 540 RemoveStatusTrayIcon();
541 }
533 content::NotificationService::current()->Notify( 542 content::NotificationService::current()->Notify(
534 chrome::NOTIFICATION_BACKGROUND_MODE_CHANGED, 543 chrome::NOTIFICATION_BACKGROUND_MODE_CHANGED,
535 content::Source<BackgroundModeManager>(this), 544 content::Source<BackgroundModeManager>(this),
536 content::Details<bool>(&in_background_mode_)); 545 content::Details<bool>(&in_background_mode_));
537 } 546 }
538 547
539 void BackgroundModeManager::EnableBackgroundMode() { 548 void BackgroundModeManager::EnableBackgroundMode() {
540 DCHECK(IsBackgroundModePrefEnabled()); 549 DCHECK(IsBackgroundModePrefEnabled());
541 // If background mode should be enabled, but isn't, turn it on. 550 // If background mode should be enabled, but isn't, turn it on.
542 if (!in_background_mode_ && ShouldBeInBackgroundMode()) { 551 if (!in_background_mode_ && ShouldBeInBackgroundMode()) {
543 StartBackgroundMode(); 552 StartBackgroundMode();
544 EnableLaunchOnStartup(true); 553 EnableLaunchOnStartup(true);
545 } 554 }
546 } 555 }
547 556
548 void BackgroundModeManager::DisableBackgroundMode() { 557 void BackgroundModeManager::DisableBackgroundMode() {
549 DCHECK(!IsBackgroundModePrefEnabled()); 558 DCHECK(!IsBackgroundModePrefEnabled());
550 // If background mode is currently enabled, turn it off. 559 // If background mode is currently enabled, turn it off.
551 if (in_background_mode_) { 560 if (in_background_mode_) {
552 EndBackgroundMode(); 561 EndBackgroundMode();
553 EnableLaunchOnStartup(false); 562 EnableLaunchOnStartup(false);
554 } 563 }
555 } 564 }
556 565
566 void BackgroundModeManager::SuspendBackgroundMode() {
567 if (background_mode_suspended_)
568 return;
569
570 background_mode_suspended_ = true;
571
572 if (!in_background_mode_)
573 return;
574
575 chrome::EndKeepAlive();
benwells 2013/10/20 23:46:22 Move the keepalive / status tray stuff into functi
Sam McNally 2013/10/21 04:31:03 Done.
576
577 RemoveStatusTrayIcon();
578 }
579
580 void BackgroundModeManager::ResumeBackgroundMode() {
581 if (!background_mode_suspended_)
582 return;
583
584 background_mode_suspended_ = false;
585
586 if (!in_background_mode_)
587 return;
588
589 chrome::StartKeepAlive();
590
591 InitStatusTrayIcon();
592 }
593
594 void BackgroundModeManager::OnBrowserAdded(Browser* browser) {
595 ResumeBackgroundMode();
596 }
597
557 int BackgroundModeManager::GetBackgroundAppCount() const { 598 int BackgroundModeManager::GetBackgroundAppCount() const {
558 int count = 0; 599 int count = 0;
559 // Walk the BackgroundModeData for all profiles and count the number of apps. 600 // Walk the BackgroundModeData for all profiles and count the number of apps.
560 for (BackgroundModeInfoMap::const_iterator it = 601 for (BackgroundModeInfoMap::const_iterator it =
561 background_mode_data_.begin(); 602 background_mode_data_.begin();
562 it != background_mode_data_.end(); 603 it != background_mode_data_.end();
563 ++it) { 604 ++it) {
564 count += it->second->GetBackgroundAppCount(); 605 count += it->second->GetBackgroundAppCount();
565 } 606 }
566 DCHECK(count >= 0); 607 DCHECK(count >= 0);
567 return count; 608 return count;
568 } 609 }
569 610
570 int BackgroundModeManager::GetBackgroundAppCountForProfile( 611 int BackgroundModeManager::GetBackgroundAppCountForProfile(
571 Profile* const profile) const { 612 Profile* const profile) const {
572 BackgroundModeData* bmd = GetBackgroundModeData(profile); 613 BackgroundModeData* bmd = GetBackgroundModeData(profile);
573 return bmd->GetBackgroundAppCount(); 614 return bmd->GetBackgroundAppCount();
574 } 615 }
575 616
576 bool BackgroundModeManager::ShouldBeInBackgroundMode() const { 617 bool BackgroundModeManager::ShouldBeInBackgroundMode() const {
577 return IsBackgroundModePrefEnabled() && 618 return IsBackgroundModePrefEnabled() &&
578 (GetBackgroundAppCount() > 0 || keep_alive_for_test_); 619 (GetBackgroundAppCount() > 0 || keep_alive_for_test_);
579 } 620 }
580 621
581 void BackgroundModeManager::OnBackgroundAppInstalled( 622 void BackgroundModeManager::OnBackgroundAppInstalled(
582 const Extension* extension) { 623 const Extension* extension) {
583 // Background mode is disabled - don't do anything. 624 // Background mode is disabled - don't do anything.
584 if (!IsBackgroundModePrefEnabled()) 625 if (!IsBackgroundModePrefEnabled())
585 return; 626 return;
627 if (background_mode_suspended_)
628 return;
586 629
587 // Check if we need a status tray icon and make one if we do (needed so we 630 // Check if we need a status tray icon and make one if we do (needed so we
588 // can display the app-installed notification below). 631 // can display the app-installed notification below).
589 CreateStatusTrayIcon(); 632 CreateStatusTrayIcon();
590 633
591 // Notify the user that a background app has been installed. 634 // Notify the user that a background app has been installed.
592 if (extension) { // NULL when called by unit tests. 635 if (extension) { // NULL when called by unit tests.
593 DisplayAppInstalledNotification(extension); 636 DisplayAppInstalledNotification(extension);
594 } 637 }
595 } 638 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 status_icon_ = status_tray_->CreateStatusIcon( 676 status_icon_ = status_tray_->CreateStatusIcon(
634 StatusTray::BACKGROUND_MODE_ICON, 677 StatusTray::BACKGROUND_MODE_ICON,
635 *image_skia, 678 *image_skia,
636 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); 679 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
637 if (!status_icon_) 680 if (!status_icon_)
638 return; 681 return;
639 UpdateStatusTrayIconContextMenu(); 682 UpdateStatusTrayIconContextMenu();
640 } 683 }
641 684
642 void BackgroundModeManager::UpdateStatusTrayIconContextMenu() { 685 void BackgroundModeManager::UpdateStatusTrayIconContextMenu() {
686 if (background_mode_suspended_)
687 return;
688
643 // If no status icon exists, it's either because one wasn't created when 689 // If no status icon exists, it's either because one wasn't created when
644 // it should have been which can happen when extensions load after the 690 // it should have been which can happen when extensions load after the
645 // profile has already been registered with the background mode manager. 691 // profile has already been registered with the background mode manager.
646 if (in_background_mode_ && !status_icon_) 692 if (in_background_mode_ && !status_icon_)
647 CreateStatusTrayIcon(); 693 CreateStatusTrayIcon();
648 694
649 // If we don't have a status icon or one could not be created succesfully, 695 // If we don't have a status icon or one could not be created succesfully,
650 // then no need to continue the update. 696 // then no need to continue the update.
651 if (!status_icon_) 697 if (!status_icon_)
652 return; 698 return;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 } 795 }
750 } 796 }
751 return profile_it; 797 return profile_it;
752 } 798 }
753 799
754 bool BackgroundModeManager::IsBackgroundModePrefEnabled() const { 800 bool BackgroundModeManager::IsBackgroundModePrefEnabled() const {
755 PrefService* service = g_browser_process->local_state(); 801 PrefService* service = g_browser_process->local_state();
756 DCHECK(service); 802 DCHECK(service);
757 return service->GetBoolean(prefs::kBackgroundModeEnabled); 803 return service->GetBoolean(prefs::kBackgroundModeEnabled);
758 } 804 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698