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