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

Side by Side Diff: chrome/browser/extensions/app_notification_manager.cc

Issue 8567018: Limit number of notifications that can be received by the client. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years, 1 month 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) 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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698