Commit 18a62fe6 authored by David Bienvenu's avatar David Bienvenu Committed by Commit Bot

Mark windows occluded when screen is locked, on Windows.

When native-win-occlusion is turned on, this will cause the page visiblity API to get triggered
when the screen is locked/unlocked.

Bug: 532128, 813093
Change-Id: Ic747188d31ebf9a692a6913d9b84a70f86c9d2aa
Reviewed-on: https://chromium-review.googlesource.com/c/1481581Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Commit-Queue: David Bienvenu <davidbienvenu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635202}
parent 1ce2fdbe
...@@ -221,6 +221,10 @@ jumbo_component("aura") { ...@@ -221,6 +221,10 @@ jumbo_component("aura") {
] ]
} }
if (is_win) {
libs = [ "wtsapi32.lib" ]
}
if (use_ozone) { if (use_ozone) {
deps += [ "//ui/ozone" ] deps += [ "//ui/ozone" ]
public += [ "screen_ozone.h" ] public += [ "screen_ozone.h" ]
......
...@@ -99,7 +99,10 @@ NativeWindowOcclusionTrackerWin::NativeWindowOcclusionTrackerWin() ...@@ -99,7 +99,10 @@ NativeWindowOcclusionTrackerWin::NativeWindowOcclusionTrackerWin()
base::TaskPriority::USER_VISIBLE, base::TaskPriority::USER_VISIBLE,
// Occlusion calculation doesn't need to happen on shutdown. // Occlusion calculation doesn't need to happen on shutdown.
// event hooks should also be cleaned up by Windows. // event hooks should also be cleaned up by Windows.
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) { base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
session_change_observer_(
base::BindRepeating(&NativeWindowOcclusionTrackerWin::OnSessionChange,
base::Unretained(this))) {
occlusion_calculator_ = std::make_unique<WindowOcclusionCalculator>( occlusion_calculator_ = std::make_unique<WindowOcclusionCalculator>(
update_occlusion_task_runner_, base::SequencedTaskRunnerHandle::Get()); update_occlusion_task_runner_, base::SequencedTaskRunnerHandle::Get());
} }
...@@ -186,6 +189,19 @@ void NativeWindowOcclusionTrackerWin::UpdateOcclusionState( ...@@ -186,6 +189,19 @@ void NativeWindowOcclusionTrackerWin::UpdateOcclusionState(
} }
} }
void NativeWindowOcclusionTrackerWin::OnSessionChange(WPARAM status_code) {
if (status_code == WTS_SESSION_LOCK) {
// Tell all root windows that they're occluded.
for (const auto& root_window_hwnd_pair : hwnd_root_window_map_) {
root_window_hwnd_pair.second->GetHost()->SetNativeWindowOcclusionState(
Window::OcclusionState::OCCLUDED);
}
}
// Other session changes don't need to trigger occlusion calculation. In
// particular, UNLOCK will cause a foreground window change, which will
// trigger an occlusion calculation on its own.
}
NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
WindowOcclusionCalculator( WindowOcclusionCalculator(
scoped_refptr<base::SequencedTaskRunner> task_runner, scoped_refptr<base::SequencedTaskRunner> task_runner,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <windows.h> #include <windows.h>
#include <winuser.h> #include <winuser.h>
#include <memory>
#include <vector> #include <vector>
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
#include "ui/aura/aura_export.h" #include "ui/aura/aura_export.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
#include "ui/base/win/session_change_observer.h"
namespace aura { namespace aura {
...@@ -199,6 +201,10 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin : public WindowObserver { ...@@ -199,6 +201,10 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin : public WindowObserver {
void UpdateOcclusionState(const base::flat_map<HWND, Window::OcclusionState>& void UpdateOcclusionState(const base::flat_map<HWND, Window::OcclusionState>&
root_window_hwnds_occlusion_state); root_window_hwnds_occlusion_state);
// This is called with session changed notifications. If the screen is locked,
// it marks app windows as occluded.
void OnSessionChange(WPARAM status_code);
// Task runner to call ComputeNativeWindowOcclusionStatus, and to handle // Task runner to call ComputeNativeWindowOcclusionStatus, and to handle
// Windows event notifications, off of the UI thread. // Windows event notifications, off of the UI thread.
const scoped_refptr<base::SequencedTaskRunner> update_occlusion_task_runner_; const scoped_refptr<base::SequencedTaskRunner> update_occlusion_task_runner_;
...@@ -213,6 +219,9 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin : public WindowObserver { ...@@ -213,6 +219,9 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin : public WindowObserver {
std::unique_ptr<WindowOcclusionCalculator> occlusion_calculator_; std::unique_ptr<WindowOcclusionCalculator> occlusion_calculator_;
// Manages observation of Windows Session Change messages.
ui::SessionChangeObserver session_change_observer_;
DISALLOW_COPY_AND_ASSIGN(NativeWindowOcclusionTrackerWin); DISALLOW_COPY_AND_ASSIGN(NativeWindowOcclusionTrackerWin);
}; };
......
...@@ -282,6 +282,8 @@ jumbo_component("base") { ...@@ -282,6 +282,8 @@ jumbo_component("base") {
"win/mouse_wheel_util.h", "win/mouse_wheel_util.h",
"win/scoped_ole_initializer.cc", "win/scoped_ole_initializer.cc",
"win/scoped_ole_initializer.h", "win/scoped_ole_initializer.h",
"win/session_change_observer.cc",
"win/session_change_observer.h",
"win/shell.cc", "win/shell.cc",
"win/shell.h", "win/shell.h",
"win/touch_input.cc", "win/touch_input.cc",
...@@ -535,6 +537,7 @@ jumbo_component("base") { ...@@ -535,6 +537,7 @@ jumbo_component("base") {
"d2d1.lib", "d2d1.lib",
"dwmapi.lib", "dwmapi.lib",
"oleacc.lib", "oleacc.lib",
"wtsapi32.lib",
] ]
} else { } else {
if (!use_aura) { if (!use_aura) {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "ui/views/win/windows_session_change_observer.h" #include "ui/base/win/session_change_observer.h"
#include <wtsapi32.h> #include <wtsapi32.h>
...@@ -18,30 +18,37 @@ ...@@ -18,30 +18,37 @@
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "ui/gfx/win/singleton_hwnd.h" #include "ui/gfx/win/singleton_hwnd.h"
#include "ui/gfx/win/singleton_hwnd_observer.h" #include "ui/gfx/win/singleton_hwnd_observer.h"
#include "ui/views/views_delegate.h"
namespace views { namespace ui {
class WindowsSessionChangeObserver::WtsRegistrationNotificationManager { class SessionChangeObserver::WtsRegistrationNotificationManager {
public: public:
static WtsRegistrationNotificationManager* GetInstance() { static WtsRegistrationNotificationManager* GetInstance() {
return base::Singleton<WtsRegistrationNotificationManager>::get(); return base::Singleton<WtsRegistrationNotificationManager>::get();
} }
WtsRegistrationNotificationManager() { WtsRegistrationNotificationManager() {
AddSingletonHwndObserver(); DCHECK(!singleton_hwnd_observer_);
} singleton_hwnd_observer_.reset(new gfx::SingletonHwndObserver(
base::BindRepeating(&WtsRegistrationNotificationManager::OnWndProc,
base::Unretained(this))));
~WtsRegistrationNotificationManager() { base::OnceClosure wts_register = base::BindOnce(
RemoveSingletonHwndObserver(); base::IgnoreResult(&WTSRegisterSessionNotification),
gfx::SingletonHwnd::GetInstance()->hwnd(), NOTIFY_FOR_THIS_SESSION);
base::CreateCOMSTATaskRunnerWithTraits({})->PostTask(
FROM_HERE, std::move(wts_register));
} }
void AddObserver(WindowsSessionChangeObserver* observer) { ~WtsRegistrationNotificationManager() { RemoveSingletonHwndObserver(); }
void AddObserver(SessionChangeObserver* observer) {
DCHECK(singleton_hwnd_observer_); DCHECK(singleton_hwnd_observer_);
observer_list_.AddObserver(observer); observer_list_.AddObserver(observer);
} }
void RemoveObserver(WindowsSessionChangeObserver* observer) { void RemoveObserver(SessionChangeObserver* observer) {
observer_list_.RemoveObserver(observer); observer_list_.RemoveObserver(observer);
} }
...@@ -52,7 +59,7 @@ class WindowsSessionChangeObserver::WtsRegistrationNotificationManager { ...@@ -52,7 +59,7 @@ class WindowsSessionChangeObserver::WtsRegistrationNotificationManager {
void OnWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { void OnWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch (message) { switch (message) {
case WM_WTSSESSION_CHANGE: case WM_WTSSESSION_CHANGE:
for (WindowsSessionChangeObserver& observer : observer_list_) for (SessionChangeObserver& observer : observer_list_)
observer.OnSessionChange(wparam); observer.OnSessionChange(wparam);
break; break;
case WM_DESTROY: case WM_DESTROY:
...@@ -61,27 +68,6 @@ class WindowsSessionChangeObserver::WtsRegistrationNotificationManager { ...@@ -61,27 +68,6 @@ class WindowsSessionChangeObserver::WtsRegistrationNotificationManager {
} }
} }
void AddSingletonHwndObserver() {
DCHECK(!singleton_hwnd_observer_);
singleton_hwnd_observer_.reset(new gfx::SingletonHwndObserver(
base::Bind(&WtsRegistrationNotificationManager::OnWndProc,
base::Unretained(this))));
base::OnceClosure wts_register = base::BindOnce(
base::IgnoreResult(&WTSRegisterSessionNotification),
gfx::SingletonHwnd::GetInstance()->hwnd(), NOTIFY_FOR_THIS_SESSION);
// This should probably always be async but it wasn't async in the absence
// of a ViewsDelegate prior to the migration to TaskScheduler and making it
// async breaks many unrelated views unittests.
if (ViewsDelegate::GetInstance()) {
base::CreateCOMSTATaskRunnerWithTraits({})->PostTask(
FROM_HERE, std::move(wts_register));
} else {
std::move(wts_register).Run();
}
}
void RemoveSingletonHwndObserver() { void RemoveSingletonHwndObserver() {
if (!singleton_hwnd_observer_) if (!singleton_hwnd_observer_)
return; return;
...@@ -94,37 +80,35 @@ class WindowsSessionChangeObserver::WtsRegistrationNotificationManager { ...@@ -94,37 +80,35 @@ class WindowsSessionChangeObserver::WtsRegistrationNotificationManager {
// Under both cases we are in shutdown, which means no other worker threads // Under both cases we are in shutdown, which means no other worker threads
// can be running. // can be running.
WTSUnRegisterSessionNotification(gfx::SingletonHwnd::GetInstance()->hwnd()); WTSUnRegisterSessionNotification(gfx::SingletonHwnd::GetInstance()->hwnd());
for (WindowsSessionChangeObserver& observer : observer_list_) for (SessionChangeObserver& observer : observer_list_)
observer.ClearCallback(); observer.ClearCallback();
} }
base::ObserverList<WindowsSessionChangeObserver, true>::Unchecked base::ObserverList<SessionChangeObserver, true>::Unchecked observer_list_;
observer_list_;
std::unique_ptr<gfx::SingletonHwndObserver> singleton_hwnd_observer_; std::unique_ptr<gfx::SingletonHwndObserver> singleton_hwnd_observer_;
DISALLOW_COPY_AND_ASSIGN(WtsRegistrationNotificationManager); DISALLOW_COPY_AND_ASSIGN(WtsRegistrationNotificationManager);
}; };
WindowsSessionChangeObserver::WindowsSessionChangeObserver( SessionChangeObserver::SessionChangeObserver(const WtsCallback& callback)
const WtsCallback& callback)
: callback_(callback) { : callback_(callback) {
DCHECK(!callback_.is_null()); DCHECK(!callback_.is_null());
WtsRegistrationNotificationManager::GetInstance()->AddObserver(this); WtsRegistrationNotificationManager::GetInstance()->AddObserver(this);
} }
WindowsSessionChangeObserver::~WindowsSessionChangeObserver() { SessionChangeObserver::~SessionChangeObserver() {
ClearCallback(); ClearCallback();
} }
void WindowsSessionChangeObserver::OnSessionChange(WPARAM wparam) { void SessionChangeObserver::OnSessionChange(WPARAM wparam) {
callback_.Run(wparam); callback_.Run(wparam);
} }
void WindowsSessionChangeObserver::ClearCallback() { void SessionChangeObserver::ClearCallback() {
if (!callback_.is_null()) { if (!callback_.is_null()) {
callback_.Reset(); callback_.Reset();
WtsRegistrationNotificationManager::GetInstance()->RemoveObserver(this); WtsRegistrationNotificationManager::GetInstance()->RemoveObserver(this);
} }
} }
} // namespace views } // namespace ui
...@@ -2,23 +2,26 @@ ...@@ -2,23 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef UI_VIEWS_WIN_WINDOWS_SESSION_CHANGE_OBSERVER_H_ #ifndef UI_BASE_WIN_SESSION_CHANGE_OBSERVER_H_
#define UI_VIEWS_WIN_WINDOWS_SESSION_CHANGE_OBSERVER_H_ #define UI_BASE_WIN_SESSION_CHANGE_OBSERVER_H_
#include <windows.h> #include <windows.h>
#include "base/callback.h" #include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/base/ui_base_export.h"
namespace views { namespace ui {
// Calls the provided callback on WM_WTSSESSION_CHANGE messages along with // Calls the provided callback on WM_WTSSESSION_CHANGE messages along with
// managing the tricky business of observing a singleton object. // managing the tricky business of observing a singleton object.
class WindowsSessionChangeObserver { class UI_BASE_EXPORT SessionChangeObserver {
public: public:
typedef base::Callback<void(WPARAM)> WtsCallback; // WPARAM is the wparam passed to the OnWndProc when message is
explicit WindowsSessionChangeObserver(const WtsCallback& callback); // WM_WTSSESSION_CHANGE.
~WindowsSessionChangeObserver(); typedef base::RepeatingCallback<void(WPARAM)> WtsCallback;
explicit SessionChangeObserver(const WtsCallback& callback);
~SessionChangeObserver();
private: private:
class WtsRegistrationNotificationManager; class WtsRegistrationNotificationManager;
...@@ -28,9 +31,9 @@ class WindowsSessionChangeObserver { ...@@ -28,9 +31,9 @@ class WindowsSessionChangeObserver {
WtsCallback callback_; WtsCallback callback_;
DISALLOW_COPY_AND_ASSIGN(WindowsSessionChangeObserver); DISALLOW_COPY_AND_ASSIGN(SessionChangeObserver);
}; };
} // namespace views } // namespace ui
#endif // UI_VIEWS_WIN_WINDOWS_SESSION_CHANGE_OBSERVER_H_ #endif // UI_BASE_WIN_SESSION_CHANGE_OBSERVER_H_
...@@ -566,7 +566,6 @@ jumbo_component("views") { ...@@ -566,7 +566,6 @@ jumbo_component("views") {
"win/hwnd_util.h", "win/hwnd_util.h",
"win/pen_event_processor.h", "win/pen_event_processor.h",
"win/scoped_fullscreen_visibility.h", "win/scoped_fullscreen_visibility.h",
"win/windows_session_change_observer.h",
] ]
sources += [ sources += [
"widget/widget_hwnd_utils.cc", "widget/widget_hwnd_utils.cc",
...@@ -575,14 +574,12 @@ jumbo_component("views") { ...@@ -575,14 +574,12 @@ jumbo_component("views") {
"win/hwnd_util_aurawin.cc", "win/hwnd_util_aurawin.cc",
"win/pen_event_processor.cc", "win/pen_event_processor.cc",
"win/scoped_fullscreen_visibility.cc", "win/scoped_fullscreen_visibility.cc",
"win/windows_session_change_observer.cc",
] ]
libs = [ libs = [
"dwmapi.lib", "dwmapi.lib",
"imm32.lib", "imm32.lib",
"oleacc.lib", "oleacc.lib",
"uiautomationcore.lib", "uiautomationcore.lib",
"wtsapi32.lib",
] ]
ldflags = [ "/DELAYLOAD:user32.dll" ] ldflags = [ "/DELAYLOAD:user32.dll" ]
deps += [ deps += [
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "ui/base/win/internal_constants.h" #include "ui/base/win/internal_constants.h"
#include "ui/base/win/lock_state.h" #include "ui/base/win/lock_state.h"
#include "ui/base/win/mouse_wheel_util.h" #include "ui/base/win/mouse_wheel_util.h"
#include "ui/base/win/session_change_observer.h"
#include "ui/base/win/shell.h" #include "ui/base/win/shell.h"
#include "ui/base/win/touch_input.h" #include "ui/base/win/touch_input.h"
#include "ui/display/win/dpi.h" #include "ui/display/win/dpi.h"
...@@ -59,7 +60,6 @@ ...@@ -59,7 +60,6 @@
#include "ui/views/win/fullscreen_handler.h" #include "ui/views/win/fullscreen_handler.h"
#include "ui/views/win/hwnd_message_handler_delegate.h" #include "ui/views/win/hwnd_message_handler_delegate.h"
#include "ui/views/win/scoped_fullscreen_visibility.h" #include "ui/views/win/scoped_fullscreen_visibility.h"
#include "ui/views/win/windows_session_change_observer.h"
namespace views { namespace views {
namespace { namespace {
...@@ -1596,9 +1596,9 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) { ...@@ -1596,9 +1596,9 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
delegate_->HandleCreate(); delegate_->HandleCreate();
windows_session_change_observer_.reset(new WindowsSessionChangeObserver( session_change_observer_ =
base::Bind(&HWNDMessageHandler::OnSessionChange, std::make_unique<ui::SessionChangeObserver>(base::BindRepeating(
base::Unretained(this)))); &HWNDMessageHandler::OnSessionChange, base::Unretained(this)));
dpi_ = display::win::ScreenWin::GetDPIForHWND(hwnd()); dpi_ = display::win::ScreenWin::GetDPIForHWND(hwnd());
...@@ -1608,7 +1608,7 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) { ...@@ -1608,7 +1608,7 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
void HWNDMessageHandler::OnDestroy() { void HWNDMessageHandler::OnDestroy() {
::RemoveProp(hwnd(), ui::kWindowTranslucent); ::RemoveProp(hwnd(), ui::kWindowTranslucent);
windows_session_change_observer_.reset(nullptr); session_change_observer_.reset(nullptr);
delegate_->HandleDestroying(); delegate_->HandleDestroying();
// If the window going away is a fullscreen window then remove its references // If the window going away is a fullscreen window then remove its references
// from the full screen window map. // from the full screen window map.
......
...@@ -44,13 +44,13 @@ class AXSystemCaretWin; ...@@ -44,13 +44,13 @@ class AXSystemCaretWin;
class InputMethod; class InputMethod;
class TextInputClient; class TextInputClient;
class ViewProp; class ViewProp;
class SessionChangeObserver;
} // namespace ui } // namespace ui
namespace views { namespace views {
class FullscreenHandler; class FullscreenHandler;
class HWNDMessageHandlerDelegate; class HWNDMessageHandlerDelegate;
class WindowsSessionChangeObserver;
// These two messages aren't defined in winuser.h, but they are sent to windows // These two messages aren't defined in winuser.h, but they are sent to windows
// with captions. They appear to paint the window caption and frame. // with captions. They appear to paint the window caption and frame.
...@@ -708,8 +708,7 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl, ...@@ -708,8 +708,7 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
uint32_t current_window_size_message_ = 0; uint32_t current_window_size_message_ = 0;
// Manages observation of Windows Session Change messages. // Manages observation of Windows Session Change messages.
std::unique_ptr<WindowsSessionChangeObserver> std::unique_ptr<ui::SessionChangeObserver> session_change_observer_;
windows_session_change_observer_;
// Some assistive software need to track the location of the caret. // Some assistive software need to track the location of the caret.
std::unique_ptr<ui::AXSystemCaretWin> ax_system_caret_; std::unique_ptr<ui::AXSystemCaretWin> ax_system_caret_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment