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