| 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 #include "chrome/browser/extensions/app_notification_manager.h" | 5 #include "chrome/browser/extensions/app_notification_manager.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/perftimer.h" | 12 #include "base/perftimer.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/time.h" | 14 #include "base/time.h" |
| 15 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
| 16 #include "chrome/common/chrome_notification_types.h" | 16 #include "chrome/common/chrome_notification_types.h" |
| 17 #include "chrome/common/extensions/extension.h" | 17 #include "chrome/common/extensions/extension.h" |
| 18 #include "content/public/browser/notification_service.h" | 18 #include "content/public/browser/notification_service.h" |
| 19 #include "sync/api/sync_error_factory.h" | 19 #include "sync/api/sync_error_factory.h" |
| 20 #include "sync/protocol/app_notification_specifics.pb.h" | 20 #include "sync/protocol/app_notification_specifics.pb.h" |
| 21 #include "sync/protocol/sync.pb.h" | 21 #include "sync/protocol/sync.pb.h" |
| 22 | 22 |
| 23 using content::BrowserThread; | 23 using content::BrowserThread; |
| 24 | 24 |
| 25 typedef std::map<std::string, SyncData> SyncDataMap; | 25 typedef std::map<std::string, csync::SyncData> SyncDataMap; |
| 26 | 26 |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 class GuidComparator | 29 class GuidComparator |
| 30 : public std::binary_function<linked_ptr<AppNotification>, | 30 : public std::binary_function<linked_ptr<AppNotification>, |
| 31 std::string, | 31 std::string, |
| 32 bool> { | 32 bool> { |
| 33 public: | 33 public: |
| 34 bool operator() (linked_ptr<AppNotification> notif, | 34 bool operator() (linked_ptr<AppNotification> notif, |
| 35 const std::string& guid) const { | 35 const std::string& guid) const { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 47 void RemoveByGuid(AppNotificationList* list, const std::string& guid) { | 47 void RemoveByGuid(AppNotificationList* list, const std::string& guid) { |
| 48 if (!list) | 48 if (!list) |
| 49 return; | 49 return; |
| 50 | 50 |
| 51 AppNotificationList::iterator iter = std::find_if( | 51 AppNotificationList::iterator iter = std::find_if( |
| 52 list->begin(), list->end(), std::bind2nd(GuidComparator(), guid)); | 52 list->begin(), list->end(), std::bind2nd(GuidComparator(), guid)); |
| 53 if (iter != list->end()) | 53 if (iter != list->end()) |
| 54 list->erase(iter); | 54 list->erase(iter); |
| 55 } | 55 } |
| 56 | 56 |
| 57 void PopulateGuidToSyncDataMap(const SyncDataList& sync_data, | 57 void PopulateGuidToSyncDataMap(const csync::SyncDataList& sync_data, |
| 58 SyncDataMap* data_map) { | 58 SyncDataMap* data_map) { |
| 59 for (SyncDataList::const_iterator iter = sync_data.begin(); | 59 for (csync::SyncDataList::const_iterator iter = sync_data.begin(); |
| 60 iter != sync_data.end(); ++iter) { | 60 iter != sync_data.end(); ++iter) { |
| 61 (*data_map)[iter->GetSpecifics().app_notification().guid()] = *iter; | 61 (*data_map)[iter->GetSpecifics().app_notification().guid()] = *iter; |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 } // namespace | 64 } // namespace |
| 65 | 65 |
| 66 const unsigned int AppNotificationManager::kMaxNotificationPerApp = 5; | 66 const unsigned int AppNotificationManager::kMaxNotificationPerApp = 5; |
| 67 | 67 |
| 68 AppNotificationManager::AppNotificationManager(Profile* profile) | 68 AppNotificationManager::AppNotificationManager(Profile* profile) |
| 69 : profile_(profile), | 69 : profile_(profile), |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 } | 171 } |
| 172 | 172 |
| 173 void AppNotificationManager::Observe( | 173 void AppNotificationManager::Observe( |
| 174 int type, | 174 int type, |
| 175 const content::NotificationSource& source, | 175 const content::NotificationSource& source, |
| 176 const content::NotificationDetails& details) { | 176 const content::NotificationDetails& details) { |
| 177 CHECK(type == chrome::NOTIFICATION_EXTENSION_UNINSTALLED); | 177 CHECK(type == chrome::NOTIFICATION_EXTENSION_UNINSTALLED); |
| 178 ClearAll(*content::Details<const std::string>(details).ptr()); | 178 ClearAll(*content::Details<const std::string>(details).ptr()); |
| 179 } | 179 } |
| 180 | 180 |
| 181 SyncDataList AppNotificationManager::GetAllSyncData( | 181 csync::SyncDataList AppNotificationManager::GetAllSyncData( |
| 182 syncable::ModelType type) const { | 182 syncable::ModelType type) const { |
| 183 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 183 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 184 DCHECK(loaded()); | 184 DCHECK(loaded()); |
| 185 DCHECK_EQ(syncable::APP_NOTIFICATIONS, type); | 185 DCHECK_EQ(syncable::APP_NOTIFICATIONS, type); |
| 186 SyncDataList data; | 186 csync::SyncDataList data; |
| 187 for (NotificationMap::const_iterator iter = notifications_->begin(); | 187 for (NotificationMap::const_iterator iter = notifications_->begin(); |
| 188 iter != notifications_->end(); ++iter) { | 188 iter != notifications_->end(); ++iter) { |
| 189 | 189 |
| 190 // Skip local notifications since they should not be synced. | 190 // Skip local notifications since they should not be synced. |
| 191 const AppNotificationList list = (*iter).second; | 191 const AppNotificationList list = (*iter).second; |
| 192 for (AppNotificationList::const_iterator list_iter = list.begin(); | 192 for (AppNotificationList::const_iterator list_iter = list.begin(); |
| 193 list_iter != list.end(); ++list_iter) { | 193 list_iter != list.end(); ++list_iter) { |
| 194 const AppNotification* notification = (*list_iter).get(); | 194 const AppNotification* notification = (*list_iter).get(); |
| 195 if (notification->is_local()) { | 195 if (notification->is_local()) { |
| 196 continue; | 196 continue; |
| 197 } | 197 } |
| 198 data.push_back(CreateSyncDataFromNotification(*notification)); | 198 data.push_back(CreateSyncDataFromNotification(*notification)); |
| 199 } | 199 } |
| 200 } | 200 } |
| 201 | 201 |
| 202 return data; | 202 return data; |
| 203 } | 203 } |
| 204 | 204 |
| 205 SyncError AppNotificationManager::ProcessSyncChanges( | 205 csync::SyncError AppNotificationManager::ProcessSyncChanges( |
| 206 const tracked_objects::Location& from_here, | 206 const tracked_objects::Location& from_here, |
| 207 const SyncChangeList& change_list) { | 207 const csync::SyncChangeList& change_list) { |
| 208 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 208 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 209 DCHECK(loaded()); | 209 DCHECK(loaded()); |
| 210 if (!models_associated_) { | 210 if (!models_associated_) { |
| 211 return sync_error_factory_->CreateAndUploadError( | 211 return sync_error_factory_->CreateAndUploadError( |
| 212 FROM_HERE, | 212 FROM_HERE, |
| 213 "Models not yet associated."); | 213 "Models not yet associated."); |
| 214 } | 214 } |
| 215 | 215 |
| 216 AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 216 AutoReset<bool> processing_changes(&processing_syncer_changes_, true); |
| 217 | 217 |
| 218 SyncError error; | 218 csync::SyncError error; |
| 219 for (SyncChangeList::const_iterator iter = change_list.begin(); | 219 for (csync::SyncChangeList::const_iterator iter = change_list.begin(); |
| 220 iter != change_list.end(); ++iter) { | 220 iter != change_list.end(); ++iter) { |
| 221 SyncData sync_data = iter->sync_data(); | 221 csync::SyncData sync_data = iter->sync_data(); |
| 222 DCHECK_EQ(syncable::APP_NOTIFICATIONS, sync_data.GetDataType()); | 222 DCHECK_EQ(syncable::APP_NOTIFICATIONS, sync_data.GetDataType()); |
| 223 SyncChange::SyncChangeType change_type = iter->change_type(); | 223 csync::SyncChange::SyncChangeType change_type = iter->change_type(); |
| 224 | 224 |
| 225 scoped_ptr<AppNotification> new_notif(CreateNotificationFromSyncData( | 225 scoped_ptr<AppNotification> new_notif(CreateNotificationFromSyncData( |
| 226 sync_data)); | 226 sync_data)); |
| 227 if (!new_notif.get()) { | 227 if (!new_notif.get()) { |
| 228 NOTREACHED() << "Failed to read notification."; | 228 NOTREACHED() << "Failed to read notification."; |
| 229 continue; | 229 continue; |
| 230 } | 230 } |
| 231 const AppNotification* existing_notif = GetNotification( | 231 const AppNotification* existing_notif = GetNotification( |
| 232 new_notif->extension_id(), new_notif->guid()); | 232 new_notif->extension_id(), new_notif->guid()); |
| 233 if (existing_notif && existing_notif->is_local()) { | 233 if (existing_notif && existing_notif->is_local()) { |
| 234 NOTREACHED() << "Matched with notification marked as local"; | 234 NOTREACHED() << "Matched with notification marked as local"; |
| 235 error = sync_error_factory_->CreateAndUploadError( | 235 error = sync_error_factory_->CreateAndUploadError( |
| 236 FROM_HERE, | 236 FROM_HERE, |
| 237 "ProcessSyncChanges received a local only notification" + | 237 "ProcessSyncChanges received a local only notification" + |
| 238 SyncChange::ChangeTypeToString(change_type)); | 238 csync::SyncChange::ChangeTypeToString(change_type)); |
| 239 continue; | 239 continue; |
| 240 } | 240 } |
| 241 | 241 |
| 242 switch (change_type) { | 242 switch (change_type) { |
| 243 case SyncChange::ACTION_ADD: | 243 case csync::SyncChange::ACTION_ADD: |
| 244 if (!existing_notif) { | 244 if (!existing_notif) { |
| 245 Add(new_notif.release()); | 245 Add(new_notif.release()); |
| 246 } else { | 246 } else { |
| 247 DLOG(ERROR) << "Got ADD change for an existing item.\n" | 247 DLOG(ERROR) << "Got ADD change for an existing item.\n" |
| 248 << "Existing item: " << existing_notif->ToString() | 248 << "Existing item: " << existing_notif->ToString() |
| 249 << "\nItem in ADD change: " << new_notif->ToString(); | 249 << "\nItem in ADD change: " << new_notif->ToString(); |
| 250 } | 250 } |
| 251 break; | 251 break; |
| 252 case SyncChange::ACTION_DELETE: | 252 case csync::SyncChange::ACTION_DELETE: |
| 253 if (existing_notif) { | 253 if (existing_notif) { |
| 254 Remove(new_notif->extension_id(), new_notif->guid()); | 254 Remove(new_notif->extension_id(), new_notif->guid()); |
| 255 } else { | 255 } else { |
| 256 // This should never happen. But we are seeting this sometimes, and | 256 // This should never happen. But we are seeting this sometimes, and |
| 257 // it stops all of sync. See bug http://crbug.com/108088 | 257 // it stops all of sync. See bug http://crbug.com/108088 |
| 258 // So until we figure out the root cause, log an error and ignore. | 258 // So until we figure out the root cause, log an error and ignore. |
| 259 DLOG(ERROR) << "Got DELETE change for non-existing item.\n" | 259 DLOG(ERROR) << "Got DELETE change for non-existing item.\n" |
| 260 << "Item in DELETE change: " << new_notif->ToString(); | 260 << "Item in DELETE change: " << new_notif->ToString(); |
| 261 } | 261 } |
| 262 break; | 262 break; |
| 263 case SyncChange::ACTION_UPDATE: | 263 case csync::SyncChange::ACTION_UPDATE: |
| 264 // Although app notifications are immutable from the model perspective, | 264 // Although app notifications are immutable from the model perspective, |
| 265 // sync can send UPDATE changes due to encryption / meta-data changes. | 265 // sync can send UPDATE changes due to encryption / meta-data changes. |
| 266 // So ignore UPDATE changes when the exitsing and new notification | 266 // So ignore UPDATE changes when the exitsing and new notification |
| 267 // objects are the same. Log an error otherwise. | 267 // objects are the same. Log an error otherwise. |
| 268 if (!existing_notif) { | 268 if (!existing_notif) { |
| 269 DLOG(ERROR) << "Got UPDATE change for non-existing item." | 269 DLOG(ERROR) << "Got UPDATE change for non-existing item." |
| 270 << "Item in UPDATE change: " << new_notif->ToString(); | 270 << "Item in UPDATE change: " << new_notif->ToString(); |
| 271 } else if (!existing_notif->Equals(*new_notif)) { | 271 } else if (!existing_notif->Equals(*new_notif)) { |
| 272 DLOG(ERROR) << "Got invalid UPDATE change:" | 272 DLOG(ERROR) << "Got invalid UPDATE change:" |
| 273 << "New and existing notifications should be the same.\n" | 273 << "New and existing notifications should be the same.\n" |
| 274 << "Existing item: " << existing_notif->ToString() << "\n" | 274 << "Existing item: " << existing_notif->ToString() << "\n" |
| 275 << "Item in UPDATE change: " << new_notif->ToString(); | 275 << "Item in UPDATE change: " << new_notif->ToString(); |
| 276 } | 276 } |
| 277 break; | 277 break; |
| 278 default: | 278 default: |
| 279 break; | 279 break; |
| 280 } | 280 } |
| 281 } | 281 } |
| 282 | 282 |
| 283 return error; | 283 return error; |
| 284 } | 284 } |
| 285 | 285 |
| 286 SyncError AppNotificationManager::MergeDataAndStartSyncing( | 286 csync::SyncError AppNotificationManager::MergeDataAndStartSyncing( |
| 287 syncable::ModelType type, | 287 syncable::ModelType type, |
| 288 const SyncDataList& initial_sync_data, | 288 const csync::SyncDataList& initial_sync_data, |
| 289 scoped_ptr<SyncChangeProcessor> sync_processor, | 289 scoped_ptr<csync::SyncChangeProcessor> sync_processor, |
| 290 scoped_ptr<SyncErrorFactory> sync_error_factory) { | 290 scoped_ptr<csync::SyncErrorFactory> sync_error_factory) { |
| 291 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 291 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 292 // AppNotificationDataTypeController ensures that modei is fully should before | 292 // AppNotificationDataTypeController ensures that modei is fully should before |
| 293 // this method is called by waiting until the load notification is received | 293 // this method is called by waiting until the load notification is received |
| 294 // from AppNotificationManager. | 294 // from AppNotificationManager. |
| 295 DCHECK(loaded()); | 295 DCHECK(loaded()); |
| 296 DCHECK_EQ(type, syncable::APP_NOTIFICATIONS); | 296 DCHECK_EQ(type, syncable::APP_NOTIFICATIONS); |
| 297 DCHECK(!sync_processor_.get()); | 297 DCHECK(!sync_processor_.get()); |
| 298 DCHECK(sync_processor.get()); | 298 DCHECK(sync_processor.get()); |
| 299 DCHECK(sync_error_factory.get()); | 299 DCHECK(sync_error_factory.get()); |
| 300 sync_processor_ = sync_processor.Pass(); | 300 sync_processor_ = sync_processor.Pass(); |
| 301 sync_error_factory_ = sync_error_factory.Pass(); | 301 sync_error_factory_ = sync_error_factory.Pass(); |
| 302 | 302 |
| 303 // We may add, or remove notifications here, so ensure we don't step on | 303 // We may add, or remove notifications here, so ensure we don't step on |
| 304 // our own toes. | 304 // our own toes. |
| 305 AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 305 AutoReset<bool> processing_changes(&processing_syncer_changes_, true); |
| 306 | 306 |
| 307 SyncDataMap local_data_map; | 307 SyncDataMap local_data_map; |
| 308 PopulateGuidToSyncDataMap(GetAllSyncData(syncable::APP_NOTIFICATIONS), | 308 PopulateGuidToSyncDataMap(GetAllSyncData(syncable::APP_NOTIFICATIONS), |
| 309 &local_data_map); | 309 &local_data_map); |
| 310 | 310 |
| 311 for (SyncDataList::const_iterator iter = initial_sync_data.begin(); | 311 for (csync::SyncDataList::const_iterator iter = initial_sync_data.begin(); |
| 312 iter != initial_sync_data.end(); ++iter) { | 312 iter != initial_sync_data.end(); ++iter) { |
| 313 const SyncData& sync_data = *iter; | 313 const csync::SyncData& sync_data = *iter; |
| 314 DCHECK_EQ(syncable::APP_NOTIFICATIONS, sync_data.GetDataType()); | 314 DCHECK_EQ(syncable::APP_NOTIFICATIONS, sync_data.GetDataType()); |
| 315 scoped_ptr<AppNotification> sync_notif(CreateNotificationFromSyncData( | 315 scoped_ptr<AppNotification> sync_notif(CreateNotificationFromSyncData( |
| 316 sync_data)); | 316 sync_data)); |
| 317 CHECK(sync_notif.get()); | 317 CHECK(sync_notif.get()); |
| 318 const AppNotification* local_notif = GetNotification( | 318 const AppNotification* local_notif = GetNotification( |
| 319 sync_notif->extension_id(), sync_notif->guid()); | 319 sync_notif->extension_id(), sync_notif->guid()); |
| 320 if (local_notif) { | 320 if (local_notif) { |
| 321 local_data_map.erase(sync_notif->guid()); | 321 local_data_map.erase(sync_notif->guid()); |
| 322 // Local notification should always match with sync notification as | 322 // Local notification should always match with sync notification as |
| 323 // notifications are immutable. | 323 // notifications are immutable. |
| 324 if (local_notif->is_local() || !sync_notif->Equals(*local_notif)) { | 324 if (local_notif->is_local() || !sync_notif->Equals(*local_notif)) { |
| 325 return sync_error_factory_->CreateAndUploadError( | 325 return sync_error_factory_->CreateAndUploadError( |
| 326 FROM_HERE, | 326 FROM_HERE, |
| 327 "MergeDataAndStartSyncing failed: local notification and sync " | 327 "MergeDataAndStartSyncing failed: local notification and sync " |
| 328 "notification have same guid but different data."); | 328 "notification have same guid but different data."); |
| 329 } | 329 } |
| 330 } else { | 330 } else { |
| 331 // Sync model has a notification that local model does not, add it. | 331 // Sync model has a notification that local model does not, add it. |
| 332 Add(sync_notif.release()); | 332 Add(sync_notif.release()); |
| 333 } | 333 } |
| 334 } | 334 } |
| 335 | 335 |
| 336 // TODO(munjal): crbug.com/10059. Work with Lingesh/Antony to resolve. | 336 // TODO(munjal): crbug.com/10059. Work with Lingesh/Antony to resolve. |
| 337 SyncChangeList new_changes; | 337 csync::SyncChangeList new_changes; |
| 338 for (SyncDataMap::const_iterator iter = local_data_map.begin(); | 338 for (SyncDataMap::const_iterator iter = local_data_map.begin(); |
| 339 iter != local_data_map.end(); ++iter) { | 339 iter != local_data_map.end(); ++iter) { |
| 340 new_changes.push_back(SyncChange(SyncChange::ACTION_ADD, iter->second)); | 340 new_changes.push_back( |
| 341 csync::SyncChange(csync::SyncChange::ACTION_ADD, iter->second)); |
| 341 } | 342 } |
| 342 | 343 |
| 343 SyncError error; | 344 csync::SyncError error; |
| 344 if (new_changes.size() > 0) | 345 if (new_changes.size() > 0) |
| 345 error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); | 346 error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); |
| 346 models_associated_ = !error.IsSet(); | 347 models_associated_ = !error.IsSet(); |
| 347 return error; | 348 return error; |
| 348 } | 349 } |
| 349 | 350 |
| 350 void AppNotificationManager::StopSyncing(syncable::ModelType type) { | 351 void AppNotificationManager::StopSyncing(syncable::ModelType type) { |
| 351 DCHECK_EQ(type, syncable::APP_NOTIFICATIONS); | 352 DCHECK_EQ(type, syncable::APP_NOTIFICATIONS); |
| 352 models_associated_ = false; | 353 models_associated_ = false; |
| 353 sync_processor_.reset(); | 354 sync_processor_.reset(); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 void AppNotificationManager::SyncAddChange(const AppNotification& notif) { | 484 void AppNotificationManager::SyncAddChange(const AppNotification& notif) { |
| 484 // Skip if either: | 485 // Skip if either: |
| 485 // - Notification is marked as local. | 486 // - Notification is marked as local. |
| 486 // - Sync is not enabled by user. | 487 // - Sync is not enabled by user. |
| 487 // - Change is generated from within the manager. | 488 // - Change is generated from within the manager. |
| 488 if (notif.is_local() || !models_associated_ || processing_syncer_changes_) | 489 if (notif.is_local() || !models_associated_ || processing_syncer_changes_) |
| 489 return; | 490 return; |
| 490 | 491 |
| 491 // TODO(munjal): crbug.com/10059. Work with Lingesh/Antony to resolve. | 492 // TODO(munjal): crbug.com/10059. Work with Lingesh/Antony to resolve. |
| 492 | 493 |
| 493 SyncChangeList changes; | 494 csync::SyncChangeList changes; |
| 494 SyncData sync_data = CreateSyncDataFromNotification(notif); | 495 csync::SyncData sync_data = CreateSyncDataFromNotification(notif); |
| 495 changes.push_back(SyncChange(SyncChange::ACTION_ADD, sync_data)); | 496 changes.push_back( |
| 497 csync::SyncChange(csync::SyncChange::ACTION_ADD, sync_data)); |
| 496 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 498 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
| 497 } | 499 } |
| 498 | 500 |
| 499 void AppNotificationManager::SyncRemoveChange(const AppNotification& notif) { | 501 void AppNotificationManager::SyncRemoveChange(const AppNotification& notif) { |
| 500 // Skip if either: | 502 // Skip if either: |
| 501 // - Sync is not enabled by user. | 503 // - Sync is not enabled by user. |
| 502 // - Change is generated from within the manager. | 504 // - Change is generated from within the manager. |
| 503 if (notif.is_local() || !models_associated_) { | 505 if (notif.is_local() || !models_associated_) { |
| 504 return; | 506 return; |
| 505 } | 507 } |
| 506 | 508 |
| 507 SyncChangeList changes; | 509 csync::SyncChangeList changes; |
| 508 SyncData sync_data = CreateSyncDataFromNotification(notif); | 510 csync::SyncData sync_data = CreateSyncDataFromNotification(notif); |
| 509 changes.push_back(SyncChange(SyncChange::ACTION_DELETE, sync_data)); | 511 changes.push_back( |
| 512 csync::SyncChange(csync::SyncChange::ACTION_DELETE, sync_data)); |
| 510 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 513 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
| 511 } | 514 } |
| 512 | 515 |
| 513 void AppNotificationManager::SyncClearAllChange( | 516 void AppNotificationManager::SyncClearAllChange( |
| 514 const AppNotificationList& list) { | 517 const AppNotificationList& list) { |
| 515 // Skip if either: | 518 // Skip if either: |
| 516 // - Sync is not enabled by user. | 519 // - Sync is not enabled by user. |
| 517 // - Change is generated from within the manager. | 520 // - Change is generated from within the manager. |
| 518 if (!models_associated_ || processing_syncer_changes_) | 521 if (!models_associated_ || processing_syncer_changes_) |
| 519 return; | 522 return; |
| 520 | 523 |
| 521 SyncChangeList changes; | 524 csync::SyncChangeList changes; |
| 522 for (AppNotificationList::const_iterator iter = list.begin(); | 525 for (AppNotificationList::const_iterator iter = list.begin(); |
| 523 iter != list.end(); ++iter) { | 526 iter != list.end(); ++iter) { |
| 524 const AppNotification& notif = *iter->get(); | 527 const AppNotification& notif = *iter->get(); |
| 525 // Skip notifications marked as local. | 528 // Skip notifications marked as local. |
| 526 if (notif.is_local()) | 529 if (notif.is_local()) |
| 527 continue; | 530 continue; |
| 528 changes.push_back(SyncChange( | 531 changes.push_back(csync::SyncChange( |
| 529 SyncChange::ACTION_DELETE, | 532 csync::SyncChange::ACTION_DELETE, |
| 530 CreateSyncDataFromNotification(notif))); | 533 CreateSyncDataFromNotification(notif))); |
| 531 } | 534 } |
| 532 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 535 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
| 533 } | 536 } |
| 534 | 537 |
| 535 // static | 538 // static |
| 536 SyncData AppNotificationManager::CreateSyncDataFromNotification( | 539 csync::SyncData AppNotificationManager::CreateSyncDataFromNotification( |
| 537 const AppNotification& notification) { | 540 const AppNotification& notification) { |
| 538 DCHECK(!notification.is_local()); | 541 DCHECK(!notification.is_local()); |
| 539 sync_pb::EntitySpecifics specifics; | 542 sync_pb::EntitySpecifics specifics; |
| 540 sync_pb::AppNotification* notif_specifics = | 543 sync_pb::AppNotification* notif_specifics = |
| 541 specifics.mutable_app_notification(); | 544 specifics.mutable_app_notification(); |
| 542 notif_specifics->set_app_id(notification.extension_id()); | 545 notif_specifics->set_app_id(notification.extension_id()); |
| 543 notif_specifics->set_creation_timestamp_ms( | 546 notif_specifics->set_creation_timestamp_ms( |
| 544 notification.creation_time().ToInternalValue()); | 547 notification.creation_time().ToInternalValue()); |
| 545 notif_specifics->set_body_text(notification.body()); | 548 notif_specifics->set_body_text(notification.body()); |
| 546 notif_specifics->set_guid(notification.guid()); | 549 notif_specifics->set_guid(notification.guid()); |
| 547 notif_specifics->set_link_text(notification.link_text()); | 550 notif_specifics->set_link_text(notification.link_text()); |
| 548 notif_specifics->set_link_url(notification.link_url().spec()); | 551 notif_specifics->set_link_url(notification.link_url().spec()); |
| 549 notif_specifics->set_title(notification.title()); | 552 notif_specifics->set_title(notification.title()); |
| 550 return SyncData::CreateLocalData( | 553 return csync::SyncData::CreateLocalData( |
| 551 notif_specifics->guid(), notif_specifics->app_id(), specifics); | 554 notif_specifics->guid(), notif_specifics->app_id(), specifics); |
| 552 } | 555 } |
| 553 | 556 |
| 554 // static | 557 // static |
| 555 AppNotification* AppNotificationManager::CreateNotificationFromSyncData( | 558 AppNotification* AppNotificationManager::CreateNotificationFromSyncData( |
| 556 const SyncData& sync_data) { | 559 const csync::SyncData& sync_data) { |
| 557 sync_pb::AppNotification specifics = | 560 sync_pb::AppNotification specifics = |
| 558 sync_data.GetSpecifics().app_notification(); | 561 sync_data.GetSpecifics().app_notification(); |
| 559 | 562 |
| 560 // Check for mandatory fields. | 563 // Check for mandatory fields. |
| 561 if (!specifics.has_app_id() || !specifics.has_guid() || | 564 if (!specifics.has_app_id() || !specifics.has_guid() || |
| 562 !specifics.has_title() || !specifics.has_body_text() || | 565 !specifics.has_title() || !specifics.has_body_text() || |
| 563 !specifics.has_creation_timestamp_ms()) { | 566 !specifics.has_creation_timestamp_ms()) { |
| 564 return NULL; | 567 return NULL; |
| 565 } | 568 } |
| 566 | 569 |
| 567 AppNotification* notification = new AppNotification( | 570 AppNotification* notification = new AppNotification( |
| 568 false, base::Time::FromInternalValue(specifics.creation_timestamp_ms()), | 571 false, base::Time::FromInternalValue(specifics.creation_timestamp_ms()), |
| 569 specifics.guid(), specifics.app_id(), | 572 specifics.guid(), specifics.app_id(), |
| 570 specifics.title(), specifics.body_text()); | 573 specifics.title(), specifics.body_text()); |
| 571 if (specifics.has_link_text()) | 574 if (specifics.has_link_text()) |
| 572 notification->set_link_text(specifics.link_text()); | 575 notification->set_link_text(specifics.link_text()); |
| 573 if (specifics.has_link_url()) | 576 if (specifics.has_link_url()) |
| 574 notification->set_link_url(GURL(specifics.link_url())); | 577 notification->set_link_url(GURL(specifics.link_url())); |
| 575 return notification; | 578 return notification; |
| 576 } | 579 } |
| OLD | NEW |