Home | History | Annotate | Download | only in proxy
      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