1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/notifications/notification_ui_manager.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h" 103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/browser_process.h" 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/fullscreen.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/idle.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/notifications/balloon_collection.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/notifications/notification.h" 153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/prefs/pref_service.h" 163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/common/pref_names.h" 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/site_instance.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace { 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kUserStatePollingIntervalSeconds = 1; 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A class which represents a notification waiting to be shown. 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass QueuedNotification { 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueuedNotification(const Notification& notification, Profile* profile) 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : notification_(notification), 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_(profile) { 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const Notification& notification() const { return notification_; } 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile() const { return profile_; } 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Replace(const Notification& new_notification) { 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch notification_ = new_notification; 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The notification to be shown. 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Notification notification_; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Non owned pointer to the user's profile. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile_; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(QueuedNotification); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 503f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenNotificationUIManager::NotificationUIManager(PrefService* local_state) 5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : balloon_collection_(NULL), 5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen is_user_active_(true) { 53201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch registrar_.Add(this, NotificationType::APP_TERMINATING, 54201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NotificationService::AllSources()); 553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen position_pref_.Init(prefs::kDesktopNotificationPosition, local_state, this); 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(OS_MACOSX) 5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InitFullScreenMonitor(); 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNotificationUIManager::~NotificationUIManager() { 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteElements(&show_queue_); 6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(OS_MACOSX) 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen StopFullScreenMonitor(); 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 693f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenNotificationUIManager* NotificationUIManager::Create(PrefService* local_state) { 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BalloonCollection* balloons = BalloonCollection::Create(); 713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NotificationUIManager* instance = new NotificationUIManager(local_state); 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch instance->Initialize(balloons); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch balloons->set_space_change_listener(instance); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return instance; 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// static 783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid NotificationUIManager::RegisterPrefs(PrefService* prefs) { 793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen prefs->RegisterIntegerPref(prefs::kDesktopNotificationPosition, 803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen BalloonCollection::DEFAULT_POSITION); 813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid NotificationUIManager::Initialize( 843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen BalloonCollection* balloon_collection) { 853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(!balloon_collection_.get()); 863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(balloon_collection); 873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen balloon_collection_.reset(balloon_collection); 883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen balloon_collection_->SetPositionPreference( 893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static_cast<BalloonCollection::PositionPreference>( 903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen position_pref_.GetValue())); 913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NotificationUIManager::Add(const Notification& notification, 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (TryReplacement(notification)) { 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "Added notification. URL: " 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << notification.content_url().spec(); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch show_queue_.push_back( 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new QueuedNotification(notification, profile)); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckAndShowNotifications(); 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool NotificationUIManager::CancelById(const std::string& id) { 107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // See if this ID hasn't been shown yet. 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationDeque::iterator iter; 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (iter = show_queue_.begin(); iter != show_queue_.end(); ++iter) { 110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if ((*iter)->notification().notification_id() == id) { 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch show_queue_.erase(iter); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // If it has been shown, remove it from the balloon collections. 116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return balloon_collection_->RemoveById(id); 117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool NotificationUIManager::CancelAllBySourceOrigin(const GURL& source) { 120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Same pattern as CancelById, but more complicated than the above 121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // because there may be multiple notifications from the same source. 122201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch bool removed = false; 123201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NotificationDeque::iterator iter; 124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (iter = show_queue_.begin(); iter != show_queue_.end();) { 125201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if ((*iter)->notification().origin_url() == source) { 126201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch iter = show_queue_.erase(iter); 127201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch removed = true; 128201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } else { 129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ++iter; 130201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return balloon_collection_->RemoveBySourceOrigin(source) || removed; 134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 135201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 136201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid NotificationUIManager::CancelAll() { 137201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch STLDeleteElements(&show_queue_); 138201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch balloon_collection_->RemoveAll(); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NotificationUIManager::CheckAndShowNotifications() { 14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CheckUserState(); 14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (is_user_active_) 14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ShowNotifications(); 14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid NotificationUIManager::CheckUserState() { 14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool is_user_active_previously = is_user_active_; 14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen is_user_active_ = CalculateIdleState(0) != IDLE_STATE_LOCKED && 15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen !IsFullScreenMode(); 15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (is_user_active_ == is_user_active_previously) 15272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 15372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (is_user_active_) { 15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen user_state_check_timer_.Stop(); 15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We need to show any postponed nofications when the user becomes active 15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // again. 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ShowNotifications(); 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else if (!user_state_check_timer_.IsRunning()) { 16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Start a timer to detect the moment at which the user becomes active. 16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen user_state_check_timer_.Start( 16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::TimeDelta::FromSeconds(kUserStatePollingIntervalSeconds), this, 16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &NotificationUIManager::CheckUserState); 16472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NotificationUIManager::ShowNotifications() { 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (!show_queue_.empty() && balloon_collection_->HasSpace()) { 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<QueuedNotification> queued_notification(show_queue_.front()); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch show_queue_.pop_front(); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch balloon_collection_->Add(queued_notification->notification(), 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queued_notification->profile()); 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NotificationUIManager::OnBalloonSpaceChanged() { 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckAndShowNotifications(); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NotificationUIManager::TryReplacement(const Notification& notification) { 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& origin = notification.origin_url(); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const string16& replace_id = notification.replace_id(); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (replace_id.empty()) 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First check the queue of pending notifications for replacement. 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Then check the list of notifications already being shown. 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationDeque::iterator iter; 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (iter = show_queue_.begin(); iter != show_queue_.end(); ++iter) { 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (origin == (*iter)->notification().origin_url() && 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replace_id == (*iter)->notification().replace_id()) { 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*iter)->Replace(notification); 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BalloonCollection::Balloons::iterator balloon_iter; 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BalloonCollection::Balloons balloons = 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch balloon_collection_->GetActiveBalloons(); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (balloon_iter = balloons.begin(); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch balloon_iter != balloons.end(); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++balloon_iter) { 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (origin == (*balloon_iter)->notification().origin_url() && 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replace_id == (*balloon_iter)->notification().replace_id()) { 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*balloon_iter)->Update(notification); 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 213201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2143f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenBalloonCollection::PositionPreference 2153f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenNotificationUIManager::GetPositionPreference() { 2163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LOG(INFO) << "Current position preference: " << position_pref_.GetValue(); 2173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 2183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return static_cast<BalloonCollection::PositionPreference>( 2193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen position_pref_.GetValue()); 2203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 2213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 2223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid NotificationUIManager::SetPositionPreference( 2233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen BalloonCollection::PositionPreference preference) { 2243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LOG(INFO) << "Setting position preference: " << preference; 2253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen position_pref_.SetValue(static_cast<int>(preference)); 2263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen balloon_collection_->SetPositionPreference(preference); 2273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 2283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 229201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid NotificationUIManager::Observe(NotificationType type, 230201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const NotificationSource& source, 231201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const NotificationDetails& details) { 2323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (type == NotificationType::APP_TERMINATING) { 233201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CancelAll(); 2343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } else if (type == NotificationType::PREF_CHANGED) { 2353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::string* name = Details<std::string>(details).ptr(); 2363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (*name == prefs::kDesktopNotificationPosition) 2373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen balloon_collection_->SetPositionPreference( 2383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static_cast<BalloonCollection::PositionPreference>( 2393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen position_pref_.GetValue())); 2403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } else { 241201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NOTREACHED(); 2423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 243201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 244