// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_NOTIFICATIONS_SYNC_NOTIFIER_CHROME_NOTIFIER_SERVICE_H_ #define CHROME_BROWSER_NOTIFICATIONS_SYNC_NOTIFIER_CHROME_NOTIFIER_SERVICE_H_ #include #include "base/basictypes.h" #include "base/memory/scoped_vector.h" #include "base/prefs/pref_member.h" #include "base/threading/non_thread_safe.h" #include "chrome/browser/notifications/sync_notifier/synced_notification.h" #include "components/browser_context_keyed_service/browser_context_keyed_service.h" #include "sync/api/syncable_service.h" class NotificationUIManager; class Profile; namespace user_prefs { class PrefRegistrySyncable; } namespace message_center { struct Notifier; } namespace notifier { extern const char kFirstSyncedNotificationServiceId[]; extern const char kServiceEnabledOnce[]; extern const char kSyncedNotificationFirstRun[]; enum ChromeNotifierServiceActionType { CHROME_NOTIFIER_SERVICE_ACTION_UNKNOWN, CHROME_NOTIFIER_SERVICE_ACTION_FIRST_SERVICE_ENABLED, CHROME_NOTIFIER_SERVICE_ACTION_FIRST_SERVICE_DISABLED, // NOTE: Add new action types only immediately above this line. Also, // make sure the enum list in tools/histogram/histograms.xml is // updated with any change in here. CHROME_NOTIFIER_SERVICE_ACTION_COUNT }; // The ChromeNotifierService holds notifications which represent the state of // delivered notifications for chrome. These are obtained from the sync service // and kept up to date. class ChromeNotifierService : public syncer::SyncableService, public BrowserContextKeyedService { public: ChromeNotifierService(Profile* profile, NotificationUIManager* manager); virtual ~ChromeNotifierService(); // Methods from BrowserContextKeyedService. virtual void Shutdown() OVERRIDE; // syncer::SyncableService implementation. virtual syncer::SyncMergeResult MergeDataAndStartSyncing( syncer::ModelType type, const syncer::SyncDataList& initial_sync_data, scoped_ptr sync_processor, scoped_ptr error_handler) OVERRIDE; virtual void StopSyncing(syncer::ModelType type) OVERRIDE; virtual syncer::SyncDataList GetAllSyncData( syncer::ModelType type) const OVERRIDE; virtual syncer::SyncError ProcessSyncChanges( const tracked_objects::Location& from_here, const syncer::SyncChangeList& change_list) OVERRIDE; // Convert from internal representation to SyncData representation. static syncer::SyncData CreateSyncDataFromNotification( const SyncedNotification& notification); // Convert from SyncData representation to internal representation. static scoped_ptr CreateNotificationFromSyncData( const syncer::SyncData& sync_data); // Get a pointer to a notification. ChromeNotifierService owns this pointer. virtual notifier::SyncedNotification* FindNotificationById( const std::string& notification_id); // Get the list of synced notification services and fill their meta data to // |notifiers|. void GetSyncedNotificationServices( std::vector* notifiers); // Called when we dismiss a notification. This is virtual so that test // subclasses can override it. virtual void MarkNotificationAsRead(const std::string& id); // Called when a notier is enabled or disabled. void OnSyncedNotificationServiceEnabled( const std::string& notifier_id, bool enabled); // Register the preferences we use to save state. static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); Profile* profile() const { return profile_; } // Functions for test. void AddForTest(scoped_ptr notification); // If we allow the tests to do bitmap fetching, they will attempt to fetch // a URL from the web, which will fail. We can already test the majority // of what we want without also trying to fetch bitmaps. Other tests will // cover bitmap fetching. static void set_avoid_bitmap_fetching_for_test(bool avoid) { avoid_bitmap_fetching_for_test_ = avoid; } // Initialize the preferences we use for the ChromeNotificationService. void InitializePrefs(); private: // Add a notification to our list. This takes ownership of the pointer. void Add(scoped_ptr notification); // Display this notification in the notification center, or remove it. void UpdateInMessageCenter(notifier::SyncedNotification* notification); // Display a notification in the notification center (eventually). void Display(notifier::SyncedNotification* notification); // Remove a notification from our store. void FreeNotificationById(const std::string& notification_id); // When a service it turned on, scan our cache for any notifications // for that service, and display them if they are unread. void DisplayUnreadNotificationsFromSource(const std::string& notifier_id); // When a service it turned off, scan our cache for any notifications // for that service, and remove them from the message center. void RemoveUnreadNotificationsFromSource(const std::string& notifier_id); // When we turn a sending service on or off, collect statistics about // how often users turn it on or off. void CollectPerServiceEnablingStatistics(const std::string& notifier_id, bool enabled); // When we start up or hear of a new service, turn it on by default. void AddNewSendingServices(); // Called when the string list pref has been changed. void OnEnabledSendingServiceListPrefChanged(std::set* ids_field); // Called when the string list pref has been changed. void OnInitializedSendingServiceListPrefChanged( std::set* ids_field); // Called when our "first run" boolean pref has been changed. void OnSyncedNotificationFirstRunBooleanPrefChanged(bool* new_value); // Convert our internal set of strings to a list value. // The second param is an outparam which the function fills in. void BuildServiceListValueInplace( std::set services, base::ListValue* list_value); // Preferences for storing which SyncedNotificationServices are enabled StringListPrefMember enabled_sending_services_prefs_; StringListPrefMember initialized_sending_services_prefs_; // Preferences to avoid toasting on SyncedNotification first run. BooleanPrefMember synced_notification_first_run_prefs_; // Back pointer to the owning profile. Profile* const profile_; NotificationUIManager* const notification_manager_; scoped_ptr sync_processor_; std::set enabled_sending_services_; std::set initialized_sending_services_; bool synced_notification_first_run_; static bool avoid_bitmap_fetching_for_test_; // TODO(petewil): Consider whether a map would better suit our data. // If there are many entries, lookup time may trump locality of reference. ScopedVector notification_data_; friend class ChromeNotifierServiceTest; FRIEND_TEST_ALL_PREFIXES(ChromeNotifierServiceTest, ServiceEnabledTest); FRIEND_TEST_ALL_PREFIXES(ChromeNotifierServiceTest, AddNewSendingServicesTest); FRIEND_TEST_ALL_PREFIXES(ChromeNotifierServiceTest, GetEnabledSendingServicesFromPreferencesTest); DISALLOW_COPY_AND_ASSIGN(ChromeNotifierService); }; } // namespace notifier #endif // CHROME_BROWSER_NOTIFICATIONS_SYNC_NOTIFIER_CHROME_NOTIFIER_SERVICE_H_