Popular sites on the NTP: re-download popular suggestions once per Chrome run
[chromium-blink-merge.git] / chrome / browser / background / background_mode_manager_mac.mm
blob1788060f05df9af7274650fccd474d08b453a986
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.
5 #include "base/bind.h"
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;
19 namespace {
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
35   // delete it.
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));
47   }
50 void EnableLaunchOnStartupOnFileThread(bool need_migration) {
51   DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
52   if (need_migration) {
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)) {
58       if (is_hidden) {
59       // We already have a hidden login item, so set the kChromeCreatedLoginItem
60       // flag.
61         BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
62                                 base::Bind(SetCreatedLoginItemPrefOnUIThread));
63       }
64       // LoginItem already exists - just exit.
65       return;
66     }
67   }
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));
79   }
82 }  // namespace
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
89   // use of LoginItems.
90   if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserDataDir))
91     return;
93   // There are a few cases we need to handle:
94   //
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.
102   //
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
107   // created.
108   if (should_launch) {
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))
112       return;
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,
120                               base::Bind(
121                                   CheckForUserRemovedLoginItemOnFileThread));
122     } else {
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,
128                                          need_migration));
129     }
130   } else {
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))
134       return;
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
140     // another one.
141     BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
142                             base::Bind(
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));
149   }
152 void BackgroundModeManager::DisplayClientInstalledNotification(
153     const base::string16& name) {
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);