| 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..03afc8d4fb16b00587a85361d7d84d9c43f50f55
|
| --- /dev/null
|
| +++ b/ppapi/proxy/vpn_provider_resource.cc
|
| @@ -0,0 +1,510 @@
|
| +// 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),
|
| + create_config_callback_var_(NULL),
|
| + get_packet_callback_var_(NULL),
|
| + get_platform_message_callback_var_(NULL),
|
| + get_config_message_callback_var_(NULL),
|
| + get_ui_message_callback_var_(NULL) {
|
| + 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_OnPlatformMessage,
|
| + OnPluginMsgOnPlatformMessage)
|
| + PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
|
| + PpapiPluginMsg_VpnProvider_OnPacketReceived, OnPluginMsgOnPacketReceived)
|
| + PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(PpapiPluginMsg_VpnProvider_OnConfigEvent,
|
| + OnPluginMsgOnConfigEvent)
|
| + PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(PpapiPluginMsg_VpnProvider_OnUIEvent,
|
| + OnPluginMsgOnUIEvent)
|
| + PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(
|
| + PluginResource::OnReplyReceived(params, msg))
|
| + PPAPI_END_MESSAGE_MAP()
|
| +}
|
| +
|
| +int32_t VpnProviderResource::CreateConfig(
|
| + const PP_Var& name,
|
| + PP_Var* id,
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + StringVar* name_var = StringVar::FromPPVar(name);
|
| + if (!name_var)
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + if (TrackedCallback::IsPending(create_config_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + create_config_callback_var_ = id;
|
| + create_config_callback_ = callback;
|
| +
|
| + Call<PpapiPluginMsg_VpnProvider_CreateConfigReply>(
|
| + BROWSER, PpapiHostMsg_VpnProvider_CreateConfig(name_var->value()),
|
| + base::Bind(&VpnProviderResource::OnPluginMsgCreateConfigReply, this));
|
| +
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +int32_t VpnProviderResource::DestroyConfig(
|
| + const PP_Var& id,
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + StringVar* name_var = StringVar::FromPPVar(id);
|
| + if (!name_var)
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + if (TrackedCallback::IsPending(destroy_config_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + destroy_config_callback_ = callback;
|
| +
|
| + Call<PpapiPluginMsg_VpnProvider_DestroyConfigReply>(
|
| + BROWSER, PpapiHostMsg_VpnProvider_DestroyConfig(name_var->value()),
|
| + base::Bind(&VpnProviderResource::OnPluginMsgDestroyConfigReply, this));
|
| +
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +int32_t VpnProviderResource::SetParameters(
|
| + const PP_Var& address,
|
| + const PP_Var& broadcast_address,
|
| + int32_t mtu,
|
| + const PP_Var& exclusion_list,
|
| + const PP_Var& inclusion_list,
|
| + const PP_Var& domain_search,
|
| + const PP_Var& dns_servers,
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + if (TrackedCallback::IsPending(set_parameters_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + set_parameters_callback_ = callback;
|
| +
|
| + SerializedVpnProviderParameters params;
|
| + StringVar* address_var = StringVar::FromPPVar(address);
|
| + if (!address_var)
|
| + return PP_ERROR_BADARGUMENT;
|
| + std::string address_str = address_var->value();
|
| + std::vector<std::string> cidr_parts = base::SplitString(
|
| + address_str, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
| + CHECK(cidr_parts.size() == 2);
|
| + params.address = cidr_parts[0];
|
| + params.subnet = cidr_parts[1];
|
| +
|
| + ArrayVar* exclusion_list_array = ArrayVar::FromPPVar(exclusion_list);
|
| + if (!exclusion_list_array) {
|
| + return PP_ERROR_BADARGUMENT;
|
| + }
|
| + for (uint32_t i = 0; i < exclusion_list_array->GetLength(); i++) {
|
| + StringVar* exclusion_list_var =
|
| + StringVar::FromPPVar(exclusion_list_array->Get(i));
|
| + if (!exclusion_list_var) {
|
| + return PP_ERROR_BADARGUMENT;
|
| + }
|
| + params.exclusion_list.push_back(exclusion_list_var->value());
|
| + }
|
| +
|
| + ArrayVar* inclusion_list_array = ArrayVar::FromPPVar(inclusion_list);
|
| + if (!inclusion_list_array) {
|
| + return PP_ERROR_BADARGUMENT;
|
| + }
|
| + for (uint32_t i = 0; i < inclusion_list_array->GetLength(); i++) {
|
| + StringVar* inclusion_list_var =
|
| + StringVar::FromPPVar(inclusion_list_array->Get(i));
|
| + if (!inclusion_list_var) {
|
| + return PP_ERROR_BADARGUMENT;
|
| + }
|
| + params.inclusion_list.push_back(inclusion_list_var->value());
|
| + }
|
| +
|
| + params.mtu = mtu;
|
| +
|
| + StringVar* broadcast_address_var = StringVar::FromPPVar(broadcast_address);
|
| + if (!broadcast_address_var)
|
| + return PP_ERROR_BADARGUMENT;
|
| + params.broadcast_address = broadcast_address_var->value();
|
| +
|
| + ArrayVar* domain_search_array = ArrayVar::FromPPVar(domain_search);
|
| + if (!domain_search_array) {
|
| + return PP_ERROR_BADARGUMENT;
|
| + }
|
| + for (uint32_t i = 0; i < domain_search_array->GetLength(); i++) {
|
| + StringVar* domain_search_var =
|
| + StringVar::FromPPVar(domain_search_array->Get(i));
|
| + if (!domain_search_var) {
|
| + return PP_ERROR_BADARGUMENT;
|
| + }
|
| + params.domain_search.push_back(domain_search_var->value());
|
| + }
|
| +
|
| + ArrayVar* dns_servers_array = ArrayVar::FromPPVar(dns_servers);
|
| + if (!dns_servers_array)
|
| + return PP_ERROR_BADARGUMENT;
|
| + for (uint32_t i = 0; i < dns_servers_array->GetLength(); i++) {
|
| + StringVar* dns_servers_var =
|
| + StringVar::FromPPVar(dns_servers_array->Get(i));
|
| + if (!dns_servers_var) {
|
| + return PP_ERROR_BADARGUMENT;
|
| + }
|
| + params.dns_servers.push_back(dns_servers_var->value());
|
| + }
|
| +
|
| + Call<PpapiPluginMsg_VpnProvider_SetParametersReply>(
|
| + BROWSER, PpapiHostMsg_VpnProvider_SetParameters(params),
|
| + base::Bind(&VpnProviderResource::OnPluginMsgSetParametersReply, this));
|
| +
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +int32_t VpnProviderResource::SendPacket(const PP_Var& data) {
|
| + // 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 data_length = data_arraybuffer->ByteLength();
|
| + std::vector<char> data_vector(data_pointer, data_pointer + data_length);
|
| + data_arraybuffer->Unmap();
|
| +
|
| + Post(BROWSER, PpapiHostMsg_VpnProvider_SendPacket(data_vector));
|
| +
|
| + return PP_OK;
|
| +}
|
| +
|
| +int32_t VpnProviderResource::NotifyConnectionStateChanged(
|
| + PP_VpnProvider_VpnConnectionState status,
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + if (TrackedCallback::IsPending(send_state_change_notification_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + send_state_change_notification_callback_ = callback;
|
| +
|
| + Call<PpapiPluginMsg_VpnProvider_NotifyConnectionStateChangedReply>(
|
| + BROWSER, PpapiHostMsg_VpnProvider_NotifyConnectionStateChanged(status),
|
| + base::Bind(
|
| + &VpnProviderResource::OnPluginMsgNotifyConnectionStateChangedReply,
|
| + 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;
|
| +}
|
| +
|
| +int32_t VpnProviderResource::GetPlatformMessage(
|
| + PP_Var* message,
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + if (TrackedCallback::IsPending(get_platform_message_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + // Just return received messages if any received message is queued.
|
| + if (!received_platform_messages_.empty()) {
|
| + get_platform_message_callback_var_ = message;
|
| + WritePlatformMessage();
|
| + return PP_OK;
|
| + }
|
| +
|
| + // Or retain |message| as buffer to store and install |callback|.
|
| + get_platform_message_callback_var_ = message;
|
| + get_platform_message_callback_ = callback;
|
| +
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +int32_t VpnProviderResource::GetConfigMessage(
|
| + PP_Var* message,
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + if (TrackedCallback::IsPending(get_config_message_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + // Just return received messages if any received message is queued.
|
| + if (!received_config_messages_.empty()) {
|
| + get_config_message_callback_var_ = message;
|
| + WriteConfigMessage();
|
| + return PP_OK;
|
| + }
|
| +
|
| + // Or retain |message| as buffer to store and install |callback|.
|
| + get_config_message_callback_var_ = message;
|
| + get_config_message_callback_ = callback;
|
| +
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +int32_t VpnProviderResource::GetUIMessage(
|
| + PP_Var* message,
|
| + const scoped_refptr<TrackedCallback>& callback) {
|
| + if (TrackedCallback::IsPending(get_ui_message_callback_))
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + // Just return received messages if any received message is queued.
|
| + if (!received_ui_messages_.empty()) {
|
| + get_ui_message_callback_var_ = message;
|
| + WriteUIMessage();
|
| + return PP_OK;
|
| + }
|
| +
|
| + // Or retain |message| as buffer to store and install |callback|.
|
| + get_ui_message_callback_var_ = message;
|
| + get_ui_message_callback_ = callback;
|
| +
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +// Responds to PpapiPluginMsg_VpnProvider_OnPlatformMessage
|
| +void VpnProviderResource::OnPluginMsgOnPlatformMessage(
|
| + const ResourceMessageReplyParams& params,
|
| + const std::string& id,
|
| + PP_VpnProvider_PlatformMessage message,
|
| + const std::string& error) {
|
| + DictionaryVar* platform_message = new DictionaryVar();
|
| + platform_message->SetWithStringKey("id", StringVar::StringToPPVar(id));
|
| + platform_message->SetWithStringKey("message", PP_MakeInt32(message));
|
| + platform_message->SetWithStringKey("error", StringVar::StringToPPVar(error));
|
| +
|
| + // Append received message to queue.
|
| + received_platform_messages_.push(scoped_refptr<Var>(platform_message));
|
| +
|
| + if (!TrackedCallback::IsPending(get_platform_message_callback_) ||
|
| + TrackedCallback::IsScheduledToRun(get_platform_message_callback_)) {
|
| + return;
|
| + }
|
| +
|
| + // The plugin may call GetPlatformMessage in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(get_platform_message_callback_);
|
| + WritePlatformMessage();
|
| + 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_OnConfigEvent
|
| +void VpnProviderResource::OnPluginMsgOnConfigEvent(
|
| + const ResourceMessageReplyParams& params,
|
| + const std::string& id,
|
| + PP_VpnProvider_ConfigMessage message,
|
| + const std::string& name,
|
| + const std::string& data) {
|
| + DictionaryVar* config_message = new DictionaryVar();
|
| + config_message->SetWithStringKey("id", StringVar::StringToPPVar(id));
|
| + config_message->SetWithStringKey("message", PP_MakeInt32(message));
|
| + if (message == PP_VPN_PROVIDER_CONFIG_CREATED) {
|
| + config_message->SetWithStringKey("name", StringVar::StringToPPVar(name));
|
| + config_message->SetWithStringKey("data", StringVar::StringToPPVar(data));
|
| + }
|
| +
|
| + // Append received message to queue.
|
| + received_config_messages_.push(scoped_refptr<Var>(config_message));
|
| +
|
| + if (!TrackedCallback::IsPending(get_config_message_callback_) ||
|
| + TrackedCallback::IsScheduledToRun(get_config_message_callback_)) {
|
| + return;
|
| + }
|
| +
|
| + // The plugin may call GetConfigMessage in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(get_config_message_callback_);
|
| + WriteConfigMessage();
|
| + callback->Run(PP_OK);
|
| +}
|
| +
|
| +// Responds to PpapiPluginMsg_VpnProvider_OnUIEvent
|
| +void VpnProviderResource::OnPluginMsgOnUIEvent(
|
| + const ResourceMessageReplyParams& params,
|
| + PP_VpnProvider_UIEvent event,
|
| + const std::string& id) {
|
| + DictionaryVar* ui_event = new DictionaryVar();
|
| + ui_event->SetWithStringKey("event", PP_MakeInt32(event));
|
| + ui_event->SetWithStringKey("id", StringVar::StringToPPVar(id));
|
| +
|
| + // Append received message to queue.
|
| + received_ui_messages_.push(scoped_refptr<Var>(ui_event));
|
| +
|
| + if (!TrackedCallback::IsPending(get_config_message_callback_) ||
|
| + TrackedCallback::IsScheduledToRun(get_config_message_callback_)) {
|
| + return;
|
| + }
|
| +
|
| + // The plugin may call GetUIMessage in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(get_ui_message_callback_);
|
| + WriteUIMessage();
|
| + callback->Run(PP_OK);
|
| +}
|
| +
|
| +// Responds to PpapiPluginMsg_VpnProvider_CreateConfigReply
|
| +// Forwards to create_config_callback_
|
| +void VpnProviderResource::OnPluginMsgCreateConfigReply(
|
| + const ResourceMessageReplyParams& params,
|
| + int32_t result,
|
| + const std::string& id) {
|
| + // The callback may have been aborted by Close().
|
| + if (TrackedCallback::IsPending(create_config_callback_)) {
|
| + *create_config_callback_var_ = StringVar::StringToPPVar(id);
|
| + // The plugin may call CreateConfig in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(create_config_callback_);
|
| + // On error: Pass return code
|
| + // On succes: Pass message
|
| + callback->Run(params.result() ? params.result() : result);
|
| + }
|
| +}
|
| +
|
| +// Responds to PpapiPluginMsg_VpnProvider_DestroyConfigReply
|
| +// Forwards to destroy_config_callback_
|
| +void VpnProviderResource::OnPluginMsgDestroyConfigReply(
|
| + const ResourceMessageReplyParams& params,
|
| + int32_t result) {
|
| + // The callback may have been aborted by Close().
|
| + if (TrackedCallback::IsPending(destroy_config_callback_)) {
|
| + // The plugin may call DestroyConfig in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(destroy_config_callback_);
|
| + // On error: Pass return code
|
| + // On succes: Pass message
|
| + callback->Run(params.result() ? params.result() : result);
|
| + }
|
| +}
|
| +
|
| +// Responds to PpapiPluginMsg_VpnProvider_SetParametersReply
|
| +// Forwards to set_parameters_callback_
|
| +void VpnProviderResource::OnPluginMsgSetParametersReply(
|
| + const ResourceMessageReplyParams& params,
|
| + int32_t result) {
|
| + // The callback may have been aborted by Close().
|
| + if (TrackedCallback::IsPending(set_parameters_callback_)) {
|
| + // The plugin may call SetParameters in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(set_parameters_callback_);
|
| + // On error: Pass return code
|
| + // On succes: Pass message
|
| + callback->Run(params.result() ? params.result() : result);
|
| + }
|
| +}
|
| +
|
| +// Responds to PpapiPluginMsg_VpnProvider_NotifyConnectionStateChangedReply
|
| +// Forwards to send_state_change_notification_callback_
|
| +void VpnProviderResource::OnPluginMsgNotifyConnectionStateChangedReply(
|
| + const ResourceMessageReplyParams& params,
|
| + int32_t result) {
|
| + // The callback may have been aborted by Close().
|
| + if (TrackedCallback::IsPending(send_state_change_notification_callback_)) {
|
| + // The plugin may call NotifyConnectionStateChanged in its callback.
|
| + scoped_refptr<TrackedCallback> callback;
|
| + callback.swap(send_state_change_notification_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;
|
| +}
|
| +
|
| +void VpnProviderResource::WritePlatformMessage() {
|
| + if (!get_platform_message_callback_var_)
|
| + return;
|
| +
|
| + *get_platform_message_callback_var_ =
|
| + received_platform_messages_.front()->GetPPVar();
|
| + received_platform_messages_.pop();
|
| + get_platform_message_callback_var_ = NULL;
|
| +}
|
| +
|
| +void VpnProviderResource::WriteConfigMessage() {
|
| + if (!get_config_message_callback_var_)
|
| + return;
|
| +
|
| + *get_config_message_callback_var_ =
|
| + received_config_messages_.front()->GetPPVar();
|
| + received_config_messages_.pop();
|
| + get_config_message_callback_var_ = NULL;
|
| +}
|
| +
|
| +void VpnProviderResource::WriteUIMessage() {
|
| + if (!get_ui_message_callback_var_)
|
| + return;
|
| +
|
| + *get_ui_message_callback_var_ = received_ui_messages_.front()->GetPPVar();
|
| + received_ui_messages_.pop();
|
| + get_ui_message_callback_var_ = NULL;
|
| +}
|
| +
|
| +} // namespace proxy
|
| +} // namespace ppapi
|
|
|