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
3 // found in the LICENSE file.
6 #include "base/command_line.h"
7 #include "base/mac/mac_util.h"
8 #include "base/prefs/pref_service.h"
9 #include "chrome/browser/background/background_mode_manager.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/common/chrome_switches.h"
12 #include "chrome/common/pref_names.h"
13 #include "chrome/grit/generated_resources.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "ui/base/l10n/l10n_util.h"
17 using content::BrowserThread;
20 void SetUserRemovedLoginItemPrefOnUIThread() {
21 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
22 PrefService* service = g_browser_process->local_state();
23 service->SetBoolean(prefs::kUserRemovedLoginItem, true);
26 void SetCreatedLoginItemPrefOnUIThread() {
27 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
28 PrefService* service = g_browser_process->local_state();
29 service->SetBoolean(prefs::kChromeCreatedLoginItem, true);
32 void DisableLaunchOnStartupOnFileThread() {
33 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
34 // If the LoginItem is not hidden, it means it's user created, so don't
36 bool is_hidden = false;
37 if (base::mac::CheckLoginItemStatus(&is_hidden) && is_hidden)
38 base::mac::RemoveFromLoginItems();
41 void CheckForUserRemovedLoginItemOnFileThread() {
42 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
43 if (!base::mac::CheckLoginItemStatus(NULL)) {
44 // There's no LoginItem, so set the kUserRemovedLoginItem pref.
45 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
46 base::Bind(SetUserRemovedLoginItemPrefOnUIThread));
50 void EnableLaunchOnStartupOnFileThread(bool need_migration) {
51 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
53 // This is the first time running Chrome since the kChromeCreatedLoginItem
54 // pref was added. Initialize the status of this pref based on whether
55 // there is already a hidden login item.
56 bool is_hidden = false;
57 if (base::mac::CheckLoginItemStatus(&is_hidden)) {
59 // We already have a hidden login item, so set the kChromeCreatedLoginItem
61 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
62 base::Bind(SetCreatedLoginItemPrefOnUIThread));
64 // LoginItem already exists - just exit.
69 // Check if Chrome is already a Login Item - if not, create one.
70 if (!base::mac::CheckLoginItemStatus(NULL)) {
71 // Call back to the UI thread to set our preference so we know that Chrome
72 // created the login item (which means we are allowed to delete it later).
73 // There's a race condition here if the user disables launch on startup
74 // before our callback is run, but the user can manually disable
75 // "Open At Login" via the dock if this happens.
76 base::mac::AddToLoginItems(true); // Hide on startup.
77 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
78 base::Bind(SetCreatedLoginItemPrefOnUIThread));
84 void BackgroundModeManager::EnableLaunchOnStartup(bool should_launch) {
85 // LoginItems are associated with an executable, not with a specific
86 // user-data-dir, so only mess with the LoginItem when running with the
87 // default user-data-dir. So if a user is running multiple instances of
88 // Chrome with different user-data-dirs, they won't conflict in their
90 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserDataDir))
93 // There are a few cases we need to handle:
95 // 1) Chrome is transitioning to "launch on startup" state, and there's no
96 // login item currently. We create a new item if the kUserRemovedLoginItem
97 // and kChromeCreatedLoginItem flags are already false, and set the
98 // kChromeCreatedLoginItem flag to true. If kChromeCreatedLoginItem is
99 // already set (meaning that we created a login item that has since been
100 // deleted) then we will set the kUserRemovedLoginItem so we do not create
101 // login items in the future.
103 // 2) Chrome is transitioning to the "do not launch on startup" state. If
104 // the kChromeCreatedLoginItem flag is false, we do nothing. Otherwise, we
105 // will delete the login item if it's present, and not we will set
106 // kUserRemovedLoginItem to true to prevent future login items from being
109 PrefService* service = g_browser_process->local_state();
110 // If the user removed the login item, don't ever create another one.
111 if (service->GetBoolean(prefs::kUserRemovedLoginItem))
114 if (service->GetBoolean(prefs::kChromeCreatedLoginItem)) {
115 DCHECK(service->GetBoolean(prefs::kMigratedLoginItemPref));
116 // If we previously created a login item, we don't need to create
117 // a new one - just check to see if the user removed it so we don't
118 // ever create another one.
119 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
121 CheckForUserRemovedLoginItemOnFileThread));
123 bool need_migration = !service->GetBoolean(
124 prefs::kMigratedLoginItemPref);
125 service->SetBoolean(prefs::kMigratedLoginItemPref, true);
126 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
127 base::Bind(EnableLaunchOnStartupOnFileThread,
131 PrefService* service = g_browser_process->local_state();
132 // If Chrome didn't create any login items, just exit.
133 if (!service->GetBoolean(prefs::kChromeCreatedLoginItem))
136 // Clear the pref now that we're removing the login item.
137 service->ClearPref(prefs::kChromeCreatedLoginItem);
139 // If the user removed our login item, note this so we don't ever create
141 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
143 CheckForUserRemovedLoginItemOnFileThread));
145 // Call to the File thread to remove the login item since it requires
146 // accessing the disk.
147 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
148 base::Bind(DisableLaunchOnStartupOnFileThread));
152 void BackgroundModeManager::DisplayAppInstalledNotification(
153 const extensions::Extension* extension) {
154 // TODO(atwilson): Display a platform-appropriate notification here.
155 // http://crbug.com/74970
158 base::string16 BackgroundModeManager::GetPreferencesMenuLabel() {
159 return l10n_util::GetStringUTF16(IDS_OPTIONS);