autolaunch_prompt_win.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 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.
4
5#include "chrome/browser/ui/startup/autolaunch_prompt.h"
6
7#include "base/command_line.h"
8#include "base/message_loop.h"
9#include "base/prefs/pref_service.h"
10#include "base/utf_string_conversions.h"
11#include "chrome/browser/auto_launch_trial.h"
12#include "chrome/browser/first_run/first_run.h"
13#include "chrome/browser/infobars/confirm_infobar_delegate.h"
14#include "chrome/browser/infobars/infobar_service.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/ui/browser.h"
17#include "chrome/browser/ui/tabs/tab_strip_model.h"
18#include "chrome/common/chrome_constants.h"
19#include "chrome/common/chrome_switches.h"
20#include "chrome/common/pref_names.h"
21#include "chrome/installer/util/auto_launch_util.h"
22#include "components/user_prefs/pref_registry_syncable.h"
23#include "content/public/browser/browser_thread.h"
24#include "content/public/browser/navigation_details.h"
25#include "content/public/browser/web_contents.h"
26#include "grit/chromium_strings.h"
27#include "grit/generated_resources.h"
28#include "grit/theme_resources.h"
29#include "ui/base/l10n/l10n_util.h"
30#include "ui/base/resource/resource_bundle.h"
31
32using content::BrowserThread;
33
34namespace {
35
36const int kMaxInfobarShown = 5;
37
38// The delegate for the infobar shown when Chrome was auto-launched.
39class AutolaunchInfoBarDelegate : public ConfirmInfoBarDelegate {
40 public:
41  // Creates an autolaunch delegate and adds it to |infobar_service|.
42  static void Create(InfoBarService* infobar_service,
43                     PrefService* prefs,
44                     Profile* profile);
45
46 private:
47  AutolaunchInfoBarDelegate(InfoBarService* infobar_service,
48                            PrefService* prefs,
49                            Profile* profile);
50  virtual ~AutolaunchInfoBarDelegate();
51
52  void AllowExpiry() { should_expire_ = true; }
53
54  // ConfirmInfoBarDelegate:
55  virtual gfx::Image* GetIcon() const OVERRIDE;
56  virtual string16 GetMessageText() const OVERRIDE;
57  virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
58  virtual bool Accept() OVERRIDE;
59  virtual bool Cancel() OVERRIDE;
60  virtual bool ShouldExpireInternal(
61      const content::LoadCommittedDetails& details) const OVERRIDE;
62
63  // The prefs to use.
64  PrefService* prefs_;
65
66  // Whether the user clicked one of the buttons.
67  bool action_taken_;
68
69  // Whether the info-bar should be dismissed on the next navigation.
70  bool should_expire_;
71
72  // Weak pointer to the profile, not owned by us.
73  Profile* profile_;
74
75  // Used to delay the expiration of the info-bar.
76  base::WeakPtrFactory<AutolaunchInfoBarDelegate> weak_factory_;
77
78  DISALLOW_COPY_AND_ASSIGN(AutolaunchInfoBarDelegate);
79};
80
81// static
82void AutolaunchInfoBarDelegate::Create(InfoBarService* infobar_service,
83                                       PrefService* prefs,
84                                       Profile* profile) {
85  infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
86      new AutolaunchInfoBarDelegate(infobar_service, prefs, profile)));
87}
88
89AutolaunchInfoBarDelegate::AutolaunchInfoBarDelegate(
90    InfoBarService* infobar_service,
91    PrefService* prefs,
92    Profile* profile)
93    : ConfirmInfoBarDelegate(infobar_service),
94      prefs_(prefs),
95      action_taken_(false),
96      should_expire_(false),
97      profile_(profile),
98      ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
99  auto_launch_trial::UpdateInfobarShownMetric();
100
101  int count = prefs_->GetInteger(prefs::kShownAutoLaunchInfobar);
102  prefs_->SetInteger(prefs::kShownAutoLaunchInfobar, count + 1);
103
104  // We want the info-bar to stick-around for a few seconds and then be hidden
105  // on the next navigation after that.
106  MessageLoop::current()->PostDelayedTask(
107      FROM_HERE,
108      base::Bind(&AutolaunchInfoBarDelegate::AllowExpiry,
109                 weak_factory_.GetWeakPtr()),
110      base::TimeDelta::FromSeconds(8));
111}
112
113AutolaunchInfoBarDelegate::~AutolaunchInfoBarDelegate() {
114  if (!action_taken_) {
115    auto_launch_trial::UpdateInfobarResponseMetric(
116        auto_launch_trial::INFOBAR_IGNORE);
117  }
118}
119
120gfx::Image* AutolaunchInfoBarDelegate::GetIcon() const {
121  return &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
122      IDR_PRODUCT_LOGO_32);
123}
124
125string16 AutolaunchInfoBarDelegate::GetMessageText() const {
126  return l10n_util::GetStringUTF16(IDS_AUTO_LAUNCH_INFOBAR_TEXT);
127}
128
129string16 AutolaunchInfoBarDelegate::GetButtonLabel(
130    InfoBarButton button) const {
131  return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
132      IDS_AUTO_LAUNCH_OK : IDS_AUTO_LAUNCH_REVERT);
133}
134
135bool AutolaunchInfoBarDelegate::Accept() {
136  action_taken_ = true;
137  auto_launch_trial::UpdateInfobarResponseMetric(
138      auto_launch_trial::INFOBAR_OK);
139  return true;
140}
141
142bool AutolaunchInfoBarDelegate::Cancel() {
143  action_taken_ = true;
144
145  // Track infobar reponse.
146  auto_launch_trial::UpdateInfobarResponseMetric(
147      auto_launch_trial::INFOBAR_CUT_IT_OUT);
148  // Also make sure we keep track of how many disable and how many enable.
149  auto_launch_trial::UpdateToggleAutoLaunchMetric(false);
150
151  content::BrowserThread::PostTask(
152      content::BrowserThread::FILE, FROM_HERE,
153      base::Bind(&auto_launch_util::DisableForegroundStartAtLogin,
154                 profile_->GetPath().BaseName().value()));
155  return true;
156}
157
158bool AutolaunchInfoBarDelegate::ShouldExpireInternal(
159    const content::LoadCommittedDetails& details) const {
160  return should_expire_;
161}
162
163}  // namespace
164
165namespace chrome {
166
167bool ShowAutolaunchPrompt(Browser* browser) {
168  if (!auto_launch_trial::IsInAutoLaunchGroup())
169    return false;
170
171  // Only supported on the main profile for now.
172  Profile* profile = browser->profile();
173  if (profile->GetPath().BaseName() !=
174      base::FilePath(ASCIIToUTF16(chrome::kInitialProfile))) {
175    return false;
176  }
177
178  int infobar_shown =
179      profile->GetPrefs()->GetInteger(prefs::kShownAutoLaunchInfobar);
180  if (infobar_shown >= kMaxInfobarShown)
181    return false;
182
183  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
184  if (command_line.HasSwitch(switches::kChromeFrame))
185    return false;
186
187  if (!command_line.HasSwitch(switches::kAutoLaunchAtStartup) &&
188      !first_run::IsChromeFirstRun()) {
189    return false;
190  }
191
192  content::WebContents* web_contents =
193      browser->tab_strip_model()->GetActiveWebContents();
194  profile = Profile::FromBrowserContext(web_contents->GetBrowserContext());
195  AutolaunchInfoBarDelegate::Create(
196      InfoBarService::FromWebContents(web_contents), profile->GetPrefs(),
197      profile);
198  return true;
199}
200
201void RegisterAutolaunchUserPrefs(PrefRegistrySyncable* registry) {
202  registry->RegisterIntegerPref(
203      prefs::kShownAutoLaunchInfobar, 0, PrefRegistrySyncable::UNSYNCABLE_PREF);
204}
205
206}  // namespace chrome
207