Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / drive / drive_notification_manager.cc
bloba3dcf3411ba641bdf9e2cf2c3995dffc534c07eb
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/drive/drive_notification_manager.h"
7 #include "base/metrics/histogram.h"
8 #include "chrome/browser/drive/drive_notification_observer.h"
9 #include "chrome/browser/invalidation/invalidation_service.h"
10 #include "chrome/browser/invalidation/invalidation_service_factory.h"
11 #include "google/cacheinvalidation/types.pb.h"
12 #include "sync/notifier/object_id_invalidation_map.h"
14 namespace drive {
16 namespace {
18 // The polling interval time is used when XMPP is disabled.
19 const int kFastPollingIntervalInSecs = 60;
21 // The polling interval time is used when XMPP is enabled. Theoretically
22 // polling should be unnecessary if XMPP is enabled, but just in case.
23 const int kSlowPollingIntervalInSecs = 300;
25 // The sync invalidation object ID for Google Drive.
26 const char kDriveInvalidationObjectId[] = "CHANGELOG";
28 } // namespace
30 DriveNotificationManager::DriveNotificationManager(
31 invalidation::InvalidationService* invalidation_service)
32 : invalidation_service_(invalidation_service),
33 push_notification_registered_(false),
34 push_notification_enabled_(false),
35 observers_notified_(false),
36 polling_timer_(true /* retain_user_task */, false /* is_repeating */),
37 weak_ptr_factory_(this) {
38 DCHECK(invalidation_service_);
39 RegisterDriveNotifications();
40 RestartPollingTimer();
43 DriveNotificationManager::~DriveNotificationManager() {}
45 void DriveNotificationManager::Shutdown() {
46 // Unregister for Drive notifications.
47 if (!invalidation_service_ || !push_notification_registered_)
48 return;
50 // We unregister the handler without updating unregistering our IDs on
51 // purpose. See the class comment on the InvalidationService interface for
52 // more information.
53 invalidation_service_->UnregisterInvalidationHandler(this);
54 invalidation_service_ = NULL;
57 void DriveNotificationManager::OnInvalidatorStateChange(
58 syncer::InvalidatorState state) {
59 push_notification_enabled_ = (state == syncer::INVALIDATIONS_ENABLED);
60 if (push_notification_enabled_) {
61 DVLOG(1) << "XMPP Notifications enabled";
62 } else {
63 DVLOG(1) << "XMPP Notifications disabled (state=" << state << ")";
65 FOR_EACH_OBSERVER(DriveNotificationObserver, observers_,
66 OnPushNotificationEnabled(push_notification_enabled_));
69 void DriveNotificationManager::OnIncomingInvalidation(
70 const syncer::ObjectIdInvalidationMap& invalidation_map) {
71 DVLOG(2) << "XMPP Drive Notification Received";
72 syncer::ObjectIdSet ids = invalidation_map.GetObjectIds();
73 DCHECK_EQ(1U, ids.size());
74 const invalidation::ObjectId object_id(
75 ipc::invalidation::ObjectSource::COSMO_CHANGELOG,
76 kDriveInvalidationObjectId);
77 DCHECK_EQ(1U, ids.count(object_id));
79 // This effectively disables 'local acks'. It tells the invalidations system
80 // to not bother saving invalidations across restarts for us.
81 // See crbug.com/320878.
82 invalidation_map.AcknowledgeAll();
83 NotifyObserversToUpdate(NOTIFICATION_XMPP);
86 void DriveNotificationManager::AddObserver(
87 DriveNotificationObserver* observer) {
88 observers_.AddObserver(observer);
91 void DriveNotificationManager::RemoveObserver(
92 DriveNotificationObserver* observer) {
93 observers_.RemoveObserver(observer);
96 void DriveNotificationManager::RestartPollingTimer() {
97 const int interval_secs = (push_notification_enabled_ ?
98 kSlowPollingIntervalInSecs :
99 kFastPollingIntervalInSecs);
100 polling_timer_.Stop();
101 polling_timer_.Start(
102 FROM_HERE,
103 base::TimeDelta::FromSeconds(interval_secs),
104 base::Bind(&DriveNotificationManager::NotifyObserversToUpdate,
105 weak_ptr_factory_.GetWeakPtr(),
106 NOTIFICATION_POLLING));
109 void DriveNotificationManager::NotifyObserversToUpdate(
110 NotificationSource source) {
111 DVLOG(1) << "Notifying observers: " << NotificationSourceToString(source);
112 FOR_EACH_OBSERVER(DriveNotificationObserver, observers_,
113 OnNotificationReceived());
114 if (!observers_notified_) {
115 UMA_HISTOGRAM_BOOLEAN("Drive.PushNotificationInitiallyEnabled",
116 push_notification_enabled_);
118 observers_notified_ = true;
120 // Note that polling_timer_ is not a repeating timer. Restarting manually
121 // here is better as XMPP may be received right before the polling timer is
122 // fired (i.e. we don't notify observers twice in a row).
123 RestartPollingTimer();
126 void DriveNotificationManager::RegisterDriveNotifications() {
127 DCHECK(!push_notification_enabled_);
129 if (!invalidation_service_)
130 return;
132 invalidation_service_->RegisterInvalidationHandler(this);
133 syncer::ObjectIdSet ids;
134 ids.insert(invalidation::ObjectId(
135 ipc::invalidation::ObjectSource::COSMO_CHANGELOG,
136 kDriveInvalidationObjectId));
137 invalidation_service_->UpdateRegisteredInvalidationIds(this, ids);
138 push_notification_registered_ = true;
139 OnInvalidatorStateChange(invalidation_service_->GetInvalidatorState());
141 UMA_HISTOGRAM_BOOLEAN("Drive.PushNotificationRegistered",
142 push_notification_registered_);
145 // static
146 std::string DriveNotificationManager::NotificationSourceToString(
147 NotificationSource source) {
148 switch (source) {
149 case NOTIFICATION_XMPP:
150 return "NOTIFICATION_XMPP";
151 case NOTIFICATION_POLLING:
152 return "NOTIFICATION_POLLING";
155 NOTREACHED();
156 return "";
159 } // namespace drive