1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/desktop_session_agent.h"
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "base/eintr_wrapper.h"
#include "base/single_thread_task_runner.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h"
#include "remoting/base/auto_thread_task_runner.h"
namespace remoting {
// Provides screen/audio capturing and input injection services for
// the network process.
class DesktopSessionAgentPosix : public DesktopSessionAgent {
public:
DesktopSessionAgentPosix(
scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
scoped_refptr<AutoThreadTaskRunner> io_task_runner);
virtual ~DesktopSessionAgentPosix();
protected:
virtual bool DoCreateNetworkChannel(
IPC::PlatformFileForTransit* client_out,
scoped_ptr<IPC::ChannelProxy>* server_out) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(DesktopSessionAgentPosix);
};
DesktopSessionAgentPosix::DesktopSessionAgentPosix(
scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
scoped_refptr<AutoThreadTaskRunner> io_task_runner)
: DesktopSessionAgent(caller_task_runner, io_task_runner) {
}
DesktopSessionAgentPosix::~DesktopSessionAgentPosix() {
}
bool DesktopSessionAgentPosix::DoCreateNetworkChannel(
IPC::PlatformFileForTransit* client_out,
scoped_ptr<IPC::ChannelProxy>* server_out) {
// Create a socket pair.
int pipe_fds[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) {
PLOG(ERROR) << "socketpair()";
return false;
}
// Set both ends to be non-blocking.
if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 ||
fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) {
PLOG(ERROR) << "fcntl(O_NONBLOCK)";
if (HANDLE_EINTR(close(pipe_fds[0])) < 0)
PLOG(ERROR) << "close()";
if (HANDLE_EINTR(close(pipe_fds[1])) < 0)
PLOG(ERROR) << "close()";
return false;
}
// Generate a unique name for the channel.
std::string channel_name = IPC::Channel::GenerateUniqueRandomChannelID();
std::string socket_name = "DesktopSessionAgent socket";
// Wrap the pipe into an IPC channel.
base::FileDescriptor fd(pipe_fds[0], false);
IPC::ChannelHandle handle(socket_name, fd);
server_out->reset(new IPC::ChannelProxy(
IPC::ChannelHandle(socket_name, fd),
IPC::Channel::MODE_SERVER,
this,
io_task_runner()));
*client_out = base::FileDescriptor(pipe_fds[1], false);
return true;
}
// static
scoped_ptr<DesktopSessionAgent> DesktopSessionAgent::Create(
scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
scoped_refptr<AutoThreadTaskRunner> io_task_runner) {
return scoped_ptr<DesktopSessionAgent>(new DesktopSessionAgentPosix(
caller_task_runner, io_task_runner));
}
} // namespace remoting
|