Index: chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc |
diff --git a/chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc b/chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc |
index cc0721360d244f0a8c7b30b45a72de3c524103bd..ef90d33499065977d8a6e074b76dd33904bd4ec8 100644 |
--- a/chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc |
+++ b/chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc |
@@ -122,7 +122,7 @@ syncer::SyncMergeResult ChromeNotifierService::MergeDataAndStartSyncing( |
found->Update(sync_data); |
// Tell the notification manager to update the notification. |
- Display(found); |
+ UpdateInMessageCenter(found); |
} |
} |
} |
@@ -177,15 +177,45 @@ syncer::SyncError ChromeNotifierService::ProcessSyncChanges( |
continue; |
} |
+ const std::string& key = new_notification->GetKey(); |
+ DCHECK_GT(key.length(), 0U); |
+ SyncedNotification* found = FindNotificationById(key); |
+ |
switch (change_type) { |
case syncer::SyncChange::ACTION_ADD: |
- // TODO(petewil): Update the notification if it already exists |
- // as opposed to adding it. |
+ if (found != NULL) { |
+ found->Update(sync_data); |
+ UpdateInMessageCenter(found); |
+ break; |
+ } |
Add(new_notification.Pass()); |
break; |
- // TODO(petewil): Implement code to add delete and update actions. |
+ |
+ case syncer::SyncChange::ACTION_UPDATE: |
+ if (found == NULL) { |
dewittj
2013/08/08 22:15:32
Unless I understand the protocol wrong, this could
Pete Williamson
2013/08/09 01:27:22
This seems like a fairly rare race condition, it s
|
+ Add(new_notification.Pass()); |
+ break; |
+ } |
+ // Update it in our store. |
+ found->Update(sync_data); |
+ // Tell the notification manager to update the notification. |
+ UpdateInMessageCenter(found); |
+ break; |
+ |
+ case syncer::SyncChange::ACTION_DELETE: |
+ if (found == NULL) { |
+ break; |
+ } |
+ // Remove it from our store. |
+ FreeNotificationById(key); |
+ // Remove it from the message center. |
+ UpdateInMessageCenter(new_notification.get()); |
+ // TODO(petewil): Do I need to remember that it was deleted in case the |
+ // add arrives after the delete? If so, how long do I need to remember? |
+ break; |
default: |
+ NOTREACHED(); |
break; |
} |
} |
@@ -224,13 +254,16 @@ scoped_ptr<SyncedNotification> |
<< specifics.coalesced_notification().has_read_state(); |
return scoped_ptr<SyncedNotification>(); |
} |
- |
- // TODO(petewil): Is this the right set? Should I add more? |
bool is_well_formed_unread_notification = |
(static_cast<SyncedNotification::ReadState>( |
specifics.coalesced_notification().read_state()) == |
SyncedNotification::kUnread && |
specifics.coalesced_notification().has_render_info()); |
+ bool is_well_formed_read_notification = |
+ (static_cast<SyncedNotification::ReadState>( |
+ specifics.coalesced_notification().read_state()) == |
+ SyncedNotification::kRead && |
+ specifics.coalesced_notification().has_render_info()); |
bool is_well_formed_dismissed_notification = |
(static_cast<SyncedNotification::ReadState>( |
specifics.coalesced_notification().read_state()) == |
@@ -238,12 +271,15 @@ scoped_ptr<SyncedNotification> |
// If the notification is poorly formed, return a null pointer. |
if (!is_well_formed_unread_notification && |
+ !is_well_formed_read_notification && |
!is_well_formed_dismissed_notification) { |
DVLOG(1) << "Synced Notification is not well formed." |
<< " unread well formed? " |
<< is_well_formed_unread_notification |
<< " dismissed well formed? " |
- << is_well_formed_dismissed_notification; |
+ << is_well_formed_dismissed_notification |
+ << " read well formed? " |
+ << is_well_formed_read_notification; |
return scoped_ptr<SyncedNotification>(); |
} |
@@ -273,6 +309,20 @@ SyncedNotification* ChromeNotifierService::FindNotificationById( |
return NULL; |
} |
+void ChromeNotifierService::FreeNotificationById( |
+ const std::string& notification_id) { |
+ for (std::vector<SyncedNotification*>::iterator it = |
+ notification_data_.begin(); |
+ it != notification_data_.end(); |
+ ++it) { |
+ SyncedNotification* notification = *it; |
+ if (notification_id == notification->GetKey()) { |
+ notification_data_.erase(it); |
+ return; |
+ } |
+ } |
+} |
+ |
void ChromeNotifierService::GetSyncedNotificationServices( |
std::vector<message_center::Notifier*>* notifiers) { |
// TODO(mukai|petewil): Check the profile's eligibility before adding the |
@@ -340,7 +390,7 @@ void ChromeNotifierService::Add(scoped_ptr<SyncedNotification> notification) { |
return; |
} |
- Display(notification_copy); |
+ UpdateInMessageCenter(notification_copy); |
} |
void ChromeNotifierService::AddForTest( |
@@ -348,12 +398,24 @@ void ChromeNotifierService::AddForTest( |
notification_data_.push_back(notification.release()); |
} |
-void ChromeNotifierService::Display(SyncedNotification* notification) { |
+void ChromeNotifierService::UpdateInMessageCenter( |
+ SyncedNotification* notification) { |
// If the feature is disabled, exit now. |
if (!notifier::ChromeNotifierServiceFactory::UseSyncedNotifications( |
CommandLine::ForCurrentProcess())) |
return; |
+ if (notification->GetReadState() == SyncedNotification::kUnread) { |
+ // If the message is unread, update it. |
+ Display(notification); |
+ } else { |
+ // If the message is read or deleted, dismiss it from the center. |
+ // We intentionally ignore errors if it is not in the center. |
+ notification_manager_->CancelById(notification->GetKey()); |
+ } |
+} |
+ |
+void ChromeNotifierService::Display(SyncedNotification* notification) { |
// Set up to fetch the bitmaps. |
notification->QueueBitmapFetchJobs(notification_manager_, |
this, |