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.
5 #include "ppapi/proxy/extensions_common_resource.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"
21 ExtensionsCommonResource::ExtensionsCommonResource(Connection connection
,
23 : PluginResource(connection
, instance
) {
24 SendCreate(RENDERER
, PpapiHostMsg_ExtensionsCommon_Create());
25 SendCreate(BROWSER
, PpapiHostMsg_ExtensionsCommon_Create());
28 ExtensionsCommonResource::~ExtensionsCommonResource() {
31 thunk::ExtensionsCommon_API
*
32 ExtensionsCommonResource::AsExtensionsCommon_API() {
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
);
44 void ExtensionsCommonResource::PostRenderer(const std::string
& request_name
,
45 const std::vector
<PP_Var
>& args
) {
46 CommonPost(RENDERER
, request_name
, args
);
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
);
57 void ExtensionsCommonResource::PostBrowser(const std::string
& request_name
,
58 const std::vector
<PP_Var
>& args
) {
59 CommonPost(BROWSER
, request_name
, args
);
62 int32_t ExtensionsCommonResource::CommonCall(
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
;
80 PluginResource::Call
<PpapiPluginMsg_ExtensionsCommon_CallReply
>(
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
;
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.";
98 dest
, PpapiHostMsg_ExtensionsCommon_Post(request_name
, *args_value
));
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
108 if (!TrackedCallback::IsPending(callback
))
111 int32_t result
= params
.result();
113 // If the size doesn't match, something must be really wrong.
114 CHECK_EQ(output_args
.size(), output
.GetSize());
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
;
127 result
= PP_ERROR_FAILED
;
128 for (std::vector
<PP_Var
*>::const_iterator dest_iter
= output_args
.begin();
129 dest_iter
!= output_args
.end();
131 **dest_iter
= PP_MakeUndefined();
135 callback
->Run(result
);