| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 } | 56 } |
| 57 | 57 |
| 58 void PopulateGuidToSyncDataMap(const SyncDataList& sync_data, | 58 void PopulateGuidToSyncDataMap(const SyncDataList& sync_data, |
| 59 SyncDataMap* data_map) { | 59 SyncDataMap* data_map) { |
| 60 for (SyncDataList::const_iterator iter = sync_data.begin(); | 60 for (SyncDataList::const_iterator iter = sync_data.begin(); |
| 61 iter != sync_data.end(); ++iter) { | 61 iter != sync_data.end(); ++iter) { |
| 62 (*data_map)[iter->GetSpecifics().GetExtension( | 62 (*data_map)[iter->GetSpecifics().GetExtension( |
| 63 sync_pb::app_notification).guid()] = *iter; | 63 sync_pb::app_notification).guid()] = *iter; |
| 64 } | 64 } |
| 65 } | 65 } |
| 66 } // namespace |
| 66 | 67 |
| 67 } // namespace | 68 const unsigned int AppNotificationManager::kMaxNotificationPerApp = 5; |
| 68 | 69 |
| 69 AppNotificationManager::AppNotificationManager(Profile* profile) | 70 AppNotificationManager::AppNotificationManager(Profile* profile) |
| 70 : profile_(profile), | 71 : profile_(profile), |
| 71 sync_processor_(NULL), | 72 sync_processor_(NULL), |
| 72 models_associated_(false), | 73 models_associated_(false), |
| 73 processing_syncer_changes_(false) { | 74 processing_syncer_changes_(false) { |
| 74 registrar_.Add(this, | 75 registrar_.Add(this, |
| 75 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, | 76 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, |
| 76 content::Source<Profile>(profile_)); | 77 content::Source<Profile>(profile_)); |
| 77 } | 78 } |
| 78 | 79 |
| 79 AppNotificationManager::~AppNotificationManager() { | 80 AppNotificationManager::~AppNotificationManager() { |
| 80 // Post a task to delete our storage on the file thread. | 81 // Post a task to delete our storage on the file thread. |
| 81 BrowserThread::PostTask( | 82 BrowserThread::PostTask( |
| 82 BrowserThread::FILE, | 83 BrowserThread::FILE, |
| 83 FROM_HERE, | 84 FROM_HERE, |
| 84 base::Bind(&DeleteStorageOnFileThread, storage_.release())); | 85 base::Bind(&DeleteStorageOnFileThread, storage_.release())); |
| 85 } | 86 } |
| 86 | 87 |
| 87 void AppNotificationManager::Init() { | 88 void AppNotificationManager::Init() { |
| 88 FilePath storage_path = profile_->GetPath().AppendASCII("App Notifications"); | 89 FilePath storage_path = profile_->GetPath().AppendASCII("App Notifications"); |
| 89 BrowserThread::PostTask( | 90 BrowserThread::PostTask( |
| 90 BrowserThread::FILE, | 91 BrowserThread::FILE, |
| 91 FROM_HERE, | 92 FROM_HERE, |
| 92 base::Bind(&AppNotificationManager::LoadOnFileThread, | 93 base::Bind(&AppNotificationManager::LoadOnFileThread, |
| 93 this, storage_path)); | 94 this, storage_path)); |
| 94 } | 95 } |
| 95 | 96 |
| 97 bool AppNotificationSortPredicate(const linked_ptr<AppNotification> a1, |
| 98 const linked_ptr<AppNotification> a2) { |
| 99 return a1.get()->creation_time() < a2.get()->creation_time(); |
| 100 } |
| 101 |
| 96 bool AppNotificationManager::Add(AppNotification* item) { | 102 bool AppNotificationManager::Add(AppNotification* item) { |
| 97 // Do this first since we own the incoming item and hence want to delete | 103 // Do this first since we own the incoming item and hence want to delete |
| 98 // it in error paths. | 104 // it in error paths. |
| 99 linked_ptr<AppNotification> linked_item(item); | 105 linked_ptr<AppNotification> linked_item(item); |
| 100 if (!loaded()) | 106 if (!loaded()) |
| 101 return false; | 107 return false; |
| 102 const std::string& extension_id = item->extension_id(); | 108 const std::string& extension_id = item->extension_id(); |
| 103 AppNotificationList& list = GetAllInternal(extension_id); | 109 AppNotificationList& list = GetAllInternal(extension_id); |
| 104 list.push_back(linked_item); | 110 list.push_back(linked_item); |
| 105 | 111 |
| 106 SyncAddChange(*linked_item); | 112 SyncAddChange(*linked_item); |
| 107 | 113 |
| 114 sort(list.begin(), list.end(), AppNotificationSortPredicate); |
| 115 |
| 116 if (list.size() > AppNotificationManager::kMaxNotificationPerApp) { |
| 117 AppNotification* removed = list.begin()->get(); |
| 118 SyncRemoveChange(*removed); |
| 119 list.erase(list.begin()); |
| 120 } |
| 121 |
| 108 if (storage_.get()) { | 122 if (storage_.get()) { |
| 109 BrowserThread::PostTask( | 123 BrowserThread::PostTask( |
| 110 BrowserThread::FILE, | 124 BrowserThread::FILE, |
| 111 FROM_HERE, | 125 FROM_HERE, |
| 112 base::Bind(&AppNotificationManager::SaveOnFileThread, | 126 base::Bind(&AppNotificationManager::SaveOnFileThread, |
| 113 this, extension_id, CopyAppNotificationList(list))); | 127 this, extension_id, CopyAppNotificationList(list))); |
| 114 } | 128 } |
| 115 | 129 |
| 116 content::NotificationService::current()->Notify( | 130 content::NotificationService::current()->Notify( |
| 117 chrome::NOTIFICATION_APP_NOTIFICATION_STATE_CHANGED, | 131 chrome::NOTIFICATION_APP_NOTIFICATION_STATE_CHANGED, |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 return; | 419 return; |
| 406 | 420 |
| 407 // TODO(munjal): crbug.com/10059. Work with Lingesh/Antony to resolve. | 421 // TODO(munjal): crbug.com/10059. Work with Lingesh/Antony to resolve. |
| 408 | 422 |
| 409 SyncChangeList changes; | 423 SyncChangeList changes; |
| 410 SyncData sync_data = CreateSyncDataFromNotification(notif); | 424 SyncData sync_data = CreateSyncDataFromNotification(notif); |
| 411 changes.push_back(SyncChange(SyncChange::ACTION_ADD, sync_data)); | 425 changes.push_back(SyncChange(SyncChange::ACTION_ADD, sync_data)); |
| 412 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | 426 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
| 413 } | 427 } |
| 414 | 428 |
| 429 void AppNotificationManager::SyncRemoveChange(const AppNotification& notif) { |
| 430 // Skip if either: |
| 431 // - Sync is not enabled by user. |
| 432 // - Change is generated from within the manager. |
| 433 if (notif.is_local() || !models_associated_) { |
| 434 return; |
| 435 } |
| 436 |
| 437 SyncChangeList changes; |
| 438 SyncData sync_data = CreateSyncDataFromNotification(notif); |
| 439 changes.push_back(SyncChange(SyncChange::ACTION_DELETE, sync_data)); |
| 440 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); |
| 441 } |
| 442 |
| 415 void AppNotificationManager::SyncClearAllChange( | 443 void AppNotificationManager::SyncClearAllChange( |
| 416 const AppNotificationList& list) { | 444 const AppNotificationList& list) { |
| 417 // Skip if either: | 445 // Skip if either: |
| 418 // - Sync is not enabled by user. | 446 // - Sync is not enabled by user. |
| 419 // - Change is generated from within the manager. | 447 // - Change is generated from within the manager. |
| 420 if (!models_associated_ || processing_syncer_changes_) | 448 if (!models_associated_ || processing_syncer_changes_) |
| 421 return; | 449 return; |
| 422 | 450 |
| 423 SyncChangeList changes; | 451 SyncChangeList changes; |
| 424 for (AppNotificationList::const_iterator iter = list.begin(); | 452 for (AppNotificationList::const_iterator iter = list.begin(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 } | 490 } |
| 463 | 491 |
| 464 // static | 492 // static |
| 465 SyncData AppNotificationManager::CreateSyncDataFromNotification( | 493 SyncData AppNotificationManager::CreateSyncDataFromNotification( |
| 466 const AppNotification& notification) { | 494 const AppNotification& notification) { |
| 467 DCHECK(!notification.is_local()); | 495 DCHECK(!notification.is_local()); |
| 468 sync_pb::EntitySpecifics specifics; | 496 sync_pb::EntitySpecifics specifics; |
| 469 sync_pb::AppNotificationSpecifics* notif_specifics = | 497 sync_pb::AppNotificationSpecifics* notif_specifics = |
| 470 specifics.MutableExtension(sync_pb::app_notification); | 498 specifics.MutableExtension(sync_pb::app_notification); |
| 471 notif_specifics->set_app_id(notification.extension_id()); | 499 notif_specifics->set_app_id(notification.extension_id()); |
| 500 notif_specifics->set_creation_timestamp_ms( |
| 501 notification.creation_time().ToInternalValue()); |
| 472 notif_specifics->set_body_text(notification.body()); | 502 notif_specifics->set_body_text(notification.body()); |
| 473 notif_specifics->set_guid(notification.guid()); | 503 notif_specifics->set_guid(notification.guid()); |
| 474 notif_specifics->set_link_text(notification.link_text()); | 504 notif_specifics->set_link_text(notification.link_text()); |
| 475 notif_specifics->set_link_url(notification.link_url().spec()); | 505 notif_specifics->set_link_url(notification.link_url().spec()); |
| 476 notif_specifics->set_title(notification.title()); | 506 notif_specifics->set_title(notification.title()); |
| 477 | |
| 478 return SyncData::CreateLocalData( | 507 return SyncData::CreateLocalData( |
| 479 notif_specifics->guid(), notif_specifics->app_id(), specifics); | 508 notif_specifics->guid(), notif_specifics->app_id(), specifics); |
| 480 } | 509 } |
| 481 | 510 |
| 482 // static | 511 // static |
| 483 AppNotification* AppNotificationManager::CreateNotificationFromSyncData( | 512 AppNotification* AppNotificationManager::CreateNotificationFromSyncData( |
| 484 const SyncData& sync_data) { | 513 const SyncData& sync_data) { |
| 485 sync_pb::AppNotificationSpecifics specifics = | 514 sync_pb::AppNotificationSpecifics specifics = |
| 486 sync_data.GetSpecifics().GetExtension(sync_pb::app_notification); | 515 sync_data.GetSpecifics().GetExtension(sync_pb::app_notification); |
| 487 | 516 |
| 488 // Check for mandatory fields. | 517 // Check for mandatory fields. |
| 489 if (!specifics.has_app_id() || !specifics.has_guid() || | 518 if (!specifics.has_app_id() || !specifics.has_guid() || |
| 490 !specifics.has_title() || !specifics.has_body_text()) { | 519 !specifics.has_title() || !specifics.has_body_text() || |
| 520 !specifics.has_creation_timestamp_ms()) { |
| 491 return NULL; | 521 return NULL; |
| 492 } | 522 } |
| 493 | 523 |
| 494 AppNotification* notification = new AppNotification( | 524 AppNotification* notification = new AppNotification( |
| 495 false, specifics.guid(), specifics.app_id(), | 525 false, base::Time::FromInternalValue(specifics.creation_timestamp_ms()), |
| 526 specifics.guid(), specifics.app_id(), |
| 496 specifics.title(), specifics.body_text()); | 527 specifics.title(), specifics.body_text()); |
| 497 if (specifics.has_link_text()) | 528 if (specifics.has_link_text()) |
| 498 notification->set_link_text(specifics.link_text()); | 529 notification->set_link_text(specifics.link_text()); |
| 499 if (specifics.has_link_url()) | 530 if (specifics.has_link_url()) |
| 500 notification->set_link_url(GURL(specifics.link_url())); | 531 notification->set_link_url(GURL(specifics.link_url())); |
| 501 return notification; | 532 return notification; |
| 502 } | 533 } |
| OLD | NEW |