| Index: ppapi/proxy/vpn_provider_resource.cc
|
| diff --git a/ppapi/proxy/vpn_provider_resource.cc b/ppapi/proxy/vpn_provider_resource.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3f7534e77b991b0ec0bf623970e95d1f83684a4f
|
| --- /dev/null
|
| +++ b/ppapi/proxy/vpn_provider_resource.cc
|
| @@ -0,0 +1,218 @@
|
| +// Copyright 2015 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 "ppapi/proxy/vpn_provider_resource.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/numerics/safe_conversions.h"
|
| +#include "base/strings/string_split.h"
|
| +#include "base/strings/string_util.h"
|
| +#include "ppapi/c/pp_errors.h"
|
| +#include "ppapi/proxy/dispatch_reply_message.h"
|
| +#include "ppapi/proxy/ppapi_messages.h"
|
| +#include "ppapi/shared_impl/array_var.h"
|
| +#include "ppapi/shared_impl/dictionary_var.h"
|
| +#include "ppapi/shared_impl/ppapi_globals.h"
|
| +#include "ppapi/shared_impl/proxy_lock.h"
|
| +#include "ppapi/shared_impl/tracked_callback.h"
|
| +#include "ppapi/shared_impl/var.h"
|
| +#include "ppapi/shared_impl/var_tracker.h"
|
| +
|
| +namespace ppapi {
|
| +namespace proxy {
|
| +VpnProviderResource::VpnProviderResource(Connection connection,
|
| + PP_Instance instance)
|
| + : PluginResource(connection, instance),
|
| + get_unbind_event_callback_(NULL),
|
| + get_packet_callback_var_(NULL),
|
| + received_unbind_event_(false) {
|
| + SendCreate(BROWSER, PpapiHostMsg_VpnProvider_Create());
|
| +}
|
| +
|
| +VpnProviderResource::~VpnProviderResource() {}
|
| +
|
| +thunk::PPB_VpnProvider_API* VpnProviderResource::AsPPB_VpnProvider_API() {
|
| + return this;
|
| +}
|
| +
|
| +void VpnProviderResource::OnReplyReceived(
|
| + const ResourceMessageReplyParams& params,
|
| + const IPC::Message& msg) {
|
| + PPAPI_BEGIN_MESSAGE_MAP(VpnProviderResource, msg)
|
| + PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(PpapiPluginMsg_VpnProvider_OnUnBind,
|
| + OnPluginMsgOnUnBindReceived)
|
| + PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
|
| + PpapiPluginMsg_VpnProvider_OnPacketReceived,
|
| + OnPluginMsgOnPacketReceived)
|
| + PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(
|
| + PluginResource::OnReplyReceived(params, msg))
|
| + PPAPI_END_MESSAGE_MAP()
|
| +}
|
| +
|
| +int32_t VpnProviderResource::Bind(
|
| + const PP_Var& name,
|
| + const PP_Var& id,
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + if (TrackedCallback::IsPending(bind_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + StringVar* name_var = StringVar::FromPPVar(name);
|
| + if (!name_var)
|
| + return PP_ERROR_BADARGUMENT;
|
| + StringVar* id_var = StringVar::FromPPVar(id);
|
| + if (!id_var)
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + bind_callback_ = callback;
|
| +
|
| + Call<PpapiPluginMsg_VpnProvider_BindReply>(
|
| + BROWSER,
|
| + PpapiHostMsg_VpnProvider_Bind(name_var->value(), id_var->value()),
|
| + base::Bind(&VpnProviderResource::OnPluginMsgBindReply, this));
|
| +
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +int32_t VpnProviderResource::GetUnBindEvent(
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + if (TrackedCallback::IsPending(get_unbind_event_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + // Just return received packets if any received packet is queued.
|
| + if (received_unbind_event_) {
|
| + return PP_OK;
|
| + }
|
| +
|
| + // Or install |callback|.
|
| + get_unbind_event_callback_ = callback;
|
| +
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +// TODO(adrian.belgun): Implement a queue here to optimize performance.
|
| +// After adding the callback, the performance of this API was impacted due to
|
| +// limiting to one the number of packets in flight.
|
| +int32_t VpnProviderResource::SendPacket(
|
| + const PP_Var& data,
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + if (TrackedCallback::IsPending(send_packet_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + send_packet_callback_ = callback;
|
| +
|
| + // Convert data to std::vector<char>, then send it.
|
| + scoped_refptr<ArrayBufferVar> data_arraybuffer =
|
| + ArrayBufferVar::FromPPVar(data);
|
| + if (!data_arraybuffer.get())
|
| + return PP_ERROR_BADARGUMENT;
|
| + char* data_pointer = static_cast<char*>(data_arraybuffer->Map());
|
| + uint32_t data_length = data_arraybuffer->ByteLength();
|
| + std::vector<char> data_vector(data_pointer, data_pointer + data_length);
|
| + data_arraybuffer->Unmap();
|
| +
|
| + Call<PpapiPluginMsg_VpnProvider_SendPacketReply>(
|
| + BROWSER, PpapiHostMsg_VpnProvider_SendPacket(data_vector),
|
| + base::Bind(&VpnProviderResource::OnPluginMsgSendPacketReply, this));
|
| +
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +int32_t VpnProviderResource::GetPacket(
|
| + PP_Var* data,
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + if (TrackedCallback::IsPending(get_packet_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + // Just return received packets if any received packet is queued.
|
| + if (!received_packets_.empty()) {
|
| + get_packet_callback_var_ = data;
|
| + WritePacket();
|
| + return PP_OK;
|
| + }
|
| +
|
| + // Or retain |packet| as buffer to store and install |callback|.
|
| + get_packet_callback_var_ = data;
|
| + get_packet_callback_ = callback;
|
| +
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +// Responds to PpapiPluginMsg_VpnProvider_OnUnBind
|
| +void VpnProviderResource::OnPluginMsgOnUnBindReceived(
|
| + const ResourceMessageReplyParams& params) {
|
| + if (!TrackedCallback::IsPending(get_unbind_event_callback_) ||
|
| + TrackedCallback::IsScheduledToRun(get_unbind_event_callback_)) {
|
| + return;
|
| + }
|
| +
|
| + // The plugin may call GetPacket in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(get_unbind_event_callback_);
|
| + callback->Run(PP_OK);
|
| +}
|
| +
|
| +// Responds to PpapiPluginMsg_VpnProvider_OnPacketReceived
|
| +void VpnProviderResource::OnPluginMsgOnPacketReceived(
|
| + const ResourceMessageReplyParams& params,
|
| + const std::vector<char>& data) {
|
| + // Append received packet to queue.
|
| + scoped_refptr<Var> data_var(
|
| + PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferVar(
|
| + base::checked_cast<uint32_t>(data.size()), &data.front()));
|
| + received_packets_.push(data_var);
|
| +
|
| + if (!TrackedCallback::IsPending(get_packet_callback_) ||
|
| + TrackedCallback::IsScheduledToRun(get_packet_callback_)) {
|
| + return;
|
| + }
|
| +
|
| + // The plugin may call GetPacket in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(get_packet_callback_);
|
| + WritePacket();
|
| + callback->Run(PP_OK);
|
| +}
|
| +
|
| +// Responds to PpapiPluginMsg_VpnProvider_BindReply
|
| +// Forwards to bind_callback_
|
| +void VpnProviderResource::OnPluginMsgBindReply(
|
| + const ResourceMessageReplyParams& params,
|
| + int32_t result) {
|
| + // The callback may have been aborted by Close().
|
| + if (TrackedCallback::IsPending(bind_callback_)) {
|
| + // The plugin may call DestroyConfig in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(bind_callback_);
|
| + // On error: Pass return code
|
| + // On succes: Pass message
|
| + callback->Run(params.result() ? params.result() : result);
|
| + }
|
| +}
|
| +
|
| +// Responds to PpapiPluginMsg_VpnProvider_SendPacketReply
|
| +// Forwards to send_packet_callback_
|
| +void VpnProviderResource::OnPluginMsgSendPacketReply(
|
| + const ResourceMessageReplyParams& params,
|
| + int32_t result) {
|
| + // The callback may have been aborted by Close().
|
| + if (TrackedCallback::IsPending(send_packet_callback_)) {
|
| + // The plugin may call SendPacket in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(send_packet_callback_);
|
| + // On error: Pass return code
|
| + // On succes: Pass message
|
| + callback->Run(params.result() ? params.result() : result);
|
| + }
|
| +}
|
| +void VpnProviderResource::WritePacket() {
|
| + if (!get_packet_callback_var_)
|
| + return;
|
| +
|
| + *get_packet_callback_var_ = received_packets_.front()->GetPPVar();
|
| + received_packets_.pop();
|
| + get_packet_callback_var_ = NULL;
|
| +}
|
| +
|
| +} // namespace proxy
|
| +} // namespace ppapi
|
|
|