• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ipc_desktop_environment.h"
6 
7 #include <utility>
8 
9 #include "base/compiler_specific.h"
10 #include "base/logging.h"
11 #include "base/process/process_handle.h"
12 #include "base/single_thread_task_runner.h"
13 #include "ipc/ipc_sender.h"
14 #include "remoting/host/audio_capturer.h"
15 #include "remoting/host/chromoting_messages.h"
16 #include "remoting/host/client_session_control.h"
17 #include "remoting/host/desktop_session.h"
18 #include "remoting/host/desktop_session_proxy.h"
19 #include "remoting/host/gnubby_auth_handler.h"
20 #include "remoting/host/input_injector.h"
21 #include "remoting/host/screen_controls.h"
22 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
23 
24 namespace remoting {
25 
IpcDesktopEnvironment(scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner,scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,base::WeakPtr<ClientSessionControl> client_session_control,base::WeakPtr<DesktopSessionConnector> desktop_session_connector,bool virtual_terminal)26 IpcDesktopEnvironment::IpcDesktopEnvironment(
27     scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner,
28     scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
29     scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
30     scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
31     base::WeakPtr<ClientSessionControl> client_session_control,
32     base::WeakPtr<DesktopSessionConnector> desktop_session_connector,
33     bool virtual_terminal) {
34   DCHECK(caller_task_runner->BelongsToCurrentThread());
35 
36   desktop_session_proxy_ = new DesktopSessionProxy(audio_task_runner,
37                                                    caller_task_runner,
38                                                    io_task_runner,
39                                                    capture_task_runner,
40                                                    client_session_control,
41                                                    desktop_session_connector,
42                                                    virtual_terminal);
43 }
44 
~IpcDesktopEnvironment()45 IpcDesktopEnvironment::~IpcDesktopEnvironment() {
46 }
47 
CreateAudioCapturer()48 scoped_ptr<AudioCapturer> IpcDesktopEnvironment::CreateAudioCapturer() {
49   return desktop_session_proxy_->CreateAudioCapturer();
50 }
51 
CreateInputInjector()52 scoped_ptr<InputInjector> IpcDesktopEnvironment::CreateInputInjector() {
53   return desktop_session_proxy_->CreateInputInjector();
54 }
55 
CreateScreenControls()56 scoped_ptr<ScreenControls> IpcDesktopEnvironment::CreateScreenControls() {
57   return desktop_session_proxy_->CreateScreenControls();
58 }
59 
60 scoped_ptr<webrtc::ScreenCapturer>
CreateVideoCapturer()61 IpcDesktopEnvironment::CreateVideoCapturer() {
62   return desktop_session_proxy_->CreateVideoCapturer();
63 }
64 
GetCapabilities() const65 std::string IpcDesktopEnvironment::GetCapabilities() const {
66   return desktop_session_proxy_->GetCapabilities();
67 }
68 
SetCapabilities(const std::string & capabilities)69 void IpcDesktopEnvironment::SetCapabilities(const std::string& capabilities) {
70   return desktop_session_proxy_->SetCapabilities(capabilities);
71 }
72 
CreateGnubbyAuthHandler(protocol::ClientStub * client_stub)73 scoped_ptr<GnubbyAuthHandler> IpcDesktopEnvironment::CreateGnubbyAuthHandler(
74     protocol::ClientStub* client_stub) {
75   return scoped_ptr<GnubbyAuthHandler>();
76 }
77 
IpcDesktopEnvironmentFactory(scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner,scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,IPC::Sender * daemon_channel)78 IpcDesktopEnvironmentFactory::IpcDesktopEnvironmentFactory(
79     scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner,
80     scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
81     scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
82     scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
83     IPC::Sender* daemon_channel)
84     : audio_task_runner_(audio_task_runner),
85       caller_task_runner_(caller_task_runner),
86       capture_task_runner_(capture_task_runner),
87       io_task_runner_(io_task_runner),
88       curtain_enabled_(false),
89       daemon_channel_(daemon_channel),
90       connector_factory_(this),
91       next_id_(0) {
92 }
93 
~IpcDesktopEnvironmentFactory()94 IpcDesktopEnvironmentFactory::~IpcDesktopEnvironmentFactory() {
95 }
96 
Create(base::WeakPtr<ClientSessionControl> client_session_control)97 scoped_ptr<DesktopEnvironment> IpcDesktopEnvironmentFactory::Create(
98     base::WeakPtr<ClientSessionControl> client_session_control) {
99   DCHECK(caller_task_runner_->BelongsToCurrentThread());
100 
101   return scoped_ptr<DesktopEnvironment>(
102       new IpcDesktopEnvironment(audio_task_runner_,
103                                 caller_task_runner_,
104                                 capture_task_runner_,
105                                 io_task_runner_,
106                                 client_session_control,
107                                 connector_factory_.GetWeakPtr(),
108                                 curtain_enabled_));
109 }
110 
SetEnableCurtaining(bool enable)111 void IpcDesktopEnvironmentFactory::SetEnableCurtaining(bool enable) {
112   DCHECK(caller_task_runner_->BelongsToCurrentThread());
113 
114   curtain_enabled_ = enable;
115 }
116 
SupportsAudioCapture() const117 bool IpcDesktopEnvironmentFactory::SupportsAudioCapture() const {
118   DCHECK(caller_task_runner_->BelongsToCurrentThread());
119 
120   return AudioCapturer::IsSupported();
121 }
122 
ConnectTerminal(DesktopSessionProxy * desktop_session_proxy,const ScreenResolution & resolution,bool virtual_terminal)123 void IpcDesktopEnvironmentFactory::ConnectTerminal(
124     DesktopSessionProxy* desktop_session_proxy,
125     const ScreenResolution& resolution,
126     bool virtual_terminal) {
127   DCHECK(caller_task_runner_->BelongsToCurrentThread());
128 
129   int id = next_id_++;
130   bool inserted = active_connections_.insert(
131       std::make_pair(id, desktop_session_proxy)).second;
132   CHECK(inserted);
133 
134   VLOG(1) << "Network: registered desktop environment " << id;
135 
136   daemon_channel_->Send(new ChromotingNetworkHostMsg_ConnectTerminal(
137       id, resolution, virtual_terminal));
138 }
139 
DisconnectTerminal(DesktopSessionProxy * desktop_session_proxy)140 void IpcDesktopEnvironmentFactory::DisconnectTerminal(
141     DesktopSessionProxy* desktop_session_proxy) {
142   DCHECK(caller_task_runner_->BelongsToCurrentThread());
143 
144   ActiveConnectionsList::iterator i;
145   for (i = active_connections_.begin(); i != active_connections_.end(); ++i) {
146     if (i->second == desktop_session_proxy)
147       break;
148   }
149 
150   if (i != active_connections_.end()) {
151     int id = i->first;
152     active_connections_.erase(i);
153 
154     VLOG(1) << "Network: unregistered desktop environment " << id;
155     daemon_channel_->Send(new ChromotingNetworkHostMsg_DisconnectTerminal(id));
156   }
157 }
158 
SetScreenResolution(DesktopSessionProxy * desktop_session_proxy,const ScreenResolution & resolution)159 void IpcDesktopEnvironmentFactory::SetScreenResolution(
160     DesktopSessionProxy* desktop_session_proxy,
161     const ScreenResolution& resolution) {
162   DCHECK(caller_task_runner_->BelongsToCurrentThread());
163 
164   ActiveConnectionsList::iterator i;
165   for (i = active_connections_.begin(); i != active_connections_.end(); ++i) {
166     if (i->second == desktop_session_proxy)
167       break;
168   }
169 
170   if (i != active_connections_.end()) {
171     daemon_channel_->Send(new ChromotingNetworkDaemonMsg_SetScreenResolution(
172         i->first, resolution));
173   }
174 }
175 
OnDesktopSessionAgentAttached(int terminal_id,base::ProcessHandle desktop_process,IPC::PlatformFileForTransit desktop_pipe)176 void IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached(
177     int terminal_id,
178     base::ProcessHandle desktop_process,
179     IPC::PlatformFileForTransit desktop_pipe) {
180   if (!caller_task_runner_->BelongsToCurrentThread()) {
181     caller_task_runner_->PostTask(FROM_HERE, base::Bind(
182         &IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached,
183         base::Unretained(this), terminal_id, desktop_process, desktop_pipe));
184     return;
185   }
186 
187   ActiveConnectionsList::iterator i = active_connections_.find(terminal_id);
188   if (i != active_connections_.end()) {
189     i->second->DetachFromDesktop();
190     i->second->AttachToDesktop(desktop_process, desktop_pipe);
191   } else {
192     base::CloseProcessHandle(desktop_process);
193 
194 #if defined(OS_POSIX)
195     DCHECK(desktop_pipe.auto_close);
196     base::File pipe_closer(IPC::PlatformFileForTransitToFile(desktop_pipe));
197 #endif  // defined(OS_POSIX)
198   }
199 }
200 
OnTerminalDisconnected(int terminal_id)201 void IpcDesktopEnvironmentFactory::OnTerminalDisconnected(int terminal_id) {
202   if (!caller_task_runner_->BelongsToCurrentThread()) {
203     caller_task_runner_->PostTask(FROM_HERE, base::Bind(
204         &IpcDesktopEnvironmentFactory::OnTerminalDisconnected,
205         base::Unretained(this), terminal_id));
206     return;
207   }
208 
209   ActiveConnectionsList::iterator i = active_connections_.find(terminal_id);
210   if (i != active_connections_.end()) {
211     DesktopSessionProxy* desktop_session_proxy = i->second;
212     active_connections_.erase(i);
213 
214     // Disconnect the client session.
215     desktop_session_proxy->DisconnectSession();
216   }
217 }
218 
219 }  // namespace remoting
220