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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/notifications/balloon_notification_ui_manager.h" 6 7 #include "base/logging.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/prefs/pref_service.h" 10 #include "base/stl_util.h" 11 #include "chrome/browser/browser_process.h" 12 #include "chrome/browser/chrome_notification_types.h" 13 #include "chrome/browser/fullscreen.h" 14 #include "chrome/browser/idle.h" 15 #include "chrome/browser/notifications/balloon_collection.h" 16 #include "chrome/browser/notifications/notification.h" 17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/common/pref_names.h" 19 #include "content/public/browser/notification_service.h" 20 21 BalloonNotificationUIManager::BalloonNotificationUIManager( 22 PrefService* local_state) 23 : NotificationUIManagerImpl(), NotificationPrefsManager(local_state) { 24 position_pref_.Init( 25 prefs::kDesktopNotificationPosition, 26 local_state, 27 base::Bind( 28 &BalloonNotificationUIManager::OnDesktopNotificationPositionChanged, 29 base::Unretained(this))); 30 } 31 32 BalloonNotificationUIManager::~BalloonNotificationUIManager() { 33 } 34 35 void BalloonNotificationUIManager::SetBalloonCollection( 36 BalloonCollection* balloon_collection) { 37 DCHECK(!balloon_collection_.get() || 38 balloon_collection_->GetActiveBalloons().size() == 0); 39 DCHECK(balloon_collection); 40 balloon_collection_.reset(balloon_collection); 41 balloon_collection_->SetPositionPreference( 42 static_cast<BalloonCollection::PositionPreference>( 43 position_pref_.GetValue())); 44 balloon_collection_->set_space_change_listener(this); 45 } 46 47 const Notification* BalloonNotificationUIManager::FindById( 48 const std::string& id) const { 49 const Notification* notification = NotificationUIManagerImpl::FindById(id); 50 if (notification) 51 return notification; 52 return balloon_collection_->FindById(id); 53 } 54 55 bool BalloonNotificationUIManager::CancelById(const std::string& id) { 56 // See if this ID hasn't been shown yet. 57 if (NotificationUIManagerImpl::CancelById(id)) 58 return true; 59 // If it has been shown, remove it from the balloon collections. 60 return balloon_collection_->RemoveById(id); 61 } 62 63 std::set<std::string> 64 BalloonNotificationUIManager::GetAllIdsByProfileAndSourceOrigin( 65 Profile* profile, 66 const GURL& source) { 67 std::set<std::string> notification_ids = 68 NotificationUIManagerImpl::GetAllIdsByProfileAndSourceOrigin(profile, 69 source); 70 71 const BalloonCollection::Balloons& balloons = 72 balloon_collection_->GetActiveBalloons(); 73 for (BalloonCollection::Balloons::const_iterator iter = balloons.begin(); 74 iter != balloons.end(); ++iter) { 75 if (profile->IsSameProfile((*iter)->profile()) && 76 source == (*iter)->notification().origin_url()) { 77 notification_ids.insert((*iter)->notification().notification_id()); 78 } 79 } 80 return notification_ids; 81 } 82 83 bool BalloonNotificationUIManager::CancelAllBySourceOrigin(const GURL& source) { 84 // Same pattern as CancelById, but more complicated than the above 85 // because there may be multiple notifications from the same source. 86 bool removed = NotificationUIManagerImpl::CancelAllBySourceOrigin(source); 87 return balloon_collection_->RemoveBySourceOrigin(source) || removed; 88 } 89 90 bool BalloonNotificationUIManager::CancelAllByProfile(Profile* profile) { 91 // Same pattern as CancelAllBySourceOrigin. 92 bool removed = NotificationUIManagerImpl::CancelAllByProfile(profile); 93 return balloon_collection_->RemoveByProfile(profile) || removed; 94 } 95 96 void BalloonNotificationUIManager::CancelAll() { 97 NotificationUIManagerImpl::CancelAll(); 98 balloon_collection_->RemoveAll(); 99 } 100 101 BalloonCollection* BalloonNotificationUIManager::balloon_collection() { 102 return balloon_collection_.get(); 103 } 104 105 NotificationPrefsManager* BalloonNotificationUIManager::prefs_manager() { 106 return this; 107 } 108 109 bool BalloonNotificationUIManager::ShowNotification( 110 const Notification& notification, 111 Profile* profile) { 112 if (!balloon_collection_->HasSpace()) 113 return false; 114 balloon_collection_->Add(notification, profile); 115 return true; 116 } 117 118 void BalloonNotificationUIManager::OnBalloonSpaceChanged() { 119 CheckAndShowNotifications(); 120 } 121 122 bool BalloonNotificationUIManager::UpdateNotification( 123 const Notification& notification, 124 Profile* profile) { 125 const GURL& origin = notification.origin_url(); 126 const string16& replace_id = notification.replace_id(); 127 128 DCHECK(!replace_id.empty()); 129 130 const BalloonCollection::Balloons& balloons = 131 balloon_collection_->GetActiveBalloons(); 132 for (BalloonCollection::Balloons::const_iterator iter = balloons.begin(); 133 iter != balloons.end(); ++iter) { 134 if (profile == (*iter)->profile() && 135 origin == (*iter)->notification().origin_url() && 136 replace_id == (*iter)->notification().replace_id()) { 137 (*iter)->Update(notification); 138 return true; 139 } 140 } 141 142 return false; 143 } 144 145 BalloonCollection::PositionPreference 146 BalloonNotificationUIManager::GetPositionPreference() const { 147 LOG(INFO) << "Current position preference: " << position_pref_.GetValue(); 148 149 return static_cast<BalloonCollection::PositionPreference>( 150 position_pref_.GetValue()); 151 } 152 153 void BalloonNotificationUIManager::SetPositionPreference( 154 BalloonCollection::PositionPreference preference) { 155 LOG(INFO) << "Setting position preference: " << preference; 156 position_pref_.SetValue(static_cast<int>(preference)); 157 balloon_collection_->SetPositionPreference(preference); 158 } 159 160 void BalloonNotificationUIManager::OnDesktopNotificationPositionChanged() { 161 balloon_collection_->SetPositionPreference( 162 static_cast<BalloonCollection::PositionPreference>( 163 position_pref_.GetValue())); 164 } 165 166 // static 167 BalloonNotificationUIManager* 168 BalloonNotificationUIManager::GetInstanceForTesting() { 169 if (NotificationUIManager::DelegatesToMessageCenter()) { 170 LOG(ERROR) << "Attempt to run a test that requires " 171 << "BalloonNotificationUIManager while delegating to a " 172 << "native MessageCenter. Test will fail. Ask dimich@"; 173 return NULL; 174 } 175 return static_cast<BalloonNotificationUIManager*>( 176 g_browser_process->notification_ui_manager()); 177 } 178