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

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

Issue 6954001: Add "Keep chrome running in background" preference. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed formatting nits Created 9 years, 7 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 <string> 5 #include <string>
6 6
7 #include "base/base_paths.h" 7 #include "base/base_paths.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
11 #include "chrome/app/chrome_command_ids.h" 11 #include "chrome/app/chrome_command_ids.h"
12 #include "chrome/browser/background_application_list_model.h" 12 #include "chrome/browser/background_application_list_model.h"
13 #include "chrome/browser/background_mode_manager.h" 13 #include "chrome/browser/background_mode_manager.h"
14 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/extensions/extension_service.h" 15 #include "chrome/browser/extensions/extension_service.h"
16 #include "chrome/browser/platform_util.h"
15 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/status_icons/status_icon.h" 18 #include "chrome/browser/status_icons/status_icon.h"
17 #include "chrome/browser/status_icons/status_tray.h" 19 #include "chrome/browser/status_icons/status_tray.h"
18 #include "chrome/browser/ui/browser_list.h" 20 #include "chrome/browser/ui/browser_list.h"
19 #include "chrome/common/chrome_switches.h" 21 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/extensions/extension.h" 22 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/pref_names.h" 23 #include "chrome/common/pref_names.h"
22 #include "content/browser/user_metrics.h" 24 #include "content/browser/user_metrics.h"
23 #include "content/common/notification_service.h" 25 #include "content/common/notification_service.h"
24 #include "content/common/notification_type.h" 26 #include "content/common/notification_type.h"
(...skipping 16 matching lines...) Expand all
41 CommandLine* command_line) 43 CommandLine* command_line)
42 : profile_(profile), 44 : profile_(profile),
43 applications_(profile), 45 applications_(profile),
44 background_app_count_(0), 46 background_app_count_(0),
45 context_menu_(NULL), 47 context_menu_(NULL),
46 context_menu_application_offset_(0), 48 context_menu_application_offset_(0),
47 in_background_mode_(false), 49 in_background_mode_(false),
48 keep_alive_for_startup_(false), 50 keep_alive_for_startup_(false),
49 status_tray_(NULL), 51 status_tray_(NULL),
50 status_icon_(NULL) { 52 status_icon_(NULL) {
51 // If background mode is disabled, just exit - don't listen for any 53 // If background mode is currently disabled, just exit - don't listen for any
52 // notifications. 54 // notifications.
53 if (!IsBackgroundModeEnabled(command_line)) 55 if (IsBackgroundModePermanentlyDisabled(command_line))
54 return; 56 return;
55 57
58 // Listen for the background mode preference changing.
59 pref_registrar_.Init(g_browser_process->local_state());
60 pref_registrar_.Add(prefs::kBackgroundModeEnabled, this);
61
56 // Keep the browser alive until extensions are done loading - this is needed 62 // Keep the browser alive until extensions are done loading - this is needed
57 // by the --no-startup-window flag. We want to stay alive until we load 63 // by the --no-startup-window flag. We want to stay alive until we load
58 // extensions, at which point we should either run in background mode (if 64 // extensions, at which point we should either run in background mode (if
59 // there are background apps) or exit if there are none. 65 // there are background apps) or exit if there are none.
60 if (command_line->HasSwitch(switches::kNoStartupWindow)) { 66 if (command_line->HasSwitch(switches::kNoStartupWindow)) {
61 keep_alive_for_startup_ = true; 67 keep_alive_for_startup_ = true;
62 BrowserList::StartKeepAlive(); 68 BrowserList::StartKeepAlive();
63 } 69 }
64 70
65 // If the -keep-alive-for-test flag is passed, then always keep chrome running 71 // If the -keep-alive-for-test flag is passed, then always keep chrome running
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 // background mode currently). This is primarily needed for unit tests, 103 // background mode currently). This is primarily needed for unit tests,
98 // because in an actual running system we'd get an APP_TERMINATING 104 // because in an actual running system we'd get an APP_TERMINATING
99 // notification before being destroyed. 105 // notification before being destroyed.
100 EndBackgroundMode(); 106 EndBackgroundMode();
101 } 107 }
102 108
103 void BackgroundModeManager::Observe(NotificationType type, 109 void BackgroundModeManager::Observe(NotificationType type,
104 const NotificationSource& source, 110 const NotificationSource& source,
105 const NotificationDetails& details) { 111 const NotificationDetails& details) {
106 switch (type.value) { 112 switch (type.value) {
113 case NotificationType::PREF_CHANGED:
114 DCHECK(*Details<std::string>(details).ptr() ==
115 prefs::kBackgroundModeEnabled);
116 if (IsBackgroundModePrefEnabled())
117 EnableBackgroundMode();
118 else
119 DisableBackgroundMode();
120 break;
107 case NotificationType::EXTENSIONS_READY: 121 case NotificationType::EXTENSIONS_READY:
108 // Extensions are loaded, so we don't need to manually keep the browser 122 // Extensions are loaded, so we don't need to manually keep the browser
109 // process alive any more when running in no-startup-window mode. 123 // process alive any more when running in no-startup-window mode.
110 EndKeepAliveForStartup(); 124 EndKeepAliveForStartup();
111 125
112 // On a Mac, we use 'login items' mechanism which has user-facing UI so we 126 // On a Mac, we use 'login items' mechanism which has user-facing UI so we
113 // don't want to stomp on user choice every time we start and load 127 // don't want to stomp on user choice every time we start and load
114 // registered extensions. This means that if a background app is removed 128 // registered extensions. This means that if a background app is removed
115 // or added while Chrome is not running, we could leave Chrome in the 129 // or added while Chrome is not running, we could leave Chrome in the
116 // wrong state, but this is better than constantly forcing Chrome to 130 // wrong state, but this is better than constantly forcing Chrome to
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 189
176 void BackgroundModeManager::OnBackgroundAppLoaded() { 190 void BackgroundModeManager::OnBackgroundAppLoaded() {
177 // When a background app loads, increment our count and also enable 191 // When a background app loads, increment our count and also enable
178 // KeepAlive mode if the preference is set. 192 // KeepAlive mode if the preference is set.
179 background_app_count_++; 193 background_app_count_++;
180 if (background_app_count_ == 1) 194 if (background_app_count_ == 1)
181 StartBackgroundMode(); 195 StartBackgroundMode();
182 } 196 }
183 197
184 void BackgroundModeManager::StartBackgroundMode() { 198 void BackgroundModeManager::StartBackgroundMode() {
185 // Don't bother putting ourselves in background mode if we're already there. 199 // Don't bother putting ourselves in background mode if we're already there
186 if (in_background_mode_) 200 // or if background mode is disabled.
201 if (in_background_mode_ || !IsBackgroundModePrefEnabled())
187 return; 202 return;
188 203
189 // Mark ourselves as running in background mode. 204 // Mark ourselves as running in background mode.
190 in_background_mode_ = true; 205 in_background_mode_ = true;
191 206
192 // Put ourselves in KeepAlive mode and create a status tray icon. 207 // Put ourselves in KeepAlive mode and create a status tray icon.
193 BrowserList::StartKeepAlive(); 208 BrowserList::StartKeepAlive();
194 209
195 // Display a status icon to exit Chrome. 210 // Display a status icon to exit Chrome.
196 CreateStatusTrayIcon(); 211 CreateStatusTrayIcon();
(...skipping 11 matching lines...) Expand all
208 void BackgroundModeManager::EndBackgroundMode() { 223 void BackgroundModeManager::EndBackgroundMode() {
209 if (!in_background_mode_) 224 if (!in_background_mode_)
210 return; 225 return;
211 in_background_mode_ = false; 226 in_background_mode_ = false;
212 227
213 // End KeepAlive mode and blow away our status tray icon. 228 // End KeepAlive mode and blow away our status tray icon.
214 BrowserList::EndKeepAlive(); 229 BrowserList::EndKeepAlive();
215 RemoveStatusTrayIcon(); 230 RemoveStatusTrayIcon();
216 } 231 }
217 232
233 void BackgroundModeManager::EnableBackgroundMode() {
234 // If background mode should be enabled, but isn't, turn it on.
235 if (background_app_count_ > 0 && !in_background_mode_) {
236 StartBackgroundMode();
237 EnableLaunchOnStartup(true);
238 }
239 }
240
241 void BackgroundModeManager::DisableBackgroundMode() {
242 // If background mode is currently enabled, turn it off.
243 if (in_background_mode_) {
244 EndBackgroundMode();
245 EnableLaunchOnStartup(false);
246 }
247 }
248
218 void BackgroundModeManager::OnBackgroundAppInstalled( 249 void BackgroundModeManager::OnBackgroundAppInstalled(
219 const Extension* extension) { 250 const Extension* extension) {
251 // Background mode is disabled - don't do anything.
252 if (!IsBackgroundModePrefEnabled())
253 return;
254
220 // We're installing a background app. If this is the first background app 255 // We're installing a background app. If this is the first background app
221 // being installed, make sure we are set to launch on startup. 256 // being installed, make sure we are set to launch on startup.
222 if (background_app_count_ == 0) 257 if (background_app_count_ == 0)
223 EnableLaunchOnStartup(true); 258 EnableLaunchOnStartup(true);
224 259
225 // Notify the user that a background app has been installed. 260 // Notify the user that a background app has been installed.
226 if (extension) // NULL when called by unit tests. 261 if (extension) // NULL when called by unit tests.
227 DisplayAppInstalledNotification(extension); 262 DisplayAppInstalledNotification(extension);
228 } 263 }
229 264
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 ++cursor, ++position) { 322 ++cursor, ++position) {
288 const SkBitmap* icon = applications_.GetIcon(*cursor); 323 const SkBitmap* icon = applications_.GetIcon(*cursor);
289 DCHECK(position == applications_.GetPosition(*cursor)); 324 DCHECK(position == applications_.GetPosition(*cursor));
290 const std::string& name = (*cursor)->name(); 325 const std::string& name = (*cursor)->name();
291 menu->AddItem(position, UTF8ToUTF16(name)); 326 menu->AddItem(position, UTF8ToUTF16(name));
292 if (icon) 327 if (icon)
293 menu->SetIcon(menu->GetItemCount() - 1, *icon); 328 menu->SetIcon(menu->GetItemCount() - 1, *icon);
294 } 329 }
295 if (applications_.size() > 0) 330 if (applications_.size() > 0)
296 menu->AddSeparator(); 331 menu->AddSeparator();
332 menu->AddCheckItem(IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND,
333 l10n_util::GetStringFUTF16(
334 IDS_KEEP_CHROME_RUNNING_IN_BACKGROUND,
335 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
297 menu->AddItemWithStringId(IDC_EXIT, IDS_EXIT); 336 menu->AddItemWithStringId(IDC_EXIT, IDS_EXIT);
298 context_menu_ = menu; 337 context_menu_ = menu;
299 status_icon_->SetContextMenu(menu); 338 status_icon_->SetContextMenu(menu);
300 } 339 }
301 340
302 bool BackgroundModeManager::IsCommandIdChecked(int command_id) const { 341 bool BackgroundModeManager::IsCommandIdChecked(int command_id) const {
303 return false; 342 DCHECK(command_id == IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND);
343 return true;
304 } 344 }
305 345
306 bool BackgroundModeManager::IsCommandIdEnabled(int command_id) const { 346 bool BackgroundModeManager::IsCommandIdEnabled(int command_id) const {
307 // For now, we do not support disabled items. 347 // For now, we do not support disabled items.
308 return true; 348 return true;
309 } 349 }
310 350
311 bool BackgroundModeManager::GetAcceleratorForCommandId( 351 bool BackgroundModeManager::GetAcceleratorForCommandId(
312 int command_id, 352 int command_id,
313 ui::Accelerator* accelerator) { 353 ui::Accelerator* accelerator) {
(...skipping 27 matching lines...) Expand all
341 case IDC_EXIT: 381 case IDC_EXIT:
342 UserMetrics::RecordAction(UserMetricsAction("Exit")); 382 UserMetrics::RecordAction(UserMetricsAction("Exit"));
343 BrowserList::CloseAllBrowsersAndExit(); 383 BrowserList::CloseAllBrowsersAndExit();
344 break; 384 break;
345 case IDC_OPTIONS: 385 case IDC_OPTIONS:
346 GetBrowserWindow()->OpenOptionsDialog(); 386 GetBrowserWindow()->OpenOptionsDialog();
347 break; 387 break;
348 case IDC_TASK_MANAGER: 388 case IDC_TASK_MANAGER:
349 GetBrowserWindow()->OpenTaskManager(true); 389 GetBrowserWindow()->OpenTaskManager(true);
350 break; 390 break;
391 case IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND: {
392 // Background mode must already be enabled (as otherwise this menu would
393 // not be visible).
394 DCHECK(IsBackgroundModePrefEnabled());
395 DCHECK(BrowserList::WillKeepAlive());
396 if (BrowserList::size() == 0) {
397 // There are no windows open - unchecking this will exit Chrome. Warn
398 // the user.
399 if (!platform_util::SimpleYesNoBox(
400 NULL,
401 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
402 l10n_util::GetStringFUTF16(
403 IDS_CONFIRM_EXIT_BACKGROUND_MODE_BODY,
404 GetPreferencesMenuLabel()))) {
405 return;
406 }
407 }
408
409 // Set the background mode pref to "disabled" - the resulting notification
410 // will result in a call to DisableBackgroundMode().
411 PrefService* service = g_browser_process->local_state();
412 DCHECK(service);
413 service->SetBoolean(prefs::kBackgroundModeEnabled, false);
414 break;
415 }
351 default: 416 default:
352 ExecuteApplication(item); 417 ExecuteApplication(item);
353 break; 418 break;
354 } 419 }
355 } 420 }
356 421
357 Browser* BackgroundModeManager::GetBrowserWindow() { 422 Browser* BackgroundModeManager::GetBrowserWindow() {
358 Browser* browser = BrowserList::GetLastActive(); 423 Browser* browser = BrowserList::GetLastActive();
359 if (!browser) { 424 if (!browser) {
360 Browser::OpenEmptyWindow(profile_); 425 Browser::OpenEmptyWindow(profile_);
361 browser = BrowserList::GetLastActive(); 426 browser = BrowserList::GetLastActive();
362 } 427 }
363 return browser; 428 return browser;
364 } 429 }
365 430
366 // static 431 // static
367 bool BackgroundModeManager::IsBackgroundModeEnabled( 432 bool BackgroundModeManager::IsBackgroundModePermanentlyDisabled(
368 const CommandLine* command_line) { 433 const CommandLine* command_line) {
369 434
370 // Background mode is disabled if the appropriate flag is passed, or if 435 // Background mode is disabled if the appropriate flag is passed, or if
371 // extensions are disabled. It's always disabled on chromeos since chrome 436 // extensions are disabled, or if the associated preference is unset. It's
372 // is always running on that platform, making it superfluous. 437 // always disabled on chromeos since chrome is always running on that
438 // platform, making it superfluous.
373 #if defined(OS_CHROMEOS) 439 #if defined(OS_CHROMEOS)
374 return false; 440 return true;
375 #else 441 #else
376 bool background_mode_enabled = 442 bool background_mode_disabled =
377 !command_line->HasSwitch(switches::kDisableBackgroundMode) && 443 command_line->HasSwitch(switches::kDisableBackgroundMode) ||
378 !command_line->HasSwitch(switches::kDisableExtensions); 444 command_line->HasSwitch(switches::kDisableExtensions);
379 return background_mode_enabled; 445 return background_mode_disabled;
380 #endif 446 #endif
381 } 447 }
382 448
449 bool BackgroundModeManager::IsBackgroundModePrefEnabled() {
450 PrefService* service = g_browser_process->local_state();
451 DCHECK(service);
452 return service->GetBoolean(prefs::kBackgroundModeEnabled);
453 }
454
383 // static 455 // static
384 void BackgroundModeManager::RegisterPrefs(PrefService* prefs) { 456 void BackgroundModeManager::RegisterPrefs(PrefService* prefs) {
385 prefs->RegisterBooleanPref(prefs::kUserCreatedLoginItem, false); 457 prefs->RegisterBooleanPref(prefs::kUserCreatedLoginItem, false);
458 prefs->RegisterBooleanPref(prefs::kBackgroundModeEnabled, true);
386 } 459 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698