• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2008, 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 "main.h"
30 #include "PluginObject.h"
31 #include "AnimationPlugin.h"
32 #include "AudioPlugin.h"
33 #include "BackgroundPlugin.h"
34 #include "FormPlugin.h"
35 #include "PaintPlugin.h"
36 
37 NPNetscapeFuncs* browser;
38 #define EXPORT __attribute__((visibility("default")))
39 
40 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
41         char* argn[], char* argv[], NPSavedData* saved);
42 NPError NPP_Destroy(NPP instance, NPSavedData** save);
43 NPError NPP_SetWindow(NPP instance, NPWindow* window);
44 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
45         NPBool seekable, uint16* stype);
46 NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
47 int32   NPP_WriteReady(NPP instance, NPStream* stream);
48 int32   NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
49         void* buffer);
50 void    NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
51 void    NPP_Print(NPP instance, NPPrint* platformPrint);
52 int16   NPP_HandleEvent(NPP instance, void* event);
53 void    NPP_URLNotify(NPP instance, const char* URL, NPReason reason,
54         void* notifyData);
55 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
56 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
57 
58 extern "C" {
59 EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env, void *application_context);
60 EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value);
61 EXPORT const char* NP_GetMIMEDescription(void);
62 EXPORT void NP_Shutdown(void);
63 };
64 
65 ANPAudioTrackInterfaceV0    gSoundI;
66 ANPBitmapInterfaceV0        gBitmapI;
67 ANPCanvasInterfaceV0        gCanvasI;
68 ANPLogInterfaceV0           gLogI;
69 ANPPaintInterfaceV0         gPaintI;
70 ANPPathInterfaceV0          gPathI;
71 ANPSurfaceInterfaceV0       gSurfaceI;
72 ANPSystemInterfaceV0        gSystemI;
73 ANPTypefaceInterfaceV0      gTypefaceI;
74 ANPWindowInterfaceV0        gWindowI;
75 
76 #define ARRAY_COUNT(array)      (sizeof(array) / sizeof(array[0]))
77 #define DEBUG_PLUGIN_EVENTS     0
78 
NP_Initialize(NPNetscapeFuncs * browserFuncs,NPPluginFuncs * pluginFuncs,void * java_env,void * application_context)79 NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env, void *application_context)
80 {
81     // Make sure we have a function table equal or larger than we are built against.
82     if (browserFuncs->size < sizeof(NPNetscapeFuncs)) {
83         return NPERR_GENERIC_ERROR;
84     }
85 
86     // Copy the function table (structure)
87     browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs));
88     memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs));
89 
90     // Build the plugin function table
91     pluginFuncs->version = 11;
92     pluginFuncs->size = sizeof(pluginFuncs);
93     pluginFuncs->newp = NPP_New;
94     pluginFuncs->destroy = NPP_Destroy;
95     pluginFuncs->setwindow = NPP_SetWindow;
96     pluginFuncs->newstream = NPP_NewStream;
97     pluginFuncs->destroystream = NPP_DestroyStream;
98     pluginFuncs->asfile = NPP_StreamAsFile;
99     pluginFuncs->writeready = NPP_WriteReady;
100     pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
101     pluginFuncs->print = NPP_Print;
102     pluginFuncs->event = NPP_HandleEvent;
103     pluginFuncs->urlnotify = NPP_URLNotify;
104     pluginFuncs->getvalue = NPP_GetValue;
105     pluginFuncs->setvalue = NPP_SetValue;
106 
107     static const struct {
108         NPNVariable     v;
109         uint32_t        size;
110         ANPInterface*   i;
111     } gPairs[] = {
112         { kAudioTrackInterfaceV0_ANPGetValue,   sizeof(gSoundI),    &gSoundI },
113         { kBitmapInterfaceV0_ANPGetValue,       sizeof(gBitmapI),   &gBitmapI },
114         { kCanvasInterfaceV0_ANPGetValue,       sizeof(gCanvasI),   &gCanvasI },
115         { kLogInterfaceV0_ANPGetValue,          sizeof(gLogI),      &gLogI },
116         { kPaintInterfaceV0_ANPGetValue,        sizeof(gPaintI),    &gPaintI },
117         { kPathInterfaceV0_ANPGetValue,         sizeof(gPathI),     &gPathI },
118         { kSurfaceInterfaceV0_ANPGetValue,      sizeof(gSurfaceI),  &gSurfaceI },
119         { kSystemInterfaceV0_ANPGetValue,       sizeof(gSystemI),   &gSystemI },
120         { kTypefaceInterfaceV0_ANPGetValue,     sizeof(gTypefaceI), &gTypefaceI },
121         { kWindowInterfaceV0_ANPGetValue,       sizeof(gWindowI),   &gWindowI },
122     };
123     for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) {
124         gPairs[i].i->inSize = gPairs[i].size;
125         NPError err = browser->getvalue(NULL, gPairs[i].v, gPairs[i].i);
126         if (err) {
127             return err;
128         }
129     }
130 
131     return NPERR_NO_ERROR;
132 }
133 
NP_Shutdown(void)134 void NP_Shutdown(void)
135 {
136 
137 }
138 
NP_GetMIMEDescription(void)139 const char *NP_GetMIMEDescription(void)
140 {
141     return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
142 }
143 
NPP_New(NPMIMEType pluginType,NPP instance,uint16 mode,int16 argc,char * argn[],char * argv[],NPSavedData * saved)144 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
145                 char* argn[], char* argv[], NPSavedData* saved)
146 {
147 
148     /* BEGIN: STANDARD PLUGIN FRAMEWORK */
149     PluginObject *obj = NULL;
150 
151     // Scripting functions appeared in NPAPI version 14
152     if (browser->version >= 14) {
153     instance->pdata = browser->createobject (instance, getPluginClass());
154     obj = static_cast<PluginObject*>(instance->pdata);
155     bzero(obj, sizeof(*obj));
156     }
157     /* END: STANDARD PLUGIN FRAMEWORK */
158 
159     // select the drawing model based on user input
160     ANPDrawingModel model = kBitmap_ANPDrawingModel;
161 
162     for (int i = 0; i < argc; i++) {
163         if (!strcmp(argn[i], "DrawingModel")) {
164             if (!strcmp(argv[i], "Bitmap")) {
165                 model = kBitmap_ANPDrawingModel;
166             }
167             else if (!strcmp(argv[i], "Surface")) {
168                model = kSurface_ANPDrawingModel;
169             }
170             gLogI.log(instance, kDebug_ANPLogType, "------ %p DrawingModel is %d", instance, model);
171             break;
172         }
173     }
174 
175     // notify the plugin API of the location of the java interface
176     char* className = "com.android.sampleplugin.SamplePluginStub";
177     NPError npErr = browser->setvalue(instance, kSetPluginStubJavaClassName_ANPSetValue,
178                                       reinterpret_cast<void*>(className));
179     if (npErr) {
180         gLogI.log(instance, kError_ANPLogType, "set class err %d", npErr);
181         return npErr;
182     }
183 
184     // notify the plugin API of the drawing model we wish to use. This must be
185     // done prior to creating certain subPlugin objects (e.g. surfaceViews)
186     NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
187                             reinterpret_cast<void*>(model));
188     if (err) {
189         gLogI.log(instance, kError_ANPLogType, "request model %d err %d", model, err);
190         return err;
191     }
192 
193     const char* path = gSystemI.getApplicationDataDirectory();
194     if (path) {
195         gLogI.log(instance, kDebug_ANPLogType, "Application data dir is %s", path);
196     } else {
197         gLogI.log(instance, kError_ANPLogType, "Can't find Application data dir");
198     }
199 
200     // select the pluginType
201     for (int i = 0; i < argc; i++) {
202         if (!strcmp(argn[i], "PluginType")) {
203             if (!strcmp(argv[i], "Animation")) {
204                 obj->pluginType = kAnimation_PluginType;
205                 obj->activePlugin = new BallAnimation(instance);
206             }
207             else if (!strcmp(argv[i], "Audio")) {
208                 obj->pluginType = kAudio_PluginType;
209                 obj->activePlugin = new AudioPlugin(instance);
210             }
211             else if (!strcmp(argv[i], "Background")) {
212                 obj->pluginType = kBackground_PluginType;
213                 obj->activePlugin = new BackgroundPlugin(instance);
214             }
215             else if (!strcmp(argv[i], "Form")) {
216                 obj->pluginType = kForm_PluginType;
217                 obj->activePlugin = new FormPlugin(instance);
218             }
219             else if (!strcmp(argv[i], "Paint")) {
220                 obj->pluginType = kPaint_PluginType;
221                 obj->activePlugin = new PaintPlugin(instance);
222             }
223             gLogI.log(instance, kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
224             break;
225         }
226     }
227 
228     // if no pluginType is specified then default to Animation
229     if (!obj->pluginType) {
230         gLogI.log(instance, kError_ANPLogType, "------ %p No PluginType attribute was found", instance);
231         obj->pluginType = kAnimation_PluginType;
232         obj->activePlugin = new BallAnimation(instance);
233     }
234 
235     // check to ensure the pluginType supports the model
236     if (!obj->activePlugin->supportsDrawingModel(model)) {
237         gLogI.log(instance, kError_ANPLogType, "------ %p Unsupported DrawingModel (%d)", instance, model);
238         return NPERR_GENERIC_ERROR;
239     }
240 
241     return NPERR_NO_ERROR;
242 }
243 
NPP_Destroy(NPP instance,NPSavedData ** save)244 NPError NPP_Destroy(NPP instance, NPSavedData** save)
245 {
246     PluginObject *obj = (PluginObject*) instance->pdata;
247     delete obj->activePlugin;
248 
249     return NPERR_NO_ERROR;
250 }
251 
NPP_SetWindow(NPP instance,NPWindow * window)252 NPError NPP_SetWindow(NPP instance, NPWindow* window)
253 {
254     PluginObject *obj = (PluginObject*) instance->pdata;
255 
256     // Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
257     if (obj != NULL) {
258         obj->window = window;
259     }
260 
261     browser->invalidaterect(instance, NULL);
262 
263     return NPERR_NO_ERROR;
264 }
265 
NPP_NewStream(NPP instance,NPMIMEType type,NPStream * stream,NPBool seekable,uint16 * stype)266 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
267 {
268     *stype = NP_ASFILEONLY;
269     return NPERR_NO_ERROR;
270 }
271 
NPP_DestroyStream(NPP instance,NPStream * stream,NPReason reason)272 NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
273 {
274     return NPERR_NO_ERROR;
275 }
276 
NPP_WriteReady(NPP instance,NPStream * stream)277 int32 NPP_WriteReady(NPP instance, NPStream* stream)
278 {
279     return 0;
280 }
281 
NPP_Write(NPP instance,NPStream * stream,int32 offset,int32 len,void * buffer)282 int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
283 {
284     return 0;
285 }
286 
NPP_StreamAsFile(NPP instance,NPStream * stream,const char * fname)287 void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
288 {
289 }
290 
NPP_Print(NPP instance,NPPrint * platformPrint)291 void NPP_Print(NPP instance, NPPrint* platformPrint)
292 {
293 }
294 
NPP_HandleEvent(NPP instance,void * event)295 int16 NPP_HandleEvent(NPP instance, void* event)
296 {
297     PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
298     const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
299 
300 #if DEBUG_PLUGIN_EVENTS
301     switch (evt->eventType) {
302         case kDraw_ANPEventType:
303 
304             if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
305 
306                 static ANPBitmapFormat currentFormat = -1;
307                 if (evt->data.draw.data.bitmap.format != currentFormat) {
308                     currentFormat = evt->data.draw.data.bitmap.format;
309                     gLogI.log(instance, kDebug_ANPLogType, "---- %p Draw (bitmap)"
310                               " clip=%d,%d,%d,%d format=%d", instance,
311                               evt->data.draw.clip.left,
312                               evt->data.draw.clip.top,
313                               evt->data.draw.clip.right,
314                               evt->data.draw.clip.bottom,
315                               evt->data.draw.data.bitmap.format);
316                 }
317             }
318             break;
319 
320         case kKey_ANPEventType:
321             gLogI.log(instance, kDebug_ANPLogType, "---- %p Key action=%d"
322                       " code=%d vcode=%d unichar=%d repeat=%d mods=%x", instance,
323                       evt->data.key.action,
324                       evt->data.key.nativeCode,
325                       evt->data.key.virtualCode,
326                       evt->data.key.unichar,
327                       evt->data.key.repeatCount,
328                       evt->data.key.modifiers);
329             break;
330 
331         case kLifecycle_ANPEventType:
332             gLogI.log(instance, kDebug_ANPLogType, "---- %p Lifecycle action=%d",
333                                 instance, evt->data.lifecycle.action);
334             break;
335 
336        case kTouch_ANPEventType:
337             gLogI.log(instance, kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
338                       instance, evt->data.touch.action, evt->data.touch.x,
339                       evt->data.touch.y);
340             break;
341 
342        case kMouse_ANPEventType:
343             gLogI.log(instance, kDebug_ANPLogType, "---- %p Mouse action=%d [%d %d]",
344                       instance, evt->data.mouse.action, evt->data.mouse.x,
345                       evt->data.mouse.y);
346             break;
347 
348        case kVisibleRect_ANPEventType:
349             gLogI.log(instance, kDebug_ANPLogType, "---- %p VisibleRect [%d %d %d %d]",
350                       instance, evt->data.visibleRect.rect.left, evt->data.visibleRect.rect.top,
351                       evt->data.visibleRect.rect.right, evt->data.visibleRect.rect.bottom);
352             break;
353 
354         default:
355             gLogI.log(instance, kError_ANPLogType, "---- %p Unknown Event [%d]",
356                       instance, evt->eventType);
357             break;
358     }
359 #endif
360 
361     if(!obj->activePlugin) {
362         gLogI.log(instance, kError_ANPLogType, "the active plugin is null.");
363         return 0; // unknown or unhandled event
364     }
365     else {
366         return obj->activePlugin->handleEvent(evt);
367     }
368 }
369 
NPP_URLNotify(NPP instance,const char * url,NPReason reason,void * notifyData)370 void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
371 {
372 
373 }
374 
NP_GetValue(NPP instance,NPPVariable variable,void * value)375 EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) {
376 
377     if (variable == NPPVpluginNameString) {
378         const char **str = (const char **)value;
379         *str = "Test Plugin";
380         return NPERR_NO_ERROR;
381     }
382 
383     if (variable == NPPVpluginDescriptionString) {
384         const char **str = (const char **)value;
385         *str = "Description of Test Plugin";
386         return NPERR_NO_ERROR;
387     }
388 
389     return NPERR_GENERIC_ERROR;
390 }
391 
NPP_GetValue(NPP instance,NPPVariable variable,void * value)392 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
393 {
394     if (variable == NPPVpluginScriptableNPObject) {
395         void **v = (void **)value;
396         PluginObject *obj = (PluginObject*) instance->pdata;
397 
398         if (obj)
399             browser->retainobject((NPObject*)obj);
400 
401         *v = obj;
402         return NPERR_NO_ERROR;
403     }
404 
405     return NPERR_GENERIC_ERROR;
406 }
407 
NPP_SetValue(NPP instance,NPNVariable variable,void * value)408 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
409 {
410     return NPERR_GENERIC_ERROR;
411 }
412 
413