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 <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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 // Keep the browser alive until extensions are done loading - this is needed | 176 // Keep the browser alive until extensions are done loading - this is needed |
177 // by the --no-startup-window flag. We want to stay alive until we load | 177 // by the --no-startup-window flag. We want to stay alive until we load |
178 // extensions, at which point we should either run in background mode (if | 178 // extensions, at which point we should either run in background mode (if |
179 // there are background apps) or exit if there are none. | 179 // there are background apps) or exit if there are none. |
180 if (command_line->HasSwitch(switches::kNoStartupWindow)) { | 180 if (command_line->HasSwitch(switches::kNoStartupWindow)) { |
181 keep_alive_for_startup_ = true; | 181 keep_alive_for_startup_ = true; |
182 browser::StartKeepAlive(); | 182 browser::StartKeepAlive(); |
183 } | 183 } |
184 | 184 |
185 // If the -keep-alive-for-test flag is passed, then always keep chrome running | 185 // If the -keep-alive-for-test flag is passed, then always keep chrome running |
186 // in the background until the user explicitly terminates it, by acting as if | 186 // in the background until the user explicitly terminates it. |
187 // we loaded a background app. | 187 if (command_line->HasSwitch(switches::kKeepAliveForTest)) |
188 if (command_line->HasSwitch(switches::kKeepAliveForTest)) { | |
189 keep_alive_for_test_ = true; | 188 keep_alive_for_test_ = true; |
| 189 |
| 190 if (ShouldBeInBackgroundMode()) |
190 StartBackgroundMode(); | 191 StartBackgroundMode(); |
191 } | |
192 | 192 |
193 // Listen for the application shutting down so we can decrement our KeepAlive | 193 // Listen for the application shutting down so we can decrement our KeepAlive |
194 // count. | 194 // count. |
195 registrar_.Add(this, content::NOTIFICATION_APP_TERMINATING, | 195 registrar_.Add(this, content::NOTIFICATION_APP_TERMINATING, |
196 content::NotificationService::AllSources()); | 196 content::NotificationService::AllSources()); |
197 } | 197 } |
198 | 198 |
199 BackgroundModeManager::~BackgroundModeManager() { | 199 BackgroundModeManager::~BackgroundModeManager() { |
200 // Remove ourselves from the application observer list (only needed by unit | 200 // Remove ourselves from the application observer list (only needed by unit |
201 // tests since APP_TERMINATING is what does this in a real running system). | 201 // tests since APP_TERMINATING is what does this in a real running system). |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 /////////////////////////////////////////////////////////////////////////////// | 281 /////////////////////////////////////////////////////////////////////////////// |
282 // BackgroundModeManager, content::NotificationObserver overrides | 282 // BackgroundModeManager, content::NotificationObserver overrides |
283 void BackgroundModeManager::Observe( | 283 void BackgroundModeManager::Observe( |
284 int type, | 284 int type, |
285 const content::NotificationSource& source, | 285 const content::NotificationSource& source, |
286 const content::NotificationDetails& details) { | 286 const content::NotificationDetails& details) { |
287 switch (type) { | 287 switch (type) { |
288 case chrome::NOTIFICATION_PREF_CHANGED: | 288 case chrome::NOTIFICATION_PREF_CHANGED: |
289 DCHECK(*content::Details<std::string>(details).ptr() == | 289 DCHECK(*content::Details<std::string>(details).ptr() == |
290 prefs::kBackgroundModeEnabled); | 290 prefs::kBackgroundModeEnabled); |
291 if (IsBackgroundModePrefEnabled()) | 291 OnBackgroundModeEnabledPrefChanged(); |
292 EnableBackgroundMode(); | |
293 else | |
294 DisableBackgroundMode(); | |
295 break; | 292 break; |
296 case chrome::NOTIFICATION_EXTENSIONS_READY: | 293 case chrome::NOTIFICATION_EXTENSIONS_READY: |
297 // Extensions are loaded, so we don't need to manually keep the browser | 294 // Extensions are loaded, so we don't need to manually keep the browser |
298 // process alive any more when running in no-startup-window mode. | 295 // process alive any more when running in no-startup-window mode. |
299 EndKeepAliveForStartup(); | 296 EndKeepAliveForStartup(); |
300 break; | 297 break; |
301 | 298 |
302 case chrome::NOTIFICATION_EXTENSION_LOADED: { | 299 case chrome::NOTIFICATION_EXTENSION_LOADED: { |
303 Extension* extension = content::Details<Extension>(details).ptr(); | 300 Extension* extension = content::Details<Extension>(details).ptr(); |
304 Profile* profile = content::Source<Profile>(source).ptr(); | 301 Profile* profile = content::Source<Profile>(source).ptr(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 ++it) { | 335 ++it) { |
339 it->second->applications_->RemoveObserver(this); | 336 it->second->applications_->RemoveObserver(this); |
340 } | 337 } |
341 break; | 338 break; |
342 default: | 339 default: |
343 NOTREACHED(); | 340 NOTREACHED(); |
344 break; | 341 break; |
345 } | 342 } |
346 } | 343 } |
347 | 344 |
| 345 void BackgroundModeManager::OnBackgroundModeEnabledPrefChanged() { |
| 346 if (IsBackgroundModePrefEnabled()) |
| 347 EnableBackgroundMode(); |
| 348 else |
| 349 DisableBackgroundMode(); |
| 350 } |
| 351 |
348 /////////////////////////////////////////////////////////////////////////////// | 352 /////////////////////////////////////////////////////////////////////////////// |
349 // BackgroundModeManager, BackgroundApplicationListModel::Observer overrides | 353 // BackgroundModeManager, BackgroundApplicationListModel::Observer overrides |
350 void BackgroundModeManager::OnApplicationDataChanged( | 354 void BackgroundModeManager::OnApplicationDataChanged( |
351 const Extension* extension, Profile* profile) { | 355 const Extension* extension, Profile* profile) { |
352 UpdateStatusTrayIconContextMenu(); | 356 UpdateStatusTrayIconContextMenu(); |
353 } | 357 } |
354 | 358 |
355 void BackgroundModeManager::OnApplicationListChanged(Profile* profile) { | 359 void BackgroundModeManager::OnApplicationListChanged(Profile* profile) { |
356 if (!IsBackgroundModePrefEnabled()) | 360 if (!IsBackgroundModePrefEnabled()) |
357 return; | 361 return; |
358 | 362 |
359 // Figure out what just happened based on the count of background apps. | |
360 int count = GetBackgroundAppCount(); | |
361 | |
362 // Update the profile cache with the fact whether background apps are running | 363 // Update the profile cache with the fact whether background apps are running |
363 // for this profile. | 364 // for this profile. |
364 size_t profile_index = profile_cache_->GetIndexOfProfileWithPath( | 365 size_t profile_index = profile_cache_->GetIndexOfProfileWithPath( |
365 profile->GetPath()); | 366 profile->GetPath()); |
366 if (profile_index != std::string::npos) { | 367 if (profile_index != std::string::npos) { |
367 profile_cache_->SetBackgroundStatusOfProfileAtIndex( | 368 profile_cache_->SetBackgroundStatusOfProfileAtIndex( |
368 profile_index, GetBackgroundAppCountForProfile(profile) != 0); | 369 profile_index, GetBackgroundAppCountForProfile(profile) != 0); |
369 } | 370 } |
370 | 371 |
371 if (count == 0) { | 372 if (!ShouldBeInBackgroundMode()) { |
372 // We've uninstalled our last background app, make sure we exit background | 373 // We've uninstalled our last background app, make sure we exit background |
373 // mode and no longer launch on startup. | 374 // mode and no longer launch on startup. |
374 EnableLaunchOnStartup(false); | 375 EnableLaunchOnStartup(false); |
375 EndBackgroundMode(); | 376 EndBackgroundMode(); |
376 } else { | 377 } else { |
377 // We have at least one background app running - make sure we're in | 378 // We have at least one background app running - make sure we're in |
378 // background mode. | 379 // background mode. |
379 if (!in_background_mode_) { | 380 if (!in_background_mode_) { |
380 // We're entering background mode - make sure we have launch-on-startup | 381 // We're entering background mode - make sure we have launch-on-startup |
381 // enabled. | 382 // enabled. |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 keep_alive_for_startup_ = false; | 529 keep_alive_for_startup_ = false; |
529 // We call this via the message queue to make sure we don't try to end | 530 // We call this via the message queue to make sure we don't try to end |
530 // keep-alive (which can shutdown Chrome) before the message loop has | 531 // keep-alive (which can shutdown Chrome) before the message loop has |
531 // started. | 532 // started. |
532 MessageLoop::current()->PostTask( | 533 MessageLoop::current()->PostTask( |
533 FROM_HERE, base::Bind(&browser::EndKeepAlive)); | 534 FROM_HERE, base::Bind(&browser::EndKeepAlive)); |
534 } | 535 } |
535 } | 536 } |
536 | 537 |
537 void BackgroundModeManager::StartBackgroundMode() { | 538 void BackgroundModeManager::StartBackgroundMode() { |
| 539 DCHECK(ShouldBeInBackgroundMode()); |
538 // Don't bother putting ourselves in background mode if we're already there | 540 // Don't bother putting ourselves in background mode if we're already there |
539 // or if background mode is disabled. | 541 // or if background mode is disabled. |
540 if (in_background_mode_ || | 542 if (in_background_mode_) |
541 (!IsBackgroundModePrefEnabled() && !keep_alive_for_test_)) | |
542 return; | 543 return; |
543 | 544 |
544 // Mark ourselves as running in background mode. | 545 // Mark ourselves as running in background mode. |
545 in_background_mode_ = true; | 546 in_background_mode_ = true; |
546 | 547 |
547 // Put ourselves in KeepAlive mode and create a status tray icon. | 548 // Put ourselves in KeepAlive mode and create a status tray icon. |
548 browser::StartKeepAlive(); | 549 browser::StartKeepAlive(); |
549 | 550 |
550 // Display a status icon to exit Chrome. | 551 // Display a status icon to exit Chrome. |
551 InitStatusTrayIcon(); | 552 InitStatusTrayIcon(); |
552 | 553 |
553 content::NotificationService::current()->Notify( | 554 content::NotificationService::current()->Notify( |
554 chrome::NOTIFICATION_BACKGROUND_MODE_CHANGED, | 555 chrome::NOTIFICATION_BACKGROUND_MODE_CHANGED, |
555 content::Source<BackgroundModeManager>(this), | 556 content::Source<BackgroundModeManager>(this), |
556 content::Details<bool>(&in_background_mode_)); | 557 content::Details<bool>(&in_background_mode_)); |
557 } | 558 } |
558 | 559 |
559 void BackgroundModeManager::InitStatusTrayIcon() { | 560 void BackgroundModeManager::InitStatusTrayIcon() { |
560 // Only initialize status tray icons for those profiles which actually | 561 // Only initialize status tray icons for those profiles which actually |
561 // have a background app running. | 562 // have a background app running. |
562 if (keep_alive_for_test_ || GetBackgroundAppCount() > 0) { | 563 if (ShouldBeInBackgroundMode()) |
563 CreateStatusTrayIcon(); | 564 CreateStatusTrayIcon(); |
564 } | |
565 } | 565 } |
566 | 566 |
567 void BackgroundModeManager::EndBackgroundMode() { | 567 void BackgroundModeManager::EndBackgroundMode() { |
568 if (!in_background_mode_) | 568 if (!in_background_mode_) |
569 return; | 569 return; |
570 in_background_mode_ = false; | 570 in_background_mode_ = false; |
571 | 571 |
572 // End KeepAlive mode and blow away our status tray icon. | 572 // End KeepAlive mode and blow away our status tray icon. |
573 browser::EndKeepAlive(); | 573 browser::EndKeepAlive(); |
574 | 574 |
575 RemoveStatusTrayIcon(); | 575 RemoveStatusTrayIcon(); |
576 content::NotificationService::current()->Notify( | 576 content::NotificationService::current()->Notify( |
577 chrome::NOTIFICATION_BACKGROUND_MODE_CHANGED, | 577 chrome::NOTIFICATION_BACKGROUND_MODE_CHANGED, |
578 content::Source<BackgroundModeManager>(this), | 578 content::Source<BackgroundModeManager>(this), |
579 content::Details<bool>(&in_background_mode_)); | 579 content::Details<bool>(&in_background_mode_)); |
580 } | 580 } |
581 | 581 |
582 void BackgroundModeManager::EnableBackgroundMode() { | 582 void BackgroundModeManager::EnableBackgroundMode() { |
583 DCHECK(IsBackgroundModePrefEnabled()); | 583 DCHECK(IsBackgroundModePrefEnabled()); |
584 // If background mode should be enabled, but isn't, turn it on. | 584 // If background mode should be enabled, but isn't, turn it on. |
585 if (!in_background_mode_ && | 585 if (!in_background_mode_ && ShouldBeInBackgroundMode()) { |
586 (GetBackgroundAppCount() > 0 || keep_alive_for_test_)) { | |
587 StartBackgroundMode(); | 586 StartBackgroundMode(); |
588 EnableLaunchOnStartup(true); | 587 EnableLaunchOnStartup(true); |
589 } | 588 } |
590 } | 589 } |
591 | 590 |
592 void BackgroundModeManager::DisableBackgroundMode() { | 591 void BackgroundModeManager::DisableBackgroundMode() { |
593 DCHECK(!IsBackgroundModePrefEnabled()); | 592 DCHECK(!IsBackgroundModePrefEnabled()); |
594 // If background mode is currently enabled, turn it off. | 593 // If background mode is currently enabled, turn it off. |
595 if (in_background_mode_) { | 594 if (in_background_mode_) { |
596 EndBackgroundMode(); | 595 EndBackgroundMode(); |
(...skipping 13 matching lines...) Expand all Loading... |
610 DCHECK(count >= 0); | 609 DCHECK(count >= 0); |
611 return count; | 610 return count; |
612 } | 611 } |
613 | 612 |
614 int BackgroundModeManager::GetBackgroundAppCountForProfile( | 613 int BackgroundModeManager::GetBackgroundAppCountForProfile( |
615 Profile* const profile) const { | 614 Profile* const profile) const { |
616 BackgroundModeData* bmd = GetBackgroundModeData(profile); | 615 BackgroundModeData* bmd = GetBackgroundModeData(profile); |
617 return bmd->GetBackgroundAppCount(); | 616 return bmd->GetBackgroundAppCount(); |
618 } | 617 } |
619 | 618 |
| 619 bool BackgroundModeManager::ShouldBeInBackgroundMode() const { |
| 620 return IsBackgroundModePrefEnabled() && |
| 621 (GetBackgroundAppCount() > 0 || keep_alive_for_test_); |
| 622 } |
| 623 |
620 void BackgroundModeManager::OnBackgroundAppInstalled( | 624 void BackgroundModeManager::OnBackgroundAppInstalled( |
621 const Extension* extension) { | 625 const Extension* extension) { |
622 // Background mode is disabled - don't do anything. | 626 // Background mode is disabled - don't do anything. |
623 if (!IsBackgroundModePrefEnabled()) | 627 if (!IsBackgroundModePrefEnabled()) |
624 return; | 628 return; |
625 | 629 |
626 // Special behavior for the Mac: We enable "launch-on-startup" only on new app | 630 // Special behavior for the Mac: We enable "launch-on-startup" only on new app |
627 // installation rather than every time we go into background mode. This is | 631 // installation rather than every time we go into background mode. This is |
628 // because the Mac exposes "Open at Login" UI to the user and we don't want to | 632 // because the Mac exposes "Open at Login" UI to the user and we don't want to |
629 // clobber the user's selection on every browser launch. | 633 // clobber the user's selection on every browser launch. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 } | 772 } |
769 } | 773 } |
770 return profile_it; | 774 return profile_it; |
771 } | 775 } |
772 | 776 |
773 bool BackgroundModeManager::IsBackgroundModePrefEnabled() const { | 777 bool BackgroundModeManager::IsBackgroundModePrefEnabled() const { |
774 PrefService* service = g_browser_process->local_state(); | 778 PrefService* service = g_browser_process->local_state(); |
775 DCHECK(service); | 779 DCHECK(service); |
776 return service->GetBoolean(prefs::kBackgroundModeEnabled); | 780 return service->GetBoolean(prefs::kBackgroundModeEnabled); |
777 } | 781 } |
OLD | NEW |