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" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/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) 290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst int ExtensionWelcomeNotification::kRequestedShowTimeDays = 14; 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, 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const message_center::NotifierId notifier_id, 390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& welcome_notification_id, 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionWelcomeNotification::Delegate* delegate) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : profile_(profile), 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch notifier_id_(notifier_id.type, notifier_id.id), 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch welcome_notification_id_(welcome_notification_id), 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_(delegate) { 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Overridden from NotificationDelegate: 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void Display() OVERRIDE {} 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void Error() OVERRIDE {} 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void Close(bool by_user) OVERRIDE { 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (by_user) { 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Setting the preference here may cause the notification erasing 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to reenter. Posting a task avoids this issue. 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_->PostTask( 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&NotificationCallbacks::MarkAsDismissed, this)); 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void Click() OVERRIDE {} 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void ButtonClick(int index) OVERRIDE { 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (index == 0) { 640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch OpenNotificationLearnMoreTab(); 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else if (index == 1) { 660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DisableNotificationProvider(); 670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Close(true); 680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else { 690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch NOTREACHED(); 700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void MarkAsDismissed() { 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch profile_->GetPrefs()->SetBoolean(prefs::kWelcomeNotificationDismissedLocal, 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) true); 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OpenNotificationLearnMoreTab() { 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::NavigateParams params( 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_, 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL(chrome::kNotificationWelcomeLearnMoreURL), 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::PAGE_TRANSITION_LINK); 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.disposition = NEW_FOREGROUND_TAB; 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.window_action = chrome::NavigateParams::SHOW_WINDOW; 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::Navigate(¶ms); 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void DisableNotificationProvider() { 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch message_center::Notifier notifier(notifier_id_, base::string16(), true); 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch message_center::MessageCenter* message_center = 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch delegate_->GetMessageCenter(); 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch message_center->DisableNotificationsByNotifier(notifier_id_); 945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu message_center->RemoveNotification(welcome_notification_id_, false); 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch message_center->GetNotifierSettingsProvider()->SetNotifierEnabled( 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch notifier, false); 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~NotificationCallbacks() {} 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Profile* const profile_; 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const message_center::NotifierId notifier_id_; 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::string welcome_notification_id_; 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Weak ref owned by ExtensionWelcomeNotification. 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionWelcomeNotification::Delegate* const delegate_; 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NotificationCallbacks); 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DefaultDelegate : public ExtensionWelcomeNotification::Delegate { 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DefaultDelegate() {} 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual message_center::MessageCenter* GetMessageCenter() OVERRIDE { 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return g_browser_process->message_center(); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual base::Time GetCurrentTime() OVERRIDE { 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::Time::Now(); 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void PostTask( 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const tracked_objects::Location& from_here, 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Closure& task) OVERRIDE { 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::MessageLoop::current()->PostTask(from_here, task); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DefaultDelegate); 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionWelcomeNotification::ExtensionWelcomeNotification( 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& extension_id, 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Profile* const profile, 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionWelcomeNotification::Delegate* const delegate) 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : notifier_id_(message_center::NotifierId::APPLICATION, extension_id), 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_(profile), 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delegate_(delegate) { 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) welcome_notification_dismissed_pref_.Init( 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs::kWelcomeNotificationDismissed, 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_->GetPrefs(), 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind( 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &ExtensionWelcomeNotification::OnWelcomeNotificationDismissedChanged, 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this))); 1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch welcome_notification_dismissed_local_pref_.Init( 1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch prefs::kWelcomeNotificationDismissedLocal, 1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch profile_->GetPrefs()); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<ExtensionWelcomeNotification> ExtensionWelcomeNotification::Create( 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& extension_id, 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Profile* const profile) { 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Create(extension_id, profile, new DefaultDelegate()).Pass(); 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<ExtensionWelcomeNotification> ExtensionWelcomeNotification::Create( 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& extension_id, 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Profile* const profile, 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Delegate* const delegate) { 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return scoped_ptr<ExtensionWelcomeNotification>( 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new ExtensionWelcomeNotification(extension_id, profile, delegate)).Pass(); 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionWelcomeNotification::~ExtensionWelcomeNotification() { 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (delayed_notification_) { 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delayed_notification_.reset(); 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrefServiceSyncable::FromProfile(profile_)->RemoveObserver(this); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HideWelcomeNotification(); 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::OnIsSyncingChanged() { 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(delayed_notification_); 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrefServiceSyncable* const pref_service_syncable = 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrefServiceSyncable::FromProfile(profile_); 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (pref_service_syncable->IsSyncing()) { 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_service_syncable->RemoveObserver(this); 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<Notification> previous_notification( 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delayed_notification_.release()); 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShowWelcomeNotificationIfNecessary(*(previous_notification.get())); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::ShowWelcomeNotificationIfNecessary( 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Notification& notification) { 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((notification.notifier_id() == notifier_id_) && !delayed_notification_) { 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrefServiceSyncable* const pref_service_syncable = 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrefServiceSyncable::FromProfile(profile_); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (pref_service_syncable->IsSyncing()) { 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrefService* const pref_service = profile_->GetPrefs(); 1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!UserHasDismissedWelcomeNotification()) { 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const PopUpRequest pop_up_request = 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_service->GetBoolean( 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs::kWelcomeNotificationPreviouslyPoppedUp) 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? POP_UP_HIDDEN 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : POP_UP_SHOWN; 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (pop_up_request == POP_UP_SHOWN) { 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_service->SetBoolean( 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs::kWelcomeNotificationPreviouslyPoppedUp, true); 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsWelcomeNotificationExpired()) { 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpireWelcomeNotification(); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShowWelcomeNotification( 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) notification.display_source(), pop_up_request); 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delayed_notification_.reset(new Notification(notification)); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_service_syncable->AddObserver(this); 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::RegisterProfilePrefs( 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_prefs::PrefRegistrySyncable* prefs) { 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs->RegisterBooleanPref(prefs::kWelcomeNotificationDismissed, 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false, 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch prefs->RegisterBooleanPref(prefs::kWelcomeNotificationDismissedLocal, 2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch false, 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs->RegisterBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp, 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false, 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs->RegisterInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp, 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)message_center::MessageCenter* 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionWelcomeNotification::GetMessageCenter() const { 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return delegate_->GetMessageCenter(); 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::ShowWelcomeNotification( 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& display_source, 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const PopUpRequest pop_up_request) { 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_center::ButtonInfo learn_more( 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_BUTTON_LEARN_MORE)); 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) learn_more.icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed( 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDR_NOTIFICATION_WELCOME_LEARN_MORE); 2530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch message_center::ButtonInfo disable( 2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch l10n_util::GetStringUTF16(IDS_NOTIFIER_WELCOME_BUTTON)); 2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch disable.icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed( 2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IDR_NOTIFIER_BLOCK_BUTTON); 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_center::RichNotificationData rich_notification_data; 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rich_notification_data.priority = 2; 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rich_notification_data.buttons.push_back(learn_more); 2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch rich_notification_data.buttons.push_back(disable); 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (welcome_notification_id_.empty()) 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) welcome_notification_id_ = base::GenerateGUID(); 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!welcome_notification_id_.empty()) { 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<message_center::Notification> message_center_notification( 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new message_center::Notification( 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_center::NOTIFICATION_TYPE_BASE_FORMAT, 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) welcome_notification_id_, 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_TITLE), 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_BODY), 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::ResourceBundle::GetSharedInstance().GetImageNamed( 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDR_NOTIFICATION_WELCOME_ICON), 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_source, 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) notifier_id_, 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rich_notification_data, 2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch new NotificationCallbacks( 2790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch profile_, notifier_id_, welcome_notification_id_, 2800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch delegate_.get()))); 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (pop_up_request == POP_UP_HIDDEN) 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_center_notification->set_shown_as_popup(true); 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetMessageCenter()->AddNotification(message_center_notification.Pass()); 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartExpirationTimer(); 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::HideWelcomeNotification() { 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!welcome_notification_id_.empty() && 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetMessageCenter()->FindVisibleNotificationById( 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) welcome_notification_id_) != NULL) { 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetMessageCenter()->RemoveNotification(welcome_notification_id_, false); 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StopExpirationTimer(); 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool ExtensionWelcomeNotification::UserHasDismissedWelcomeNotification() const { 3000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // This was previously a syncable preference; now it's per-machine. 3010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Only the local pref will be written moving forward, but check for both so 3020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // users won't be double-toasted. 3030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool shown_synced = profile_->GetPrefs()->GetBoolean( 3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch prefs::kWelcomeNotificationDismissed); 3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool shown_local = profile_->GetPrefs()->GetBoolean( 3060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch prefs::kWelcomeNotificationDismissedLocal); 3070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return (shown_synced || shown_local); 3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 3090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::OnWelcomeNotificationDismissedChanged() { 3110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (UserHasDismissedWelcomeNotification()) { 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HideWelcomeNotification(); 3130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::StartExpirationTimer() { 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!expiration_timer_ && !IsWelcomeNotificationExpired()) { 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time expiration_timestamp = GetExpirationTimestamp(); 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (expiration_timestamp.is_null()) { 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetExpirationTimestampFromNow(); 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) expiration_timestamp = GetExpirationTimestamp(); 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!expiration_timestamp.is_null()); 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) expiration_timer_.reset( 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new base::OneShotTimer<ExtensionWelcomeNotification>()); 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) expiration_timer_->Start( 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) expiration_timestamp - delegate_->GetCurrentTime(), 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &ExtensionWelcomeNotification::ExpireWelcomeNotification); 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::StopExpirationTimer() { 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (expiration_timer_) { 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) expiration_timer_->Stop(); 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) expiration_timer_.reset(); 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::ExpireWelcomeNotification() { 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(IsWelcomeNotificationExpired()); 3430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch profile_->GetPrefs()->SetBoolean( 3440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch prefs::kWelcomeNotificationDismissedLocal, true); 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HideWelcomeNotification(); 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Time ExtensionWelcomeNotification::GetExpirationTimestamp() const { 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrefService* const pref_service = profile_->GetPrefs(); 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int64 expiration_timestamp = 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_service->GetInt64(prefs::kWelcomeNotificationExpirationTimestamp); 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (expiration_timestamp == 0) 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? base::Time() 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : base::Time::FromInternalValue(expiration_timestamp); 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionWelcomeNotification::SetExpirationTimestampFromNow() { 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrefService* const pref_service = profile_->GetPrefs(); 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_service->SetInt64( 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs::kWelcomeNotificationExpirationTimestamp, 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (delegate_->GetCurrentTime() + 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromDays(kRequestedShowTimeDays)).ToInternalValue()); 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ExtensionWelcomeNotification::IsWelcomeNotificationExpired() const { 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Time expiration_timestamp = GetExpirationTimestamp(); 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return !expiration_timestamp.is_null() && 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (expiration_timestamp <= delegate_->GetCurrentTime()); 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 370