Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: ppapi/proxy/vpn_provider_resource.cc

Issue 1726303003: ppapi: PPB_VpnProvider: Define API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "ppapi/proxy/vpn_provider_resource.h"
6
7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h"
9 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/proxy/dispatch_reply_message.h"
11 #include "ppapi/proxy/ppapi_messages.h"
12 #include "ppapi/shared_impl/array_var.h"
13 #include "ppapi/shared_impl/ppapi_globals.h"
14 #include "ppapi/shared_impl/proxy_lock.h"
15 #include "ppapi/shared_impl/tracked_callback.h"
16 #include "ppapi/shared_impl/var.h"
17 #include "ppapi/shared_impl/var_tracker.h"
18
19 namespace ppapi {
20 namespace proxy {
21
22 VpnProviderResource::VpnProviderResource(Connection connection,
23 PP_Instance instance)
24 : PluginResource(connection, instance),
25 get_unbind_event_callback_(NULL),
26 receive_packet_callback_var_(NULL) {
27 SendCreate(BROWSER, PpapiHostMsg_VpnProvider_Create());
28 }
29
30 VpnProviderResource::~VpnProviderResource() {}
31
32 thunk::PPB_VpnProvider_API* VpnProviderResource::AsPPB_VpnProvider_API() {
33 return this;
34 }
35
36 void VpnProviderResource::OnReplyReceived(
37 const ResourceMessageReplyParams& params,
38 const IPC::Message& msg) {
39 PPAPI_BEGIN_MESSAGE_MAP(VpnProviderResource, msg)
40 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(PpapiPluginMsg_VpnProvider_OnUnBind,
41 OnPluginMsgOnUnBindReceived)
42 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
43 PpapiPluginMsg_VpnProvider_OnPacketReceived,
44 OnPluginMsgOnPacketReceived)
45 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(
46 PluginResource::OnReplyReceived(params, msg))
47 PPAPI_END_MESSAGE_MAP()
48 }
49
50 int32_t VpnProviderResource::Bind(
51 const PP_Var& configuration_id,
52 const PP_Var& configuration_name,
53 const scoped_refptr<TrackedCallback>& callback) {
54 if (TrackedCallback::IsPending(bind_callback_))
55 return PP_ERROR_INPROGRESS;
56
57 StringVar* configuration_id_var = StringVar::FromPPVar(configuration_id);
58 if (!configuration_id_var)
59 return PP_ERROR_BADARGUMENT;
60 StringVar* configuration_name_var = StringVar::FromPPVar(configuration_name);
61 if (!configuration_name_var)
62 return PP_ERROR_BADARGUMENT;
63
64 bind_callback_ = callback;
65
66 Call<PpapiPluginMsg_VpnProvider_BindReply>(
67 BROWSER, PpapiHostMsg_VpnProvider_Bind(configuration_id_var->value(),
68 configuration_name_var->value()),
69 base::Bind(&VpnProviderResource::OnPluginMsgBindReply, this));
70
71 return PP_OK_COMPLETIONPENDING;
72 }
73
74 int32_t VpnProviderResource::GetUnBindEvent(
75 const scoped_refptr<TrackedCallback>& callback) {
76 if (TrackedCallback::IsPending(get_unbind_event_callback_))
77 return PP_ERROR_INPROGRESS;
78
79 // Or install |callback|.
80 get_unbind_event_callback_ = callback;
81
82 return PP_OK_COMPLETIONPENDING;
83 }
84
85 int32_t VpnProviderResource::SendPacket(
86 const PP_Var& data,
87 const scoped_refptr<TrackedCallback>& callback) {
88 if (!ArrayBufferVar::FromPPVar(data))
89 return PP_ERROR_BADARGUMENT;
90 if (TrackedCallback::IsPending(send_packet_callback_))
91 return PP_ERROR_INPROGRESS;
92
93 uint32_t id;
94 if (send_packet_buffer_.get() && send_packet_buffer_->GetAvailable(&id)) {
95 // Send packet immeditatelly
96 send_packet_buffer_->SetAvailable(id, false);
97 return DoSendPacket(data, id);
98 } else {
99 // Packet will be sent later
100 send_packet_callback_ = callback;
101 PpapiGlobals::Get()->GetVarTracker()->AddRefVar(data);
102 send_packets_.push(data);
103
104 return PP_OK_COMPLETIONPENDING;
105 }
106 }
107
108 int32_t VpnProviderResource::DoSendPacket(const PP_Var& data, uint32_t id) {
109 // Convert data to std::vector<char>, then send it.
110 scoped_refptr<ArrayBufferVar> data_arraybuffer =
111 ArrayBufferVar::FromPPVar(data);
112 if (!data_arraybuffer.get())
113 return PP_ERROR_BADARGUMENT;
114
115 char* data_pointer = static_cast<char*>(data_arraybuffer->Map());
116 uint32_t data_length = data_arraybuffer->ByteLength();
117 memcpy(send_packet_buffer_->GetBuffer(id), data_pointer, data_length);
118 data_arraybuffer->Unmap();
119
120 Call<PpapiPluginMsg_VpnProvider_SendPacketReply>(
121 BROWSER, PpapiHostMsg_VpnProvider_SendPacket(data_length, id),
122 base::Bind(&VpnProviderResource::OnPluginMsgSendPacketReply, this));
123
124 return PP_OK;
125 }
126
127 int32_t VpnProviderResource::ReceivePacket(
128 PP_Var* data,
129 const scoped_refptr<TrackedCallback>& callback) {
130 if (TrackedCallback::IsPending(receive_packet_callback_))
131 return PP_ERROR_INPROGRESS;
132
133 // Just return received packets if any received packet is queued.
134 if (!received_packets_.empty()) {
135 receive_packet_callback_var_ = data;
136 WritePacket();
137 return PP_OK;
138 }
139
140 // Or retain |packet| as buffer to store and install |callback|.
141 receive_packet_callback_var_ = data;
142 receive_packet_callback_ = callback;
143
144 return PP_OK_COMPLETIONPENDING;
145 }
146
147 // Responds to PpapiPluginMsg_VpnProvider_OnUnBind
148 void VpnProviderResource::OnPluginMsgOnUnBindReceived(
149 const ResourceMessageReplyParams& params) {
150 if (!TrackedCallback::IsPending(get_unbind_event_callback_) ||
151 TrackedCallback::IsScheduledToRun(get_unbind_event_callback_)) {
152 return;
153 }
154
155 // The plugin may call GetUnBindEvent in its callback.
156 scoped_refptr<TrackedCallback> callback;
157 callback.swap(get_unbind_event_callback_);
158 callback->Run(PP_OK);
159 }
160
161 // Responds to PpapiPluginMsg_VpnProvider_OnPacketReceived
162 void VpnProviderResource::OnPluginMsgOnPacketReceived(
163 const ResourceMessageReplyParams& params,
164 uint32_t data_length,
165 uint32_t id) {
166 // Append received packet to queue.
167 void* data_pointer = receive_packet_buffer_->GetBuffer(id);
168 scoped_refptr<Var> data_var(
169 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferVar(data_length,
170 data_pointer));
171 received_packets_.push(data_var);
172
173 // Mark shared memory as available for next packet
174 Post(BROWSER, PpapiHostMsg_VpnProvider_OnPacketReceivedReply(id));
175
176 if (!TrackedCallback::IsPending(receive_packet_callback_) ||
177 TrackedCallback::IsScheduledToRun(receive_packet_callback_)) {
178 return;
179 }
180
181 // The plugin may call GetPacket in its callback.
182 scoped_refptr<TrackedCallback> callback;
183 callback.swap(receive_packet_callback_);
184 WritePacket();
185 callback->Run(PP_OK);
186 }
187
188 // Responds to PpapiPluginMsg_VpnProvider_BindReply
189 // Forwards to bind_callback_
190 void VpnProviderResource::OnPluginMsgBindReply(
191 const ResourceMessageReplyParams& params,
192 uint32_t queue_depth,
193 uint32_t packet_size,
194 int32_t result) {
195 std::vector<base::SharedMemoryHandle> shm_handles;
196 params.TakeAllSharedMemoryHandles(&shm_handles);
197
198 std::unique_ptr<base::SharedMemory> send_shm(
199 new base::SharedMemory(shm_handles[0], false));
200 std::unique_ptr<base::SharedMemory> receive_shm(
201 new base::SharedMemory(shm_handles[1], false));
202 size_t buffer_size = queue_depth * packet_size;
203 if (!send_shm->Map(buffer_size))
204 return;
205 if (!receive_shm->Map(buffer_size))
206 return;
207 send_packet_buffer_ = base::WrapUnique(new ppapi::VpnProviderSharedBuffer(
208 queue_depth, packet_size, std::move(send_shm)));
209 receive_packet_buffer_ = base::WrapUnique(new ppapi::VpnProviderSharedBuffer(
210 queue_depth, packet_size, std::move(receive_shm)));
211
212 // The callback may have been aborted by Close().
213 if (TrackedCallback::IsPending(bind_callback_)) {
214 // The plugin may call DestroyConfig in its callback.
215 scoped_refptr<TrackedCallback> callback;
216 callback.swap(bind_callback_);
217 // On error: Pass return code
218 // On succes: Pass message
219 callback->Run(params.result() ? params.result() : result);
220 }
221 }
222
223 // Responds to PpapiPluginMsg_VpnProvider_SendPacketReply
224 // Forwards to send_packet_callback_
225 void VpnProviderResource::OnPluginMsgSendPacketReply(
226 const ResourceMessageReplyParams& params,
227 int32_t id) {
228 if (!send_packets_.empty()) {
229 // Process remaining packets
230 DoSendPacket(send_packets_.front(), id);
231 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(send_packets_.front());
232 send_packets_.pop();
233 } else {
234 send_packet_buffer_->SetAvailable(id, true);
235
236 // Avilable slots - Run callback to process new packets.
237 // The callback may have been aborted by Close().
238 if (TrackedCallback::IsPending(send_packet_callback_)) {
239 // The plugin may call SendPacket in its callback.
240 scoped_refptr<TrackedCallback> callback;
241 callback.swap(send_packet_callback_);
242 // On error: Pass return code
243 // On succes: Pass message
244 callback->Run(PP_OK);
245 }
246 }
247 }
248
249 void VpnProviderResource::WritePacket() {
250 if (!receive_packet_callback_var_)
251 return;
252
253 *receive_packet_callback_var_ = received_packets_.front()->GetPPVar();
254 received_packets_.pop();
255 receive_packet_callback_var_ = NULL;
256 }
257
258 } // namespace proxy
259 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698