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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
// 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.
#ifndef PPAPI_PROXY_PROXY_CHANNEL_H_
#define PPAPI_PROXY_PROXY_CHANNEL_H_
#include "base/files/scoped_file.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/process/process.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_platform_file.h"
#include "ipc/ipc_sender.h"
#include "ipc/ipc_sync_channel.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
namespace base {
class SingleThreadTaskRunner;
class WaitableEvent;
}
namespace IPC {
class TestSink;
}
namespace ppapi {
namespace proxy {
class PPAPI_PROXY_EXPORT ProxyChannel
: public IPC::Listener,
public IPC::Sender {
public:
class PPAPI_PROXY_EXPORT Delegate {
public:
virtual ~Delegate() {}
// Returns the task runner for processing IPC requests.
virtual base::SingleThreadTaskRunner* GetIPCTaskRunner() = 0;
// Returns the event object that becomes signalled when the main thread's
// message loop exits.
virtual base::WaitableEvent* GetShutdownEvent() = 0;
// Duplicates a handle to the provided object, returning one that is valid
// on the other side of the channel. This is part of the delegate interface
// because both sides of the channel may not have sufficient permission to
// duplicate handles directly. The implementation must provide the same
// guarantees as ProxyChannel::ShareHandleWithRemote below.
virtual IPC::PlatformFileForTransit ShareHandleWithRemote(
base::PlatformFile handle,
base::ProcessId remote_pid,
bool should_close_source) = 0;
// Duplicates a shared memory handle, returning one that is valid on the
// other side of the channel. This is part of the delegate interface
// because both sides of the channel may not have sufficient permission to
// duplicate handles directly. The implementation must provide the same
// guarantees as ProxyChannel::ShareSharedMemoryHandleWithRemote below.
virtual base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
const base::SharedMemoryHandle& handle,
base::ProcessId remote_pid) = 0;
};
~ProxyChannel() override;
// Alternative to InitWithChannel() for unit tests that want to send all
// messages sent via this channel to the given test sink. The test sink
// must outlive this class. In this case, the peer PID will be the current
// process ID.
void InitWithTestSink(IPC::TestSink* test_sink);
// Shares a file handle (HANDLE / file descriptor) with the remote side. It
// returns a handle that should be sent in exactly one IPC message. Upon
// receipt, the remote side then owns that handle. Note: if sending the
// message fails, the returned handle is properly closed by the IPC system. If
// should_close_source is set to true, the original handle is closed by this
// operation and should not be used again.
IPC::PlatformFileForTransit ShareHandleWithRemote(
base::PlatformFile handle,
bool should_close_source);
// Shares a shared memory handle with the remote side. It returns a handle
// that should be sent in exactly one IPC message. Upon receipt, the remote
// side then owns that handle. Note: if sending the message fails, the
// returned handle is properly closed by the IPC system. The original handle
// is not closed by this operation.
base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
const base::SharedMemoryHandle& handle);
// IPC::Sender implementation.
bool Send(IPC::Message* msg) override;
// IPC::Listener implementation.
void OnChannelError() override;
// Will be NULL in some unit tests and if the remote side has crashed.
IPC::SyncChannel* channel() const {
return channel_.get();
}
#if defined(OS_POSIX) && !defined(OS_NACL)
base::ScopedFD TakeRendererFD();
#endif
protected:
explicit ProxyChannel();
// You must call this function before anything else. Returns true on success.
// The delegate pointer must outlive this class, ownership is not
// transferred.
virtual bool InitWithChannel(Delegate* delegate,
base::ProcessId peer_pid,
const IPC::ChannelHandle& channel_handle,
bool is_client);
ProxyChannel::Delegate* delegate() const {
return delegate_;
}
private:
// Non-owning pointer. Guaranteed non-NULL after init is called.
ProxyChannel::Delegate* delegate_;
// PID of the remote process. Use this instead of the Channel::peer_pid since
// this is set synchronously on construction rather than waiting on the
// "hello" message from the peer (which introduces a race condition).
base::ProcessId peer_pid_;
// When we're unit testing, this will indicate the sink for the messages to
// be deposited so they can be inspected by the test. When non-NULL, this
// indicates that the channel should not be used.
IPC::TestSink* test_sink_;
// Will be null for some tests when there is a test_sink_, and if the
// remote side has crashed.
scoped_ptr<IPC::SyncChannel> channel_;
DISALLOW_COPY_AND_ASSIGN(ProxyChannel);
};
} // namespace proxy
} // namespace ppapi
#endif // PPAPI_PROXY_PROXY_CHANNEL_H_
|