15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppp_class_proxy.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_var_deprecated.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppp_class_deprecated.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_var.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/dispatcher.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_globals.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/serialized_var.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/api_id.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPP_Class in the browser implementation -------------------------------------
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Represents a plugin-implemented class in the browser process. This just
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stores the data necessary to call back the plugin.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ObjectProxy {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy(Dispatcher* d, int64 p, int64 ud)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : dispatcher(d),
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ppp_class(p),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        user_data(ud) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Dispatcher* dispatcher;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 ppp_class;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 user_data;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ObjectProxy* ToObjectProxy(void* data) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ObjectProxy* obj = reinterpret_cast<ObjectProxy*>(data);
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!obj || !obj->dispatcher)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!obj->dispatcher->permissions().HasPermission(PERMISSION_DEV))
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return obj;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasProperty(void* object, PP_Var name, PP_Var* exception) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* obj = ToObjectProxy(object);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!obj)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedException se(obj->dispatcher, exception);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  obj->dispatcher->Send(new PpapiMsg_PPPClass_HasProperty(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SerializedVarSendInput(obj->dispatcher, name), &se, &result));
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasMethod(void* object, PP_Var name, PP_Var* exception) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* obj = ToObjectProxy(object);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!obj)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedException se(obj->dispatcher, exception);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  obj->dispatcher->Send(new PpapiMsg_PPPClass_HasMethod(
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SerializedVarSendInput(obj->dispatcher, name), &se, &result));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var GetProperty(void* object,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   PP_Var name,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   PP_Var* exception) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* obj = ToObjectProxy(object);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!obj)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_MakeUndefined();
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedException se(obj->dispatcher, exception);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedVarReturnValue result;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  obj->dispatcher->Send(new PpapiMsg_PPPClass_GetProperty(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SerializedVarSendInput(obj->dispatcher, name), &se, &result));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result.Return(obj->dispatcher);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetAllPropertyNames(void* object,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         uint32_t* property_count,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         PP_Var** properties,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         PP_Var* exception) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw) implement this.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetProperty(void* object,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 PP_Var name,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 PP_Var value,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 PP_Var* exception) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* obj = ToObjectProxy(object);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!obj)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedException se(obj->dispatcher, exception);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  obj->dispatcher->Send(new PpapiMsg_PPPClass_SetProperty(
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SerializedVarSendInput(obj->dispatcher, name),
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SerializedVarSendInput(obj->dispatcher, value), &se));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveProperty(void* object,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PP_Var name,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PP_Var* exception) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* obj = ToObjectProxy(object);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!obj)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedException se(obj->dispatcher, exception);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  obj->dispatcher->Send(new PpapiMsg_PPPClass_RemoveProperty(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SerializedVarSendInput(obj->dispatcher, name), &se));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var Call(void* object,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PP_Var method_name,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            uint32_t argc,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PP_Var* argv,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PP_Var* exception) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* obj = ToObjectProxy(object);
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!obj)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_MakeUndefined();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedVarReturnValue result;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedException se(obj->dispatcher, exception);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<SerializedVar> argv_vect;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarSendInput::ConvertVector(obj->dispatcher, argv, argc,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        &argv_vect);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  obj->dispatcher->Send(new PpapiMsg_PPPClass_Call(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPP_CLASS, obj->ppp_class, obj->user_data,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SerializedVarSendInput(obj->dispatcher, method_name), argv_vect,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &se, &result));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result.Return(obj->dispatcher);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var Construct(void* object,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 uint32_t argc,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 PP_Var* argv,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 PP_Var* exception) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* obj = ToObjectProxy(object);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!obj)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_MakeUndefined();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedVarReturnValue result;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReceiveSerializedException se(obj->dispatcher, exception);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<SerializedVar> argv_vect;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarSendInput::ConvertVector(obj->dispatcher, argv, argc,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        &argv_vect);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  obj->dispatcher->Send(new PpapiMsg_PPPClass_Construct(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPP_CLASS,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      obj->ppp_class, obj->user_data, argv_vect, &se, &result));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result.Return(obj->dispatcher);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Deallocate(void* object) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* obj = ToObjectProxy(object);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!obj)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  obj->dispatcher->Send(new PpapiMsg_PPPClass_Deallocate(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPP_CLASS, obj->ppp_class, obj->user_data));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete obj;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPP_Class_Deprecated class_interface = {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &HasProperty,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &HasMethod,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &GetProperty,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &GetAllPropertyNames,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &SetProperty,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &RemoveProperty,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &Call,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &Construct,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &Deallocate
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Plugin helper functions -----------------------------------------------------
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts an int64 object from IPC to a PPP_Class* for calling into the
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// plugin's implementation.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPP_Class_Deprecated* ToPPPClass(int64 value) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reinterpret_cast<const PPP_Class_Deprecated*>(
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<intptr_t>(value));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts an int64 object from IPC to a void* for calling into the plugin's
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementation as the user data.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* ToUserData(int64 value) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reinterpret_cast<void*>(static_cast<intptr_t>(value));
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPP_Class_Proxy -------------------------------------------------------------
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPP_Class_Proxy::PPP_Class_Proxy(Dispatcher* dispatcher)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : InterfaceProxy(dispatcher) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPP_Class_Proxy::~PPP_Class_Proxy() {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InterfaceProxy* PPP_Class_Proxy::Create(Dispatcher* dispatcher) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new PPP_Class_Proxy(dispatcher);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var PPP_Class_Proxy::CreateProxiedObject(const PPB_Var_Deprecated* var,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            Dispatcher* dispatcher,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            PP_Instance instance_id,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            int64 ppp_class,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            int64 class_data) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* object_proxy = new ObjectProxy(dispatcher,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              ppp_class, class_data);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return var->CreateObject(instance_id, &class_interface, object_proxy);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool PPP_Class_Proxy::IsInstanceOf(const PPB_Var_Deprecated* ppb_var_impl,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const PP_Var& var,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int64 ppp_class,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int64* ppp_class_data) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* proxied_object = NULL;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ppb_var_impl->IsInstanceOf(var,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 &class_interface,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 &proxied_object)) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (static_cast<ObjectProxy*>(proxied_object)->ppp_class == ppp_class) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(ppp_class_data);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *ppp_class_data = static_cast<ObjectProxy*>(proxied_object)->user_data;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_TRUE;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_FALSE;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPP_Class_Proxy::OnMessageReceived(const IPC::Message& msg) {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dispatcher()->IsPlugin())
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;  // These messages are only valid from host->plugin.
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(PPP_Class_Proxy, msg)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_HasProperty,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnMsgHasProperty)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_HasMethod,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnMsgHasMethod)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_GetProperty,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnMsgGetProperty)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_EnumerateProperties,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnMsgEnumerateProperties)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_SetProperty,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnMsgSetProperty)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Call,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnMsgCall)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Construct,
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnMsgConstruct)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Deallocate,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnMsgDeallocate)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPP_Class_Proxy::OnMsgHasProperty(int64 ppp_class, int64 object,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SerializedVarReceiveInput property,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SerializedVarOutParam exception,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       bool* result) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ValidateUserData(ppp_class, object, &exception))
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result = CallWhileUnlocked(ToPPPClass(ppp_class)->HasProperty,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              ToUserData(object),
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              property.Get(dispatcher()),
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              exception.OutParam(dispatcher()));
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPP_Class_Proxy::OnMsgHasMethod(int64 ppp_class, int64 object,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     SerializedVarReceiveInput property,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     SerializedVarOutParam exception,
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bool* result) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ValidateUserData(ppp_class, object, &exception))
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result = CallWhileUnlocked(ToPPPClass(ppp_class)->HasMethod,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              ToUserData(object),
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              property.Get(dispatcher()),
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              exception.OutParam(dispatcher()));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPP_Class_Proxy::OnMsgGetProperty(int64 ppp_class, int64 object,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SerializedVarReceiveInput property,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SerializedVarOutParam exception,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SerializedVarReturnValue result) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ValidateUserData(ppp_class, object, &exception))
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.Return(dispatcher(), CallWhileUnlocked(
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ToPPPClass(ppp_class)->GetProperty,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ToUserData(object), property.Get(dispatcher()),
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exception.OutParam(dispatcher())));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPP_Class_Proxy::OnMsgEnumerateProperties(
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 ppp_class, int64 object,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<SerializedVar>* props,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVarOutParam exception) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ValidateUserData(ppp_class, object, &exception))
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw) implement this.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPP_Class_Proxy::OnMsgSetProperty(int64 ppp_class, int64 object,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SerializedVarReceiveInput property,
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SerializedVarReceiveInput value,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SerializedVarOutParam exception) {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ValidateUserData(ppp_class, object, &exception))
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallWhileUnlocked(ToPPPClass(ppp_class)->SetProperty,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ToUserData(object), property.Get(dispatcher()), value.Get(dispatcher()),
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exception.OutParam(dispatcher()));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPP_Class_Proxy::OnMsgRemoveProperty(int64 ppp_class, int64 object,
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          SerializedVarReceiveInput property,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          SerializedVarOutParam exception) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ValidateUserData(ppp_class, object, &exception))
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallWhileUnlocked(ToPPPClass(ppp_class)->RemoveProperty,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ToUserData(object), property.Get(dispatcher()),
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exception.OutParam(dispatcher()));
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPP_Class_Proxy::OnMsgCall(
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 ppp_class, int64 object,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVarReceiveInput method_name,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVarVectorReceiveInput arg_vector,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVarOutParam exception,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVarReturnValue result) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ValidateUserData(ppp_class, object, &exception))
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t arg_count = 0;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.Return(dispatcher(), CallWhileUnlocked(ToPPPClass(ppp_class)->Call,
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ToUserData(object), method_name.Get(dispatcher()),
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arg_count, args, exception.OutParam(dispatcher())));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPP_Class_Proxy::OnMsgConstruct(
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 ppp_class, int64 object,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVarVectorReceiveInput arg_vector,
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVarOutParam exception,
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVarReturnValue result) {
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ValidateUserData(ppp_class, object, &exception))
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t arg_count = 0;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.Return(dispatcher(), CallWhileUnlocked(
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ToPPPClass(ppp_class)->Construct,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ToUserData(object), arg_count, args, exception.OutParam(dispatcher())));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPP_Class_Proxy::OnMsgDeallocate(int64 ppp_class, int64 object) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ValidateUserData(ppp_class, object, NULL))
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PluginGlobals::Get()->plugin_var_tracker()->PluginImplementedObjectDestroyed(
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ToUserData(object));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallWhileUnlocked(ToPPPClass(ppp_class)->Deallocate, ToUserData(object));
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPP_Class_Proxy::ValidateUserData(int64 ppp_class, int64 class_data,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SerializedVarOutParam* exception) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!PluginGlobals::Get()->plugin_var_tracker()->ValidatePluginObjectCall(
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ToPPPClass(ppp_class), ToUserData(class_data))) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set the exception. This is so the caller will know about the error and
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // also that we won't assert that somebody forgot to call OutParam on the
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // output parameter. Although this exception of "1" won't be very useful
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // this shouldn't happen in normal usage, only when the renderer is being
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // malicious.
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exception)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *exception->OutParam(dispatcher()) = PP_MakeInt32(1);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace proxy
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
397