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

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: Eliminating excess header includes: Windows 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/profile.h" 18 #include "chrome/browser/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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 // When uninstalling a background app, disable launch on startup if 237 // When uninstalling a background app, disable launch on startup if
378 // we have no more background apps. 238 // we have no more background apps.
379 if (background_app_count_ == 0) 239 if (background_app_count_ == 0)
380 EnableLaunchOnStartup(false); 240 EnableLaunchOnStartup(false);
381 } 241 }
382 242
383 void BackgroundModeManager::EnableLaunchOnStartup(bool should_launch) { 243 void BackgroundModeManager::EnableLaunchOnStartup(bool should_launch) {
384 // This functionality is only defined for default profile, currently. 244 // This functionality is only defined for default profile, currently.
385 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserDataDir)) 245 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserDataDir))
386 return; 246 return;
387 #if defined(OS_WIN) || defined(OS_LINUX)
388 if (should_launch) { 247 if (should_launch) {
389 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 248 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
390 new EnableLaunchOnStartupTask()); 249 new EnableLaunchOnStartupTask(this));
Andrew T Wilson (Slow) 2010/12/03 02:06:59 See my comment about moving this entire statement
The wrong rickcam account 2010/12/04 02:08:04 Done.
391 } else { 250 } else {
392 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 251 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
393 new DisableLaunchOnStartupTask()); 252 new DisableLaunchOnStartupTask(this));
394 } 253 }
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 } 254 }
421 255
422 void BackgroundModeManager::CreateStatusTrayIcon() { 256 void BackgroundModeManager::CreateStatusTrayIcon() {
423 // Only need status icons on windows/linux. ChromeOS doesn't allow exiting 257 // Only need status icons on windows/linux. ChromeOS doesn't allow exiting
424 // Chrome and Mac can use the dock icon instead. 258 // Chrome and Mac can use the dock icon instead.
425 #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) 259 #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS)
426 if (!status_tray_) 260 if (!status_tray_)
427 status_tray_ = profile_->GetStatusTray(); 261 status_tray_ = profile_->GetStatusTray();
428 #endif 262 #endif
429 263
(...skipping 25 matching lines...) Expand all
455 289
456 void BackgroundModeManager::UpdateStatusTrayIconContextMenu() { 290 void BackgroundModeManager::UpdateStatusTrayIconContextMenu() {
457 if (!status_icon_) 291 if (!status_icon_)
458 return; 292 return;
459 293
460 // Create a context menu item for Chrome. 294 // Create a context menu item for Chrome.
461 menus::SimpleMenuModel* menu = new menus::SimpleMenuModel(this); 295 menus::SimpleMenuModel* menu = new menus::SimpleMenuModel(this);
462 // Add About item 296 // Add About item
463 menu->AddItem(IDC_ABOUT, l10n_util::GetStringFUTF16(IDS_ABOUT, 297 menu->AddItem(IDC_ABOUT, l10n_util::GetStringFUTF16(IDS_ABOUT,
464 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); 298 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
465 299 AddPreferencesItem(menu);
Andrew T Wilson (Slow) 2010/12/03 02:06:59 One other way to do this is to define: string16 G
The wrong rickcam account 2010/12/04 02:08:04 Done. I'd argue that yours is cleaner. It makes
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); 300 menu->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
479 menu->AddSeparator(); 301 menu->AddSeparator();
480 int application_position = 0; 302 int application_position = 0;
481 context_menu_application_offset_ = menu->GetItemCount(); 303 context_menu_application_offset_ = menu->GetItemCount();
482 for (ExtensionList::const_iterator cursor = applications_.begin(); 304 for (ExtensionList::const_iterator cursor = applications_.begin();
483 cursor != applications_.end(); 305 cursor != applications_.end();
484 ++cursor, ++application_position) { 306 ++cursor, ++application_position) {
485 const SkBitmap* icon = applications_.GetIcon(*cursor); 307 const SkBitmap* icon = applications_.GetIcon(*cursor);
486 int sort_position = applications_.GetPosition(*cursor); 308 int sort_position = applications_.GetPosition(*cursor);
487 DCHECK(sort_position == application_position); 309 DCHECK(sort_position == application_position);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 #if !defined(OS_WIN) 398 #if !defined(OS_WIN)
577 // BackgroundMode is enabled by default on windows. On other platforms, it 399 // BackgroundMode is enabled by default on windows. On other platforms, it
578 // is enabled via about:flags. 400 // is enabled via about:flags.
579 background_mode_enabled = background_mode_enabled && 401 background_mode_enabled = background_mode_enabled &&
580 command_line->HasSwitch(switches::kEnableBackgroundMode); 402 command_line->HasSwitch(switches::kEnableBackgroundMode);
581 #endif 403 #endif
582 404
583 return background_mode_enabled; 405 return background_mode_enabled;
584 } 406 }
585 407
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698