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