Index: ash/system/chromeos/power/power_event_observer.cc |
diff --git a/ash/system/chromeos/power/power_event_observer.cc b/ash/system/chromeos/power/power_event_observer.cc |
index 65567f4ed0212ae97e70810a73ca2cb144506225..78612d3d2084f5d60172f0892822c71b552490bd 100644 |
--- a/ash/system/chromeos/power/power_event_observer.cc |
+++ b/ash/system/chromeos/power/power_event_observer.cc |
@@ -8,9 +8,13 @@ |
#include "ash/shell.h" |
#include "ash/system/tray/system_tray_notifier.h" |
#include "ash/wm/power_button_controller.h" |
+#include "base/message_loop/message_loop.h" |
#include "base/prefs/pref_service.h" |
#include "chromeos/dbus/dbus_thread_manager.h" |
+#include "ui/aura/window.h" |
+#include "ui/aura/window_tree_host.h" |
#include "ui/base/user_activity/user_activity_detector.h" |
+#include "ui/compositor/compositor.h" |
#include "ui/display/chromeos/display_configurator.h" |
namespace ash { |
@@ -48,6 +52,13 @@ void PowerEventObserver::SuspendImminent() { |
VLOG(1) << "Requesting screen lock from PowerEventObserver"; |
chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> |
RequestLockScreen(); |
+ } else { |
+ // If the screen needs to be locked then rendering requests must be blocked |
+ // _after_ the lock screen is visible. Otherwise the display will show the |
+ // contents of the user's screen at resume time, which is a security issue. |
+ // This is handled in the ScreenIsLocked() method. In case the screen does |
+ // not need to be locked, we can stop rendering now. |
+ StopRenderingRequests(); |
} |
ui::UserActivityDetector::Get()->OnDisplayPowerChanging(); |
@@ -57,6 +68,13 @@ void PowerEventObserver::SuspendImminent() { |
void PowerEventObserver::SuspendDone(const base::TimeDelta& sleep_duration) { |
Shell::GetInstance()->display_configurator()->ResumeDisplays(); |
Shell::GetInstance()->system_tray_notifier()->NotifyRefreshClock(); |
+ |
+ ResumeRenderingRequests(); |
+ |
+ // If the suspend request was being blocked, clear the callback since the |
+ // request has already completed. This prevents rendering requests from being |
+ // blocked after a resume if the lock screen took too long to show. |
+ screen_lock_callback_.Reset(); |
} |
void PowerEventObserver::ScreenIsLocked() { |
@@ -65,6 +83,10 @@ void PowerEventObserver::ScreenIsLocked() { |
// Stop blocking suspend after the screen is locked. |
if (!screen_lock_callback_.is_null()) { |
VLOG(1) << "Screen locked due to suspend"; |
+ |
+ // Stop the compositors from making any new rendering requests. |
+ StopRenderingRequests(); |
+ |
// Run the callback asynchronously. ScreenIsLocked() is currently |
// called asynchronously after RequestLockScreen(), but this guards |
// against it being made synchronous later. |
@@ -79,4 +101,20 @@ void PowerEventObserver::ScreenIsUnlocked() { |
screen_locked_ = false; |
} |
+void PowerEventObserver::ResumeRenderingRequests() { |
+ for (aura::Window* window : Shell::GetAllRootWindows()) { |
+ ui::Compositor* compositor = window->GetHost()->compositor(); |
+ compositor->SetVisible(true); |
+ compositor->ScheduleDraw(); |
piman
2015/02/11 02:48:22
I don't think the ScheduleDraw should be needed.
Chirantan Ekbote
2015/02/18 02:47:13
Done.
|
+ } |
+} |
+ |
+void PowerEventObserver::StopRenderingRequests() { |
+ for (aura::Window* window : Shell::GetAllRootWindows()) { |
+ ui::Compositor* compositor = window->GetHost()->compositor(); |
+ compositor->SetVisible(false); |
+ compositor->DisableSwap(); |
+ } |
+} |
+ |
} // namespace ash |