Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: remoting/host/curtain_mode_mac.cc

Issue 10829306: Make curtain-mode controllable by policy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added missing ifdef. Removed unnecessary change. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_mac.h" 5 #include "remoting/host/curtain_mode_mac.h"
6 6
7 #include <ApplicationServices/ApplicationServices.h> 7 #include <ApplicationServices/ApplicationServices.h>
8 #include <Security/Security.h> 8 #include <Security/Security.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/mac/scoped_cftyperef.h" 11 #include "base/mac/scoped_cftyperef.h"
12 12
13 namespace { 13 namespace {
14 const char* kCGSessionPath = 14 const char* kCGSessionPath =
15 "/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/" 15 "/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/"
16 "CGSession"; 16 "CGSession";
17 } 17 }
18 18
19 namespace remoting { 19 namespace remoting {
20 20
21 CurtainMode::CurtainMode() : event_handler_(NULL) { 21 CurtainMode::CurtainMode(const base::Closure& on_session_activate,
22 const base::Closure& on_error)
23 : on_session_activate_(on_session_activate),
24 on_error_(on_error),
25 connection_active_(false),
26 event_handler_(NULL) {
22 } 27 }
23 28
24 CurtainMode::~CurtainMode() { 29 CurtainMode::~CurtainMode() {
25 if (event_handler_) { 30 SetEnabled(false);
26 RemoveEventHandler(event_handler_); 31 }
32
33 void CurtainMode::SetEnabled(bool enabled) {
34 if (enabled) {
35 if (connection_active_) {
36 if (!ActivateCurtain()) {
37 on_error_.Run();
38 }
39 }
40 } else {
41 RemoveEventHandler();
27 } 42 }
28 } 43 }
29 44
30 bool CurtainMode::Init(const base::Closure& on_session_activate) { 45 bool CurtainMode::ActivateCurtain() {
31 DCHECK(on_session_activate_.is_null()); 46 // Try to install the switch-in handler. Do this before switching out the
32 on_session_activate_ = on_session_activate; 47 // current session so that the console session is not affected if it fails.
33 EventTypeSpec event; 48 if (!InstallEventHandler()) {
34 event.eventClass = kEventClassSystem; 49 return false;
35 event.eventKind = kEventSystemUserSessionActivated; 50 }
36 OSStatus result = InstallApplicationEventHandler(
37 NewEventHandlerUPP(SessionActivateHandler), 1, &event, this,
38 &event_handler_);
39 return result == noErr;
40 }
41 51
42 void CurtainMode::OnClientAuthenticated(const std::string& jid) {
43 // If the current session is attached to the console and is not showing
44 // the logon screen then switch it out to ensure privacy.
45 base::mac::ScopedCFTypeRef<CFDictionaryRef> session( 52 base::mac::ScopedCFTypeRef<CFDictionaryRef> session(
46 CGSessionCopyCurrentDictionary()); 53 CGSessionCopyCurrentDictionary());
47 const void* on_console = CFDictionaryGetValue(session, 54 const void* on_console = CFDictionaryGetValue(session,
48 kCGSessionOnConsoleKey); 55 kCGSessionOnConsoleKey);
49 const void* logged_in = CFDictionaryGetValue(session, kCGSessionLoginDoneKey); 56 const void* logged_in = CFDictionaryGetValue(session, kCGSessionLoginDoneKey);
50 if (logged_in == kCFBooleanTrue && on_console == kCFBooleanTrue) { 57 if (logged_in == kCFBooleanTrue && on_console == kCFBooleanTrue) {
51 pid_t child = fork(); 58 pid_t child = fork();
52 if (child == 0) { 59 if (child == 0) {
53 execl(kCGSessionPath, kCGSessionPath, "-suspend", NULL); 60 execl(kCGSessionPath, kCGSessionPath, "-suspend", NULL);
54 _exit(1); 61 _exit(1);
55 } else if (child > 0) { 62 } else if (child > 0) {
56 int status = 0; 63 int status = 0;
57 waitpid(child, &status, 0); 64 waitpid(child, &status, 0);
65 if (status != 0) {
66 LOG(ERROR) << kCGSessionPath << " failed.";
67 return false;
68 }
69 } else {
70 LOG(ERROR) << "fork() failed.";
71 return false;
58 } 72 }
59 } 73 }
74 return true;
75 }
76
77 // TODO(jamiewalch): This code assumes at most one client connection at a time.
78 // Add OnFirstClientConnected and OnLastClientDisconnected optional callbacks
79 // to the HostStatusObserver interface to address this.
80 void CurtainMode::OnClientAuthenticated(const std::string& jid) {
81 connection_active_ = true;
82 SetEnabled(true);
83 }
84
85 void CurtainMode::OnClientDisconnected(const std::string& jid) {
86 SetEnabled(false);
87 connection_active_ = false;
60 } 88 }
61 89
62 OSStatus CurtainMode::SessionActivateHandler(EventHandlerCallRef handler, 90 OSStatus CurtainMode::SessionActivateHandler(EventHandlerCallRef handler,
63 EventRef event, 91 EventRef event,
64 void* user_data) { 92 void* user_data) {
65 CurtainMode* self = static_cast<CurtainMode*>(user_data); 93 CurtainMode* self = static_cast<CurtainMode*>(user_data);
66 self->OnSessionActivate(); 94 self->OnSessionActivate();
67 return noErr; 95 return noErr;
68 } 96 }
69 97
70 void CurtainMode::OnSessionActivate() { 98 void CurtainMode::OnSessionActivate() {
71 if (!on_session_activate_.is_null()) { 99 on_session_activate_.Run();
72 on_session_activate_.Run(); 100 }
101
102 bool CurtainMode::InstallEventHandler() {
103 OSStatus result = noErr;
104 if (!event_handler_) {
105 EventTypeSpec event;
106 event.eventClass = kEventClassSystem;
107 event.eventKind = kEventSystemUserSessionActivated;
108 result = ::InstallApplicationEventHandler(
109 NewEventHandlerUPP(SessionActivateHandler), 1, &event, this,
110 &event_handler_);
73 } 111 }
112 return result == noErr;
113 }
114
115 bool CurtainMode::RemoveEventHandler() {
116 OSStatus result = noErr;
117 if (event_handler_) {
118 result = ::RemoveEventHandler(event_handler_);
119 }
120 return result == noErr;
74 } 121 }
75 122
76 } // namespace remoting 123 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698