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