diff options
6 files changed, 82 insertions, 12 deletions
diff --git a/chrome/browser/chromeos/extensions/file_browser_notifications_browsertest.cc b/chrome/browser/chromeos/extensions/file_browser_notifications_browsertest.cc index 3b41a46..bb2f99d 100644 --- a/chrome/browser/chromeos/extensions/file_browser_notifications_browsertest.cc +++ b/chrome/browser/chromeos/extensions/file_browser_notifications_browsertest.cc @@ -76,6 +76,10 @@ class FileBrowserNotificationsTest : public InProcessBrowserTest { public: FileBrowserNotificationsTest() : collection_(NULL) {} + virtual void CleanUpOnMainThread() OVERRIDE { + notifications_.reset(); + } + protected: // This must be initialized late in test startup. void InitNotifications() { diff --git a/chrome/browser/chromeos/notifications/system_notification.cc b/chrome/browser/chromeos/notifications/system_notification.cc index f248707..70a842a 100644 --- a/chrome/browser/chromeos/notifications/system_notification.cc +++ b/chrome/browser/chromeos/notifications/system_notification.cc @@ -11,10 +11,12 @@ #include "chrome/browser/notifications/notification.h" #include "chrome/browser/notifications/notification_ui_manager.h" #include "chrome/browser/ui/webui/web_ui_util.h" +#include "chromeos/dbus/dbus_thread_manager.h" namespace chromeos { void SystemNotification::Init(int icon_resource_id) { + DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this); collection_ = static_cast<BalloonCollectionImplType*>( g_browser_process->notification_ui_manager()->balloon_collection()); std::string url = web_ui_util::GetImageDataUrlFromResource(icon_resource_id); @@ -32,7 +34,9 @@ SystemNotification::SystemNotification(Profile* profile, delegate_(delegate), title_(title), visible_(false), - urgent_(false) { + sticky_(false), + urgent_(false), + show_on_unlock_(false) { Init(icon_resource_id); } @@ -45,11 +49,23 @@ SystemNotification::SystemNotification(Profile* profile, delegate_(new Delegate(id)), title_(title), visible_(false), - urgent_(false) { + sticky_(false), + urgent_(false), + show_on_unlock_(false) { Init(icon_resource_id); } SystemNotification::~SystemNotification() { + DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); +} + +void SystemNotification::UnlockScreen() { + if (show_on_unlock_) { + DCHECK(!visible_); + Notification notify = SystemNotificationFactory::Create( + icon_, title_, message_, link_, delegate_.get()); + ShowNotification(notify); + } } void SystemNotification::Show(const string16& message, @@ -63,8 +79,24 @@ void SystemNotification::Show(const string16& message, const BalloonViewHost::MessageCallback& callback, bool urgent, bool sticky) { - Notification notify = SystemNotificationFactory::Create(icon_, - title_, message, link, delegate_.get()); + message_ = message; + link_ = link; + callback_ = callback; + sticky_ = sticky; + + if (DBusThreadManager::Get()->GetPowerManagerClient()->GetIsScreenLocked()) { + if (visible_ && urgent && !urgent_) { + // Hide the notification so that we show/update it on unlock. + Hide(); + urgent_ = true; + } + if (!visible_) + show_on_unlock_ = true; + return; + } + + Notification notify = SystemNotificationFactory::Create( + icon_, title_, message_, link_, delegate_.get()); if (visible_) { // Force showing a user hidden notification on an urgent transition. if (urgent && !urgent_) { @@ -74,14 +106,17 @@ void SystemNotification::Show(const string16& message, collection_->UpdateNotification(notify); } } - if (!visible_) { - collection_->AddSystemNotification(notify, profile_, sticky); - collection_->AddWebUIMessageCallback(notify, "link", callback); - } - visible_ = true; + if (!visible_) + ShowNotification(notify); urgent_ = urgent; } +void SystemNotification::ShowNotification(const Notification& notify) { + collection_->AddSystemNotification(notify, profile_, sticky_); + collection_->AddWebUIMessageCallback(notify, "link", callback_); + visible_ = true; +} + void SystemNotification::Hide() { if (visible_) { collection_->RemoveById(delegate_->id()); diff --git a/chrome/browser/chromeos/notifications/system_notification.h b/chrome/browser/chromeos/notifications/system_notification.h index ff9275a..aacca0d 100644 --- a/chrome/browser/chromeos/notifications/system_notification.h +++ b/chrome/browser/chromeos/notifications/system_notification.h @@ -13,8 +13,10 @@ #include "base/string16.h" #include "chrome/browser/chromeos/notifications/balloon_view_host_chromeos.h" // MessageCallback #include "chrome/browser/notifications/notification_delegate.h" +#include "chromeos/dbus/power_manager_client.h" #include "googleurl/src/gurl.h" +class Notification; class Profile; namespace chromeos { @@ -24,7 +26,7 @@ typedef class BalloonCollectionImplAura BalloonCollectionImplType; // The system notification object handles the display of a system notification -class SystemNotification { +class SystemNotification : public PowerManagerClient::Observer { public: // The profile is the current user profile. The id is any string used // to uniquely identify this notification. The title is the title of @@ -42,6 +44,9 @@ class SystemNotification { virtual ~SystemNotification(); + // PowerManagerClient::Observer override. + virtual void UnlockScreen() OVERRIDE; + void set_title(const string16& title) { title_ = title; } // Show will show or update the message for this notification @@ -82,14 +87,20 @@ class SystemNotification { }; void Init(int icon_resource_id); + void ShowNotification(const Notification& notify); Profile* profile_; BalloonCollectionImplType* collection_; scoped_refptr<NotificationDelegate> delegate_; + string16 message_; + string16 link_; + BalloonViewHost::MessageCallback callback_; GURL icon_; string16 title_; bool visible_; + bool sticky_; bool urgent_; + bool show_on_unlock_; DISALLOW_COPY_AND_ASSIGN(SystemNotification); }; diff --git a/chromeos/dbus/mock_power_manager_client.h b/chromeos/dbus/mock_power_manager_client.h index 81e8fdd..5d03e31 100644 --- a/chromeos/dbus/mock_power_manager_client.h +++ b/chromeos/dbus/mock_power_manager_client.h @@ -40,6 +40,7 @@ class MockPowerManagerClient : public PowerManagerClient { MOCK_METHOD0(NotifyScreenLockCompleted, void(void)); MOCK_METHOD0(NotifyScreenUnlockRequested, void(void)); MOCK_METHOD0(NotifyScreenUnlockCompleted, void(void)); + MOCK_METHOD0(GetIsScreenLocked, bool(void)); }; } // namespace chromeos diff --git a/chromeos/dbus/power_manager_client.cc b/chromeos/dbus/power_manager_client.cc index 5c03a1a..e09e2f8 100644 --- a/chromeos/dbus/power_manager_client.cc +++ b/chromeos/dbus/power_manager_client.cc @@ -29,6 +29,7 @@ class PowerManagerClientImpl : public PowerManagerClient { public: explicit PowerManagerClientImpl(dbus::Bus* bus) : power_manager_proxy_(NULL), + screen_locked_(false), weak_ptr_factory_(this) { power_manager_proxy_ = bus->GetObjectProxy( power_manager::kPowerManagerServiceName, @@ -270,6 +271,10 @@ class PowerManagerClientImpl : public PowerManagerClient { SimpleMethodCallToPowerManager(power_manager::kScreenIsUnlockedMethod); } + virtual bool GetIsScreenLocked() OVERRIDE { + return screen_locked_; + } + private: // Called when a dbus signal is initially connected. void SignalConnected(const std::string& interface_name, @@ -437,10 +442,12 @@ class PowerManagerClientImpl : public PowerManagerClient { // as expected. As per http://crbug.com/126217, this will help determine // if the problem is with dbus or in chrome. LOG(WARNING) << "LockScreen signal received from power manager."; + screen_locked_ = true; FOR_EACH_OBSERVER(Observer, observers_, LockScreen()); } void ScreenUnlockSignalReceived(dbus::Signal* signal) { + screen_locked_ = false; FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen()); } @@ -502,6 +509,7 @@ class PowerManagerClientImpl : public PowerManagerClient { dbus::ObjectProxy* power_manager_proxy_; dbus::ObjectProxy* session_manager_proxy_; ObserverList<Observer> observers_; + bool screen_locked_; base::WeakPtrFactory<PowerManagerClientImpl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(PowerManagerClientImpl); @@ -515,7 +523,8 @@ class PowerManagerClientStubImpl : public PowerManagerClient { : discharging_(true), battery_percentage_(40), brightness_(50.0), - pause_count_(2) { + pause_count_(2), + screen_locked_(false) { } virtual ~PowerManagerClientStubImpl() {} @@ -589,14 +598,18 @@ class PowerManagerClientStubImpl : public PowerManagerClient { const PowerStateRequestIdCallback& callback) OVERRIDE {} virtual void NotifyScreenLockRequested() OVERRIDE { + screen_locked_ = true; FOR_EACH_OBSERVER(Observer, observers_, LockScreen()); } virtual void NotifyScreenLockCompleted() OVERRIDE {} virtual void NotifyScreenUnlockRequested() OVERRIDE { + screen_locked_ = false; FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen()); } - virtual void NotifyScreenUnlockCompleted() OVERRIDE {} + virtual bool GetIsScreenLocked() OVERRIDE { + return screen_locked_; + } private: void Update() { @@ -644,6 +657,7 @@ class PowerManagerClientStubImpl : public PowerManagerClient { ObserverList<Observer> observers_; base::RepeatingTimer<PowerManagerClientStubImpl> timer_; PowerSupplyStatus status_; + bool screen_locked_; }; PowerManagerClient::PowerManagerClient() { diff --git a/chromeos/dbus/power_manager_client.h b/chromeos/dbus/power_manager_client.h index 00c27b8..e224395 100644 --- a/chromeos/dbus/power_manager_client.h +++ b/chromeos/dbus/power_manager_client.h @@ -141,6 +141,11 @@ class CHROMEOS_EXPORT PowerManagerClient { // Notifies PowerManager that screen is unlocked. virtual void NotifyScreenUnlockCompleted() = 0; + // Return whether or not the screen is locked. Implementation should cache + // this state so that it can return immediately. Useful for observers that + // need to know the current screen lock state when they are added. + virtual bool GetIsScreenLocked() = 0; + // Idle management functions: // Calculates idle time asynchronously, after the idle time request has |