| Index: remoting/host/curtain_mode_mac.cc
|
| diff --git a/remoting/host/curtain_mode_mac.cc b/remoting/host/curtain_mode_mac.cc
|
| index 07e186de57c1516549f3a0afb94cd4bb86ed268c..a7dedff6ea1ba109f6cec6cd41a4d2b110337788 100644
|
| --- a/remoting/host/curtain_mode_mac.cc
|
| +++ b/remoting/host/curtain_mode_mac.cc
|
| @@ -18,30 +18,37 @@ const char* kCGSessionPath =
|
|
|
| namespace remoting {
|
|
|
| -CurtainMode::CurtainMode() : event_handler_(NULL) {
|
| +CurtainMode::CurtainMode(const base::Closure& on_session_activate,
|
| + const base::Closure& on_error)
|
| + : on_session_activate_(on_session_activate),
|
| + on_error_(on_error),
|
| + connection_active_(false),
|
| + event_handler_(NULL) {
|
| }
|
|
|
| CurtainMode::~CurtainMode() {
|
| - if (event_handler_) {
|
| - RemoveEventHandler(event_handler_);
|
| - }
|
| + SetEnabled(false);
|
| }
|
|
|
| -bool CurtainMode::Init(const base::Closure& on_session_activate) {
|
| - DCHECK(on_session_activate_.is_null());
|
| - on_session_activate_ = on_session_activate;
|
| - EventTypeSpec event;
|
| - event.eventClass = kEventClassSystem;
|
| - event.eventKind = kEventSystemUserSessionActivated;
|
| - OSStatus result = InstallApplicationEventHandler(
|
| - NewEventHandlerUPP(SessionActivateHandler), 1, &event, this,
|
| - &event_handler_);
|
| - return result == noErr;
|
| +void CurtainMode::SetEnabled(bool enabled) {
|
| + if (enabled) {
|
| + if (connection_active_) {
|
| + if (!ActivateCurtain()) {
|
| + on_error_.Run();
|
| + }
|
| + }
|
| + } else {
|
| + RemoveEventHandler();
|
| + }
|
| }
|
|
|
| -void CurtainMode::OnClientAuthenticated(const std::string& jid) {
|
| - // If the current session is attached to the console and is not showing
|
| - // the logon screen then switch it out to ensure privacy.
|
| +bool CurtainMode::ActivateCurtain() {
|
| + // Try to install the switch-in handler. Do this before switching out the
|
| + // current session so that the console session is not affected if it fails.
|
| + if (!InstallEventHandler()) {
|
| + return false;
|
| + }
|
| +
|
| base::mac::ScopedCFTypeRef<CFDictionaryRef> session(
|
| CGSessionCopyCurrentDictionary());
|
| const void* on_console = CFDictionaryGetValue(session,
|
| @@ -55,8 +62,29 @@ void CurtainMode::OnClientAuthenticated(const std::string& jid) {
|
| } else if (child > 0) {
|
| int status = 0;
|
| waitpid(child, &status, 0);
|
| + if (status != 0) {
|
| + LOG(ERROR) << kCGSessionPath << " failed.";
|
| + return false;
|
| + }
|
| + } else {
|
| + LOG(ERROR) << "fork() failed.";
|
| + return false;
|
| }
|
| }
|
| + return true;
|
| +}
|
| +
|
| +// TODO(jamiewalch): This code assumes at most one client connection at a time.
|
| +// Add OnFirstClientConnected and OnLastClientDisconnected optional callbacks
|
| +// to the HostStatusObserver interface to address this.
|
| +void CurtainMode::OnClientAuthenticated(const std::string& jid) {
|
| + connection_active_ = true;
|
| + SetEnabled(true);
|
| +}
|
| +
|
| +void CurtainMode::OnClientDisconnected(const std::string& jid) {
|
| + SetEnabled(false);
|
| + connection_active_ = false;
|
| }
|
|
|
| OSStatus CurtainMode::SessionActivateHandler(EventHandlerCallRef handler,
|
| @@ -68,9 +96,28 @@ OSStatus CurtainMode::SessionActivateHandler(EventHandlerCallRef handler,
|
| }
|
|
|
| void CurtainMode::OnSessionActivate() {
|
| - if (!on_session_activate_.is_null()) {
|
| - on_session_activate_.Run();
|
| + on_session_activate_.Run();
|
| +}
|
| +
|
| +bool CurtainMode::InstallEventHandler() {
|
| + OSStatus result = noErr;
|
| + if (!event_handler_) {
|
| + EventTypeSpec event;
|
| + event.eventClass = kEventClassSystem;
|
| + event.eventKind = kEventSystemUserSessionActivated;
|
| + result = ::InstallApplicationEventHandler(
|
| + NewEventHandlerUPP(SessionActivateHandler), 1, &event, this,
|
| + &event_handler_);
|
| + }
|
| + return result == noErr;
|
| +}
|
| +
|
| +bool CurtainMode::RemoveEventHandler() {
|
| + OSStatus result = noErr;
|
| + if (event_handler_) {
|
| + result = ::RemoveEventHandler(event_handler_);
|
| }
|
| + return result == noErr;
|
| }
|
|
|
| } // namespace remoting
|
|
|