1/* 2 * Copyright 2009, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include <stdlib.h> 27#include <string.h> 28#include <stdio.h> 29#include "android_npapi.h" 30#include "main.h" 31#include "PluginObject.h" 32#include "EventPlugin.h" 33 34NPNetscapeFuncs* browser; 35#define EXPORT __attribute__((visibility("default"))) 36 37NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, 38 char* argn[], char* argv[], NPSavedData* saved); 39NPError NPP_Destroy(NPP instance, NPSavedData** save); 40NPError NPP_SetWindow(NPP instance, NPWindow* window); 41NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, 42 NPBool seekable, uint16_t* stype); 43NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason); 44int32_t NPP_WriteReady(NPP instance, NPStream* stream); 45int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, 46 void* buffer); 47void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname); 48void NPP_Print(NPP instance, NPPrint* platformPrint); 49int16_t NPP_HandleEvent(NPP instance, void* event); 50void NPP_URLNotify(NPP instance, const char* URL, NPReason reason, 51 void* notifyData); 52NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value); 53NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value); 54 55extern "C" { 56EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env); 57EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value); 58EXPORT const char* NP_GetMIMEDescription(void); 59EXPORT void NP_Shutdown(void); 60}; 61 62ANPAudioTrackInterfaceV0 gSoundI; 63ANPBitmapInterfaceV0 gBitmapI; 64ANPCanvasInterfaceV0 gCanvasI; 65ANPLogInterfaceV0 gLogI; 66ANPPaintInterfaceV0 gPaintI; 67ANPPathInterfaceV0 gPathI; 68ANPTypefaceInterfaceV0 gTypefaceI; 69ANPWindowInterfaceV0 gWindowI; 70 71#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) 72 73NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env) 74{ 75 // Make sure we have a function table equal or larger than we are built against. 76 if (browserFuncs->size < sizeof(NPNetscapeFuncs)) { 77 return NPERR_GENERIC_ERROR; 78 } 79 80 // Copy the function table (structure) 81 browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs)); 82 memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs)); 83 84 // Build the plugin function table 85 pluginFuncs->version = 11; 86 pluginFuncs->size = sizeof(pluginFuncs); 87 pluginFuncs->newp = NPP_New; 88 pluginFuncs->destroy = NPP_Destroy; 89 pluginFuncs->setwindow = NPP_SetWindow; 90 pluginFuncs->newstream = NPP_NewStream; 91 pluginFuncs->destroystream = NPP_DestroyStream; 92 pluginFuncs->asfile = NPP_StreamAsFile; 93 pluginFuncs->writeready = NPP_WriteReady; 94 pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write; 95 pluginFuncs->print = NPP_Print; 96 pluginFuncs->event = NPP_HandleEvent; 97 pluginFuncs->urlnotify = NPP_URLNotify; 98 pluginFuncs->getvalue = NPP_GetValue; 99 pluginFuncs->setvalue = NPP_SetValue; 100 101 static const struct { 102 NPNVariable v; 103 uint32_t size; 104 ANPInterface* i; 105 } gPairs[] = { 106 { kCanvasInterfaceV0_ANPGetValue, sizeof(gCanvasI), &gCanvasI }, 107 { kLogInterfaceV0_ANPGetValue, sizeof(gLogI), &gLogI }, 108 { kPaintInterfaceV0_ANPGetValue, sizeof(gPaintI), &gPaintI }, 109 { kTypefaceInterfaceV0_ANPGetValue, sizeof(gTypefaceI), &gTypefaceI }, 110 }; 111 for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) { 112 gPairs[i].i->inSize = gPairs[i].size; 113 NPError err = browser->getvalue(NULL, gPairs[i].v, gPairs[i].i); 114 if (err) { 115 return err; 116 } 117 } 118 119 return NPERR_NO_ERROR; 120} 121 122void NP_Shutdown(void) 123{ 124 125} 126 127const char *NP_GetMIMEDescription(void) 128{ 129 return "application/x-browsertestplugin:btp:Android Browser Test Plugin"; 130} 131 132NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, 133 char* argn[], char* argv[], NPSavedData* saved) 134{ 135 136 137 gLogI.log(kDebug_ANPLogType, "creating plugin"); 138 139 PluginObject *obj = NULL; 140 141 // Scripting functions appeared in NPAPI version 14 142 if (browser->version >= 14) { 143 instance->pdata = browser->createobject (instance, getPluginClass()); 144 obj = static_cast<PluginObject*>(instance->pdata); 145 memset(obj, 0, sizeof(*obj)); 146 } else { 147 return NPERR_GENERIC_ERROR; 148 } 149 150 // select the drawing model 151 ANPDrawingModel model = kBitmap_ANPDrawingModel; 152 153 // notify the plugin API of the drawing model we wish to use. This must be 154 // done prior to creating certain subPlugin objects (e.g. surfaceViews) 155 NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue, 156 reinterpret_cast<void*>(model)); 157 if (err) { 158 gLogI.log(kError_ANPLogType, "request model %d err %d", model, err); 159 return err; 160 } 161 162 // create the sub-plugin 163 obj->subPlugin = new EventPlugin(instance); 164 165 return NPERR_NO_ERROR; 166} 167 168NPError NPP_Destroy(NPP instance, NPSavedData** save) 169{ 170 PluginObject *obj = (PluginObject*) instance->pdata; 171 if (obj) { 172 delete obj->subPlugin; 173 browser->releaseobject(&obj->header); 174 } 175 176 return NPERR_NO_ERROR; 177} 178 179NPError NPP_SetWindow(NPP instance, NPWindow* window) 180{ 181 PluginObject *obj = (PluginObject*) instance->pdata; 182 183 // Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject. 184 if (obj != NULL) { 185 obj->window = window; 186 } 187 188 return NPERR_NO_ERROR; 189} 190 191NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype) 192{ 193 *stype = NP_ASFILEONLY; 194 return NPERR_NO_ERROR; 195} 196 197NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) 198{ 199 return NPERR_NO_ERROR; 200} 201 202int32_t NPP_WriteReady(NPP instance, NPStream* stream) 203{ 204 return 0; 205} 206 207int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer) 208{ 209 return 0; 210} 211 212void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) 213{ 214} 215 216void NPP_Print(NPP instance, NPPrint* platformPrint) 217{ 218} 219 220int16_t NPP_HandleEvent(NPP instance, void* event) 221{ 222 PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata); 223 const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event); 224 225 if(!obj->subPlugin) { 226 gLogI.log(kError_ANPLogType, "the sub-plugin is null."); 227 return 0; // unknown or unhandled event 228 } 229 else { 230 return obj->subPlugin->handleEvent(evt); 231 } 232} 233 234void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) 235{ 236} 237 238EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) { 239 240 if (variable == NPPVpluginNameString) { 241 const char **str = (const char **)value; 242 *str = "Browser Test Plugin"; 243 return NPERR_NO_ERROR; 244 } 245 246 if (variable == NPPVpluginDescriptionString) { 247 const char **str = (const char **)value; 248 *str = "Description of Browser Test Plugin"; 249 return NPERR_NO_ERROR; 250 } 251 252 return NPERR_GENERIC_ERROR; 253} 254 255NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) 256{ 257 if (variable == NPPVpluginScriptableNPObject) { 258 void **v = (void **)value; 259 PluginObject *obj = (PluginObject*) instance->pdata; 260 261 if (obj) 262 browser->retainobject((NPObject*)obj); 263 264 *v = obj; 265 return NPERR_NO_ERROR; 266 } 267 268 return NPERR_GENERIC_ERROR; 269} 270 271NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) 272{ 273 return NPERR_GENERIC_ERROR; 274} 275 276