| // Copyright (c) 2013 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/extensions_common_resource.h" |
| |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/values.h" |
| #include "ppapi/c/pp_errors.h" |
| #include "ppapi/proxy/ppapi_messages.h" |
| #include "ppapi/proxy/resource_message_params.h" |
| #include "ppapi/shared_impl/tracked_callback.h" |
| #include "ppapi/shared_impl/var_value_conversions.h" |
| |
| namespace ppapi { |
| namespace proxy { |
| |
| ExtensionsCommonResource::ExtensionsCommonResource(Connection connection, |
| PP_Instance instance) |
| : PluginResource(connection, instance) { |
| SendCreate(RENDERER, PpapiHostMsg_ExtensionsCommon_Create()); |
| SendCreate(BROWSER, PpapiHostMsg_ExtensionsCommon_Create()); |
| } |
| |
| ExtensionsCommonResource::~ExtensionsCommonResource() { |
| } |
| |
| thunk::ExtensionsCommon_API* |
| ExtensionsCommonResource::AsExtensionsCommon_API() { |
| return this; |
| } |
| |
| int32_t ExtensionsCommonResource::CallRenderer( |
| const std::string& request_name, |
| const std::vector<PP_Var>& input_args, |
| const std::vector<PP_Var*>& output_args, |
| scoped_refptr<TrackedCallback> callback) { |
| return CommonCall(RENDERER, request_name, input_args, output_args, callback); |
| } |
| |
| void ExtensionsCommonResource::PostRenderer(const std::string& request_name, |
| const std::vector<PP_Var>& args) { |
| CommonPost(RENDERER, request_name, args); |
| } |
| |
| int32_t ExtensionsCommonResource::CallBrowser( |
| const std::string& request_name, |
| const std::vector<PP_Var>& input_args, |
| const std::vector<PP_Var*>& output_args, |
| scoped_refptr<TrackedCallback> callback) { |
| return CommonCall(BROWSER, request_name, input_args, output_args, callback); |
| } |
| |
| void ExtensionsCommonResource::PostBrowser(const std::string& request_name, |
| const std::vector<PP_Var>& args) { |
| CommonPost(BROWSER, request_name, args); |
| } |
| |
| int32_t ExtensionsCommonResource::CommonCall( |
| Destination dest, |
| const std::string& request_name, |
| const std::vector<PP_Var>& input_args, |
| const std::vector<PP_Var*>& output_args, |
| scoped_refptr<TrackedCallback> callback) { |
| // TODO(yzshen): CreateValueFromVar() doesn't generate null fields for |
| // dictionary values. That is the expected behavior for most APIs. If later we |
| // want to support APIs that require to preserve null fields in dictionaries, |
| // we should change the behavior to always preserve null fields at the plugin |
| // side, and figure out whether they should be stripped at the renderer side. |
| scoped_ptr<base::ListValue> input_args_value( |
| CreateListValueFromVarVector(input_args)); |
| if (!input_args_value.get()) { |
| LOG(WARNING) << "Failed to convert PP_Var input arguments."; |
| return PP_ERROR_BADARGUMENT; |
| } |
| |
| PluginResource::Call<PpapiPluginMsg_ExtensionsCommon_CallReply>( |
| dest, |
| PpapiHostMsg_ExtensionsCommon_Call(request_name, *input_args_value), |
| base::Bind(&ExtensionsCommonResource::OnPluginMsgCallReply, |
| base::Unretained(this), output_args, callback)); |
| return PP_OK_COMPLETIONPENDING; |
| } |
| |
| void ExtensionsCommonResource::CommonPost(Destination dest, |
| const std::string& request_name, |
| const std::vector<PP_Var>& args) { |
| scoped_ptr<base::ListValue> args_value(CreateListValueFromVarVector(args)); |
| if (!args_value.get()) { |
| LOG(WARNING) << "Failed to convert PP_Var input arguments."; |
| return; |
| } |
| |
| PluginResource::Post( |
| dest, PpapiHostMsg_ExtensionsCommon_Post(request_name, *args_value)); |
| } |
| |
| void ExtensionsCommonResource::OnPluginMsgCallReply( |
| const std::vector<PP_Var*>& output_args, |
| scoped_refptr<TrackedCallback> callback, |
| const ResourceMessageReplyParams& params, |
| const base::ListValue& output) { |
| // |output_args| may be invalid and shouldn't be accessed if the callback has |
| // been called. |
| if (!TrackedCallback::IsPending(callback)) |
| return; |
| |
| int32_t result = params.result(); |
| |
| // If the size doesn't match, something must be really wrong. |
| CHECK_EQ(output_args.size(), output.GetSize()); |
| |
| std::vector<PP_Var> output_vars; |
| if (CreateVarVectorFromListValue(output, &output_vars)) { |
| DCHECK_EQ(output_args.size(), output_vars.size()); |
| std::vector<PP_Var>::const_iterator src_iter = output_vars.begin(); |
| std::vector<PP_Var*>::const_iterator dest_iter = output_args.begin(); |
| for (; src_iter != output_vars.end() && dest_iter != output_args.end(); |
| ++src_iter, ++dest_iter) { |
| **dest_iter = *src_iter; |
| } |
| } else { |
| NOTREACHED(); |
| result = PP_ERROR_FAILED; |
| for (std::vector<PP_Var*>::const_iterator dest_iter = output_args.begin(); |
| dest_iter != output_args.end(); |
| ++dest_iter) { |
| **dest_iter = PP_MakeUndefined(); |
| } |
| } |
| |
| callback->Run(result); |
| } |
| |
| } // namespace proxy |
| } // namespace ppapi |