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

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

Issue 1931513002: ppapi: PPB_VpnProvider: Implement Resource Stub (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@vpn-api-messages
Patch Set: Fix Widows build & Organize headers 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 2016 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/tracked_callback.h"
bbudge 2016/05/17 09:50:12 included in header, so redundant
adrian.belgun 2016/05/17 11:05:29 Done.
15 #include "ppapi/shared_impl/var_tracker.h"
16
17 namespace ppapi {
18 namespace proxy {
19
20 VpnProviderResource::VpnProviderResource(Connection connection,
21 PP_Instance instance)
22 : PluginResource(connection, instance),
23 bind_callback_(NULL),
bbudge 2016/05/17 09:50:12 nullptr
adrian.belgun 2016/05/17 11:05:29 Done.
24 send_packet_callback_(NULL),
25 receive_packet_callback_(NULL),
26 receive_packet_callback_var_(NULL),
27 bound_(false) {
28 SendCreate(BROWSER, PpapiHostMsg_VpnProvider_Create());
29 }
30
31 VpnProviderResource::~VpnProviderResource() {}
32
33 thunk::PPB_VpnProvider_API* VpnProviderResource::AsPPB_VpnProvider_API() {
34 return this;
35 }
36
37 void VpnProviderResource::OnReplyReceived(
38 const ResourceMessageReplyParams& params,
39 const IPC::Message& msg) {
40 PPAPI_BEGIN_MESSAGE_MAP(VpnProviderResource, msg)
41 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(PpapiPluginMsg_VpnProvider_OnUnbind,
42 OnPluginMsgOnUnbindReceived)
43 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
44 PpapiPluginMsg_VpnProvider_OnPacketReceived,
45 OnPluginMsgOnPacketReceived)
46 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(
47 PluginResource::OnReplyReceived(params, msg))
48 PPAPI_END_MESSAGE_MAP()
49 }
50
51 int32_t VpnProviderResource::Bind(
52 const PP_Var& configuration_id,
53 const PP_Var& configuration_name,
54 const scoped_refptr<TrackedCallback>& callback) {
55 if (TrackedCallback::IsPending(bind_callback_))
56 return PP_ERROR_INPROGRESS;
57
58 StringVar* configuration_id_var = StringVar::FromPPVar(configuration_id);
59 if (!configuration_id_var)
60 return PP_ERROR_BADARGUMENT;
61 StringVar* configuration_name_var = StringVar::FromPPVar(configuration_name);
62 if (!configuration_name_var)
63 return PP_ERROR_BADARGUMENT;
64
65 bind_callback_ = callback;
66
67 Call<PpapiPluginMsg_VpnProvider_BindReply>(
68 BROWSER, PpapiHostMsg_VpnProvider_Bind(configuration_id_var->value(),
69 configuration_name_var->value()),
70 base::Bind(&VpnProviderResource::OnPluginMsgBindReply, this));
71
72 return PP_OK_COMPLETIONPENDING;
73 }
74
75 int32_t VpnProviderResource::SendPacket(
76 const PP_Var& packet,
77 const scoped_refptr<TrackedCallback>& callback) {
78 if (!bound_)
79 return PP_ERROR_FAILED;
80 if (TrackedCallback::IsPending(send_packet_callback_))
81 return PP_ERROR_INPROGRESS;
82 if (!ArrayBufferVar::FromPPVar(packet))
83 return PP_ERROR_BADARGUMENT;
84
85 uint32_t id;
86 if (send_packet_buffer_.get() && send_packet_buffer_->GetAvailable(&id)) {
87 // Send packet immediately
88 send_packet_buffer_->SetAvailable(id, false);
89 return DoSendPacket(packet, id);
90 } else {
91 // Packet will be sent later
92 send_packet_callback_ = callback;
93 PpapiGlobals::Get()->GetVarTracker()->AddRefVar(packet);
94 send_packets_.push(packet);
95
96 return PP_OK_COMPLETIONPENDING;
97 }
98 }
99
100 int32_t VpnProviderResource::DoSendPacket(const PP_Var& packet, uint32_t id) {
101 // Convert packet to std::vector<char>, then send it.
102 scoped_refptr<ArrayBufferVar> packet_arraybuffer =
103 ArrayBufferVar::FromPPVar(packet);
104 if (!packet_arraybuffer.get())
105 return PP_ERROR_BADARGUMENT;
106
107 char* packet_pointer = static_cast<char*>(packet_arraybuffer->Map());
108 uint32_t packet_size = packet_arraybuffer->ByteLength();
109 memcpy(send_packet_buffer_->GetBuffer(id), packet_pointer, packet_size);
110 packet_arraybuffer->Unmap();
111
112 Call<PpapiPluginMsg_VpnProvider_SendPacketReply>(
113 BROWSER, PpapiHostMsg_VpnProvider_SendPacket(packet_size, id),
114 base::Bind(&VpnProviderResource::OnPluginMsgSendPacketReply, this));
115
116 return PP_OK;
117 }
118
119 int32_t VpnProviderResource::ReceivePacket(
120 PP_Var* packet,
121 const scoped_refptr<TrackedCallback>& callback) {
122 if (TrackedCallback::IsPending(receive_packet_callback_))
123 return PP_ERROR_INPROGRESS;
124
125 // Return previously received packet.
126 if (!received_packets_.empty()) {
127 receive_packet_callback_var_ = packet;
128 WritePacket();
129 return PP_OK;
130 }
131
132 // Or retain packet var and install callback.
133 receive_packet_callback_var_ = packet;
134 receive_packet_callback_ = callback;
135
136 return PP_OK_COMPLETIONPENDING;
137 }
138
139 // Responds to PpapiPluginMsg_VpnProvider_OnUnbind
140 void VpnProviderResource::OnPluginMsgOnUnbindReceived(
141 const ResourceMessageReplyParams& params) {
142 bound_ = false;
143
144 // Cleanup in-flight packets.
145 while (!received_packets_.empty()) {
146 received_packets_.pop();
147 }
148 while (!send_packets_.empty()) {
149 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(send_packets_.front());
150 send_packets_.pop();
151 }
152 }
153
154 // Responds to PpapiPluginMsg_VpnProvider_OnPacketReceived
155 void VpnProviderResource::OnPluginMsgOnPacketReceived(
156 const ResourceMessageReplyParams& params,
157 uint32_t packet_size,
158 uint32_t id) {
159 if (!bound_) {
160 // Ignore packet and mark shared memory as available
161 Post(BROWSER, PpapiHostMsg_VpnProvider_OnPacketReceivedReply(id));
162 return;
163 }
164
165 // Append received packet to queue.
166 void* packet_pointer = receive_packet_buffer_->GetBuffer(id);
167 scoped_refptr<Var> packet_var(
168 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferVar(packet_size,
169 packet_pointer));
170 received_packets_.push(packet_var);
171
172 // Mark shared memory as available for next packet
173 Post(BROWSER, PpapiHostMsg_VpnProvider_OnPacketReceivedReply(id));
174
175 if (!TrackedCallback::IsPending(receive_packet_callback_) ||
176 TrackedCallback::IsScheduledToRun(receive_packet_callback_)) {
177 return;
178 }
179
180 scoped_refptr<TrackedCallback> callback;
181 callback.swap(receive_packet_callback_);
182 WritePacket();
183 callback->Run(PP_OK);
184 }
185
186 // Responds to PpapiPluginMsg_VpnProvider_BindReply
187 // Forwards to bind_callback_
188 void VpnProviderResource::OnPluginMsgBindReply(
189 const ResourceMessageReplyParams& params,
190 uint32_t queue_depth,
191 uint32_t max_packet_size,
192 int32_t result) {
193 if (!TrackedCallback::IsPending(bind_callback_))
194 return;
195
196 if (params.result() == PP_OK) {
197 std::vector<base::SharedMemoryHandle> shm_handles;
198 params.TakeAllSharedMemoryHandles(&shm_handles);
199 std::unique_ptr<base::SharedMemory> send_shm(
200 new base::SharedMemory(shm_handles[0], false));
201 std::unique_ptr<base::SharedMemory> receive_shm(
202 new base::SharedMemory(shm_handles[1], false));
203 size_t buffer_size = queue_depth * max_packet_size;
204 if (!send_shm->Map(buffer_size) || !receive_shm->Map(buffer_size)) {
205 NOTREACHED();
206 return;
207 }
208 send_packet_buffer_ = base::WrapUnique(new ppapi::VpnProviderSharedBuffer(
209 queue_depth, max_packet_size, std::move(send_shm)));
210 receive_packet_buffer_ =
211 base::WrapUnique(new ppapi::VpnProviderSharedBuffer(
212 queue_depth, max_packet_size, std::move(receive_shm)));
213
214 bound_ = (result == PP_OK);
215 }
216
217 scoped_refptr<TrackedCallback> callback;
218 callback.swap(bind_callback_);
219 callback->Run(params.result() ? params.result() : result);
220 }
221
222 // Responds to PpapiPluginMsg_VpnProvider_SendPacketReply
223 // Forwards to send_packet_callback_
224 void VpnProviderResource::OnPluginMsgSendPacketReply(
225 const ResourceMessageReplyParams& params,
226 int32_t id) {
227 if (!send_packets_.empty() && bound_) {
228 // Process remaining packets
229 DoSendPacket(send_packets_.front(), id);
230 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(send_packets_.front());
231 send_packets_.pop();
232 } else {
233 send_packet_buffer_->SetAvailable(id, true);
234
235 // Available slots - Run callback to process new packets.
236 if (TrackedCallback::IsPending(send_packet_callback_)) {
237 scoped_refptr<TrackedCallback> callback;
238 callback.swap(send_packet_callback_);
239 callback->Run(PP_OK);
240 }
241 }
242 }
243
244 void VpnProviderResource::WritePacket() {
245 if (!receive_packet_callback_var_)
246 return;
247
248 *receive_packet_callback_var_ = received_packets_.front()->GetPPVar();
249 received_packets_.pop();
250 receive_packet_callback_var_ = NULL;
251 }
252
253 } // namespace proxy
254 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698