blob: 356448fbd1dd1eabbd87edb8a5b6763d4bd38c31 [file] [log] [blame]
// 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 <string>
#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<syncer::SyncChangeProcessor> sync_processor,
scoped_ptr<syncer::SyncErrorFactory> 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<SyncedNotification> 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<message_center::Notifier*>* 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<notifier::SyncedNotification> 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<notifier::SyncedNotification> 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<std::string>* ids_field);
// Called when the string list pref has been changed.
void OnInitializedSendingServiceListPrefChanged(
std::set<std::string>* 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<std::string> 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<syncer::SyncChangeProcessor> sync_processor_;
std::set<std::string> enabled_sending_services_;
std::set<std::string> 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<notifier::SyncedNotification> 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_