Home | History | Annotate | Download | only in notifications
      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