Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / keystone_infobar_delegate.mm
bloba66a8bfaeed1e6ea22d43da7abdb9c584a2c9c1f
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.
5 #include "chrome/browser/ui/cocoa/keystone_infobar_delegate.h"
7 #import <AppKit/AppKit.h>
9 #include <string>
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/prefs/pref_service.h"
16 #include "chrome/browser/first_run/first_run.h"
17 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
18 #include "chrome/browser/infobars/infobar.h"
19 #include "chrome/browser/infobars/infobar_service.h"
20 #import "chrome/browser/mac/keystone_glue.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/browser.h"
23 #include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
24 #include "chrome/browser/ui/tabs/tab_strip_model.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/pref_names.h"
27 #include "content/public/browser/navigation_details.h"
28 #include "content/public/browser/web_contents.h"
29 #include "grit/chromium_strings.h"
30 #include "grit/generated_resources.h"
31 #include "grit/theme_resources.h"
32 #include "ui/base/l10n/l10n_util.h"
34 class SkBitmap;
36 namespace {
38 // KeystonePromotionInfoBarDelegate -------------------------------------------
40 class KeystonePromotionInfoBarDelegate : public ConfirmInfoBarDelegate {
41  public:
42   // If there's an active tab, creates a keystone promotion delegate and adds it
43   // to the InfoBarService associated with that tab.
44   static void Create();
46  private:
47   explicit KeystonePromotionInfoBarDelegate(PrefService* prefs);
48   virtual ~KeystonePromotionInfoBarDelegate();
50   // Sets this info bar to be able to expire.  Called a predetermined amount
51   // of time after this object is created.
52   void SetCanExpire() { can_expire_ = true; }
54   // ConfirmInfoBarDelegate
55   virtual int GetIconID() const OVERRIDE;
56   virtual base::string16 GetMessageText() const OVERRIDE;
57   virtual base::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;
63   // The prefs to use.
64   PrefService* prefs_;  // weak
66   // Whether the info bar should be dismissed on the next navigation.
67   bool can_expire_;
69   // Used to delay the expiration of the info bar.
70   base::WeakPtrFactory<KeystonePromotionInfoBarDelegate> weak_ptr_factory_;
72   DISALLOW_COPY_AND_ASSIGN(KeystonePromotionInfoBarDelegate);
75 // static
76 void KeystonePromotionInfoBarDelegate::Create() {
77   Browser* browser = chrome::GetLastActiveBrowser();
78   if (!browser)
79     return;
80   content::WebContents* webContents =
81       browser->tab_strip_model()->GetActiveWebContents();
82   if (!webContents)
83     return;
84   InfoBarService* infobar_service =
85       InfoBarService::FromWebContents(webContents);
86   infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
87       scoped_ptr<ConfirmInfoBarDelegate>(new KeystonePromotionInfoBarDelegate(
88           Profile::FromBrowserContext(
89               webContents->GetBrowserContext())->GetPrefs()))));
92 KeystonePromotionInfoBarDelegate::KeystonePromotionInfoBarDelegate(
93     PrefService* prefs)
94     : ConfirmInfoBarDelegate(),
95       prefs_(prefs),
96       can_expire_(false),
97       weak_ptr_factory_(this) {
98   const base::TimeDelta kCanExpireOnNavigationAfterDelay =
99       base::TimeDelta::FromSeconds(8);
100   base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
101       base::Bind(&KeystonePromotionInfoBarDelegate::SetCanExpire,
102                  weak_ptr_factory_.GetWeakPtr()),
103       kCanExpireOnNavigationAfterDelay);
106 KeystonePromotionInfoBarDelegate::~KeystonePromotionInfoBarDelegate() {
109 int KeystonePromotionInfoBarDelegate::GetIconID() const {
110   return IDR_PRODUCT_LOGO_32;
113 base::string16 KeystonePromotionInfoBarDelegate::GetMessageText() const {
114   return l10n_util::GetStringFUTF16(IDS_PROMOTE_INFOBAR_TEXT,
115       l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
118 base::string16 KeystonePromotionInfoBarDelegate::GetButtonLabel(
119     InfoBarButton button) const {
120   return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
121       IDS_PROMOTE_INFOBAR_PROMOTE_BUTTON : IDS_PROMOTE_INFOBAR_DONT_ASK_BUTTON);
124 bool KeystonePromotionInfoBarDelegate::Accept() {
125   [[KeystoneGlue defaultKeystoneGlue] promoteTicket];
126   return true;
129 bool KeystonePromotionInfoBarDelegate::Cancel() {
130   prefs_->SetBoolean(prefs::kShowUpdatePromotionInfoBar, false);
131   return true;
134 bool KeystonePromotionInfoBarDelegate::ShouldExpireInternal(
135     const content::LoadCommittedDetails& details) const {
136   return can_expire_;
139 }  // namespace
142 // KeystonePromotionInfoBar ---------------------------------------------------
144 @interface KeystonePromotionInfoBar : NSObject
145 - (void)checkAndShowInfoBarForProfile:(Profile*)profile;
146 - (void)updateStatus:(NSNotification*)notification;
147 - (void)removeObserver;
148 @end  // @interface KeystonePromotionInfoBar
150 @implementation KeystonePromotionInfoBar
152 - (void)dealloc {
153   [self removeObserver];
154   [super dealloc];
157 - (void)checkAndShowInfoBarForProfile:(Profile*)profile {
158   // If this is the first run, the user clicked the "don't ask again" button
159   // at some point in the past, or if the "don't ask about the default
160   // browser" command-line switch is present, bail out.  That command-line
161   // switch is recycled here because it's likely that the set of users that
162   // don't want to be nagged about the default browser also don't want to be
163   // nagged about the update check.  (Automated testers, I'm thinking of
164   // you...)
165   CommandLine* commandLine = CommandLine::ForCurrentProcess();
166   if (first_run::IsChromeFirstRun() ||
167       !profile->GetPrefs()->GetBoolean(prefs::kShowUpdatePromotionInfoBar) ||
168       commandLine->HasSwitch(switches::kNoDefaultBrowserCheck)) {
169     return;
170   }
172   // If there is no Keystone glue (maybe because this application isn't
173   // Keystone-enabled) or the application is on a read-only filesystem,
174   // doing anything related to auto-update is pointless.  Bail out.
175   KeystoneGlue* keystoneGlue = [KeystoneGlue defaultKeystoneGlue];
176   if (!keystoneGlue || [keystoneGlue isOnReadOnlyFilesystem]) {
177     return;
178   }
180   // Stay alive as long as needed.  This is balanced by a release in
181   // -updateStatus:.
182   [self retain];
184   AutoupdateStatus recentStatus = [keystoneGlue recentStatus];
185   if (recentStatus == kAutoupdateNone ||
186       recentStatus == kAutoupdateRegistering) {
187     NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
188     [center addObserver:self
189                selector:@selector(updateStatus:)
190                    name:kAutoupdateStatusNotification
191                  object:nil];
192   } else {
193     [self updateStatus:[keystoneGlue recentNotification]];
194   }
197 - (void)updateStatus:(NSNotification*)notification {
198   NSDictionary* dictionary = [notification userInfo];
199   AutoupdateStatus status = static_cast<AutoupdateStatus>(
200       [[dictionary objectForKey:kAutoupdateStatusStatus] intValue]);
202   if (status == kAutoupdateNone || status == kAutoupdateRegistering) {
203     return;
204   }
206   [self removeObserver];
208   if (status != kAutoupdateRegisterFailed &&
209       [[KeystoneGlue defaultKeystoneGlue] needsPromotion]) {
210     KeystonePromotionInfoBarDelegate::Create();
211   }
213   [self release];
216 - (void)removeObserver {
217   [[NSNotificationCenter defaultCenter] removeObserver:self];
220 @end  // @implementation KeystonePromotionInfoBar
222 // static
223 void KeystoneInfoBar::PromotionInfoBar(Profile* profile) {
224   KeystonePromotionInfoBar* promotionInfoBar =
225       [[[KeystonePromotionInfoBar alloc] init] autorelease];
227   [promotionInfoBar checkAndShowInfoBarForProfile:profile];