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 34 NPNetscapeFuncs* browser; 35 #define EXPORT __attribute__((visibility("default"))) 36 37 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, 38 char* argn[], char* argv[], NPSavedData* saved); 39 NPError NPP_Destroy(NPP instance, NPSavedData** save); 40 NPError NPP_SetWindow(NPP instance, NPWindow* window); 41 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, 42 NPBool seekable, uint16_t* stype); 43 NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason); 44 int32_t NPP_WriteReady(NPP instance, NPStream* stream); 45 int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, 46 void* buffer); 47 void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname); 48 void NPP_Print(NPP instance, NPPrint* platformPrint); 49 int16_t NPP_HandleEvent(NPP instance, void* event); 50 void NPP_URLNotify(NPP instance, const char* URL, NPReason reason, 51 void* notifyData); 52 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value); 53 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value); 54 55 extern "C" { 56 EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env); 57 EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value); 58 EXPORT const char* NP_GetMIMEDescription(void); 59 EXPORT void NP_Shutdown(void); 60 }; 61 62 ANPAudioTrackInterfaceV0 gSoundI; 63 ANPBitmapInterfaceV0 gBitmapI; 64 ANPCanvasInterfaceV0 gCanvasI; 65 ANPLogInterfaceV0 gLogI; 66 ANPPaintInterfaceV0 gPaintI; 67 ANPPathInterfaceV0 gPathI; 68 ANPTypefaceInterfaceV0 gTypefaceI; 69 ANPWindowInterfaceV0 gWindowI; 70 71 #define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) 72 73 NPError 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 122 void NP_Shutdown(void) 123 { 124 125 } 126 127 const char *NP_GetMIMEDescription(void) 128 { 129 return "application/x-browsertestplugin:btp:Android Browser Test Plugin"; 130 } 131 132 NPError 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 168 NPError 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 179 NPError 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 191 NPError 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 197 NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) 198 { 199 return NPERR_NO_ERROR; 200 } 201 202 int32_t NPP_WriteReady(NPP instance, NPStream* stream) 203 { 204 return 0; 205 } 206 207 int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer) 208 { 209 return 0; 210 } 211 212 void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) 213 { 214 } 215 216 void NPP_Print(NPP instance, NPPrint* platformPrint) 217 { 218 } 219 220 int16_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 234 void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) 235 { 236 } 237 238 EXPORT 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 255 NPError 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 271 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) 272 { 273 return NPERR_GENERIC_ERROR; 274 } 275 276