This source file includes following definitions.
- delegate_
- Display
- Error
- Close
- Click
- ButtonClick
- MarkAsDismissed
- OpenNotificationLearnMoreTab
- GetMessageCenter
- GetCurrentTime
- PostTask
- delegate_
- Create
- Create
- OnIsSyncingChanged
- ShowWelcomeNotificationIfNecessary
- RegisterProfilePrefs
- GetMessageCenter
- ShowWelcomeNotification
- HideWelcomeNotification
- OnWelcomeNotificationDismissedChanged
- StartExpirationTimer
- StopExpirationTimer
- ExpireWelcomeNotification
- GetExpirationTimestamp
- SetExpirationTimestampFromNow
- IsWelcomeNotificationExpired
#include "chrome/browser/notifications/extension_welcome_notification.h"
#include "base/guid.h"
#include "base/lazy_instance.h"
#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/prefs/pref_service_syncable.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_delegate.h"
#include "ui/message_center/notification_types.h"
const int ExtensionWelcomeNotification::kRequestedShowTimeDays = 1;
namespace {
class NotificationCallbacks
: public message_center::NotificationDelegate {
public:
NotificationCallbacks(
Profile* profile,
ExtensionWelcomeNotification::Delegate* delegate)
: profile_(profile),
delegate_(delegate) {
}
virtual void Display() OVERRIDE {}
virtual void Error() OVERRIDE {}
virtual void Close(bool by_user) OVERRIDE {
if (by_user) {
delegate_->PostTask(
FROM_HERE,
base::Bind(&NotificationCallbacks::MarkAsDismissed, this));
}
}
virtual void Click() OVERRIDE {}
virtual void ButtonClick(int index) OVERRIDE {
DCHECK_EQ(index, 0);
OpenNotificationLearnMoreTab();
}
private:
void MarkAsDismissed() {
profile_->GetPrefs()->SetBoolean(prefs::kWelcomeNotificationDismissed,
true);
}
void OpenNotificationLearnMoreTab() {
chrome::NavigateParams params(
profile_,
GURL(chrome::kNotificationWelcomeLearnMoreURL),
content::PAGE_TRANSITION_LINK);
params.disposition = NEW_FOREGROUND_TAB;
params.window_action = chrome::NavigateParams::SHOW_WINDOW;
chrome::Navigate(¶ms);
}
virtual ~NotificationCallbacks() {}
Profile* const profile_;
ExtensionWelcomeNotification::Delegate* const delegate_;
DISALLOW_COPY_AND_ASSIGN(NotificationCallbacks);
};
class DefaultDelegate : public ExtensionWelcomeNotification::Delegate {
public:
DefaultDelegate() {}
virtual message_center::MessageCenter* GetMessageCenter() OVERRIDE {
return g_browser_process->message_center();
}
virtual base::Time GetCurrentTime() OVERRIDE {
return base::Time::Now();
}
virtual void PostTask(
const tracked_objects::Location& from_here,
const base::Closure& task) OVERRIDE {
base::MessageLoop::current()->PostTask(from_here, task);
}
private:
DISALLOW_COPY_AND_ASSIGN(DefaultDelegate);
};
}
ExtensionWelcomeNotification::ExtensionWelcomeNotification(
const std::string& extension_id,
Profile* const profile,
ExtensionWelcomeNotification::Delegate* const delegate)
: notifier_id_(message_center::NotifierId::APPLICATION, extension_id),
profile_(profile),
delegate_(delegate) {
welcome_notification_dismissed_pref_.Init(
prefs::kWelcomeNotificationDismissed,
profile_->GetPrefs(),
base::Bind(
&ExtensionWelcomeNotification::OnWelcomeNotificationDismissedChanged,
base::Unretained(this)));
}
scoped_ptr<ExtensionWelcomeNotification> ExtensionWelcomeNotification::Create(
const std::string& extension_id,
Profile* const profile) {
return Create(extension_id, profile, new DefaultDelegate()).Pass();
}
scoped_ptr<ExtensionWelcomeNotification> ExtensionWelcomeNotification::Create(
const std::string& extension_id,
Profile* const profile,
Delegate* const delegate) {
return scoped_ptr<ExtensionWelcomeNotification>(
new ExtensionWelcomeNotification(extension_id, profile, delegate)).Pass();
}
ExtensionWelcomeNotification::~ExtensionWelcomeNotification() {
if (delayed_notification_) {
delayed_notification_.reset();
PrefServiceSyncable::FromProfile(profile_)->RemoveObserver(this);
} else {
HideWelcomeNotification();
}
}
void ExtensionWelcomeNotification::OnIsSyncingChanged() {
DCHECK(delayed_notification_);
PrefServiceSyncable* const pref_service_syncable =
PrefServiceSyncable::FromProfile(profile_);
if (pref_service_syncable->IsSyncing()) {
pref_service_syncable->RemoveObserver(this);
scoped_ptr<Notification> previous_notification(
delayed_notification_.release());
ShowWelcomeNotificationIfNecessary(*(previous_notification.get()));
}
}
void ExtensionWelcomeNotification::ShowWelcomeNotificationIfNecessary(
const Notification& notification) {
if ((notification.notifier_id() == notifier_id_) && !delayed_notification_) {
PrefServiceSyncable* const pref_service_syncable =
PrefServiceSyncable::FromProfile(profile_);
if (pref_service_syncable->IsSyncing()) {
PrefService* const pref_service = profile_->GetPrefs();
if (!pref_service->GetBoolean(prefs::kWelcomeNotificationDismissed)) {
const PopUpRequest pop_up_request =
pref_service->GetBoolean(
prefs::kWelcomeNotificationPreviouslyPoppedUp)
? POP_UP_HIDDEN
: POP_UP_SHOWN;
if (pop_up_request == POP_UP_SHOWN) {
pref_service->SetBoolean(
prefs::kWelcomeNotificationPreviouslyPoppedUp, true);
}
if (IsWelcomeNotificationExpired()) {
ExpireWelcomeNotification();
} else {
ShowWelcomeNotification(
notification.display_source(), pop_up_request);
}
}
} else {
delayed_notification_.reset(new Notification(notification));
pref_service_syncable->AddObserver(this);
}
}
}
void ExtensionWelcomeNotification::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* prefs) {
prefs->RegisterBooleanPref(prefs::kWelcomeNotificationDismissed,
false,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
prefs->RegisterBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp,
false,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
prefs->RegisterInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp,
0,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
}
message_center::MessageCenter*
ExtensionWelcomeNotification::GetMessageCenter() const {
return delegate_->GetMessageCenter();
}
void ExtensionWelcomeNotification::ShowWelcomeNotification(
const base::string16& display_source,
const PopUpRequest pop_up_request) {
message_center::ButtonInfo learn_more(
l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_BUTTON_LEARN_MORE));
learn_more.icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
IDR_NOTIFICATION_WELCOME_LEARN_MORE);
message_center::RichNotificationData rich_notification_data;
rich_notification_data.priority = 2;
rich_notification_data.buttons.push_back(learn_more);
if (welcome_notification_id_.empty())
welcome_notification_id_ = base::GenerateGUID();
if (!welcome_notification_id_.empty()) {
scoped_ptr<message_center::Notification> message_center_notification(
new message_center::Notification(
message_center::NOTIFICATION_TYPE_BASE_FORMAT,
welcome_notification_id_,
l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_TITLE),
l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_BODY),
ui::ResourceBundle::GetSharedInstance().GetImageNamed(
IDR_NOTIFICATION_WELCOME_ICON),
display_source,
notifier_id_,
rich_notification_data,
new NotificationCallbacks(profile_, delegate_.get())));
if (pop_up_request == POP_UP_HIDDEN)
message_center_notification->set_shown_as_popup(true);
GetMessageCenter()->AddNotification(message_center_notification.Pass());
StartExpirationTimer();
}
}
void ExtensionWelcomeNotification::HideWelcomeNotification() {
if (!welcome_notification_id_.empty() &&
GetMessageCenter()->HasNotification(welcome_notification_id_)) {
GetMessageCenter()->RemoveNotification(welcome_notification_id_, false);
StopExpirationTimer();
}
}
void ExtensionWelcomeNotification::OnWelcomeNotificationDismissedChanged() {
const bool welcome_notification_dismissed =
profile_->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed);
if (welcome_notification_dismissed)
HideWelcomeNotification();
}
void ExtensionWelcomeNotification::StartExpirationTimer() {
if (!expiration_timer_ && !IsWelcomeNotificationExpired()) {
base::Time expiration_timestamp = GetExpirationTimestamp();
if (expiration_timestamp.is_null()) {
SetExpirationTimestampFromNow();
expiration_timestamp = GetExpirationTimestamp();
DCHECK(!expiration_timestamp.is_null());
}
expiration_timer_.reset(
new base::OneShotTimer<ExtensionWelcomeNotification>());
expiration_timer_->Start(
FROM_HERE,
expiration_timestamp - delegate_->GetCurrentTime(),
this,
&ExtensionWelcomeNotification::ExpireWelcomeNotification);
}
}
void ExtensionWelcomeNotification::StopExpirationTimer() {
if (expiration_timer_) {
expiration_timer_->Stop();
expiration_timer_.reset();
}
}
void ExtensionWelcomeNotification::ExpireWelcomeNotification() {
DCHECK(IsWelcomeNotificationExpired());
profile_->GetPrefs()->SetBoolean(prefs::kWelcomeNotificationDismissed, true);
HideWelcomeNotification();
}
base::Time ExtensionWelcomeNotification::GetExpirationTimestamp() const {
PrefService* const pref_service = profile_->GetPrefs();
const int64 expiration_timestamp =
pref_service->GetInt64(prefs::kWelcomeNotificationExpirationTimestamp);
return (expiration_timestamp == 0)
? base::Time()
: base::Time::FromInternalValue(expiration_timestamp);
}
void ExtensionWelcomeNotification::SetExpirationTimestampFromNow() {
PrefService* const pref_service = profile_->GetPrefs();
pref_service->SetInt64(
prefs::kWelcomeNotificationExpirationTimestamp,
(delegate_->GetCurrentTime() +
base::TimeDelta::FromDays(kRequestedShowTimeDays)).ToInternalValue());
}
bool ExtensionWelcomeNotification::IsWelcomeNotificationExpired() const {
const base::Time expiration_timestamp = GetExpirationTimestamp();
return !expiration_timestamp.is_null() &&
(expiration_timestamp <= delegate_->GetCurrentTime());
}