Chromium Code Reviews| 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 // 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 |
| 11 #include <set> | 11 #include <set> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <vector> | 13 #include <vector> |
| 14 | 14 |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/guid.h" | 16 #include "base/guid.h" |
| 17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 18 #include "base/prefs/pref_service.h" | 18 #include "base/prefs/pref_service.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/values.h" | 20 #include "base/values.h" |
| 21 #include "chrome/browser/notifications/desktop_notification_service.h" | 21 #include "chrome/browser/notifications/desktop_notification_service.h" |
| 22 #include "chrome/browser/notifications/desktop_notification_service_factory.h" | 22 #include "chrome/browser/notifications/desktop_notification_service_factory.h" |
| 23 #include "chrome/browser/notifications/notification.h" | 23 #include "chrome/browser/notifications/notification.h" |
| 24 #include "chrome/browser/notifications/notification_ui_manager.h" | 24 #include "chrome/browser/notifications/notification_ui_manager.h" |
| 25 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.h" | 25 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.h" |
| 26 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_fac tory.h" | 26 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_fac tory.h" |
| 27 #include "chrome/browser/notifications/sync_notifier/synced_notification_app_inf o.h" | |
| 28 #include "chrome/browser/notifications/sync_notifier/synced_notification_app_inf o_service.h" | |
| 29 #include "chrome/browser/notifications/sync_notifier/synced_notification_app_inf o_service_factory.h" | |
| 27 #include "chrome/browser/notifications/sync_notifier/welcome_delegate.h" | 30 #include "chrome/browser/notifications/sync_notifier/welcome_delegate.h" |
| 28 #include "chrome/browser/profiles/profile.h" | 31 #include "chrome/browser/profiles/profile.h" |
| 29 #include "chrome/common/pref_names.h" | 32 #include "chrome/common/pref_names.h" |
| 30 #include "components/user_prefs/pref_registry_syncable.h" | 33 #include "components/user_prefs/pref_registry_syncable.h" |
| 31 #include "content/public/browser/browser_thread.h" | 34 #include "content/public/browser/browser_thread.h" |
| 32 #include "content/public/browser/user_metrics.h" | 35 #include "content/public/browser/user_metrics.h" |
| 33 #include "grit/generated_resources.h" | 36 #include "grit/generated_resources.h" |
| 34 #include "grit/theme_resources.h" | 37 #include "grit/theme_resources.h" |
| 35 #include "sync/api/sync_change.h" | 38 #include "sync/api/sync_change.h" |
| 36 #include "sync/api/sync_change_processor.h" | 39 #include "sync/api/sync_change_processor.h" |
| 37 #include "sync/api/sync_error_factory.h" | 40 #include "sync/api/sync_error_factory.h" |
| 38 #include "sync/protocol/sync.pb.h" | 41 #include "sync/protocol/sync.pb.h" |
| 39 #include "sync/protocol/synced_notification_specifics.pb.h" | 42 #include "sync/protocol/synced_notification_specifics.pb.h" |
| 40 #include "third_party/WebKit/public/web/WebTextDirection.h" | 43 #include "third_party/WebKit/public/web/WebTextDirection.h" |
| 41 #include "ui/base/l10n/l10n_util.h" | 44 #include "ui/base/l10n/l10n_util.h" |
| 42 #include "ui/base/resource/resource_bundle.h" | 45 #include "ui/base/resource/resource_bundle.h" |
| 43 #include "ui/message_center/notifier_settings.h" | 46 #include "ui/message_center/notifier_settings.h" |
| 44 #include "url/gurl.h" | 47 #include "url/gurl.h" |
| 45 | 48 |
| 46 using base::UserMetricsAction; | 49 using base::UserMetricsAction; |
| 47 | 50 |
| 48 namespace notifier { | 51 namespace notifier { |
| 49 const char kFirstSyncedNotificationServiceId[] = "Google+"; | 52 const char kFirstSyncedNotificationServiceId[] = "Google+"; |
| 50 const char kSyncedNotificationsWelcomeOrigin[] = | 53 const char kSyncedNotificationsWelcomeOrigin[] = |
| 51 "synced-notifications://welcome"; | 54 "synced-notifications://welcome"; |
| 52 | 55 |
| 53 // SyncedNotificationAppInfoTemp is a class that contains the information | |
| 54 // necessary to produce a welcome notification and the app badges for all synced | |
| 55 // notification. | |
| 56 // TODO(dewittj): Convert this into a sync protobuf-backed data structure. | |
| 57 class SyncedNotificationAppInfoTemp { | |
| 58 public: | |
| 59 explicit SyncedNotificationAppInfoTemp(const std::string& app_id, | |
| 60 const base::string16& service_name); | |
| 61 ~SyncedNotificationAppInfoTemp(); | |
| 62 | |
| 63 const std::string& app_id() const { return app_id_; } | |
| 64 const base::string16& service_name() const { return service_name_; } | |
| 65 const base::string16& title() const { return title_; } | |
| 66 | |
| 67 void set_icon(const gfx::Image& icon) { icon_ = icon; } | |
| 68 const gfx::Image& icon() const { return icon_; } | |
| 69 | |
| 70 void set_small_icon(const gfx::Image& small_icon) { | |
| 71 small_icon_ = small_icon; | |
| 72 } | |
| 73 const gfx::Image& small_icon() const { return small_icon_; } | |
| 74 | |
| 75 const message_center::NotifierId GetNotifierId() const; | |
| 76 | |
| 77 private: | |
| 78 std::string app_id_; | |
| 79 base::string16 service_name_; | |
| 80 gfx::Image icon_; | |
| 81 gfx::Image small_icon_; | |
| 82 base::string16 title_; | |
| 83 base::string16 message_; | |
| 84 }; | |
| 85 | |
| 86 SyncedNotificationAppInfoTemp::SyncedNotificationAppInfoTemp( | |
| 87 const std::string& app_id, | |
| 88 const base::string16& service_name) | |
| 89 : app_id_(app_id), service_name_(service_name) { | |
| 90 title_ = | |
| 91 l10n_util::GetStringFUTF16(IDS_NOTIFIER_WELCOME_TITLE, service_name_); | |
| 92 } | |
| 93 | |
| 94 SyncedNotificationAppInfoTemp::~SyncedNotificationAppInfoTemp() {} | |
| 95 | |
| 96 const message_center::NotifierId SyncedNotificationAppInfoTemp::GetNotifierId() | |
| 97 const { | |
| 98 return message_center::NotifierId( | |
| 99 message_center::NotifierId::SYNCED_NOTIFICATION_SERVICE, app_id()); | |
| 100 } | |
| 101 | |
| 102 bool ChromeNotifierService::avoid_bitmap_fetching_for_test_ = false; | 56 bool ChromeNotifierService::avoid_bitmap_fetching_for_test_ = false; |
| 103 | 57 |
| 104 ChromeNotifierService::ChromeNotifierService(Profile* profile, | 58 ChromeNotifierService::ChromeNotifierService(Profile* profile, |
| 105 NotificationUIManager* manager) | 59 NotificationUIManager* manager) |
| 106 : profile_(profile), | 60 : profile_(profile), |
| 107 notification_manager_(manager), | 61 notification_manager_(manager), |
| 108 synced_notification_first_run_(false) { | 62 synced_notification_first_run_(false) { |
| 109 SyncedNotificationAppInfoTemp* temp_app_info = | |
| 110 new SyncedNotificationAppInfoTemp( | |
| 111 kFirstSyncedNotificationServiceId, | |
| 112 l10n_util::GetStringUTF16(IDS_FIRST_SYNCED_NOTIFICATION_SERVICE_NAME)); | |
| 113 temp_app_info->set_small_icon( | |
| 114 ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
| 115 IDR_TEMPORARY_GOOGLE_PLUS_ICON)); | |
| 116 app_info_data_.push_back(temp_app_info); | |
| 117 | 63 |
| 118 InitializePrefs(); | 64 InitializePrefs(); |
| 65 | |
| 66 // Get a pointer to the app info service so we can get app info data. | |
| 67 synced_notification_app_info_service_ = | |
| 68 SyncedNotificationAppInfoServiceFactory::GetForProfile( | |
| 69 profile_, Profile::EXPLICIT_ACCESS); | |
| 70 | |
| 71 DCHECK(synced_notification_app_info_service_ != NULL); | |
| 72 | |
| 73 synced_notification_app_info_service_->set_chrome_notifier_service(this); | |
| 74 | |
| 119 } | 75 } |
| 120 | 76 |
| 121 ChromeNotifierService::~ChromeNotifierService() {} | 77 ChromeNotifierService::~ChromeNotifierService() { |
| 78 if (synced_notification_app_info_service_) | |
| 79 synced_notification_app_info_service_->set_chrome_notifier_service(NULL); | |
| 80 } | |
| 122 | 81 |
| 123 // Methods from BrowserContextKeyedService. | 82 // Methods from BrowserContextKeyedService. |
| 124 void ChromeNotifierService::Shutdown() {} | 83 void ChromeNotifierService::Shutdown() {} |
| 125 | 84 |
| 126 // syncer::SyncableService implementation. | 85 // syncer::SyncableService implementation. |
| 127 | 86 |
| 128 // This is called at startup to sync with the server. | 87 // This is called at startup to sync with the server. |
| 129 // This code is not thread safe. | 88 // This code is not thread safe. |
| 130 syncer::SyncMergeResult ChromeNotifierService::MergeDataAndStartSyncing( | 89 syncer::SyncMergeResult ChromeNotifierService::MergeDataAndStartSyncing( |
| 131 syncer::ModelType type, | 90 syncer::ModelType type, |
| 132 const syncer::SyncDataList& initial_sync_data, | 91 const syncer::SyncDataList& initial_sync_data, |
| 133 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, | 92 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, |
| 134 scoped_ptr<syncer::SyncErrorFactory> error_handler) { | 93 scoped_ptr<syncer::SyncErrorFactory> error_handler) { |
| 135 thread_checker_.CalledOnValidThread(); | 94 thread_checker_.CalledOnValidThread(); |
| 136 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, type); | 95 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, type); |
| 137 syncer::SyncMergeResult merge_result(syncer::SYNCED_NOTIFICATIONS); | 96 syncer::SyncMergeResult merge_result(syncer::SYNCED_NOTIFICATIONS); |
| 138 // A list of local changes to send up to the sync server. | 97 // A list of local changes to send up to the sync server. |
| 139 syncer::SyncChangeList new_changes; | 98 syncer::SyncChangeList new_changes; |
| 140 sync_processor_ = sync_processor.Pass(); | 99 sync_processor_ = sync_processor.Pass(); |
| 141 | 100 |
| 142 for (syncer::SyncDataList::const_iterator it = initial_sync_data.begin(); | 101 for (syncer::SyncDataList::const_iterator it = initial_sync_data.begin(); |
| 143 it != initial_sync_data.end(); ++it) { | 102 it != initial_sync_data.end(); ++it) { |
| 144 const syncer::SyncData& sync_data = *it; | 103 const syncer::SyncData& sync_data = *it; |
| 145 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, sync_data.GetDataType()); | 104 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, sync_data.GetDataType()); |
| 146 | 105 |
| 147 // Build a local notification object from the sync data. | 106 // Build a local notification object from the sync data. |
| 148 scoped_ptr<SyncedNotification> incoming(CreateNotificationFromSyncData( | 107 scoped_ptr<SyncedNotification> incoming(CreateNotificationFromSyncData( |
| 149 sync_data)); | 108 sync_data)); |
| 150 if (!incoming) { | 109 if (!incoming) { |
| 151 // TODO(petewil): Turn this into a NOTREACHED() call once we fix the | 110 NOTREACHED(); |
| 152 // underlying problem causing bad data. | |
| 153 LOG(WARNING) << "Badly formed sync data in incoming notification"; | |
| 154 continue; | 111 continue; |
| 155 } | 112 } |
| 156 | 113 |
| 157 // Process each incoming remote notification. | 114 // Process each incoming remote notification. |
| 158 const std::string& key = incoming->GetKey(); | 115 const std::string& key = incoming->GetKey(); |
| 159 DCHECK_GT(key.length(), 0U); | 116 DCHECK_GT(key.length(), 0U); |
| 160 SyncedNotification* found = FindNotificationById(key); | 117 SyncedNotification* found = FindNotificationById(key); |
| 161 | 118 |
| 162 if (NULL == found) { | 119 if (NULL == found) { |
| 163 // If there are no conflicts, copy in the data from remote. | 120 // If there are no conflicts, copy in the data from remote. |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 notification_data_.erase(it); | 351 notification_data_.erase(it); |
| 395 return; | 352 return; |
| 396 } | 353 } |
| 397 } | 354 } |
| 398 } | 355 } |
| 399 | 356 |
| 400 void ChromeNotifierService::GetSyncedNotificationServices( | 357 void ChromeNotifierService::GetSyncedNotificationServices( |
| 401 std::vector<message_center::Notifier*>* notifiers) { | 358 std::vector<message_center::Notifier*>* notifiers) { |
| 402 // TODO(mukai|petewil): Check the profile's eligibility before adding the | 359 // TODO(mukai|petewil): Check the profile's eligibility before adding the |
| 403 // sample app. | 360 // sample app. |
| 404 ScopedVector<SyncedNotificationAppInfoTemp>::iterator it = | 361 std::vector<std::string> sending_service_names; |
| 405 app_info_data_.begin(); | |
| 406 for (; it != app_info_data_.end(); ++it) { | |
| 407 SyncedNotificationAppInfoTemp* app_info = *it; | |
| 408 message_center::NotifierId notifier_id = app_info->GetNotifierId(); | |
| 409 | 362 |
| 410 // Enable or disable the sending service per saved settings. | 363 if (synced_notification_app_info_service_ == NULL) |
| 364 return; | |
| 365 | |
| 366 sending_service_names = | |
| 367 synced_notification_app_info_service_->GetAllSendingServiceNames(); | |
|
dewittj
2014/03/20 18:00:28
We should just GetAllSendingServices, not the Name
Pete Williamson
2014/03/25 00:08:37
My intent here is to keep the services decoupled,
| |
| 368 | |
| 369 // TODO(petewil): If this set becomes large, or when the API is open to all | |
| 370 // parties, we should use a set difference instead of this n^2 algorithm. | |
| 371 for (size_t ii = 0; ii < sending_service_names.size(); ++ii) { | |
| 372 // Make a notifier ID corresponding to this sending service name. | |
| 373 message_center::NotifierId notifier_id = message_center::NotifierId( | |
| 374 message_center::NotifierId::SYNCED_NOTIFICATION_SERVICE, | |
| 375 sending_service_names[ii]); | |
|
dewittj
2014/03/20 18:00:28
This should call SyncedNotificationAppInfo::GetNot
Pete Williamson
2014/03/25 00:08:37
Done.
| |
| 376 | |
| 377 SyncedNotificationAppInfo* synced_notification_app_info = | |
| 378 synced_notification_app_info_service_-> | |
| 379 FindSyncedNotificationAppInfoByName(sending_service_names[ii]); | |
| 380 | |
| 381 // Enable or disable the sending service per saved preferences. | |
| 411 bool app_enabled = false; | 382 bool app_enabled = false; |
| 412 std::set<std::string>::iterator iter; | 383 std::set<std::string>::iterator iter; |
| 413 iter = find(enabled_sending_services_.begin(), | 384 iter = find(enabled_sending_services_.begin(), |
| 414 enabled_sending_services_.end(), | 385 enabled_sending_services_.end(), |
| 415 notifier_id.id); | 386 notifier_id.id); |
| 416 app_enabled = iter != enabled_sending_services_.end(); | 387 app_enabled = iter != enabled_sending_services_.end(); |
| 417 | 388 |
| 418 message_center::Notifier* app_info_notifier = new message_center::Notifier( | 389 message_center::Notifier* app_info_notifier = new message_center::Notifier( |
| 419 notifier_id, app_info->service_name(), app_enabled); | 390 notifier_id, |
| 391 base::UTF8ToUTF16( | |
| 392 synced_notification_app_info->settings_display_name()), | |
| 393 app_enabled); | |
| 420 | 394 |
| 421 app_info_notifier->icon = app_info->small_icon(); | 395 app_info_notifier->icon = synced_notification_app_info->icon(); |
| 422 | 396 |
| 423 // |notifiers| takes ownership of |app_info_notifier|. | 397 // |notifiers| takes ownership of |app_info_notifier|. |
| 424 notifiers->push_back(app_info_notifier); | 398 notifiers->push_back(app_info_notifier); |
| 425 } | 399 } |
| 426 } | 400 } |
| 427 | 401 |
| 402 void ChromeNotifierService::SetAddedAppIds( | |
| 403 std::vector<std::string> added_app_ids) { | |
| 404 | |
| 405 std::vector<std::string>::const_iterator app_id_iter; | |
| 406 for (app_id_iter = added_app_ids.begin(); app_id_iter != added_app_ids.end(); | |
| 407 ++app_id_iter) { | |
| 408 // Make sure this is not a dup, if it is, do nothing. | |
| 409 // TODO(petewil): consider a case insensitive compare. | |
| 410 std::set<std::string>::iterator sending_service_iter; | |
| 411 sending_service_iter = enabled_sending_services_.find(*app_id_iter); | |
| 412 if (sending_service_iter != enabled_sending_services_.end()) | |
| 413 continue; | |
| 414 | |
| 415 // Find any newly enabled notifications and call display on them. | |
| 416 // Show the welcome toast if required. | |
| 417 ScopedVector<SyncedNotification>::iterator notification_iter; | |
| 418 for (notification_iter = notification_data_.begin(); | |
| 419 notification_iter != notification_data_.end(); | |
| 420 ++notification_iter) { | |
| 421 (*notification_iter)->set_notifier_service(this); | |
| 422 (*notification_iter)->set_notification_manager(notification_manager_); | |
| 423 (*notification_iter)->ShowAllForAppId(profile_, *app_id_iter); | |
| 424 } | |
| 425 } | |
| 426 } | |
| 427 | |
| 428 void ChromeNotifierService::SetRemovedAppIds( | |
| 429 std::vector<std::string> removed_app_ids) { | |
| 430 // Remove from enabled sending services. | |
| 431 // Don't remove from initialized sending services. If it gets re-added later, | |
| 432 // we want to remember the user's decision, so we also leave prefs intact. | |
| 433 | |
| 434 // Find any displayed notifications and remove them from the notification | |
| 435 // center. | |
| 436 std::vector<std::string>::const_iterator app_id_iter; | |
| 437 for (app_id_iter = removed_app_ids.begin(); | |
| 438 app_id_iter != removed_app_ids.end(); | |
| 439 ++app_id_iter) { | |
| 440 // Find any newly disabled notifications and remove them. | |
| 441 ScopedVector<SyncedNotification>::iterator notification_iter; | |
| 442 for (notification_iter = notification_data_.begin(); | |
| 443 notification_iter != notification_data_.end(); | |
| 444 ++notification_iter) { | |
| 445 (*notification_iter)->set_notification_manager(notification_manager_); | |
| 446 (*notification_iter)->HideAllForAppId(*app_id_iter); | |
| 447 } | |
| 448 } | |
| 449 } | |
| 450 | |
| 428 void ChromeNotifierService::MarkNotificationAsRead( | 451 void ChromeNotifierService::MarkNotificationAsRead( |
| 429 const std::string& key) { | 452 const std::string& key) { |
| 430 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 453 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 431 SyncedNotification* notification = FindNotificationById(key); | 454 SyncedNotification* notification = FindNotificationById(key); |
| 432 CHECK(notification != NULL); | 455 CHECK(notification != NULL); |
| 433 | 456 |
| 434 notification->NotificationHasBeenRead(); | 457 notification->NotificationHasBeenRead(); |
| 435 syncer::SyncChangeList new_changes; | 458 syncer::SyncChangeList new_changes; |
| 436 | 459 |
| 437 syncer::SyncData sync_data = CreateSyncDataFromNotification(*notification); | 460 syncer::SyncData sync_data = CreateSyncDataFromNotification(*notification); |
| 438 new_changes.push_back( | 461 new_changes.push_back( |
| 439 syncer::SyncChange(FROM_HERE, | 462 syncer::SyncChange(FROM_HERE, |
| 440 syncer::SyncChange::ACTION_UPDATE, | 463 syncer::SyncChange::ACTION_UPDATE, |
| 441 sync_data)); | 464 sync_data)); |
| 442 | 465 |
| 443 // Send up the changes that were made locally. | 466 // Send up the changes that were made locally. |
| 444 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); | 467 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); |
| 445 } | 468 } |
| 446 | 469 |
| 447 // Add a new notification to our data structure. This takes ownership | 470 // Add a new notification to our data structure. This takes ownership |
| 448 // of the passed in pointer. | 471 // of the passed in pointer. |
| 449 void ChromeNotifierService::Add(scoped_ptr<SyncedNotification> notification) { | 472 void ChromeNotifierService::Add(scoped_ptr<SyncedNotification> notification) { |
| 450 SyncedNotification* notification_copy = notification.get(); | 473 SyncedNotification* notification_copy = notification.get(); |
| 451 // Take ownership of the object and put it into our local storage. | 474 // Take ownership of the object and put it into our local storage. |
| 452 notification_data_.push_back(notification.release()); | 475 notification_data_.push_back(notification.release()); |
| 453 | 476 |
| 454 // If the user is not interested in this type of notification, ignore it. | 477 // If the user is not interested in this type of notification, ignore it. |
| 455 std::set<std::string>::iterator iter = | 478 std::string sending_service_id = GetSendingServiceId(notification_copy); |
| 456 find(enabled_sending_services_.begin(), | 479 std::set<std::string>::iterator iter = find(enabled_sending_services_.begin(), |
| 457 enabled_sending_services_.end(), | 480 enabled_sending_services_.end(), |
| 458 notification_copy->GetSendingServiceId()); | 481 sending_service_id); |
| 459 if (iter == enabled_sending_services_.end()) { | 482 if (iter == enabled_sending_services_.end()) { |
| 460 iter = find(initialized_sending_services_.begin(), | 483 iter = find(initialized_sending_services_.begin(), |
| 461 initialized_sending_services_.end(), | 484 initialized_sending_services_.end(), |
| 462 notification_copy->GetSendingServiceId()); | 485 sending_service_id); |
| 463 if (iter != initialized_sending_services_.end()) | 486 if (iter != initialized_sending_services_.end()) |
| 464 return; | 487 return; |
| 465 } | 488 } |
| 466 | 489 |
| 467 UpdateInMessageCenter(notification_copy); | 490 UpdateInMessageCenter(notification_copy); |
| 468 } | 491 } |
| 469 | 492 |
| 493 std::string ChromeNotifierService::GetSendingServiceId( | |
| 494 const SyncedNotification* synced_notification) { | |
| 495 // Get the App Id from the notification, and look it up in the synced | |
| 496 // notification app info service. | |
| 497 std::string app_id = synced_notification->GetAppId(); | |
| 498 | |
| 499 DCHECK(synced_notification_app_info_service_ != NULL); | |
| 500 | |
| 501 return synced_notification_app_info_service_->FindSendingServiceNameFromAppId( | |
| 502 app_id); | |
| 503 } | |
| 504 | |
| 470 void ChromeNotifierService::AddForTest( | 505 void ChromeNotifierService::AddForTest( |
| 471 scoped_ptr<notifier::SyncedNotification> notification) { | 506 scoped_ptr<notifier::SyncedNotification> notification) { |
| 472 notification_data_.push_back(notification.release()); | 507 notification_data_.push_back(notification.release()); |
| 473 } | 508 } |
| 474 | 509 |
| 510 void ChromeNotifierService::SetSyncedNotificationAppInfoServiceForTest( | |
| 511 SyncedNotificationAppInfoService* synced_notification_app_info_service) { | |
| 512 // If there already is a service attached, clear their reference to us. | |
| 513 if (synced_notification_app_info_service_) | |
| 514 synced_notification_app_info_service_->set_chrome_notifier_service(NULL); | |
| 515 | |
| 516 synced_notification_app_info_service_ = synced_notification_app_info_service; | |
| 517 synced_notification_app_info_service_->set_chrome_notifier_service(this); | |
| 518 } | |
| 519 | |
| 475 void ChromeNotifierService::UpdateInMessageCenter( | 520 void ChromeNotifierService::UpdateInMessageCenter( |
| 476 SyncedNotification* notification) { | 521 SyncedNotification* notification) { |
| 477 // If the feature is disabled, exit now. | 522 // If the feature is disabled, exit now. |
| 478 if (!notifier::ChromeNotifierServiceFactory::UseSyncedNotifications( | 523 if (!notifier::ChromeNotifierServiceFactory::UseSyncedNotifications( |
| 479 CommandLine::ForCurrentProcess())) | 524 CommandLine::ForCurrentProcess())) |
| 480 return; | 525 return; |
| 481 | 526 |
| 482 notification->LogNotification(); | 527 notification->LogNotification(); |
| 483 | 528 |
| 484 if (notification->GetReadState() == SyncedNotification::kUnread) { | 529 if (notification->GetReadState() == SyncedNotification::kUnread) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 495 // If this is the first run for the feature, don't surprise the user. | 540 // If this is the first run for the feature, don't surprise the user. |
| 496 // Instead, place all backlogged notifications into the notification | 541 // Instead, place all backlogged notifications into the notification |
| 497 // center. | 542 // center. |
| 498 if (synced_notification_first_run_) { | 543 if (synced_notification_first_run_) { |
| 499 // Setting the toast state to false will prevent toasting the notification. | 544 // Setting the toast state to false will prevent toasting the notification. |
| 500 notification->SetToastState(false); | 545 notification->SetToastState(false); |
| 501 } | 546 } |
| 502 | 547 |
| 503 // Our tests cannot use the network for reliability reasons. | 548 // Our tests cannot use the network for reliability reasons. |
| 504 if (avoid_bitmap_fetching_for_test_) { | 549 if (avoid_bitmap_fetching_for_test_) { |
| 505 notification->Show(notification_manager_, this, profile_); | 550 notification->set_notifier_service(this); |
| 551 notification->set_notification_manager(notification_manager_); | |
| 552 notification->Show(profile_); | |
| 506 return; | 553 return; |
| 507 } | 554 } |
| 508 | 555 |
| 509 // Set up to fetch the bitmaps. | 556 // Set up to fetch the bitmaps. |
| 510 notification->QueueBitmapFetchJobs(notification_manager_, this, profile_); | 557 notification->set_notification_manager(notification_manager_); |
| 558 notification->QueueBitmapFetchJobs(this, profile_); | |
| 511 | 559 |
| 512 // Start the bitmap fetching, Show() will be called when the last bitmap | 560 // Start the bitmap fetching, Show() will be called when the last bitmap |
| 513 // either arrives or times out. | 561 // either arrives or times out. |
| 514 notification->StartBitmapFetch(); | 562 notification->StartBitmapFetch(); |
| 515 } | 563 } |
| 516 | 564 |
| 517 void ChromeNotifierService::OnSyncedNotificationServiceEnabled( | 565 void ChromeNotifierService::OnSyncedNotificationServiceEnabled( |
| 518 const std::string& notifier_id, bool enabled) { | 566 const std::string& notifier_id, bool enabled) { |
| 519 std::set<std::string>::iterator iter; | 567 std::set<std::string>::iterator iter; |
| 520 | 568 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 601 list_value->Append(string_value); | 649 list_value->Append(string_value); |
| 602 } | 650 } |
| 603 } | 651 } |
| 604 | 652 |
| 605 void ChromeNotifierService::DisplayUnreadNotificationsFromSource( | 653 void ChromeNotifierService::DisplayUnreadNotificationsFromSource( |
| 606 const std::string& notifier_id) { | 654 const std::string& notifier_id) { |
| 607 for (std::vector<SyncedNotification*>::const_iterator iter = | 655 for (std::vector<SyncedNotification*>::const_iterator iter = |
| 608 notification_data_.begin(); | 656 notification_data_.begin(); |
| 609 iter != notification_data_.end(); | 657 iter != notification_data_.end(); |
| 610 ++iter) { | 658 ++iter) { |
| 611 if ((*iter)->GetSendingServiceId() == notifier_id && | 659 if (GetSendingServiceId(*iter) == notifier_id && |
| 612 (*iter)->GetReadState() == SyncedNotification::kUnread) | 660 (*iter)->GetReadState() == SyncedNotification::kUnread) |
| 613 Display(*iter); | 661 Display(*iter); |
| 614 } | 662 } |
| 615 } | 663 } |
| 616 | 664 |
| 617 void ChromeNotifierService::RemoveUnreadNotificationsFromSource( | 665 void ChromeNotifierService::RemoveUnreadNotificationsFromSource( |
| 618 const std::string& notifier_id) { | 666 const std::string& notifier_id) { |
| 619 for (std::vector<SyncedNotification*>::const_iterator iter = | 667 for (std::vector<SyncedNotification*>::const_iterator iter = |
| 620 notification_data_.begin(); | 668 notification_data_.begin(); |
| 621 iter != notification_data_.end(); | 669 iter != notification_data_.end(); |
| 622 ++iter) { | 670 ++iter) { |
| 623 if ((*iter)->GetSendingServiceId() == notifier_id && | 671 if (GetSendingServiceId(*iter) == notifier_id && |
| 624 (*iter)->GetReadState() == SyncedNotification::kUnread) { | 672 (*iter)->GetReadState() == SyncedNotification::kUnread) { |
| 625 notification_manager_->CancelById((*iter)->GetKey()); | 673 notification_manager_->CancelById((*iter)->GetKey()); |
| 626 } | 674 } |
| 627 } | 675 } |
| 628 } | 676 } |
| 629 | 677 |
| 630 void ChromeNotifierService::OnEnabledSendingServiceListPrefChanged( | 678 void ChromeNotifierService::OnEnabledSendingServiceListPrefChanged( |
| 631 std::set<std::string>* ids_field) { | 679 std::set<std::string>* ids_field) { |
| 632 ids_field->clear(); | 680 ids_field->clear(); |
| 633 const std::vector<std::string> pref_list = | 681 const std::vector<std::string> pref_list = |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 OnInitializedSendingServiceListPrefChanged(&initialized_sending_services_); | 757 OnInitializedSendingServiceListPrefChanged(&initialized_sending_services_); |
| 710 | 758 |
| 711 synced_notification_first_run_ = | 759 synced_notification_first_run_ = |
| 712 profile_->GetPrefs()->GetBoolean(prefs::kSyncedNotificationFirstRun); | 760 profile_->GetPrefs()->GetBoolean(prefs::kSyncedNotificationFirstRun); |
| 713 } | 761 } |
| 714 | 762 |
| 715 void ChromeNotifierService::ShowWelcomeToastIfNecessary( | 763 void ChromeNotifierService::ShowWelcomeToastIfNecessary( |
| 716 const SyncedNotification* synced_notification, | 764 const SyncedNotification* synced_notification, |
| 717 NotificationUIManager* notification_ui_manager) { | 765 NotificationUIManager* notification_ui_manager) { |
| 718 const std::string& sending_service_id = | 766 const std::string& sending_service_id = |
| 719 synced_notification->GetSendingServiceId(); | 767 GetSendingServiceId(synced_notification); |
| 720 | 768 |
| 721 std::set<std::string>::iterator iter; | 769 std::set<std::string>::iterator iter; |
| 722 iter = find(initialized_sending_services_.begin(), | 770 iter = find(initialized_sending_services_.begin(), |
| 723 initialized_sending_services_.end(), | 771 initialized_sending_services_.end(), |
| 724 sending_service_id); | 772 sending_service_id); |
| 725 | 773 |
| 726 // If we already initialized the sending service, then return early since no | 774 // If we already initialized the sending service, then return early since no |
| 727 // welcome toast is necessary. | 775 // welcome toast is necessary. |
| 728 if (iter != initialized_sending_services_.end()) | 776 if (iter != initialized_sending_services_.end()) |
| 729 return; | 777 return; |
| 730 | 778 |
| 731 // If there is no app info, we can't show a welcome toast. Ideally all synced | 779 // If there is no app info, we can't show a welcome toast. All synced |
| 732 // notifications will be delayed until an app_info data structure can be | 780 // notifications will be delayed until an app_info data structure can be |
| 733 // constructed for them. | 781 // constructed for them. |
| 734 // TODO(dewittj): Refactor when app_info is populated asynchronously. | 782 notifier::SyncedNotificationAppInfo* app_info = |
| 735 SyncedNotificationAppInfoTemp* app_info = FindAppInfo(sending_service_id); | 783 FindAppInfoByAppId(synced_notification->GetAppId()); |
| 736 if (!app_info) | 784 if (!app_info) |
| 737 return; | 785 return; |
| 738 | 786 |
| 739 // TODO(dewittj): Ensure that the app info icon is set before this point. | 787 if (app_info->settings_icon_url().is_empty()) { |
| 740 if (app_info->icon().IsEmpty()) { | |
| 741 gfx::Image notification_app_icon = synced_notification->GetAppIcon(); | 788 gfx::Image notification_app_icon = synced_notification->GetAppIcon(); |
| 742 if (!notification_app_icon.IsEmpty()) { | 789 if (notification_app_icon.IsEmpty()) { |
| 743 app_info->set_icon(notification_app_icon); | |
| 744 } else { | |
| 745 // This block should only be reached in tests since the downloads are | 790 // This block should only be reached in tests since the downloads are |
| 746 // already finished for |synced_notification|. | 791 // already finished for |synced_notification|. |
| 747 DVLOG(1) << "Unable to find the app icon for the welcome notification. " | 792 DVLOG(1) << "Unable to find the app icon for the welcome notification. " |
| 748 << "Service ID: " << sending_service_id; | 793 << "Service ID: " << sending_service_id; |
| 749 } | 794 } |
| 750 } | 795 } |
| 751 | 796 |
| 752 message_center::NotifierId notifier_id( | 797 message_center::NotifierId notifier_id( |
| 753 message_center::NotifierId::SYNCED_NOTIFICATION_SERVICE, | 798 message_center::NotifierId::SYNCED_NOTIFICATION_SERVICE, |
| 754 sending_service_id); | 799 sending_service_id); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 769 profile_->GetPrefs()->Set(prefs::kEnabledSyncedNotificationSendingServices, | 814 profile_->GetPrefs()->Set(prefs::kEnabledSyncedNotificationSendingServices, |
| 770 enabled_sending_services); | 815 enabled_sending_services); |
| 771 // Mark any new services as initialized in preferences. | 816 // Mark any new services as initialized in preferences. |
| 772 BuildServiceListValueInplace(initialized_sending_services_, | 817 BuildServiceListValueInplace(initialized_sending_services_, |
| 773 &initialized_sending_services); | 818 &initialized_sending_services); |
| 774 profile_->GetPrefs()->Set( | 819 profile_->GetPrefs()->Set( |
| 775 prefs::kInitializedSyncedNotificationSendingServices, | 820 prefs::kInitializedSyncedNotificationSendingServices, |
| 776 initialized_sending_services); | 821 initialized_sending_services); |
| 777 } | 822 } |
| 778 | 823 |
| 779 SyncedNotificationAppInfoTemp* ChromeNotifierService::FindAppInfo( | 824 notifier::SyncedNotificationAppInfo* ChromeNotifierService::FindAppInfoByAppId( |
| 780 const std::string& app_id) const { | 825 const std::string& app_id) const { |
| 781 ScopedVector<SyncedNotificationAppInfoTemp>::const_iterator iter = | 826 if (NULL == synced_notification_app_info_service_) |
| 782 app_info_data_.begin(); | 827 return NULL; |
| 783 while (iter != app_info_data_.end()) { | |
| 784 if ((*iter)->app_id() == app_id) | |
| 785 return (*iter); | |
| 786 | 828 |
| 787 ++iter; | 829 return synced_notification_app_info_service_-> |
| 788 } | 830 FindSyncedNotificationAppInfoByAppId(app_id); |
| 789 | |
| 790 return NULL; | |
| 791 } | 831 } |
| 792 | 832 |
| 793 const Notification ChromeNotifierService::CreateWelcomeNotificationForService( | 833 const Notification ChromeNotifierService::CreateWelcomeNotificationForService( |
| 794 SyncedNotificationAppInfoTemp* app_info) { | 834 SyncedNotificationAppInfo* app_info) { |
| 795 std::string welcome_notification_id = base::GenerateGUID(); | 835 std::string welcome_notification_id = base::GenerateGUID(); |
| 796 scoped_refptr<WelcomeDelegate> delegate(new WelcomeDelegate( | 836 message_center::NotifierId notifier_id = app_info->GetNotifierId(); |
| 797 welcome_notification_id, profile_, app_info->GetNotifierId())); | 837 scoped_refptr<WelcomeDelegate> delegate( |
| 838 new WelcomeDelegate(welcome_notification_id, profile_, | |
| 839 app_info->GetNotifierId())); | |
|
dewittj
2014/03/20 18:00:28
this should probably just be |notifier_id|
Pete Williamson
2014/03/25 00:08:37
Done.
| |
| 798 | 840 |
| 799 message_center::ButtonInfo button_info( | 841 message_center::ButtonInfo button_info( |
| 800 l10n_util::GetStringUTF16(IDS_NOTIFIER_WELCOME_BUTTON)); | 842 l10n_util::GetStringUTF16(IDS_NOTIFIER_WELCOME_BUTTON)); |
| 801 button_info.icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed( | 843 button_info.icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
| 802 IDR_NOTIFIER_BLOCK_BUTTON); | 844 IDR_NOTIFIER_BLOCK_BUTTON); |
| 803 | 845 |
| 804 message_center::RichNotificationData rich_notification_data; | 846 message_center::RichNotificationData rich_notification_data; |
| 805 rich_notification_data.buttons.push_back(button_info); | 847 rich_notification_data.buttons.push_back(button_info); |
| 806 return Notification( | 848 return Notification( |
| 807 message_center::NOTIFICATION_TYPE_BASE_FORMAT, | 849 message_center::NOTIFICATION_TYPE_BASE_FORMAT, |
| 808 GURL(kSyncedNotificationsWelcomeOrigin), | 850 GURL(kSyncedNotificationsWelcomeOrigin), |
| 809 app_info->title(), | 851 base::UTF8ToUTF16(app_info->settings_display_name()), |
| 810 l10n_util::GetStringUTF16(IDS_NOTIFIER_WELCOME_BODY), | 852 l10n_util::GetStringUTF16(IDS_NOTIFIER_WELCOME_BODY), |
| 811 app_info->icon(), | 853 app_info->icon(), |
| 812 blink::WebTextDirectionDefault, | 854 blink::WebTextDirectionDefault, |
| 813 app_info->GetNotifierId(), | 855 notifier_id, |
| 814 l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_DISPLAY_SOURCE), | 856 l10n_util::GetStringUTF16(IDS_NOTIFICATION_WELCOME_DISPLAY_SOURCE), |
| 815 base::UTF8ToUTF16(welcome_notification_id), | 857 base::UTF8ToUTF16(welcome_notification_id), |
| 816 rich_notification_data, | 858 rich_notification_data, |
| 817 delegate.get()); | 859 delegate.get()); |
| 818 } | 860 } |
| 819 | 861 |
| 820 } // namespace notifier | 862 } // namespace notifier |
| OLD | NEW |