1 // Copyright 2013 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/notifications/welcome_notification.h"
8 #include "base/lazy_instance.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/notifications/notification.h"
13 #include "chrome/browser/prefs/pref_service_syncable.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser_navigator.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/common/url_constants.h"
18 #include "components/user_prefs/pref_registry_syncable.h"
19 #include "grit/generated_resources.h"
20 #include "grit/theme_resources.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/resource/resource_bundle.h"
23 #include "ui/message_center/message_center.h"
24 #include "ui/message_center/notification.h"
25 #include "ui/message_center/notification_delegate.h"
26 #include "ui/message_center/notification_types.h"
28 const char kChromeNowExtensionID
[] = "pafkbggdmjlpgkdkcbjmhmfcdpncadgh";
30 class WelcomeNotificationDelegate
31 : public message_center::NotificationDelegate
{
33 WelcomeNotificationDelegate(const std::string
& id
, Profile
* profile
)
34 : profile_(profile
) {}
36 // Overridden from NotificationDelegate:
37 virtual void Display() OVERRIDE
{}
38 virtual void Error() OVERRIDE
{}
40 virtual void Close(bool by_user
) OVERRIDE
{
42 // Setting the preference here may cause the notification erasing
43 // to reenter. Posting a task avoids this issue.
44 base::MessageLoop::current()->PostTask(
46 base::Bind(&WelcomeNotificationDelegate::MarkAsDismissed
, this));
50 virtual void Click() OVERRIDE
{}
51 virtual void ButtonClick(int index
) OVERRIDE
{
53 OpenNotificationLearnMoreTab();
57 void MarkAsDismissed() {
58 profile_
->GetPrefs()->
59 SetBoolean(prefs::kWelcomeNotificationDismissed
, true);
62 void OpenNotificationLearnMoreTab() {
63 chrome::NavigateParams
params(
65 GURL(chrome::kNotificationWelcomeLearnMoreURL
),
66 content::PAGE_TRANSITION_LINK
);
67 params
.disposition
= NEW_FOREGROUND_TAB
;
68 params
.window_action
= chrome::NavigateParams::SHOW_WINDOW
;
69 chrome::Navigate(¶ms
);
72 virtual ~WelcomeNotificationDelegate() {}
74 Profile
* const profile_
;
76 DISALLOW_COPY_AND_ASSIGN(WelcomeNotificationDelegate
);
79 WelcomeNotification::WelcomeNotification(
81 message_center::MessageCenter
* message_center
)
83 message_center_(message_center
) {
84 welcome_notification_dismissed_pref_
.Init(
85 prefs::kWelcomeNotificationDismissed
,
88 &WelcomeNotification::OnWelcomeNotificationDismissedChanged
,
89 base::Unretained(this)));
92 WelcomeNotification::~WelcomeNotification() {
93 if (delayed_notification_
) {
94 delayed_notification_
.reset();
95 PrefServiceSyncable::FromProfile(profile_
)->RemoveObserver(this);
99 void WelcomeNotification::OnIsSyncingChanged() {
100 DCHECK(delayed_notification_
);
101 PrefServiceSyncable
* pref_service_syncable
=
102 PrefServiceSyncable::FromProfile(profile_
);
103 if (pref_service_syncable
->IsSyncing()) {
104 pref_service_syncable
->RemoveObserver(this);
105 scoped_ptr
<Notification
> previous_notification(
106 delayed_notification_
.release());
107 ShowWelcomeNotificationIfNecessary(*(previous_notification
.get()));
111 void WelcomeNotification::ShowWelcomeNotificationIfNecessary(
112 const Notification
& notification
) {
113 message_center::NotifierId notifier_id
= notification
.notifier_id();
114 if ((notifier_id
.id
== kChromeNowExtensionID
) && !delayed_notification_
) {
115 PrefServiceSyncable
* pref_service_syncable
=
116 PrefServiceSyncable::FromProfile(profile_
);
117 if (pref_service_syncable
->IsSyncing()) {
118 PrefService
* pref_service
= profile_
->GetPrefs();
119 if (!pref_service
->GetBoolean(prefs::kWelcomeNotificationDismissed
)) {
120 PopUpRequest pop_up_request
=
121 pref_service
->GetBoolean(
122 prefs::kWelcomeNotificationPreviouslyPoppedUp
)
125 if (pop_up_request
== POP_UP_SHOWN
) {
126 pref_service
->SetBoolean(
127 prefs::kWelcomeNotificationPreviouslyPoppedUp
, true);
130 ShowWelcomeNotification(notifier_id
,
131 notification
.display_source(),
135 delayed_notification_
.reset(new Notification(notification
));
136 pref_service_syncable
->AddObserver(this);
142 void WelcomeNotification::RegisterProfilePrefs(
143 user_prefs::PrefRegistrySyncable
* prefs
) {
144 prefs
->RegisterBooleanPref(
145 prefs::kWelcomeNotificationDismissed
,
147 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
148 prefs
->RegisterBooleanPref(
149 prefs::kWelcomeNotificationPreviouslyPoppedUp
,
151 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
154 void WelcomeNotification::ShowWelcomeNotification(
155 const message_center::NotifierId notifier_id
,
156 const base::string16
& display_source
,
157 PopUpRequest pop_up_request
) {
158 message_center::ButtonInfo
learn_more(
159 l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_BUTTON_LEARN_MORE
));
160 learn_more
.icon
= ui::ResourceBundle::GetSharedInstance().GetImageNamed(
161 IDR_NOTIFICATION_WELCOME_LEARN_MORE
);
163 message_center::RichNotificationData rich_notification_data
;
164 rich_notification_data
.priority
= 2;
165 rich_notification_data
.buttons
.push_back(learn_more
);
167 if (welcome_notification_id_
.empty())
168 welcome_notification_id_
= base::GenerateGUID();
170 if (!welcome_notification_id_
.empty()) {
171 scoped_ptr
<message_center::Notification
> message_center_notification(
172 new message_center::Notification(
173 message_center::NOTIFICATION_TYPE_BASE_FORMAT
,
174 welcome_notification_id_
,
175 l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_TITLE
),
176 l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_BODY
),
177 ui::ResourceBundle::GetSharedInstance().GetImageNamed(
178 IDR_NOTIFICATION_WELCOME_ICON
),
181 rich_notification_data
,
182 new WelcomeNotificationDelegate(
183 welcome_notification_id_
, profile_
)));
185 if (pop_up_request
== POP_UP_HIDDEN
)
186 message_center_notification
->set_shown_as_popup(true);
188 message_center_
->AddNotification(message_center_notification
.Pass());
192 void WelcomeNotification::HideWelcomeNotification() {
193 if (!welcome_notification_id_
.empty() &&
194 message_center_
->HasNotification(welcome_notification_id_
)) {
195 message_center_
->RemoveNotification(welcome_notification_id_
, false);
199 void WelcomeNotification::OnWelcomeNotificationDismissedChanged() {
200 const bool welcome_notification_dismissed
=
201 profile_
->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
);
202 if (welcome_notification_dismissed
)
203 HideWelcomeNotification();