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

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

Powered by Google App Engine
This is Rietveld 408576698