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

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

Issue 5368002: Move Mac LaunchOnStartup enable/disable to File thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed previous attempt to resolve merge conflict Created 10 years 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) 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 "app/l10n_util.h" 5 #include "app/l10n_util.h"
6 #include "app/resource_bundle.h" 6 #include "app/resource_bundle.h"
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/file_path.h"
10 #include "base/logging.h" 9 #include "base/logging.h"
11 #include "base/path_service.h"
12 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
13 #include "chrome/app/chrome_command_ids.h" 11 #include "chrome/app/chrome_command_ids.h"
14 #include "chrome/browser/background_application_list_model.h" 12 #include "chrome/browser/background_application_list_model.h"
15 #include "chrome/browser/background_mode_manager.h" 13 #include "chrome/browser/background_mode_manager.h"
16 #include "chrome/browser/browser_list.h" 14 #include "chrome/browser/browser_list.h"
17 #include "chrome/browser/extensions/extensions_service.h" 15 #include "chrome/browser/extensions/extensions_service.h"
18 #include "chrome/browser/metrics/user_metrics.h" 16 #include "chrome/browser/metrics/user_metrics.h"
19 #include "chrome/browser/prefs/pref_service.h" 17 #include "chrome/browser/prefs/pref_service.h"
20 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/shell_integration.h"
22 #include "chrome/browser/status_icons/status_icon.h" 19 #include "chrome/browser/status_icons/status_icon.h"
23 #include "chrome/browser/status_icons/status_tray.h" 20 #include "chrome/browser/status_icons/status_tray.h"
24 #include "chrome/common/chrome_switches.h" 21 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/extensions/extension.h" 22 #include "chrome/common/extensions/extension.h"
26 #include "chrome/common/notification_service.h" 23 #include "chrome/common/notification_service.h"
27 #include "chrome/common/notification_type.h" 24 #include "chrome/common/notification_type.h"
28 #include "chrome/common/pref_names.h" 25 #include "chrome/common/pref_names.h"
29 #include "grit/browser_resources.h"
30 #include "grit/chromium_strings.h" 26 #include "grit/chromium_strings.h"
31 #include "grit/generated_resources.h" 27 #include "grit/generated_resources.h"
32 #include "grit/theme_resources.h" 28 #include "grit/theme_resources.h"
33 29
34 #if defined(OS_LINUX)
35 #include <unistd.h>
36 #include "base/environment.h"
37 #include "base/file_util.h"
38 #include "base/nix/xdg_util.h"
39 #include "base/task.h"
40 #include "base/utf_string_conversions.h"
41 #include "chrome/common/chrome_version_info.h"
42 #endif
43
44 #if defined(OS_MACOSX)
45 #include "base/mac_util.h"
46 #endif
47
48 #if defined(TOOLKIT_GTK)
49 #include "chrome/browser/gtk/gtk_util.h"
50 #endif
51
52 #if defined(OS_LINUX)
53 static const FilePath::CharType kAutostart[] = "autostart";
54 static const FilePath::CharType kConfig[] = ".config";
55 static const char kXdgConfigHome[] = "XDG_CONFIG_HOME";
56 #endif
57
58 #if defined(OS_WIN)
59 #include "base/win/registry.h"
60 const HKEY kBackgroundModeRegistryRootKey = HKEY_CURRENT_USER;
61 const wchar_t* kBackgroundModeRegistrySubkey =
62 L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
63 const wchar_t* kBackgroundModeRegistryKeyName = L"chromium";
64 #endif
65
66 #if defined(OS_LINUX)
67 namespace {
68
69 FilePath GetAutostartDirectory(base::Environment* environment) {
70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
71 FilePath result =
72 base::nix::GetXDGDirectory(environment, kXdgConfigHome, kConfig);
73 result = result.Append(kAutostart);
74 return result;
75 }
76
77 FilePath GetAutostartFilename(base::Environment* environment) {
78 FilePath directory = GetAutostartDirectory(environment);
79 return directory.Append(ShellIntegration::GetDesktopName(environment));
80 }
81
82 } // namespace
83 #endif // defined(OS_LINUX)
84
85 #if defined(OS_WIN) || defined(OS_LINUX)
86 class DisableLaunchOnStartupTask : public Task {
87 public:
88 virtual void Run() {
89 #if defined(OS_LINUX)
90 scoped_ptr<base::Environment> environment(base::Environment::Create());
91 if (!file_util::Delete(GetAutostartFilename(environment.get()), false)) {
92 LOG(WARNING) << "Failed to deregister launch on login.";
93 }
94 #elif defined(OS_WIN)
95 const wchar_t* key_name = kBackgroundModeRegistryKeyName;
96 base::win::RegKey read_key(kBackgroundModeRegistryRootKey,
97 kBackgroundModeRegistrySubkey, KEY_READ);
98 base::win::RegKey write_key(kBackgroundModeRegistryRootKey,
99 kBackgroundModeRegistrySubkey, KEY_WRITE);
100 if (read_key.ValueExists(key_name) && !write_key.DeleteValue(key_name))
101 LOG(WARNING) << "Failed to deregister launch on login.";
102 #endif
103 }
104 };
105 #endif // defined(OS_WIN) || defined(OS_LINUX)
106
107 // TODO(rickcam): Bug 56280: Share implementation with ShellIntegration
108 #if defined(OS_WIN) || defined(OS_LINUX)
109 class EnableLaunchOnStartupTask : public Task {
110 public:
111 virtual void Run() {
112 #if defined(OS_LINUX)
113 scoped_ptr<base::Environment> environment(base::Environment::Create());
114 scoped_ptr<chrome::VersionInfo> version_info(new chrome::VersionInfo());
115 FilePath autostart_directory = GetAutostartDirectory(environment.get());
116 FilePath autostart_file = GetAutostartFilename(environment.get());
117 if (!file_util::DirectoryExists(autostart_directory) &&
118 !file_util::CreateDirectory(autostart_directory)) {
119 LOG(WARNING)
120 << "Failed to register launch on login. No autostart directory.";
121 return;
122 }
123 std::string wrapper_script;
124 if (!environment->GetVar("CHROME_WRAPPER", &wrapper_script)) {
125 LOG(WARNING)
126 << "Failed to register launch on login. CHROME_WRAPPER not set.";
127 return;
128 }
129 std::string autostart_file_contents =
130 "[Desktop Entry]\n"
131 "Type=Application\n"
132 "Terminal=false\n"
133 "Exec=" + wrapper_script +
134 " --enable-background-mode --no-startup-window\n"
135 "Name=" + version_info->Name() + "\n";
136 std::string::size_type content_length = autostart_file_contents.length();
137 if (file_util::WriteFile(autostart_file, autostart_file_contents.c_str(),
138 content_length) !=
139 static_cast<int>(content_length)) {
140 LOG(WARNING) << "Failed to register launch on login. Failed to write "
141 << autostart_file.value();
142 file_util::Delete(GetAutostartFilename(environment.get()), false);
143 }
144 #elif defined(OS_WIN)
145 // TODO(rickcam): Bug 53597: Make RegKey mockable.
146 // TODO(rickcam): Bug 53600: Use distinct registry keys per flavor+profile.
147 const wchar_t* key_name = kBackgroundModeRegistryKeyName;
148 base::win::RegKey read_key(kBackgroundModeRegistryRootKey,
149 kBackgroundModeRegistrySubkey, KEY_READ);
150 base::win::RegKey write_key(kBackgroundModeRegistryRootKey,
151 kBackgroundModeRegistrySubkey, KEY_WRITE);
152 FilePath executable;
153 if (!PathService::Get(base::FILE_EXE, &executable))
154 return;
155 std::wstring new_value = executable.value() + L" --no-startup-window";
156 if (read_key.ValueExists(key_name)) {
157 std::wstring current_value;
158 if (read_key.ReadValue(key_name, &current_value) &&
159 (current_value == new_value)) {
160 return;
161 }
162 }
163 if (!write_key.WriteValue(key_name, new_value.c_str()))
164 LOG(WARNING) << "Failed to register launch on login.";
165 #endif
166 }
167 };
168 #endif // defined(OS_WIN) || defined(OS_LINUX)
169
170 void BackgroundModeManager::OnApplicationDataChanged( 30 void BackgroundModeManager::OnApplicationDataChanged(
171 const Extension* extension) { 31 const Extension* extension) {
172 UpdateContextMenuEntryIcon(extension); 32 UpdateContextMenuEntryIcon(extension);
173 } 33 }
174 34
175 void BackgroundModeManager::OnApplicationListChanged() { 35 void BackgroundModeManager::OnApplicationListChanged() {
176 UpdateStatusTrayIconContextMenu(); 36 UpdateStatusTrayIconContextMenu();
177 } 37 }
178 38
179 BackgroundModeManager::BackgroundModeManager(Profile* profile, 39 BackgroundModeManager::BackgroundModeManager(Profile* profile,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 BackgroundModeManager::~BackgroundModeManager() { 98 BackgroundModeManager::~BackgroundModeManager() {
239 applications_.RemoveObserver(this); 99 applications_.RemoveObserver(this);
240 100
241 // We're going away, so exit background mode (does nothing if we aren't in 101 // We're going away, so exit background mode (does nothing if we aren't in
242 // background mode currently). This is primarily needed for unit tests, 102 // background mode currently). This is primarily needed for unit tests,
243 // because in an actual running system we'd get an APP_TERMINATING 103 // because in an actual running system we'd get an APP_TERMINATING
244 // notification before being destroyed. 104 // notification before being destroyed.
245 EndBackgroundMode(); 105 EndBackgroundMode();
246 } 106 }
247 107
248 bool BackgroundModeManager::IsLaunchOnStartupResetAllowed() {
249 return profile_->GetPrefs()->GetBoolean(prefs::kLaunchOnStartupResetAllowed);
250 }
251
252 void BackgroundModeManager::SetLaunchOnStartupResetAllowed(bool allowed) {
253 profile_->GetPrefs()->SetBoolean(prefs::kLaunchOnStartupResetAllowed,
254 allowed);
255 }
256
257 void BackgroundModeManager::Observe(NotificationType type, 108 void BackgroundModeManager::Observe(NotificationType type,
258 const NotificationSource& source, 109 const NotificationSource& source,
259 const NotificationDetails& details) { 110 const NotificationDetails& details) {
260 switch (type.value) { 111 switch (type.value) {
261 case NotificationType::EXTENSIONS_READY: 112 case NotificationType::EXTENSIONS_READY:
262 // Extensions are loaded, so we don't need to manually keep the browser 113 // Extensions are loaded, so we don't need to manually keep the browser
263 // process alive any more when running in no-startup-window mode. 114 // process alive any more when running in no-startup-window mode.
264 EndKeepAliveForStartup(); 115 EndKeepAliveForStartup();
265 116
266 // On a Mac, we use 'login items' mechanism which has user-facing UI so we 117 // On a Mac, we use 'login items' mechanism which has user-facing UI so we
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 EnableLaunchOnStartup(true); 224 EnableLaunchOnStartup(true);
374 } 225 }
375 226
376 void BackgroundModeManager::OnBackgroundAppUninstalled() { 227 void BackgroundModeManager::OnBackgroundAppUninstalled() {
377 // When uninstalling a background app, disable launch on startup if 228 // When uninstalling a background app, disable launch on startup if
378 // we have no more background apps. 229 // we have no more background apps.
379 if (background_app_count_ == 0) 230 if (background_app_count_ == 0)
380 EnableLaunchOnStartup(false); 231 EnableLaunchOnStartup(false);
381 } 232 }
382 233
383 void BackgroundModeManager::EnableLaunchOnStartup(bool should_launch) {
384 // This functionality is only defined for default profile, currently.
385 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserDataDir))
386 return;
387 #if defined(OS_WIN) || defined(OS_LINUX)
388 if (should_launch) {
389 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
390 new EnableLaunchOnStartupTask());
391 } else {
392 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
393 new DisableLaunchOnStartupTask());
394 }
395 #elif defined(OS_MACOSX)
396 if (should_launch) {
397 // Return if Chrome is already a Login Item (avoid overriding user choice).
398 if (mac_util::CheckLoginItemStatus(NULL))
399 return;
400
401 mac_util::AddToLoginItems(true); // Hide on startup.
402
403 // Remember we set Login Item, not the user - so we can reset it later.
404 SetLaunchOnStartupResetAllowed(true);
405 } else {
406 // If we didn't set Login Item, don't mess with it.
407 if (!IsLaunchOnStartupResetAllowed())
408 return;
409 SetLaunchOnStartupResetAllowed(false);
410
411 // Check if Chrome is not a login Item, or is a Login Item but w/o 'hidden'
412 // flag - most likely user has modified the setting, don't override it.
413 bool is_hidden = false;
414 if (!mac_util::CheckLoginItemStatus(&is_hidden) || !is_hidden)
415 return;
416
417 mac_util::RemoveFromLoginItems();
418 }
419 #endif
420 }
421
422 void BackgroundModeManager::CreateStatusTrayIcon() { 234 void BackgroundModeManager::CreateStatusTrayIcon() {
423 // Only need status icons on windows/linux. ChromeOS doesn't allow exiting 235 // Only need status icons on windows/linux. ChromeOS doesn't allow exiting
424 // Chrome and Mac can use the dock icon instead. 236 // Chrome and Mac can use the dock icon instead.
425 #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) 237 #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS)
426 if (!status_tray_) 238 if (!status_tray_)
427 status_tray_ = profile_->GetStatusTray(); 239 status_tray_ = profile_->GetStatusTray();
428 #endif 240 #endif
429 241
430 // If the platform doesn't support status icons, or we've already created 242 // If the platform doesn't support status icons, or we've already created
431 // our status icon, just return. 243 // our status icon, just return.
(...skipping 23 matching lines...) Expand all
455 267
456 void BackgroundModeManager::UpdateStatusTrayIconContextMenu() { 268 void BackgroundModeManager::UpdateStatusTrayIconContextMenu() {
457 if (!status_icon_) 269 if (!status_icon_)
458 return; 270 return;
459 271
460 // Create a context menu item for Chrome. 272 // Create a context menu item for Chrome.
461 menus::SimpleMenuModel* menu = new menus::SimpleMenuModel(this); 273 menus::SimpleMenuModel* menu = new menus::SimpleMenuModel(this);
462 // Add About item 274 // Add About item
463 menu->AddItem(IDC_ABOUT, l10n_util::GetStringFUTF16(IDS_ABOUT, 275 menu->AddItem(IDC_ABOUT, l10n_util::GetStringFUTF16(IDS_ABOUT,
464 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); 276 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
465 277 menu->AddItem(IDC_OPTIONS, GetPreferencesMenuLabel());
466 // Add Preferences item
467 #if defined(OS_CHROMEOS)
468 menu->AddItemWithStringId(IDC_OPTIONS, IDS_SETTINGS);
469 #elif defined(TOOLKIT_GTK)
470 string16 preferences = gtk_util::GetStockPreferencesMenuLabel();
471 if (!preferences.empty())
472 menu->AddItem(IDC_OPTIONS, preferences);
473 else
474 menu->AddItemWithStringId(IDC_OPTIONS, IDS_PREFERENCES);
475 #else
476 menu->AddItemWithStringId(IDC_OPTIONS, IDS_OPTIONS);
477 #endif
478 menu->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); 278 menu->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
479 menu->AddSeparator(); 279 menu->AddSeparator();
480 int application_position = 0; 280 int application_position = 0;
481 context_menu_application_offset_ = menu->GetItemCount(); 281 context_menu_application_offset_ = menu->GetItemCount();
482 for (ExtensionList::const_iterator cursor = applications_.begin(); 282 for (ExtensionList::const_iterator cursor = applications_.begin();
483 cursor != applications_.end(); 283 cursor != applications_.end();
484 ++cursor, ++application_position) { 284 ++cursor, ++application_position) {
485 const SkBitmap* icon = applications_.GetIcon(*cursor); 285 const SkBitmap* icon = applications_.GetIcon(*cursor);
486 int sort_position = applications_.GetPosition(*cursor); 286 int sort_position = applications_.GetPosition(*cursor);
487 DCHECK(sort_position == application_position); 287 DCHECK(sort_position == application_position);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 Browser* BackgroundModeManager::GetBrowserWindow() { 353 Browser* BackgroundModeManager::GetBrowserWindow() {
554 Browser* browser = BrowserList::GetLastActive(); 354 Browser* browser = BrowserList::GetLastActive();
555 if (!browser) { 355 if (!browser) {
556 Browser::OpenEmptyWindow(profile_); 356 Browser::OpenEmptyWindow(profile_);
557 browser = BrowserList::GetLastActive(); 357 browser = BrowserList::GetLastActive();
558 } 358 }
559 return browser; 359 return browser;
560 } 360 }
561 361
562 // static 362 // static
563 void BackgroundModeManager::RegisterUserPrefs(PrefService* prefs) {
564 prefs->RegisterBooleanPref(prefs::kLaunchOnStartupResetAllowed, false);
565 }
566
567 // static
568 bool BackgroundModeManager::IsBackgroundModeEnabled( 363 bool BackgroundModeManager::IsBackgroundModeEnabled(
569 const CommandLine* command_line) { 364 const CommandLine* command_line) {
570 365
571 // Background mode is disabled if the appropriate flag is passed, or if 366 // Background mode is disabled if the appropriate flag is passed, or if
572 // extensions are disabled. 367 // extensions are disabled.
573 bool background_mode_enabled = 368 bool background_mode_enabled =
574 !command_line->HasSwitch(switches::kDisableBackgroundMode) && 369 !command_line->HasSwitch(switches::kDisableBackgroundMode) &&
575 !command_line->HasSwitch(switches::kDisableExtensions); 370 !command_line->HasSwitch(switches::kDisableExtensions);
576 #if !defined(OS_WIN) 371 #if !defined(OS_WIN)
577 // BackgroundMode is enabled by default on windows. On other platforms, it 372 // BackgroundMode is enabled by default on windows. On other platforms, it
578 // is enabled via about:flags. 373 // is enabled via about:flags.
579 background_mode_enabled = background_mode_enabled && 374 background_mode_enabled = background_mode_enabled &&
580 command_line->HasSwitch(switches::kEnableBackgroundMode); 375 command_line->HasSwitch(switches::kEnableBackgroundMode);
581 #endif 376 #endif
582 377
583 return background_mode_enabled; 378 return background_mode_enabled;
584 } 379 }
585 380
OLDNEW
« no previous file with comments | « chrome/browser/background_mode_manager.h ('k') | chrome/browser/background_mode_manager_chromeos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698