OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // The ChromeNotifierService works together with sync to maintain the state of | 5 // The ChromeNotifierService works together with sync to maintain the state of |
6 // user notifications, which can then be presented in the notification center, | 6 // user notifications, which can then be presented in the notification center, |
7 // via the Notification UI Manager. | 7 // via the Notification UI Manager. |
8 | 8 |
9 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h" | 9 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h" |
10 | 10 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 // If local state changed, notify Notification UI Manager. | 120 // If local state changed, notify Notification UI Manager. |
121 } | 121 } |
122 // For any other conflict besides read state, treat it as an update. | 122 // For any other conflict besides read state, treat it as an update. |
123 } else { | 123 } else { |
124 // If different, just replace the local with the remote. | 124 // If different, just replace the local with the remote. |
125 // TODO(petewil): Someday we may allow changes from the client to | 125 // TODO(petewil): Someday we may allow changes from the client to |
126 // flow upwards, when we do, we will need better merge resolution. | 126 // flow upwards, when we do, we will need better merge resolution. |
127 found->Update(sync_data); | 127 found->Update(sync_data); |
128 | 128 |
129 // Tell the notification manager to update the notification. | 129 // Tell the notification manager to update the notification. |
130 Display(found); | 130 UpdateInMessageCenter(found); |
131 } | 131 } |
132 } | 132 } |
133 } | 133 } |
134 | 134 |
135 // Send up the changes that were made locally. | 135 // Send up the changes that were made locally. |
136 if (new_changes.size() > 0) { | 136 if (new_changes.size() > 0) { |
137 merge_result.set_error(sync_processor_->ProcessSyncChanges( | 137 merge_result.set_error(sync_processor_->ProcessSyncChanges( |
138 FROM_HERE, new_changes)); | 138 FROM_HERE, new_changes)); |
139 } | 139 } |
140 | 140 |
141 return merge_result; | 141 return merge_result; |
142 } | 142 } |
143 | 143 |
144 void ChromeNotifierService::StopSyncing(syncer::ModelType type) { | 144 void ChromeNotifierService::StopSyncing(syncer::ModelType type) { |
145 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, type); | 145 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, type); |
146 // TODO(petewil): implement | 146 // TODO(petewil): implement |
147 } | 147 } |
148 | 148 |
149 syncer::SyncDataList ChromeNotifierService::GetAllSyncData( | 149 syncer::SyncDataList ChromeNotifierService::GetAllSyncData( |
150 syncer::ModelType type) const { | 150 syncer::ModelType type) const { |
151 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, type); | 151 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, type); |
152 syncer::SyncDataList sync_data; | 152 syncer::SyncDataList sync_data; |
153 | 153 |
154 // Copy our native format data into a SyncDataList format. | 154 // Copy our native format data into a SyncDataList format. |
155 for (std::vector<SyncedNotification*>::const_iterator it = | 155 ScopedVector<SyncedNotification>::const_iterator it = |
156 notification_data_.begin(); | 156 notification_data_.begin(); |
157 it != notification_data_.end(); | 157 for (; it != notification_data_.end(); ++it) { |
158 ++it) { | |
159 sync_data.push_back(CreateSyncDataFromNotification(**it)); | 158 sync_data.push_back(CreateSyncDataFromNotification(**it)); |
160 } | 159 } |
161 | 160 |
162 return sync_data; | 161 return sync_data; |
163 } | 162 } |
164 | 163 |
165 // This method is called when there is an incoming sync change from the server. | 164 // This method is called when there is an incoming sync change from the server. |
166 syncer::SyncError ChromeNotifierService::ProcessSyncChanges( | 165 syncer::SyncError ChromeNotifierService::ProcessSyncChanges( |
167 const tracked_objects::Location& from_here, | 166 const tracked_objects::Location& from_here, |
168 const syncer::SyncChangeList& change_list) { | 167 const syncer::SyncChangeList& change_list) { |
169 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 168 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
170 syncer::SyncError error; | 169 syncer::SyncError error; |
171 | 170 |
172 for (syncer::SyncChangeList::const_iterator it = change_list.begin(); | 171 for (syncer::SyncChangeList::const_iterator it = change_list.begin(); |
173 it != change_list.end(); ++it) { | 172 it != change_list.end(); ++it) { |
174 syncer::SyncData sync_data = it->sync_data(); | 173 syncer::SyncData sync_data = it->sync_data(); |
175 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, sync_data.GetDataType()); | 174 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, sync_data.GetDataType()); |
176 syncer::SyncChange::SyncChangeType change_type = it->change_type(); | 175 syncer::SyncChange::SyncChangeType change_type = it->change_type(); |
177 | 176 |
178 scoped_ptr<SyncedNotification> new_notification( | 177 scoped_ptr<SyncedNotification> new_notification( |
179 CreateNotificationFromSyncData(sync_data)); | 178 CreateNotificationFromSyncData(sync_data)); |
180 if (!new_notification.get()) { | 179 if (!new_notification.get()) { |
181 NOTREACHED() << "Failed to read notification."; | 180 NOTREACHED() << "Failed to read notification."; |
182 continue; | 181 continue; |
183 } | 182 } |
184 | 183 |
| 184 const std::string& key = new_notification->GetKey(); |
| 185 DCHECK_GT(key.length(), 0U); |
| 186 SyncedNotification* found = FindNotificationById(key); |
| 187 |
185 switch (change_type) { | 188 switch (change_type) { |
186 case syncer::SyncChange::ACTION_ADD: | 189 case syncer::SyncChange::ACTION_ADD: |
187 // TODO(petewil): Update the notification if it already exists | 190 // Intentional fall through, cases are identical. |
188 // as opposed to adding it. | 191 case syncer::SyncChange::ACTION_UPDATE: |
189 Add(new_notification.Pass()); | 192 if (found == NULL) { |
| 193 Add(new_notification.Pass()); |
| 194 break; |
| 195 } |
| 196 // Update it in our store. |
| 197 found->Update(sync_data); |
| 198 // Tell the notification manager to update the notification. |
| 199 UpdateInMessageCenter(found); |
190 break; | 200 break; |
191 // TODO(petewil): Implement code to add delete and update actions. | 201 |
| 202 case syncer::SyncChange::ACTION_DELETE: |
| 203 if (found == NULL) { |
| 204 break; |
| 205 } |
| 206 // Remove it from our store. |
| 207 FreeNotificationById(key); |
| 208 // Remove it from the message center. |
| 209 UpdateInMessageCenter(new_notification.get()); |
| 210 // TODO(petewil): Do I need to remember that it was deleted in case the |
| 211 // add arrives after the delete? If so, how long do I need to remember? |
| 212 break; |
192 | 213 |
193 default: | 214 default: |
| 215 NOTREACHED(); |
194 break; | 216 break; |
195 } | 217 } |
196 } | 218 } |
197 | 219 |
198 return error; | 220 return error; |
199 } | 221 } |
200 | 222 |
201 // Support functions for data type conversion. | 223 // Support functions for data type conversion. |
202 | 224 |
203 // Static method. Get to the sync data in our internal format. | 225 // Static method. Get to the sync data in our internal format. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 return notification.Pass(); | 288 return notification.Pass(); |
267 } | 289 } |
268 | 290 |
269 // This returns a pointer into a vector that we own. Caller must not free it. | 291 // This returns a pointer into a vector that we own. Caller must not free it. |
270 // Returns NULL if no match is found. | 292 // Returns NULL if no match is found. |
271 SyncedNotification* ChromeNotifierService::FindNotificationById( | 293 SyncedNotification* ChromeNotifierService::FindNotificationById( |
272 const std::string& notification_id) { | 294 const std::string& notification_id) { |
273 // TODO(petewil): We can make a performance trade off here. | 295 // TODO(petewil): We can make a performance trade off here. |
274 // While the vector has good locality of reference, a map has faster lookup. | 296 // While the vector has good locality of reference, a map has faster lookup. |
275 // Based on how big we expect this to get, maybe change this to a map. | 297 // Based on how big we expect this to get, maybe change this to a map. |
276 for (std::vector<SyncedNotification*>::const_iterator it = | 298 ScopedVector<SyncedNotification>::const_iterator it = |
277 notification_data_.begin(); | 299 notification_data_.begin(); |
278 it != notification_data_.end(); | 300 for (; it != notification_data_.end(); ++it) { |
279 ++it) { | |
280 SyncedNotification* notification = *it; | 301 SyncedNotification* notification = *it; |
281 if (notification_id == notification->GetKey()) | 302 if (notification_id == notification->GetKey()) |
282 return *it; | 303 return *it; |
283 } | 304 } |
284 | 305 |
285 return NULL; | 306 return NULL; |
286 } | 307 } |
287 | 308 |
| 309 void ChromeNotifierService::FreeNotificationById( |
| 310 const std::string& notification_id) { |
| 311 ScopedVector<SyncedNotification>::iterator it = notification_data_.begin(); |
| 312 for (; it != notification_data_.end(); ++it) { |
| 313 SyncedNotification* notification = *it; |
| 314 if (notification_id == notification->GetKey()) { |
| 315 notification_data_.erase(it); |
| 316 return; |
| 317 } |
| 318 } |
| 319 } |
| 320 |
288 void ChromeNotifierService::GetSyncedNotificationServices( | 321 void ChromeNotifierService::GetSyncedNotificationServices( |
289 std::vector<message_center::Notifier*>* notifiers) { | 322 std::vector<message_center::Notifier*>* notifiers) { |
290 // TODO(mukai|petewil): Check the profile's eligibility before adding the | 323 // TODO(mukai|petewil): Check the profile's eligibility before adding the |
291 // sample app. | 324 // sample app. |
292 | 325 |
293 // TODO(petewil): Really obtain the list of synced notification sending | 326 // TODO(petewil): Really obtain the list of synced notification sending |
294 // services from the server and create the list of ids here. Until then, we | 327 // services from the server and create the list of ids here. Until then, we |
295 // are hardcoding the service names. Once that is done, remove this | 328 // are hardcoding the service names. Once that is done, remove this |
296 // hardcoding. | 329 // hardcoding. |
297 // crbug.com/248337 | 330 // crbug.com/248337 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 | 378 |
346 // If the user is not interested in this type of notification, ignore it. | 379 // If the user is not interested in this type of notification, ignore it. |
347 std::vector<std::string>::iterator iter = | 380 std::vector<std::string>::iterator iter = |
348 find(enabled_sending_services_.begin(), | 381 find(enabled_sending_services_.begin(), |
349 enabled_sending_services_.end(), | 382 enabled_sending_services_.end(), |
350 notification_copy->GetSendingServiceId()); | 383 notification_copy->GetSendingServiceId()); |
351 if (iter == enabled_sending_services_.end()) { | 384 if (iter == enabled_sending_services_.end()) { |
352 return; | 385 return; |
353 } | 386 } |
354 | 387 |
355 Display(notification_copy); | 388 UpdateInMessageCenter(notification_copy); |
356 } | 389 } |
357 | 390 |
358 void ChromeNotifierService::AddForTest( | 391 void ChromeNotifierService::AddForTest( |
359 scoped_ptr<notifier::SyncedNotification> notification) { | 392 scoped_ptr<notifier::SyncedNotification> notification) { |
360 notification_data_.push_back(notification.release()); | 393 notification_data_.push_back(notification.release()); |
361 } | 394 } |
362 | 395 |
363 void ChromeNotifierService::Display(SyncedNotification* notification) { | 396 void ChromeNotifierService::UpdateInMessageCenter( |
| 397 SyncedNotification* notification) { |
364 // If the feature is disabled, exit now. | 398 // If the feature is disabled, exit now. |
365 if (!notifier::ChromeNotifierServiceFactory::UseSyncedNotifications( | 399 if (!notifier::ChromeNotifierServiceFactory::UseSyncedNotifications( |
366 CommandLine::ForCurrentProcess())) | 400 CommandLine::ForCurrentProcess())) |
367 return; | 401 return; |
368 | 402 |
369 notification->LogNotification(); | 403 notification->LogNotification(); |
370 | 404 |
| 405 if (notification->GetReadState() == SyncedNotification::kUnread) { |
| 406 // If the message is unread, update it. |
| 407 Display(notification); |
| 408 } else { |
| 409 // If the message is read or deleted, dismiss it from the center. |
| 410 // We intentionally ignore errors if it is not in the center. |
| 411 notification_manager_->CancelById(notification->GetKey()); |
| 412 } |
| 413 } |
| 414 |
| 415 void ChromeNotifierService::Display(SyncedNotification* notification) { |
371 // Set up to fetch the bitmaps. | 416 // Set up to fetch the bitmaps. |
372 notification->QueueBitmapFetchJobs(notification_manager_, | 417 notification->QueueBitmapFetchJobs(notification_manager_, |
373 this, | 418 this, |
374 profile_); | 419 profile_); |
375 | 420 |
376 // Our tests cannot use the network for reliability reasons. | 421 // Our tests cannot use the network for reliability reasons. |
377 if (avoid_bitmap_fetching_for_test_) { | 422 if (avoid_bitmap_fetching_for_test_) { |
378 return; | 423 return; |
379 } | 424 } |
380 | 425 |
(...skipping 17 matching lines...) Expand all Loading... |
398 // Remove the notifier_id if it is disabled and present. | 443 // Remove the notifier_id if it is disabled and present. |
399 } else if (iter != enabled_sending_services_.end() && !enabled) { | 444 } else if (iter != enabled_sending_services_.end() && !enabled) { |
400 enabled_sending_services_.erase(iter); | 445 enabled_sending_services_.erase(iter); |
401 } | 446 } |
402 | 447 |
403 // Otherwise, nothing to do, we can exit. | 448 // Otherwise, nothing to do, we can exit. |
404 return; | 449 return; |
405 } | 450 } |
406 | 451 |
407 } // namespace notifier | 452 } // namespace notifier |
OLD | NEW |