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