• 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 "NavigationPlugin.h"
36 #include "PaintPlugin.h"
37 #include "VideoPlugin.h"
38 
39 NPNetscapeFuncs* browser;
40 JavaVM* gVM;
41 
42 #define EXPORT __attribute__((visibility("default")))
43 
44 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
45         char* argn[], char* argv[], NPSavedData* saved);
46 NPError NPP_Destroy(NPP instance, NPSavedData** save);
47 NPError NPP_SetWindow(NPP instance, NPWindow* window);
48 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
49         NPBool seekable, uint16* stype);
50 NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
51 int32   NPP_WriteReady(NPP instance, NPStream* stream);
52 int32   NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
53         void* buffer);
54 void    NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
55 void    NPP_Print(NPP instance, NPPrint* platformPrint);
56 int16   NPP_HandleEvent(NPP instance, void* event);
57 void    NPP_URLNotify(NPP instance, const char* URL, NPReason reason,
58         void* notifyData);
59 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
60 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
61 
62 extern "C" {
63 EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env);
64 EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value);
65 EXPORT const char* NP_GetMIMEDescription(void);
66 EXPORT void NP_Shutdown(void);
67 };
68 
69 ANPAudioTrackInterfaceV0    gSoundI;
70 ANPBitmapInterfaceV0        gBitmapI;
71 ANPCanvasInterfaceV0        gCanvasI;
72 ANPEventInterfaceV0         gEventI;
73 ANPLogInterfaceV0           gLogI;
74 ANPPaintInterfaceV0         gPaintI;
75 ANPPathInterfaceV0          gPathI;
76 ANPSurfaceInterfaceV0       gSurfaceI;
77 ANPSystemInterfaceV0        gSystemI;
78 ANPTypefaceInterfaceV0      gTypefaceI;
79 ANPWindowInterfaceV0        gWindowI;
80 
81 #define ARRAY_COUNT(array)      (sizeof(array) / sizeof(array[0]))
82 #define DEBUG_PLUGIN_EVENTS     0
83 
NP_Initialize(NPNetscapeFuncs * browserFuncs,NPPluginFuncs * pluginFuncs,void * java_env)84 NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env)
85 {
86     // Make sure we have a function table equal or larger than we are built against.
87     if (browserFuncs->size < sizeof(NPNetscapeFuncs)) {
88         return NPERR_GENERIC_ERROR;
89     }
90 
91     // Copy the function table (structure)
92     browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs));
93     memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs));
94 
95     // Build the plugin function table
96     pluginFuncs->version = 11;
97     pluginFuncs->size = sizeof(pluginFuncs);
98     pluginFuncs->newp = NPP_New;
99     pluginFuncs->destroy = NPP_Destroy;
100     pluginFuncs->setwindow = NPP_SetWindow;
101     pluginFuncs->newstream = NPP_NewStream;
102     pluginFuncs->destroystream = NPP_DestroyStream;
103     pluginFuncs->asfile = NPP_StreamAsFile;
104     pluginFuncs->writeready = NPP_WriteReady;
105     pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
106     pluginFuncs->print = NPP_Print;
107     pluginFuncs->event = NPP_HandleEvent;
108     pluginFuncs->urlnotify = NPP_URLNotify;
109     pluginFuncs->getvalue = NPP_GetValue;
110     pluginFuncs->setvalue = NPP_SetValue;
111 
112     static const struct {
113         NPNVariable     v;
114         uint32_t        size;
115         ANPInterface*   i;
116     } gPairs[] = {
117         { kAudioTrackInterfaceV0_ANPGetValue,   sizeof(gSoundI),    &gSoundI },
118         { kBitmapInterfaceV0_ANPGetValue,       sizeof(gBitmapI),   &gBitmapI },
119         { kCanvasInterfaceV0_ANPGetValue,       sizeof(gCanvasI),   &gCanvasI },
120         { kEventInterfaceV0_ANPGetValue,        sizeof(gEventI),    &gEventI },
121         { kLogInterfaceV0_ANPGetValue,          sizeof(gLogI),      &gLogI },
122         { kPaintInterfaceV0_ANPGetValue,        sizeof(gPaintI),    &gPaintI },
123         { kPathInterfaceV0_ANPGetValue,         sizeof(gPathI),     &gPathI },
124         { kSurfaceInterfaceV0_ANPGetValue,      sizeof(gSurfaceI),  &gSurfaceI },
125         { kSystemInterfaceV0_ANPGetValue,       sizeof(gSystemI),   &gSystemI },
126         { kTypefaceInterfaceV0_ANPGetValue,     sizeof(gTypefaceI), &gTypefaceI },
127         { kWindowInterfaceV0_ANPGetValue,       sizeof(gWindowI),   &gWindowI },
128     };
129     for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) {
130         gPairs[i].i->inSize = gPairs[i].size;
131         NPError err = browser->getvalue(NULL, gPairs[i].v, gPairs[i].i);
132         if (err) {
133             return err;
134         }
135     }
136 
137     // store the JavaVM for the plugin
138     JNIEnv* env = (JNIEnv*)java_env;
139     env->GetJavaVM(&gVM);
140 
141     return NPERR_NO_ERROR;
142 }
143 
NP_Shutdown(void)144 void NP_Shutdown(void)
145 {
146 
147 }
148 
NP_GetMIMEDescription(void)149 const char *NP_GetMIMEDescription(void)
150 {
151     return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
152 }
153 
NPP_New(NPMIMEType pluginType,NPP instance,uint16 mode,int16 argc,char * argn[],char * argv[],NPSavedData * saved)154 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
155                 char* argn[], char* argv[], NPSavedData* saved)
156 {
157 
158     /* BEGIN: STANDARD PLUGIN FRAMEWORK */
159     PluginObject *obj = NULL;
160 
161     // Scripting functions appeared in NPAPI version 14
162     if (browser->version >= 14) {
163         instance->pdata = browser->createobject (instance, getPluginClass());
164         obj = static_cast<PluginObject*>(instance->pdata);
165     }
166     /* END: STANDARD PLUGIN FRAMEWORK */
167 
168     // select the drawing model based on user input
169     ANPDrawingModel model = kBitmap_ANPDrawingModel;
170 
171     for (int i = 0; i < argc; i++) {
172         if (!strcmp(argn[i], "DrawingModel")) {
173             if (!strcmp(argv[i], "Bitmap")) {
174                 model = kBitmap_ANPDrawingModel;
175             }
176             else if (!strcmp(argv[i], "Surface")) {
177                model = kSurface_ANPDrawingModel;
178             }
179             gLogI.log(kDebug_ANPLogType, "------ %p DrawingModel is %d", instance, model);
180             break;
181         }
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(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(kDebug_ANPLogType, "Application data dir is %s", path);
196     } else {
197         gLogI.log(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], "Navigation")) {
220                 obj->pluginType = kNavigation_PluginType;
221                 obj->activePlugin = new NavigationPlugin(instance);
222             }
223             else if (!strcmp(argv[i], "Paint")) {
224                 obj->pluginType = kPaint_PluginType;
225                 obj->activePlugin = new PaintPlugin(instance);
226             }
227             else if (!strcmp(argv[i], "Video")) {
228                 obj->pluginType = kVideo_PluginType;
229                 obj->activePlugin = new VideoPlugin(instance);
230             }
231             gLogI.log(kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
232             break;
233         }
234     }
235 
236     // if no pluginType is specified then default to Animation
237     if (!obj->pluginType) {
238         gLogI.log(kError_ANPLogType, "------ %p No PluginType attribute was found", instance);
239         obj->pluginType = kAnimation_PluginType;
240         obj->activePlugin = new BallAnimation(instance);
241     }
242 
243     // check to ensure the pluginType supports the model
244     if (!obj->activePlugin->supportsDrawingModel(model)) {
245         gLogI.log(kError_ANPLogType, "------ %p Unsupported DrawingModel (%d)", instance, model);
246         return NPERR_GENERIC_ERROR;
247     }
248 
249     // if the plugin uses the surface drawing model then set the java context
250     if (model == kSurface_ANPDrawingModel) {
251         SurfaceSubPlugin* surfacePlugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
252 
253         jobject context;
254         NPError err = browser->getvalue(instance, kJavaContext_ANPGetValue,
255                                         static_cast<void*>(&context));
256         if (err) {
257             gLogI.log(kError_ANPLogType, "request context err: %d", err);
258             return err;
259         }
260 
261         surfacePlugin->setContext(context);
262     }
263 
264 
265     return NPERR_NO_ERROR;
266 }
267 
NPP_Destroy(NPP instance,NPSavedData ** save)268 NPError NPP_Destroy(NPP instance, NPSavedData** save)
269 {
270     PluginObject *obj = (PluginObject*) instance->pdata;
271     if (obj) {
272         delete obj->activePlugin;
273         browser->releaseobject(&obj->header);
274     }
275 
276     return NPERR_NO_ERROR;
277 }
278 
NPP_SetWindow(NPP instance,NPWindow * window)279 NPError NPP_SetWindow(NPP instance, NPWindow* window)
280 {
281     PluginObject *obj = (PluginObject*) instance->pdata;
282 
283     // Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
284     if (obj != NULL) {
285         obj->window = window;
286     }
287 
288     browser->invalidaterect(instance, NULL);
289 
290     return NPERR_NO_ERROR;
291 }
292 
NPP_NewStream(NPP instance,NPMIMEType type,NPStream * stream,NPBool seekable,uint16 * stype)293 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
294 {
295     *stype = NP_ASFILEONLY;
296     return NPERR_NO_ERROR;
297 }
298 
NPP_DestroyStream(NPP instance,NPStream * stream,NPReason reason)299 NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
300 {
301     return NPERR_NO_ERROR;
302 }
303 
NPP_WriteReady(NPP instance,NPStream * stream)304 int32 NPP_WriteReady(NPP instance, NPStream* stream)
305 {
306     return 0;
307 }
308 
NPP_Write(NPP instance,NPStream * stream,int32 offset,int32 len,void * buffer)309 int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
310 {
311     return 0;
312 }
313 
NPP_StreamAsFile(NPP instance,NPStream * stream,const char * fname)314 void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
315 {
316 }
317 
NPP_Print(NPP instance,NPPrint * platformPrint)318 void NPP_Print(NPP instance, NPPrint* platformPrint)
319 {
320 }
321 
NPP_HandleEvent(NPP instance,void * event)322 int16 NPP_HandleEvent(NPP instance, void* event)
323 {
324     PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
325     const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
326 
327 #if DEBUG_PLUGIN_EVENTS
328     switch (evt->eventType) {
329         case kDraw_ANPEventType:
330 
331             if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
332 
333                 static ANPBitmapFormat currentFormat = -1;
334                 if (evt->data.draw.data.bitmap.format != currentFormat) {
335                     currentFormat = evt->data.draw.data.bitmap.format;
336                     gLogI.log(kDebug_ANPLogType, "---- %p Draw (bitmap)"
337                               " clip=%d,%d,%d,%d format=%d", instance,
338                               evt->data.draw.clip.left,
339                               evt->data.draw.clip.top,
340                               evt->data.draw.clip.right,
341                               evt->data.draw.clip.bottom,
342                               evt->data.draw.data.bitmap.format);
343                 }
344             }
345             break;
346 
347         case kKey_ANPEventType:
348             gLogI.log(kDebug_ANPLogType, "---- %p Key action=%d"
349                       " code=%d vcode=%d unichar=%d repeat=%d mods=%x", instance,
350                       evt->data.key.action,
351                       evt->data.key.nativeCode,
352                       evt->data.key.virtualCode,
353                       evt->data.key.unichar,
354                       evt->data.key.repeatCount,
355                       evt->data.key.modifiers);
356             break;
357 
358         case kLifecycle_ANPEventType:
359             gLogI.log(kDebug_ANPLogType, "---- %p Lifecycle action=%d",
360                                 instance, evt->data.lifecycle.action);
361             break;
362 
363        case kTouch_ANPEventType:
364             gLogI.log(kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
365                       instance, evt->data.touch.action, evt->data.touch.x,
366                       evt->data.touch.y);
367             break;
368 
369        case kMouse_ANPEventType:
370             gLogI.log(kDebug_ANPLogType, "---- %p Mouse action=%d [%d %d]",
371                       instance, evt->data.mouse.action, evt->data.mouse.x,
372                       evt->data.mouse.y);
373             break;
374 
375        case kVisibleRect_ANPEventType:
376             gLogI.log(kDebug_ANPLogType, "---- %p VisibleRect [%d %d %d %d]",
377                       instance, evt->data.visibleRect.rect.left, evt->data.visibleRect.rect.top,
378                       evt->data.visibleRect.rect.right, evt->data.visibleRect.rect.bottom);
379             break;
380 
381         default:
382             gLogI.log(kError_ANPLogType, "---- %p Unknown Event [%d]",
383                       instance, evt->eventType);
384             break;
385     }
386 #endif
387 
388     if(!obj->activePlugin) {
389         gLogI.log(kError_ANPLogType, "the active plugin is null.");
390         return 0; // unknown or unhandled event
391     }
392     else {
393         return obj->activePlugin->handleEvent(evt);
394     }
395 }
396 
NPP_URLNotify(NPP instance,const char * url,NPReason reason,void * notifyData)397 void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
398 {
399 
400 }
401 
NP_GetValue(NPP instance,NPPVariable variable,void * value)402 EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) {
403 
404     if (variable == NPPVpluginNameString) {
405         const char **str = (const char **)value;
406         *str = "Test Plugin";
407         return NPERR_NO_ERROR;
408     }
409 
410     if (variable == NPPVpluginDescriptionString) {
411         const char **str = (const char **)value;
412         *str = "Description of Test Plugin";
413         return NPERR_NO_ERROR;
414     }
415 
416     return NPERR_GENERIC_ERROR;
417 }
418 
NPP_GetValue(NPP instance,NPPVariable variable,void * value)419 NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value)
420 {
421     if (variable == NPPVpluginScriptableNPObject) {
422         void **v = (void **)value;
423         PluginObject *obj = (PluginObject*) instance->pdata;
424 
425         if (obj)
426             browser->retainobject(&obj->header);
427 
428         *v = &(obj->header);
429         return NPERR_NO_ERROR;
430     }
431 
432     if (variable == kJavaSurface_ANPGetValue) {
433         //get the surface sub-plugin
434         PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
435         if (obj && obj->activePlugin) {
436 
437             if(obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)) {
438                 SurfaceSubPlugin* plugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
439                 jobject* surface = static_cast<jobject*>(value);
440                 *surface = plugin->getSurface();
441                 return NPERR_NO_ERROR;
442             } else {
443                 gLogI.log(kError_ANPLogType,
444                           "-- %p Tried to retrieve surface for non-surface plugin",
445                           instance);
446             }
447         }
448     }
449 
450     return NPERR_GENERIC_ERROR;
451 }
452 
NPP_SetValue(NPP instance,NPNVariable variable,void * value)453 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
454 {
455     return NPERR_GENERIC_ERROR;
456 }
457 
458