blob: a0649cda7977a20828606e31c72e0f0376de8ad2 [file] [log] [blame]
Grace Klobafbe47c02009-05-14 17:31:45 -07001/*
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"
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040031#include "AnimationPlugin.h"
Derek Sollenbergerf42e2f42009-06-26 11:42:46 -040032#include "AudioPlugin.h"
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -040033#include "BackgroundPlugin.h"
Derek Sollenbergerdb398a72009-06-29 13:53:04 -040034#include "FormPlugin.h"
Derek Sollenberger4fb83e62009-07-27 16:40:13 -040035#include "PaintPlugin.h"
Derek Sollenbergerc0f26572009-07-16 11:38:02 -040036#include "SurfacePlugin.h"
Grace Klobafbe47c02009-05-14 17:31:45 -070037#include "android_npapi.h"
38
39NPNetscapeFuncs* browser;
40#define EXPORT __attribute__((visibility("default")))
41
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040042NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
Grace Klobafbe47c02009-05-14 17:31:45 -070043 char* argn[], char* argv[], NPSavedData* saved);
44NPError NPP_Destroy(NPP instance, NPSavedData** save);
45NPError NPP_SetWindow(NPP instance, NPWindow* window);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040046NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
Grace Klobafbe47c02009-05-14 17:31:45 -070047 NPBool seekable, uint16* stype);
48NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
49int32 NPP_WriteReady(NPP instance, NPStream* stream);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040050int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
Grace Klobafbe47c02009-05-14 17:31:45 -070051 void* buffer);
52void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
53void NPP_Print(NPP instance, NPPrint* platformPrint);
54int16 NPP_HandleEvent(NPP instance, void* event);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040055void NPP_URLNotify(NPP instance, const char* URL, NPReason reason,
Grace Klobafbe47c02009-05-14 17:31:45 -070056 void* notifyData);
57NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
58NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
59
60extern "C" {
61EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env, void *application_context);
62EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value);
63EXPORT const char* NP_GetMIMEDescription(void);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040064EXPORT void NP_Shutdown(void);
Grace Klobafbe47c02009-05-14 17:31:45 -070065};
66
67ANPAudioTrackInterfaceV0 gSoundI;
Mike Reed224adad2009-06-10 10:24:01 -040068ANPBitmapInterfaceV0 gBitmapI;
Grace Klobafbe47c02009-05-14 17:31:45 -070069ANPCanvasInterfaceV0 gCanvasI;
70ANPLogInterfaceV0 gLogI;
71ANPPaintInterfaceV0 gPaintI;
72ANPPathInterfaceV0 gPathI;
Derek Sollenbergerc0f26572009-07-16 11:38:02 -040073ANPSurfaceInterfaceV0 gSurfaceI;
Grace Klobafbe47c02009-05-14 17:31:45 -070074ANPTypefaceInterfaceV0 gTypefaceI;
Derek Sollenberger5b011e32009-06-22 11:39:40 -040075ANPWindowInterfaceV0 gWindowI;
Grace Klobafbe47c02009-05-14 17:31:45 -070076
77#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
Derek Sollenberger5b011e32009-06-22 11:39:40 -040078#define DEBUG_PLUGIN_EVENTS 0
Grace Klobafbe47c02009-05-14 17:31:45 -070079
80NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env, void *application_context)
81{
82 // Make sure we have a function table equal or larger than we are built against.
83 if (browserFuncs->size < sizeof(NPNetscapeFuncs)) {
84 return NPERR_GENERIC_ERROR;
85 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040086
Grace Klobafbe47c02009-05-14 17:31:45 -070087 // Copy the function table (structure)
88 browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs));
89 memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs));
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040090
Grace Klobafbe47c02009-05-14 17:31:45 -070091 // Build the plugin function table
92 pluginFuncs->version = 11;
93 pluginFuncs->size = sizeof(pluginFuncs);
94 pluginFuncs->newp = NPP_New;
95 pluginFuncs->destroy = NPP_Destroy;
96 pluginFuncs->setwindow = NPP_SetWindow;
97 pluginFuncs->newstream = NPP_NewStream;
98 pluginFuncs->destroystream = NPP_DestroyStream;
99 pluginFuncs->asfile = NPP_StreamAsFile;
100 pluginFuncs->writeready = NPP_WriteReady;
101 pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
102 pluginFuncs->print = NPP_Print;
103 pluginFuncs->event = NPP_HandleEvent;
104 pluginFuncs->urlnotify = NPP_URLNotify;
105 pluginFuncs->getvalue = NPP_GetValue;
106 pluginFuncs->setvalue = NPP_SetValue;
107
108 static const struct {
109 NPNVariable v;
110 uint32_t size;
111 ANPInterface* i;
112 } gPairs[] = {
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400113 { kAudioTrackInterfaceV0_ANPGetValue, sizeof(gSoundI), &gSoundI },
Mike Reed224adad2009-06-10 10:24:01 -0400114 { kBitmapInterfaceV0_ANPGetValue, sizeof(gBitmapI), &gBitmapI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700115 { kCanvasInterfaceV0_ANPGetValue, sizeof(gCanvasI), &gCanvasI },
Mike Reed224adad2009-06-10 10:24:01 -0400116 { kLogInterfaceV0_ANPGetValue, sizeof(gLogI), &gLogI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700117 { kPaintInterfaceV0_ANPGetValue, sizeof(gPaintI), &gPaintI },
118 { kPathInterfaceV0_ANPGetValue, sizeof(gPathI), &gPathI },
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400119 { kSurfaceInterfaceV0_ANPGetValue, sizeof(gSurfaceI), &gSurfaceI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700120 { kTypefaceInterfaceV0_ANPGetValue, sizeof(gPaintI), &gTypefaceI },
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400121 { kWindowInterfaceV0_ANPGetValue, sizeof(gWindowI), &gWindowI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700122 };
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 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400130
Grace Klobafbe47c02009-05-14 17:31:45 -0700131 return NPERR_NO_ERROR;
132}
133
134void NP_Shutdown(void)
135{
136
137}
138
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400139const char *NP_GetMIMEDescription(void)
Grace Klobafbe47c02009-05-14 17:31:45 -0700140{
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400141 return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
Grace Klobafbe47c02009-05-14 17:31:45 -0700142}
143
144NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
145 char* argn[], char* argv[], NPSavedData* saved)
146{
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400147
148 /* BEGIN: STANDARD PLUGIN FRAMEWORK */
Grace Klobafbe47c02009-05-14 17:31:45 -0700149 PluginObject *obj = NULL;
150
151 // Scripting functions appeared in NPAPI version 14
152 if (browser->version >= 14) {
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400153 instance->pdata = browser->createobject (instance, getPluginClass());
154 obj = static_cast<PluginObject*>(instance->pdata);
155 bzero(obj, sizeof(*obj));
Grace Klobafbe47c02009-05-14 17:31:45 -0700156 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400157 /* END: STANDARD PLUGIN FRAMEWORK */
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400158
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400159 // 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 drawing model we wish to use. This must be
176 // done prior to creating certain subPlugin objects (e.g. surfaceViews)
177 NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
178 reinterpret_cast<void*>(model));
179 if (err) {
180 gLogI.log(instance, kError_ANPLogType, "request model %d err %d", model, err);
181 return err;
182 }
183
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400184 // select the pluginType
185 for (int i = 0; i < argc; i++) {
186 if (!strcmp(argn[i], "PluginType")) {
187 if (!strcmp(argv[i], "Animation")) {
188 obj->pluginType = kAnimation_PluginType;
189 obj->activePlugin = new BallAnimation(instance);
190 }
191 else if (!strcmp(argv[i], "Audio")) {
192 obj->pluginType = kAudio_PluginType;
Derek Sollenbergerf42e2f42009-06-26 11:42:46 -0400193 obj->activePlugin = new AudioPlugin(instance);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400194 }
195 else if (!strcmp(argv[i], "Background")) {
196 obj->pluginType = kBackground_PluginType;
197 obj->activePlugin = new BackgroundPlugin(instance);
198 }
Derek Sollenbergerdb398a72009-06-29 13:53:04 -0400199 else if (!strcmp(argv[i], "Form")) {
200 obj->pluginType = kForm_PluginType;
201 obj->activePlugin = new FormPlugin(instance);
202 }
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400203 else if (!strcmp(argv[i], "Paint")) {
204 obj->pluginType = kPaint_PluginType;
205 obj->activePlugin = new PaintPlugin(instance);
206 }
Derek Sollenbergerc0f26572009-07-16 11:38:02 -0400207 else if (!strcmp(argv[i], "RGBA_Surface")) {
208 obj->pluginType = kSurface_PluginType;
209 obj->activePlugin = new SurfacePlugin(instance, kRGBA_ANPSurfaceType);
210 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400211 gLogI.log(instance, kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
212 break;
213 }
214 }
215
216 // if no pluginType is specified then default to Animation
217 if (!obj->pluginType) {
Derek Sollenberger4fb83e62009-07-27 16:40:13 -0400218 gLogI.log(instance, kError_ANPLogType, "------ %p No PluginType attribute was found", instance);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400219 obj->pluginType = kAnimation_PluginType;
220 obj->activePlugin = new BallAnimation(instance);
221 }
222
Derek Sollenberger21f39912009-07-09 09:19:39 -0400223 // check to ensure the pluginType supports the model
224 if (!obj->activePlugin->supportsDrawingModel(model)) {
225 gLogI.log(instance, kError_ANPLogType, "------ %p Unsupported DrawingModel (%d)", instance, model);
226 return NPERR_GENERIC_ERROR;
227 }
228
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400229 return NPERR_NO_ERROR;
Grace Klobafbe47c02009-05-14 17:31:45 -0700230}
231
232NPError NPP_Destroy(NPP instance, NPSavedData** save)
233{
234 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400235 delete obj->activePlugin;
Grace Klobafbe47c02009-05-14 17:31:45 -0700236
237 return NPERR_NO_ERROR;
238}
239
Grace Klobafbe47c02009-05-14 17:31:45 -0700240NPError NPP_SetWindow(NPP instance, NPWindow* window)
241{
242 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400243
Grace Klobafbe47c02009-05-14 17:31:45 -0700244 // Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
245 if (obj != NULL) {
246 obj->window = window;
247 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400248
Grace Klobafbe47c02009-05-14 17:31:45 -0700249 browser->invalidaterect(instance, NULL);
250
251 return NPERR_NO_ERROR;
252}
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400253
Grace Klobafbe47c02009-05-14 17:31:45 -0700254NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
255{
256 *stype = NP_ASFILEONLY;
257 return NPERR_NO_ERROR;
258}
259
260NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
261{
262 return NPERR_NO_ERROR;
263}
264
265int32 NPP_WriteReady(NPP instance, NPStream* stream)
266{
267 return 0;
268}
269
270int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
271{
272 return 0;
273}
274
275void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
276{
277}
278
279void NPP_Print(NPP instance, NPPrint* platformPrint)
280{
Grace Klobafbe47c02009-05-14 17:31:45 -0700281}
282
Grace Klobafbe47c02009-05-14 17:31:45 -0700283int16 NPP_HandleEvent(NPP instance, void* event)
284{
285 PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
286 const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
287
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400288#if DEBUG_PLUGIN_EVENTS
Grace Klobafbe47c02009-05-14 17:31:45 -0700289 switch (evt->eventType) {
290 case kDraw_ANPEventType:
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400291
292 if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
293
294 static ANPBitmapFormat currentFormat = -1;
295 if (evt->data.draw.data.bitmap.format != currentFormat) {
296 currentFormat = evt->data.draw.data.bitmap.format;
297 gLogI.log(instance, kDebug_ANPLogType, "---- %p Draw (bitmap)"
298 " clip=%d,%d,%d,%d format=%d", instance,
299 evt->data.draw.clip.left,
300 evt->data.draw.clip.top,
301 evt->data.draw.clip.right,
302 evt->data.draw.clip.bottom,
303 evt->data.draw.data.bitmap.format);
304 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700305 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400306 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700307
308 case kKey_ANPEventType:
309 gLogI.log(instance, kDebug_ANPLogType, "---- %p Key action=%d"
310 " code=%d vcode=%d unichar=%d repeat=%d mods=%x", instance,
311 evt->data.key.action,
312 evt->data.key.nativeCode,
313 evt->data.key.virtualCode,
314 evt->data.key.unichar,
315 evt->data.key.repeatCount,
316 evt->data.key.modifiers);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400317 break;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400318
319 case kLifecycle_ANPEventType:
320 gLogI.log(instance, kDebug_ANPLogType, "---- %p Lifecycle action=%d",
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400321 instance, evt->data.lifecycle.action);
Mike Reed1e7c3312009-05-26 16:37:45 -0400322 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700323
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400324 case kTouch_ANPEventType:
Grace Klobafbe47c02009-05-14 17:31:45 -0700325 gLogI.log(instance, kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
326 instance, evt->data.touch.action, evt->data.touch.x,
327 evt->data.touch.y);
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400328 break;
329
Derek Sollenbergerdb398a72009-06-29 13:53:04 -0400330 case kMouse_ANPEventType:
331 gLogI.log(instance, kDebug_ANPLogType, "---- %p Mouse action=%d [%d %d]",
332 instance, evt->data.mouse.action, evt->data.mouse.x,
333 evt->data.mouse.y);
334 break;
335
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400336 case kVisibleRect_ANPEventType:
337 gLogI.log(instance, kDebug_ANPLogType, "---- %p VisibleRect [%d %d %d %d]",
Derek Sollenbergerf42e2f42009-06-26 11:42:46 -0400338 instance, evt->data.visibleRect.rect.left, evt->data.visibleRect.rect.top,
339 evt->data.visibleRect.rect.right, evt->data.visibleRect.rect.bottom);
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400340 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700341
342 default:
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400343 gLogI.log(instance, kError_ANPLogType, "---- %p Unknown Event [%d]",
344 instance, evt->eventType);
Grace Klobafbe47c02009-05-14 17:31:45 -0700345 break;
346 }
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400347#endif
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400348
349 if(!obj->activePlugin) {
350 gLogI.log(instance, kError_ANPLogType, "the active plugin is null.");
351 return 0; // unknown or unhandled event
352 }
353 else {
354 return obj->activePlugin->handleEvent(evt);
355 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700356}
357
358void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
359{
360
361}
362
363EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) {
364
365 if (variable == NPPVpluginNameString) {
366 const char **str = (const char **)value;
367 *str = "Test Plugin";
368 return NPERR_NO_ERROR;
369 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400370
Grace Klobafbe47c02009-05-14 17:31:45 -0700371 if (variable == NPPVpluginDescriptionString) {
372 const char **str = (const char **)value;
373 *str = "Description of Test Plugin";
374 return NPERR_NO_ERROR;
375 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400376
Grace Klobafbe47c02009-05-14 17:31:45 -0700377 return NPERR_GENERIC_ERROR;
378}
379
380NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
381{
382 if (variable == NPPVpluginScriptableNPObject) {
383 void **v = (void **)value;
384 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400385
Grace Klobafbe47c02009-05-14 17:31:45 -0700386 if (obj)
387 browser->retainobject((NPObject*)obj);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400388
Grace Klobafbe47c02009-05-14 17:31:45 -0700389 *v = obj;
390 return NPERR_NO_ERROR;
391 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400392
Grace Klobafbe47c02009-05-14 17:31:45 -0700393 return NPERR_GENERIC_ERROR;
394}
395
396NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
397{
398 return NPERR_GENERIC_ERROR;
399}
400