Automated Commit: Committing new LKGM version 7479.0.0 for chromeos.
[chromium-blink-merge.git] / ui / views / win / windows_session_change_observer.cc
blob777bf8c339a5d873a265b72f9e28c2d06edcf11e
1 // Copyright 2015 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.
5 #include "ui/views/win/windows_session_change_observer.h"
7 #include <wtsapi32.h>
8 #pragma comment(lib, "wtsapi32.lib")
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback.h"
13 #include "base/location.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/singleton.h"
17 #include "base/observer_list.h"
18 #include "base/task_runner.h"
19 #include "ui/gfx/win/singleton_hwnd.h"
20 #include "ui/gfx/win/singleton_hwnd_observer.h"
21 #include "ui/views/views_delegate.h"
23 namespace views {
25 class WindowsSessionChangeObserver::WtsRegistrationNotificationManager {
26 public:
27 static WtsRegistrationNotificationManager* GetInstance() {
28 return base::Singleton<WtsRegistrationNotificationManager>::get();
31 WtsRegistrationNotificationManager() {
32 AddSingletonHwndObserver();
35 ~WtsRegistrationNotificationManager() {
36 RemoveSingletonHwndObserver();
39 void AddObserver(WindowsSessionChangeObserver* observer) {
40 DCHECK(singleton_hwnd_observer_);
41 observer_list_.AddObserver(observer);
44 void RemoveObserver(WindowsSessionChangeObserver* observer) {
45 observer_list_.RemoveObserver(observer);
48 private:
49 friend struct base::DefaultSingletonTraits<
50 WtsRegistrationNotificationManager>;
52 void OnWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
53 switch (message) {
54 case WM_WTSSESSION_CHANGE:
55 FOR_EACH_OBSERVER(WindowsSessionChangeObserver,
56 observer_list_,
57 OnSessionChange(wparam));
58 break;
59 case WM_DESTROY:
60 RemoveSingletonHwndObserver();
61 break;
65 void AddSingletonHwndObserver() {
66 DCHECK(!singleton_hwnd_observer_);
67 singleton_hwnd_observer_.reset(new gfx::SingletonHwndObserver(
68 base::Bind(&WtsRegistrationNotificationManager::OnWndProc,
69 base::Unretained(this))));
70 scoped_refptr<base::TaskRunner> task_runner;
71 if (ViewsDelegate::GetInstance()) {
72 task_runner = ViewsDelegate::GetInstance()->GetBlockingPoolTaskRunner();
75 base::Closure wts_register =
76 base::Bind(base::IgnoreResult(&WTSRegisterSessionNotification),
77 gfx::SingletonHwnd::GetInstance()->hwnd(),
78 NOTIFY_FOR_THIS_SESSION);
79 if (task_runner) {
80 task_runner->PostTask(FROM_HERE, wts_register);
81 } else {
82 wts_register.Run();
86 void RemoveSingletonHwndObserver() {
87 if (!singleton_hwnd_observer_)
88 return;
90 singleton_hwnd_observer_.reset(nullptr);
91 // There is no race condition between this code and the worker thread.
92 // RemoveSingletonHwndObserver is only called from two places:
93 // 1) Destruction due to Singleton Destruction.
94 // 2) WM_DESTROY fired by SingletonHwnd.
95 // Under both cases we are in shutdown, which means no other worker threads
96 // can be running.
97 WTSUnRegisterSessionNotification(gfx::SingletonHwnd::GetInstance()->hwnd());
98 FOR_EACH_OBSERVER(WindowsSessionChangeObserver,
99 observer_list_,
100 ClearCallback());
103 base::ObserverList<WindowsSessionChangeObserver, true> observer_list_;
104 scoped_ptr<gfx::SingletonHwndObserver> singleton_hwnd_observer_;
106 DISALLOW_COPY_AND_ASSIGN(WtsRegistrationNotificationManager);
109 WindowsSessionChangeObserver::WindowsSessionChangeObserver(
110 const WtsCallback& callback)
111 : callback_(callback) {
112 DCHECK(!callback_.is_null());
113 WtsRegistrationNotificationManager::GetInstance()->AddObserver(this);
116 WindowsSessionChangeObserver::~WindowsSessionChangeObserver() {
117 ClearCallback();
120 void WindowsSessionChangeObserver::OnSessionChange(WPARAM wparam) {
121 callback_.Run(wparam);
124 void WindowsSessionChangeObserver::ClearCallback() {
125 if (!callback_.is_null()) {
126 callback_.Reset();
127 WtsRegistrationNotificationManager::GetInstance()->RemoveObserver(this);
131 } // namespace views