| 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 |