OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/curtain_mode.h" | 5 #include "remoting/host/curtain_mode.h" |
6 | 6 |
7 #include <ApplicationServices/ApplicationServices.h> | 7 #include <ApplicationServices/ApplicationServices.h> |
8 #include <Carbon/Carbon.h> | 8 #include <Carbon/Carbon.h> |
9 #include <Security/Security.h> | 9 #include <Security/Security.h> |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 DISALLOW_COPY_AND_ASSIGN(SessionWatcher); | 77 DISALLOW_COPY_AND_ASSIGN(SessionWatcher); |
78 }; | 78 }; |
79 | 79 |
80 SessionWatcher::SessionWatcher( | 80 SessionWatcher::SessionWatcher( |
81 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 81 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
82 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, | 82 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
83 base::WeakPtr<ClientSessionControl> client_session_control) | 83 base::WeakPtr<ClientSessionControl> client_session_control) |
84 : caller_task_runner_(caller_task_runner), | 84 : caller_task_runner_(caller_task_runner), |
85 ui_task_runner_(ui_task_runner), | 85 ui_task_runner_(ui_task_runner), |
86 client_session_control_(client_session_control), | 86 client_session_control_(client_session_control), |
87 event_handler_(NULL) { | 87 event_handler_(nullptr) { |
88 } | 88 } |
89 | 89 |
90 void SessionWatcher::Start() { | 90 void SessionWatcher::Start() { |
91 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 91 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
92 | 92 |
93 // Activate curtain asynchronously since it has to be done on the UI thread. | 93 // Activate curtain asynchronously since it has to be done on the UI thread. |
94 // Because the curtain activation is asynchronous, it is possible that | 94 // Because the curtain activation is asynchronous, it is possible that |
95 // the connection will not be curtained for a brief moment. This seems to be | 95 // the connection will not be curtained for a brief moment. This seems to be |
96 // unaviodable as long as the curtain enforcement depends on processing of | 96 // unaviodable as long as the curtain enforcement depends on processing of |
97 // the switch-in notifications. | 97 // the switch-in notifications. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 // current session so that the console session is not affected if it fails. | 130 // current session so that the console session is not affected if it fails. |
131 if (!InstallEventHandler()) { | 131 if (!InstallEventHandler()) { |
132 LOG(ERROR) << "Failed to install the switch-in handler."; | 132 LOG(ERROR) << "Failed to install the switch-in handler."; |
133 DisconnectSession(); | 133 DisconnectSession(); |
134 return; | 134 return; |
135 } | 135 } |
136 | 136 |
137 base::ScopedCFTypeRef<CFDictionaryRef> session( | 137 base::ScopedCFTypeRef<CFDictionaryRef> session( |
138 CGSessionCopyCurrentDictionary()); | 138 CGSessionCopyCurrentDictionary()); |
139 | 139 |
140 // CGSessionCopyCurrentDictionary has been observed to return NULL in some | 140 // CGSessionCopyCurrentDictionary has been observed to return nullptr in some |
141 // cases. Once the system is in this state, curtain mode will fail as the | 141 // cases. Once the system is in this state, curtain mode will fail as the |
142 // CGSession command thinks the session is not attached to the console. The | 142 // CGSession command thinks the session is not attached to the console. The |
143 // only known remedy is logout or reboot. Since we're not sure what causes | 143 // only known remedy is logout or reboot. Since we're not sure what causes |
144 // this, or how common it is, a crash report is useful in this case (note | 144 // this, or how common it is, a crash report is useful in this case (note |
145 // that the connection would have to be refused in any case, so this is no | 145 // that the connection would have to be refused in any case, so this is no |
146 // loss of functionality). | 146 // loss of functionality). |
147 CHECK(session != NULL); | 147 CHECK(session != nullptr); |
148 | 148 |
149 const void* on_console = CFDictionaryGetValue(session, | 149 const void* on_console = CFDictionaryGetValue(session, |
150 kCGSessionOnConsoleKey); | 150 kCGSessionOnConsoleKey); |
151 const void* logged_in = CFDictionaryGetValue(session, kCGSessionLoginDoneKey); | 151 const void* logged_in = CFDictionaryGetValue(session, kCGSessionLoginDoneKey); |
152 if (logged_in == kCFBooleanTrue && on_console == kCFBooleanTrue) { | 152 if (logged_in == kCFBooleanTrue && on_console == kCFBooleanTrue) { |
153 pid_t child = fork(); | 153 pid_t child = fork(); |
154 if (child == 0) { | 154 if (child == 0) { |
155 execl(kCGSessionPath, kCGSessionPath, "-suspend", NULL); | 155 execl(kCGSessionPath, kCGSessionPath, "-suspend", nullptr); |
156 _exit(1); | 156 _exit(1); |
157 } else if (child > 0) { | 157 } else if (child > 0) { |
158 int status = 0; | 158 int status = 0; |
159 waitpid(child, &status, 0); | 159 waitpid(child, &status, 0); |
160 if (status != 0) { | 160 if (status != 0) { |
161 LOG(ERROR) << kCGSessionPath << " failed."; | 161 LOG(ERROR) << kCGSessionPath << " failed."; |
162 DisconnectSession(); | 162 DisconnectSession(); |
163 return; | 163 return; |
164 } | 164 } |
165 } else { | 165 } else { |
166 LOG(ERROR) << "fork() failed."; | 166 LOG(ERROR) << "fork() failed."; |
167 DisconnectSession(); | 167 DisconnectSession(); |
168 return; | 168 return; |
169 } | 169 } |
170 } | 170 } |
171 } | 171 } |
172 | 172 |
173 bool SessionWatcher::InstallEventHandler() { | 173 bool SessionWatcher::InstallEventHandler() { |
174 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 174 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
175 DCHECK(!event_handler_); | 175 DCHECK(!event_handler_); |
176 | 176 |
177 EventTypeSpec event; | 177 EventTypeSpec event; |
178 event.eventClass = kEventClassSystem; | 178 event.eventClass = kEventClassSystem; |
179 event.eventKind = kEventSystemUserSessionActivated; | 179 event.eventKind = kEventSystemUserSessionActivated; |
180 OSStatus result = ::InstallApplicationEventHandler( | 180 OSStatus result = ::InstallApplicationEventHandler( |
181 NewEventHandlerUPP(SessionActivateHandler), 1, &event, this, | 181 NewEventHandlerUPP(SessionActivateHandler), 1, &event, this, |
182 &event_handler_); | 182 &event_handler_); |
183 if (result != noErr) { | 183 if (result != noErr) { |
184 event_handler_ = NULL; | 184 event_handler_ = nullptr; |
185 DisconnectSession(); | 185 DisconnectSession(); |
186 return false; | 186 return false; |
187 } | 187 } |
188 | 188 |
189 return true; | 189 return true; |
190 } | 190 } |
191 | 191 |
192 void SessionWatcher::RemoveEventHandler() { | 192 void SessionWatcher::RemoveEventHandler() { |
193 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 193 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
194 | 194 |
195 if (event_handler_) { | 195 if (event_handler_) { |
196 ::RemoveEventHandler(event_handler_); | 196 ::RemoveEventHandler(event_handler_); |
197 event_handler_ = NULL; | 197 event_handler_ = nullptr; |
198 } | 198 } |
199 } | 199 } |
200 | 200 |
201 void SessionWatcher::DisconnectSession() { | 201 void SessionWatcher::DisconnectSession() { |
202 if (!caller_task_runner_->BelongsToCurrentThread()) { | 202 if (!caller_task_runner_->BelongsToCurrentThread()) { |
203 caller_task_runner_->PostTask( | 203 caller_task_runner_->PostTask( |
204 FROM_HERE, base::Bind(&SessionWatcher::DisconnectSession, this)); | 204 FROM_HERE, base::Bind(&SessionWatcher::DisconnectSession, this)); |
205 return; | 205 return; |
206 } | 206 } |
207 | 207 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 // static | 258 // static |
259 scoped_ptr<CurtainMode> CurtainMode::Create( | 259 scoped_ptr<CurtainMode> CurtainMode::Create( |
260 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 260 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
261 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, | 261 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
262 base::WeakPtr<ClientSessionControl> client_session_control) { | 262 base::WeakPtr<ClientSessionControl> client_session_control) { |
263 return make_scoped_ptr(new CurtainModeMac( | 263 return make_scoped_ptr(new CurtainModeMac( |
264 caller_task_runner, ui_task_runner, client_session_control)); | 264 caller_task_runner, ui_task_runner, client_session_control)); |
265 } | 265 } |
266 | 266 |
267 } // namespace remoting | 267 } // namespace remoting |
OLD | NEW |