Upstream version 10.39.233.0
[platform/framework/web/crosswalk.git] / src / remoting / host / desktop_process.cc
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 // This file implements the Windows service controlling Me2Me host processes
6 // running within user sessions.
7
8 #include "remoting/host/desktop_process.h"
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/debug/alias.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/strings/string_util.h"
17 #include "ipc/ipc_channel_proxy.h"
18 #include "remoting/base/auto_thread.h"
19 #include "remoting/base/auto_thread_task_runner.h"
20 #include "remoting/host/chromoting_messages.h"
21 #include "remoting/host/desktop_environment.h"
22 #include "remoting/host/desktop_session_agent.h"
23
24 namespace remoting {
25
26 DesktopProcess::DesktopProcess(
27     scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
28     scoped_refptr<AutoThreadTaskRunner> input_task_runner,
29     const std::string& daemon_channel_name)
30     : caller_task_runner_(caller_task_runner),
31       input_task_runner_(input_task_runner),
32       daemon_channel_name_(daemon_channel_name) {
33   DCHECK(caller_task_runner_->BelongsToCurrentThread());
34   DCHECK(base::MessageLoopForUI::IsCurrent());
35 }
36
37 DesktopProcess::~DesktopProcess() {
38   DCHECK(!daemon_channel_);
39   DCHECK(!desktop_agent_.get());
40 }
41
42 DesktopEnvironmentFactory& DesktopProcess::desktop_environment_factory() {
43   DCHECK(caller_task_runner_->BelongsToCurrentThread());
44
45   return *desktop_environment_factory_;
46 }
47
48 void DesktopProcess::OnNetworkProcessDisconnected() {
49   DCHECK(caller_task_runner_->BelongsToCurrentThread());
50
51   OnChannelError();
52 }
53
54 void DesktopProcess::InjectSas() {
55   DCHECK(caller_task_runner_->BelongsToCurrentThread());
56
57   daemon_channel_->Send(new ChromotingDesktopDaemonMsg_InjectSas());
58 }
59
60 bool DesktopProcess::OnMessageReceived(const IPC::Message& message) {
61   DCHECK(caller_task_runner_->BelongsToCurrentThread());
62
63   bool handled = true;
64   IPC_BEGIN_MESSAGE_MAP(DesktopProcess, message)
65     IPC_MESSAGE_HANDLER(ChromotingDaemonMsg_Crash, OnCrash)
66     IPC_MESSAGE_UNHANDLED(handled = false)
67   IPC_END_MESSAGE_MAP()
68
69   CHECK(handled) << "Received unexpected IPC type: " << message.type();
70   return handled;
71 }
72
73 void DesktopProcess::OnChannelConnected(int32 peer_pid) {
74   DCHECK(caller_task_runner_->BelongsToCurrentThread());
75
76   VLOG(1) << "IPC: desktop <- daemon (" << peer_pid << ")";
77 }
78
79 void DesktopProcess::OnChannelError() {
80   // Shutdown the desktop process.
81   daemon_channel_.reset();
82   if (desktop_agent_.get()) {
83     desktop_agent_->Stop();
84     desktop_agent_ = NULL;
85   }
86
87   caller_task_runner_ = NULL;
88   input_task_runner_ = NULL;
89   desktop_environment_factory_.reset();
90 }
91
92 bool DesktopProcess::Start(
93     scoped_ptr<DesktopEnvironmentFactory> desktop_environment_factory) {
94   DCHECK(caller_task_runner_->BelongsToCurrentThread());
95   DCHECK(!desktop_environment_factory_);
96   DCHECK(desktop_environment_factory);
97
98   desktop_environment_factory_ = desktop_environment_factory.Pass();
99
100   // Launch the audio capturing thread.
101   scoped_refptr<AutoThreadTaskRunner> audio_task_runner;
102 #if defined(OS_WIN)
103   // On Windows the AudioCapturer requires COM, so we run a single-threaded
104   // apartment, which requires a UI thread.
105   audio_task_runner =
106       AutoThread::CreateWithLoopAndComInitTypes("ChromotingAudioThread",
107                                                 caller_task_runner_,
108                                                 base::MessageLoop::TYPE_UI,
109                                                 AutoThread::COM_INIT_STA);
110 #else // !defined(OS_WIN)
111   audio_task_runner = AutoThread::CreateWithType(
112       "ChromotingAudioThread", caller_task_runner_, base::MessageLoop::TYPE_IO);
113 #endif  // !defined(OS_WIN)
114
115   // Launch the I/O thread.
116   scoped_refptr<AutoThreadTaskRunner> io_task_runner =
117       AutoThread::CreateWithType(
118           "I/O thread", caller_task_runner_, base::MessageLoop::TYPE_IO);
119
120   // Launch the video capture thread.
121   scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner =
122       AutoThread::Create("Video capture thread", caller_task_runner_);
123
124   // Create a desktop agent.
125   desktop_agent_ = new DesktopSessionAgent(audio_task_runner,
126                                            caller_task_runner_,
127                                            input_task_runner_,
128                                            io_task_runner,
129                                            video_capture_task_runner);
130
131   // Start the agent and create an IPC channel to talk to it.
132   IPC::PlatformFileForTransit desktop_pipe;
133   if (!desktop_agent_->Start(AsWeakPtr(), &desktop_pipe)) {
134     desktop_agent_ = NULL;
135     caller_task_runner_ = NULL;
136     input_task_runner_ = NULL;
137     desktop_environment_factory_.reset();
138     return false;
139   }
140
141   // Connect to the daemon.
142   daemon_channel_ = IPC::ChannelProxy::Create(daemon_channel_name_,
143                                               IPC::Channel::MODE_CLIENT,
144                                               this,
145                                               io_task_runner.get());
146
147   // Pass |desktop_pipe| to the daemon.
148   daemon_channel_->Send(
149       new ChromotingDesktopDaemonMsg_DesktopAttached(desktop_pipe));
150
151   return true;
152 }
153
154 void DesktopProcess::OnCrash(const std::string& function_name,
155                              const std::string& file_name,
156                              const int& line_number) {
157   char message[1024];
158   base::snprintf(message, sizeof(message),
159                  "Requested by %s at %s, line %d.",
160                  function_name.c_str(), file_name.c_str(), line_number);
161   base::debug::Alias(message);
162
163   // The daemon requested us to crash the process.
164   CHECK(false) << message;
165 }
166
167 } // namespace remoting