extension_welcome_notification.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/notifications/extension_welcome_notification.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/guid.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/lazy_instance.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/prefs/pref_service.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/browser_process.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/notifications/notification.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/prefs/pref_service_syncable.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/pref_names.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/url_constants.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/generated_resources.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/theme_resources.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/message_center/message_center.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/message_center/notification.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/message_center/notification_delegate.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/message_center/notification_types.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int ExtensionWelcomeNotification::kRequestedShowTimeDays = 1;
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class NotificationCallbacks
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public message_center::NotificationDelegate {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NotificationCallbacks(
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Profile* profile,
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ExtensionWelcomeNotification::Delegate* delegate)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : profile_(profile),
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        delegate_(delegate) {
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overridden from NotificationDelegate:
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Display() OVERRIDE {}
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Error() OVERRIDE {}
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Close(bool by_user) OVERRIDE {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (by_user) {
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Setting the preference here may cause the notification erasing
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // to reenter. Posting a task avoids this issue.
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delegate_->PostTask(
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          FROM_HERE,
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(&NotificationCallbacks::MarkAsDismissed, this));
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Click() OVERRIDE {}
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void ButtonClick(int index) OVERRIDE {
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK_EQ(index, 0);
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    OpenNotificationLearnMoreTab();
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void MarkAsDismissed() {
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    profile_->GetPrefs()->SetBoolean(prefs::kWelcomeNotificationDismissed,
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     true);
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OpenNotificationLearnMoreTab() {
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome::NavigateParams params(
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        profile_,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        GURL(chrome::kNotificationWelcomeLearnMoreURL),
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content::PAGE_TRANSITION_LINK);
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.disposition = NEW_FOREGROUND_TAB;
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.window_action = chrome::NavigateParams::SHOW_WINDOW;
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome::Navigate(&params);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~NotificationCallbacks() {}
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Profile* const profile_;
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Weak ref owned by ExtensionWelcomeNotification.
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionWelcomeNotification::Delegate* const delegate_;
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NotificationCallbacks);
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DefaultDelegate : public ExtensionWelcomeNotification::Delegate {
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DefaultDelegate() {}
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual message_center::MessageCenter* GetMessageCenter() OVERRIDE {
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return g_browser_process->message_center();
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual base::Time GetCurrentTime() OVERRIDE {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::Time::Now();
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void PostTask(
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const tracked_objects::Location& from_here,
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const base::Closure& task) OVERRIDE {
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->PostTask(from_here, task);
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DefaultDelegate);
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionWelcomeNotification::ExtensionWelcomeNotification(
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& extension_id,
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Profile* const profile,
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ExtensionWelcomeNotification::Delegate* const delegate)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : notifier_id_(message_center::NotifierId::APPLICATION, extension_id),
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      profile_(profile),
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delegate_(delegate) {
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  welcome_notification_dismissed_pref_.Init(
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      prefs::kWelcomeNotificationDismissed,
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      profile_->GetPrefs(),
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          &ExtensionWelcomeNotification::OnWelcomeNotificationDismissedChanged,
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Unretained(this)));
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<ExtensionWelcomeNotification> ExtensionWelcomeNotification::Create(
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& extension_id,
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Profile* const profile) {
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return Create(extension_id, profile, new DefaultDelegate()).Pass();
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<ExtensionWelcomeNotification> ExtensionWelcomeNotification::Create(
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& extension_id,
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Profile* const profile,
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Delegate* const delegate) {
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return scoped_ptr<ExtensionWelcomeNotification>(
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new ExtensionWelcomeNotification(extension_id, profile, delegate)).Pass();
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionWelcomeNotification::~ExtensionWelcomeNotification() {
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (delayed_notification_) {
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delayed_notification_.reset();
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PrefServiceSyncable::FromProfile(profile_)->RemoveObserver(this);
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    HideWelcomeNotification();
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::OnIsSyncingChanged() {
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(delayed_notification_);
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefServiceSyncable* const pref_service_syncable =
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PrefServiceSyncable::FromProfile(profile_);
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (pref_service_syncable->IsSyncing()) {
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    pref_service_syncable->RemoveObserver(this);
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<Notification> previous_notification(
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        delayed_notification_.release());
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ShowWelcomeNotificationIfNecessary(*(previous_notification.get()));
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::ShowWelcomeNotificationIfNecessary(
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Notification& notification) {
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if ((notification.notifier_id() == notifier_id_) && !delayed_notification_) {
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PrefServiceSyncable* const pref_service_syncable =
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        PrefServiceSyncable::FromProfile(profile_);
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (pref_service_syncable->IsSyncing()) {
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PrefService* const pref_service = profile_->GetPrefs();
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!pref_service->GetBoolean(prefs::kWelcomeNotificationDismissed)) {
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        const PopUpRequest pop_up_request =
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            pref_service->GetBoolean(
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                prefs::kWelcomeNotificationPreviouslyPoppedUp)
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                ? POP_UP_HIDDEN
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                : POP_UP_SHOWN;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (pop_up_request == POP_UP_SHOWN) {
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          pref_service->SetBoolean(
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              prefs::kWelcomeNotificationPreviouslyPoppedUp, true);
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (IsWelcomeNotificationExpired()) {
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ExpireWelcomeNotification();
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        } else {
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ShowWelcomeNotification(
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              notification.display_source(), pop_up_request);
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delayed_notification_.reset(new Notification(notification));
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      pref_service_syncable->AddObserver(this);
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::RegisterProfilePrefs(
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    user_prefs::PrefRegistrySyncable* prefs) {
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kWelcomeNotificationDismissed,
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             false,
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp,
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             false,
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  prefs->RegisterInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp,
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           0,
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)message_center::MessageCenter*
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionWelcomeNotification::GetMessageCenter() const {
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return delegate_->GetMessageCenter();
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::ShowWelcomeNotification(
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& display_source,
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const PopUpRequest pop_up_request) {
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message_center::ButtonInfo learn_more(
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_BUTTON_LEARN_MORE));
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  learn_more.icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      IDR_NOTIFICATION_WELCOME_LEARN_MORE);
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message_center::RichNotificationData rich_notification_data;
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rich_notification_data.priority = 2;
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rich_notification_data.buttons.push_back(learn_more);
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (welcome_notification_id_.empty())
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    welcome_notification_id_ = base::GenerateGUID();
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!welcome_notification_id_.empty()) {
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<message_center::Notification> message_center_notification(
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new message_center::Notification(
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            message_center::NOTIFICATION_TYPE_BASE_FORMAT,
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            welcome_notification_id_,
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_TITLE),
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_BODY),
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            ui::ResourceBundle::GetSharedInstance().GetImageNamed(
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                IDR_NOTIFICATION_WELCOME_ICON),
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            display_source,
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            notifier_id_,
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            rich_notification_data,
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            new NotificationCallbacks(profile_, delegate_.get())));
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (pop_up_request == POP_UP_HIDDEN)
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      message_center_notification->set_shown_as_popup(true);
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetMessageCenter()->AddNotification(message_center_notification.Pass());
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    StartExpirationTimer();
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::HideWelcomeNotification() {
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!welcome_notification_id_.empty() &&
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetMessageCenter()->HasNotification(welcome_notification_id_)) {
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetMessageCenter()->RemoveNotification(welcome_notification_id_, false);
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    StopExpirationTimer();
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::OnWelcomeNotificationDismissedChanged() {
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const bool welcome_notification_dismissed =
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      profile_->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed);
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (welcome_notification_dismissed)
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    HideWelcomeNotification();
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::StartExpirationTimer() {
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!expiration_timer_ && !IsWelcomeNotificationExpired()) {
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::Time expiration_timestamp = GetExpirationTimestamp();
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (expiration_timestamp.is_null()) {
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SetExpirationTimestampFromNow();
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      expiration_timestamp = GetExpirationTimestamp();
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(!expiration_timestamp.is_null());
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    expiration_timer_.reset(
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new base::OneShotTimer<ExtensionWelcomeNotification>());
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    expiration_timer_->Start(
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        expiration_timestamp - delegate_->GetCurrentTime(),
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        this,
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        &ExtensionWelcomeNotification::ExpireWelcomeNotification);
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::StopExpirationTimer() {
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (expiration_timer_) {
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    expiration_timer_->Stop();
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    expiration_timer_.reset();
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::ExpireWelcomeNotification() {
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(IsWelcomeNotificationExpired());
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  profile_->GetPrefs()->SetBoolean(prefs::kWelcomeNotificationDismissed, true);
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HideWelcomeNotification();
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Time ExtensionWelcomeNotification::GetExpirationTimestamp() const {
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefService* const pref_service = profile_->GetPrefs();
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int64 expiration_timestamp =
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      pref_service->GetInt64(prefs::kWelcomeNotificationExpirationTimestamp);
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return (expiration_timestamp == 0)
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ? base::Time()
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : base::Time::FromInternalValue(expiration_timestamp);
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::SetExpirationTimestampFromNow() {
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefService* const pref_service = profile_->GetPrefs();
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pref_service->SetInt64(
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      prefs::kWelcomeNotificationExpirationTimestamp,
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      (delegate_->GetCurrentTime() +
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::TimeDelta::FromDays(kRequestedShowTimeDays)).ToInternalValue());
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtensionWelcomeNotification::IsWelcomeNotificationExpired() const {
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Time expiration_timestamp = GetExpirationTimestamp();
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return !expiration_timestamp.is_null() &&
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         (expiration_timestamp <= delegate_->GetCurrentTime());
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// C++ Readability Review Change Trigger
323