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
3// found in the LICENSE file.
4
5#include "remoting/host/me2me_desktop_environment.h"
6
7#include "base/logging.h"
8#include "base/single_thread_task_runner.h"
9#include "remoting/base/logging.h"
10#include "remoting/host/client_session_control.h"
11#include "remoting/host/curtain_mode.h"
12#include "remoting/host/desktop_resizer.h"
13#include "remoting/host/gnubby_auth_handler.h"
14#include "remoting/host/host_window.h"
15#include "remoting/host/host_window.h"
16#include "remoting/host/host_window_proxy.h"
17#include "remoting/host/local_input_monitor.h"
18#include "remoting/host/resizing_host_observer.h"
19#include "remoting/host/screen_controls.h"
20#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
21#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
22
23#if defined(OS_POSIX)
24#include <sys/types.h>
25#include <unistd.h>
26#endif  // defined(OS_POSIX)
27
28const char kRateLimitResizeRequests[] = "rateLimitResizeRequests";
29
30namespace remoting {
31
32Me2MeDesktopEnvironment::~Me2MeDesktopEnvironment() {
33  DCHECK(caller_task_runner()->BelongsToCurrentThread());
34}
35
36scoped_ptr<ScreenControls> Me2MeDesktopEnvironment::CreateScreenControls() {
37  DCHECK(caller_task_runner()->BelongsToCurrentThread());
38
39  return scoped_ptr<ScreenControls>(
40      new ResizingHostObserver(DesktopResizer::Create()));
41}
42
43std::string Me2MeDesktopEnvironment::GetCapabilities() const {
44  return kRateLimitResizeRequests;
45}
46
47Me2MeDesktopEnvironment::Me2MeDesktopEnvironment(
48    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
49    scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
50    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
51    : BasicDesktopEnvironment(caller_task_runner,
52                              input_task_runner,
53                              ui_task_runner),
54      gnubby_auth_enabled_(false) {
55  DCHECK(caller_task_runner->BelongsToCurrentThread());
56  desktop_capture_options()->set_use_update_notifications(true);
57}
58
59scoped_ptr<GnubbyAuthHandler> Me2MeDesktopEnvironment::CreateGnubbyAuthHandler(
60    protocol::ClientStub* client_stub) {
61  DCHECK(caller_task_runner()->BelongsToCurrentThread());
62
63  if (gnubby_auth_enabled_)
64    return scoped_ptr<GnubbyAuthHandler>(
65        GnubbyAuthHandler::Create(client_stub));
66
67  HOST_LOG << "gnubby auth is not enabled";
68  return scoped_ptr<GnubbyAuthHandler>();
69}
70
71bool Me2MeDesktopEnvironment::InitializeSecurity(
72    base::WeakPtr<ClientSessionControl> client_session_control,
73    bool curtain_enabled) {
74  DCHECK(caller_task_runner()->BelongsToCurrentThread());
75
76  // Detach the session from the local console if the caller requested.
77  if (curtain_enabled) {
78    curtain_ = CurtainMode::Create(caller_task_runner(),
79                                   ui_task_runner(),
80                                   client_session_control);
81    bool active = curtain_->Activate();
82    if (!active)
83      LOG(ERROR) << "Failed to activate the curtain mode.";
84    return active;
85  }
86
87  // Otherwise, if the session is shared with the local user start monitoring
88  // the local input and create the in-session UI.
89
90#if defined(OS_LINUX)
91  bool want_user_interface = false;
92#elif defined(OS_MACOSX)
93  // Don't try to display any UI on top of the system's login screen as this
94  // is rejected by the Window Server on OS X 10.7.4, and prevents the
95  // capturer from working (http://crbug.com/140984).
96
97  // TODO(lambroslambrou): Use a better technique of detecting whether we're
98  // running in the LoginWindow context, and refactor this into a separate
99  // function to be used here and in CurtainMode::ActivateCurtain().
100  bool want_user_interface = getuid() != 0;
101#elif defined(OS_WIN)
102  bool want_user_interface = true;
103#endif  // defined(OS_WIN)
104
105  // Create the disconnect window.
106  if (want_user_interface) {
107    // Create the local input monitor.
108    local_input_monitor_ = LocalInputMonitor::Create(caller_task_runner(),
109                                                     input_task_runner(),
110                                                     ui_task_runner(),
111                                                     client_session_control);
112
113    disconnect_window_ = HostWindow::CreateDisconnectWindow();
114    disconnect_window_.reset(new HostWindowProxy(
115        caller_task_runner(),
116        ui_task_runner(),
117        disconnect_window_.Pass()));
118    disconnect_window_->Start(client_session_control);
119  }
120
121  return true;
122}
123
124void Me2MeDesktopEnvironment::SetEnableGnubbyAuth(bool gnubby_auth_enabled) {
125  gnubby_auth_enabled_ = gnubby_auth_enabled;
126}
127
128Me2MeDesktopEnvironmentFactory::Me2MeDesktopEnvironmentFactory(
129    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
130    scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
131    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
132    : BasicDesktopEnvironmentFactory(caller_task_runner,
133                                     input_task_runner,
134                                     ui_task_runner),
135      curtain_enabled_(false) {
136}
137
138Me2MeDesktopEnvironmentFactory::~Me2MeDesktopEnvironmentFactory() {
139}
140
141scoped_ptr<DesktopEnvironment> Me2MeDesktopEnvironmentFactory::Create(
142    base::WeakPtr<ClientSessionControl> client_session_control) {
143  DCHECK(caller_task_runner()->BelongsToCurrentThread());
144
145  scoped_ptr<Me2MeDesktopEnvironment> desktop_environment(
146      new Me2MeDesktopEnvironment(caller_task_runner(),
147                                  input_task_runner(),
148                                  ui_task_runner()));
149  if (!desktop_environment->InitializeSecurity(client_session_control,
150                                               curtain_enabled_)) {
151    return scoped_ptr<DesktopEnvironment>();
152  }
153  desktop_environment->SetEnableGnubbyAuth(gnubby_auth_enabled_);
154
155  return desktop_environment.PassAs<DesktopEnvironment>();
156}
157
158void Me2MeDesktopEnvironmentFactory::SetEnableCurtaining(bool enable) {
159  DCHECK(caller_task_runner()->BelongsToCurrentThread());
160
161  curtain_enabled_ = enable;
162}
163
164void Me2MeDesktopEnvironmentFactory::SetEnableGnubbyAuth(
165    bool gnubby_auth_enabled) {
166  gnubby_auth_enabled_ = gnubby_auth_enabled;
167}
168
169}  // namespace remoting
170