- add sources.
[platform/framework/web/crosswalk.git] / src / ppapi / proxy / extensions_common_resource.cc
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