1// Copyright (c) 2011 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// This implements the required interfaces for representing a plugin module 6// instance in browser interactions and provides a way to register custom 7// plugin interfaces. 8// 9 10#include <stdio.h> 11#include <string.h> 12 13#include <map> 14 15#include "native_client/src/include/nacl_macros.h" 16#include "native_client/src/shared/platform/nacl_check.h" 17 18#include "ppapi/c/dev/ppb_var_deprecated.h" 19#include "ppapi/c/pp_errors.h" 20#include "ppapi/c/pp_instance.h" 21#include "ppapi/c/pp_module.h" 22#include "ppapi/c/pp_var.h" 23#include "ppapi/c/ppb.h" 24#include "ppapi/c/ppb_var.h" 25#include "ppapi/c/ppp.h" 26#include "ppapi/c/ppp_instance.h" 27#include "ppapi/c/ppp_messaging.h" 28 29#include "ppapi/native_client/tests/ppapi_test_lib/get_browser_interface.h" 30#include "ppapi/native_client/tests/ppapi_test_lib/internal_utils.h" 31#include "ppapi/native_client/tests/ppapi_test_lib/test_interface.h" 32 33/////////////////////////////////////////////////////////////////////////////// 34// Plugin interface registration 35/////////////////////////////////////////////////////////////////////////////// 36 37namespace { 38 39class PluginInterfaceTable { 40 public: 41 // Return singleton intsance. 42 static PluginInterfaceTable* Get() { 43 static PluginInterfaceTable table; 44 return &table; 45 } 46 47 void AddInterface(const char* interface_name, const void* ppp_interface) { 48 interface_map_[nacl::string(interface_name)] = ppp_interface; 49 } 50 const void* GetInterface(const char* interface_name) { 51 // This will add a NULL element for missing interfaces. 52 return interface_map_[nacl::string(interface_name)]; 53 } 54 55 private: 56 NACL_DISALLOW_COPY_AND_ASSIGN(PluginInterfaceTable); 57 58 PluginInterfaceTable() {} 59 60 typedef std::map<nacl::string, const void*> InterfaceMap; 61 InterfaceMap interface_map_; 62}; 63 64} // namespace 65 66void RegisterPluginInterface(const char* interface_name, 67 const void* ppp_interface) { 68 PluginInterfaceTable::Get()->AddInterface(interface_name, ppp_interface); 69} 70 71 72/////////////////////////////////////////////////////////////////////////////// 73// PPP_Instance implementation 74/////////////////////////////////////////////////////////////////////////////// 75 76PP_Bool DidCreateDefault(PP_Instance instance, 77 uint32_t /*argc*/, 78 const char* /*argn*/[], 79 const char* /*argv*/[]) { 80 CHECK(ppb_get_interface() != NULL); 81 CHECK(PPBCore() != NULL); 82 CHECK(PPBGraphics2D() != NULL); 83 CHECK(PPBImageData() != NULL); 84 CHECK(PPBInstance() != NULL); 85 CHECK(PPBMessaging() != NULL); 86 CHECK(PPBURLLoader() != NULL); 87 CHECK(PPBURLRequestInfo() != NULL); 88 CHECK(PPBURLResponseInfo() != NULL); 89 CHECK(PPBVar() != NULL); 90 91 set_pp_instance(instance); 92 SetupTests(); 93 94 return PP_TRUE; 95} 96 97void DidDestroyDefault(PP_Instance /*instance*/) { 98} 99 100void DidChangeViewDefault(PP_Instance /*instance*/, PP_Resource /*view*/) { 101} 102 103void DidChangeFocusDefault(PP_Instance /*instance*/, 104 PP_Bool /*has_focus*/) { 105} 106 107PP_Bool HandleDocumentLoadDefault(PP_Instance instance, 108 PP_Resource url_loader) { 109 return PP_TRUE; 110} 111 112namespace { 113 114const PPP_Instance ppp_instance_interface = { 115 DidCreateDefault, 116 DidDestroyDefault, 117 DidChangeViewDefault, 118 DidChangeFocusDefault, 119 HandleDocumentLoadDefault 120}; 121 122/////////////////////////////////////////////////////////////////////////////// 123// PPP_Messaging implementation 124/////////////////////////////////////////////////////////////////////////////// 125 126void HandleMessage(PP_Instance instance, PP_Var message) { 127 if (message.type != PP_VARTYPE_STRING) 128 return; 129 uint32_t len = 0; 130 const char* test_name = PPBVar()->VarToUtf8(message, &len); 131 RunTest(test_name); 132} 133 134const PPP_Messaging ppp_messaging_interface = { 135 HandleMessage 136}; 137 138} // namespace 139 140/////////////////////////////////////////////////////////////////////////////// 141// PPP implementation 142/////////////////////////////////////////////////////////////////////////////// 143 144int32_t PPP_InitializeModule(PP_Module module, 145 PPB_GetInterface get_browser_interface) { 146 set_pp_module(module); 147 set_ppb_get_interface(get_browser_interface); 148 SetupPluginInterfaces(); 149 return PP_OK; 150} 151 152void PPP_ShutdownModule() { 153} 154 155const void* PPP_GetInterface(const char* interface_name) { 156 const void* ppp = PluginInterfaceTable::Get()->GetInterface(interface_name); 157 158 // The PPP_Instance interface is required for every plugin, 159 // so supply one if the tester has not. 160 if (ppp == NULL && 0 == strncmp(PPP_INSTANCE_INTERFACE, interface_name, 161 strlen(PPP_INSTANCE_INTERFACE))) { 162 return &ppp_instance_interface; 163 } 164 // The PPP_Messaging interface is required for the test set-up, 165 // so we supply our own. 166 if (0 == strncmp(PPP_MESSAGING_INTERFACE, interface_name, 167 strlen(PPP_MESSAGING_INTERFACE))) { 168 CHECK(ppp == NULL); 169 return &ppp_messaging_interface; 170 } 171 // All other interfaces are to be optionally supplied by the tester, 172 // so we return whatever was added in SetupPluginInterfaces() (if anything). 173 return ppp; 174} 175