1 // Copyright (c) 2013 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/extensions_common_resource.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/logging.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/values.h" 12 #include "ppapi/c/pp_errors.h" 13 #include "ppapi/proxy/ppapi_messages.h" 14 #include "ppapi/proxy/resource_message_params.h" 15 #include "ppapi/shared_impl/tracked_callback.h" 16 #include "ppapi/shared_impl/var_value_conversions.h" 17 18 namespace ppapi { 19 namespace proxy { 20 21 ExtensionsCommonResource::ExtensionsCommonResource(Connection connection, 22 PP_Instance instance) 23 : PluginResource(connection, instance) { 24 SendCreate(RENDERER, PpapiHostMsg_ExtensionsCommon_Create()); 25 SendCreate(BROWSER, PpapiHostMsg_ExtensionsCommon_Create()); 26 } 27 28 ExtensionsCommonResource::~ExtensionsCommonResource() { 29 } 30 31 thunk::ExtensionsCommon_API* 32 ExtensionsCommonResource::AsExtensionsCommon_API() { 33 return this; 34 } 35 36 int32_t ExtensionsCommonResource::CallRenderer( 37 const std::string& request_name, 38 const std::vector<PP_Var>& input_args, 39 const std::vector<PP_Var*>& output_args, 40 scoped_refptr<TrackedCallback> callback) { 41 return CommonCall(RENDERER, request_name, input_args, output_args, callback); 42 } 43 44 void ExtensionsCommonResource::PostRenderer(const std::string& request_name, 45 const std::vector<PP_Var>& args) { 46 CommonPost(RENDERER, request_name, args); 47 } 48 49 int32_t ExtensionsCommonResource::CallBrowser( 50 const std::string& request_name, 51 const std::vector<PP_Var>& input_args, 52 const std::vector<PP_Var*>& output_args, 53 scoped_refptr<TrackedCallback> callback) { 54 return CommonCall(BROWSER, request_name, input_args, output_args, callback); 55 } 56 57 void ExtensionsCommonResource::PostBrowser(const std::string& request_name, 58 const std::vector<PP_Var>& args) { 59 CommonPost(BROWSER, request_name, args); 60 } 61 62 int32_t ExtensionsCommonResource::CommonCall( 63 Destination dest, 64 const std::string& request_name, 65 const std::vector<PP_Var>& input_args, 66 const std::vector<PP_Var*>& output_args, 67 scoped_refptr<TrackedCallback> callback) { 68 // TODO(yzshen): CreateValueFromVar() doesn't generate null fields for 69 // dictionary values. That is the expected behavior for most APIs. If later we 70 // want to support APIs that require to preserve null fields in dictionaries, 71 // we should change the behavior to always preserve null fields at the plugin 72 // side, and figure out whether they should be stripped at the renderer side. 73 scoped_ptr<base::ListValue> input_args_value( 74 CreateListValueFromVarVector(input_args)); 75 if (!input_args_value.get()) { 76 LOG(WARNING) << "Failed to convert PP_Var input arguments."; 77 return PP_ERROR_BADARGUMENT; 78 } 79 80 PluginResource::Call<PpapiPluginMsg_ExtensionsCommon_CallReply>( 81 dest, 82 PpapiHostMsg_ExtensionsCommon_Call(request_name, *input_args_value), 83 base::Bind(&ExtensionsCommonResource::OnPluginMsgCallReply, 84 base::Unretained(this), output_args, callback)); 85 return PP_OK_COMPLETIONPENDING; 86 } 87 88 void ExtensionsCommonResource::CommonPost(Destination dest, 89 const std::string& request_name, 90 const std::vector<PP_Var>& args) { 91 scoped_ptr<base::ListValue> args_value(CreateListValueFromVarVector(args)); 92 if (!args_value.get()) { 93 LOG(WARNING) << "Failed to convert PP_Var input arguments."; 94 return; 95 } 96 97 PluginResource::Post( 98 dest, PpapiHostMsg_ExtensionsCommon_Post(request_name, *args_value)); 99 } 100 101 void ExtensionsCommonResource::OnPluginMsgCallReply( 102 const std::vector<PP_Var*>& output_args, 103 scoped_refptr<TrackedCallback> callback, 104 const ResourceMessageReplyParams& params, 105 const base::ListValue& output) { 106 // |output_args| may be invalid and shouldn't be accessed if the callback has 107 // been called. 108 if (!TrackedCallback::IsPending(callback)) 109 return; 110 111 int32_t result = params.result(); 112 113 // If the size doesn't match, something must be really wrong. 114 CHECK_EQ(output_args.size(), output.GetSize()); 115 116 std::vector<PP_Var> output_vars; 117 if (CreateVarVectorFromListValue(output, &output_vars)) { 118 DCHECK_EQ(output_args.size(), output_vars.size()); 119 std::vector<PP_Var>::const_iterator src_iter = output_vars.begin(); 120 std::vector<PP_Var*>::const_iterator dest_iter = output_args.begin(); 121 for (; src_iter != output_vars.end() && dest_iter != output_args.end(); 122 ++src_iter, ++dest_iter) { 123 **dest_iter = *src_iter; 124 } 125 } else { 126 NOTREACHED(); 127 result = PP_ERROR_FAILED; 128 for (std::vector<PP_Var*>::const_iterator dest_iter = output_args.begin(); 129 dest_iter != output_args.end(); 130 ++dest_iter) { 131 **dest_iter = PP_MakeUndefined(); 132 } 133 } 134 135 callback->Run(result); 136 } 137 138 } // namespace proxy 139 } // namespace ppapi 140