Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc

Issue 22470006: Process incoming updates and deletes properly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: updates and deletes: CR feedback from DewittJ and Zea Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698