1 // Copyright 2014 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 #ifndef CHROME_BROWSER_NOTIFICATIONS_EXTENSION_WELCOME_NOTIFICATION_H_ 6 #define CHROME_BROWSER_NOTIFICATIONS_EXTENSION_WELCOME_NOTIFICATION_H_ 7 8 #include <string> 9 10 #include "base/memory/scoped_ptr.h" 11 #include "base/prefs/pref_member.h" 12 #include "base/timer/timer.h" 13 #include "chrome/browser/prefs/pref_service_syncable_observer.h" 14 #include "components/keyed_service/core/keyed_service.h" 15 #include "ui/message_center/notifier_settings.h" 16 17 namespace base { 18 typedef Callback<void(void)> Closure; 19 } 20 21 namespace message_center { 22 class MessageCenter; 23 } 24 25 namespace tracked_objects { 26 class Location; 27 } 28 29 namespace user_prefs { 30 class PrefRegistrySyncable; 31 } 32 33 class Notification; 34 class Profile; 35 36 // ExtensionWelcomeNotification is a keyed service which manages showing and 37 // hiding a welcome notification for built-in components that show 38 // notifications. The Welcome Notification presumes network connectivity since 39 // it relies on synced preferences to work. This is generally fine since the 40 // current consumers on the welcome notification also presume network 41 // connectivity. 42 // 43 // This class expects to be created and called from the UI thread. 44 class ExtensionWelcomeNotification : public KeyedService, 45 public PrefServiceSyncableObserver { 46 public: 47 // Allows for overriding global calls. 48 class Delegate { 49 public: 50 Delegate() {} 51 virtual ~Delegate() {} 52 virtual message_center::MessageCenter* GetMessageCenter() = 0; 53 virtual base::Time GetCurrentTime() = 0; 54 virtual void PostTask( 55 const tracked_objects::Location& from_here, 56 const base::Closure& task) = 0; 57 private: 58 DISALLOW_COPY_AND_ASSIGN(Delegate); 59 }; 60 61 // Requested time from showing the welcome notification to expiration. 62 static const int kRequestedShowTimeDays; 63 64 // The extension Id associated with the Google Now extension. 65 static const char kChromeNowExtensionID[]; 66 67 virtual ~ExtensionWelcomeNotification(); 68 69 // To workaround the lack of delegating constructors prior to C++11, we use 70 // static Create methods. 71 // Creates an ExtensionWelcomeNotification with the default delegate. 72 static ExtensionWelcomeNotification* Create(Profile* const profile); 73 74 // Creates an ExtensionWelcomeNotification with the specified delegate. 75 static ExtensionWelcomeNotification* Create(Profile* const profile, 76 Delegate* const delegate); 77 78 // PrefServiceSyncableObserver 79 virtual void OnIsSyncingChanged() OVERRIDE; 80 81 // Adds in the welcome notification if required for components built 82 // into Chrome that show notifications like Chrome Now. 83 void ShowWelcomeNotificationIfNecessary(const Notification& notification); 84 85 // Handles Preference Registration for the Welcome Notification. 86 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs); 87 88 private: 89 enum PopUpRequest { POP_UP_HIDDEN = 0, POP_UP_SHOWN = 1, }; 90 91 ExtensionWelcomeNotification( 92 Profile* const profile, 93 ExtensionWelcomeNotification::Delegate* const delegate); 94 95 // Gets the message center from the delegate. 96 message_center::MessageCenter* GetMessageCenter() const; 97 98 // Unconditionally shows the welcome notification. 99 void ShowWelcomeNotification(const base::string16& display_source, 100 const PopUpRequest pop_up_request); 101 102 // Hides the welcome notification. 103 void HideWelcomeNotification(); 104 105 // Whether the notification has been dismissed. 106 bool UserHasDismissedWelcomeNotification() const; 107 108 // Called when the Welcome Notification Dismissed pref has been changed. 109 void OnWelcomeNotificationDismissedChanged(); 110 111 // Starts the welcome notification expiration timer. 112 void StartExpirationTimer(); 113 114 // Stops the welcome notification expiration timer. 115 void StopExpirationTimer(); 116 117 // Expires the welcome notification by hiding it and marking it dismissed. 118 void ExpireWelcomeNotification(); 119 120 // Gets the expiration timestamp or a null time is there is none. 121 base::Time GetExpirationTimestamp() const; 122 123 // Sets the expiration timestamp from now. 124 void SetExpirationTimestampFromNow(); 125 126 // True if the welcome notification has expired, false otherwise. 127 bool IsWelcomeNotificationExpired() const; 128 129 // Prefs listener for welcome_notification_dismissed. 130 BooleanPrefMember welcome_notification_dismissed_pref_; 131 132 // Prefs listener for welcome_notification_dismissed_local. 133 // Dismissal flag migrated from a synced pref to a local one. 134 BooleanPrefMember welcome_notification_dismissed_local_pref_; 135 136 // The notifier for the extension that we're listening for. 137 message_center::NotifierId notifier_id_; 138 139 // The profile which owns this object. 140 Profile* profile_; 141 142 // Notification ID of the Welcome Notification. 143 std::string welcome_notification_id_; 144 145 // If the preferences are still syncing, store the last notification here 146 // so we can replay ShowWelcomeNotificationIfNecessary once the sync finishes. 147 // Simplifying Assumption: The delayed notification has passed the 148 // extension ID check. This means we do not need to store all of the 149 // notifications that may also show a welcome notification. 150 scoped_ptr<Notification> delayed_notification_; 151 152 // If the welcome notification is shown, this timer tracks when to hide the 153 // welcome notification. 154 scoped_ptr<base::OneShotTimer<ExtensionWelcomeNotification> > 155 expiration_timer_; 156 157 // Delegate for Chrome global calls like base::Time::GetTime() for 158 // testability. 159 scoped_ptr<Delegate> delegate_; 160 161 DISALLOW_COPY_AND_ASSIGN(ExtensionWelcomeNotification); 162 }; 163 164 #endif // CHROME_BROWSER_NOTIFICATIONS_EXTENSION_WELCOME_NOTIFICATION_H_ 165