blob: 5019e420c618f63ea53bc1fe265a137a998d779a [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"
Grace Klobafbe47c02009-05-14 17:31:45 -070035#include "android_npapi.h"
36
37NPNetscapeFuncs* browser;
38#define EXPORT __attribute__((visibility("default")))
39
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040040NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
Grace Klobafbe47c02009-05-14 17:31:45 -070041 char* argn[], char* argv[], NPSavedData* saved);
42NPError NPP_Destroy(NPP instance, NPSavedData** save);
43NPError NPP_SetWindow(NPP instance, NPWindow* window);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040044NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
Grace Klobafbe47c02009-05-14 17:31:45 -070045 NPBool seekable, uint16* stype);
46NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
47int32 NPP_WriteReady(NPP instance, NPStream* stream);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040048int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
Grace Klobafbe47c02009-05-14 17:31:45 -070049 void* buffer);
50void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
51void NPP_Print(NPP instance, NPPrint* platformPrint);
52int16 NPP_HandleEvent(NPP instance, void* event);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040053void NPP_URLNotify(NPP instance, const char* URL, NPReason reason,
Grace Klobafbe47c02009-05-14 17:31:45 -070054 void* notifyData);
55NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
56NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
57
58extern "C" {
59EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env, void *application_context);
60EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value);
61EXPORT const char* NP_GetMIMEDescription(void);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040062EXPORT void NP_Shutdown(void);
Grace Klobafbe47c02009-05-14 17:31:45 -070063};
64
65ANPAudioTrackInterfaceV0 gSoundI;
Mike Reed224adad2009-06-10 10:24:01 -040066ANPBitmapInterfaceV0 gBitmapI;
Grace Klobafbe47c02009-05-14 17:31:45 -070067ANPCanvasInterfaceV0 gCanvasI;
68ANPLogInterfaceV0 gLogI;
69ANPPaintInterfaceV0 gPaintI;
70ANPPathInterfaceV0 gPathI;
71ANPTypefaceInterfaceV0 gTypefaceI;
Derek Sollenberger5b011e32009-06-22 11:39:40 -040072ANPWindowInterfaceV0 gWindowI;
Grace Klobafbe47c02009-05-14 17:31:45 -070073
74#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
Derek Sollenberger5b011e32009-06-22 11:39:40 -040075#define DEBUG_PLUGIN_EVENTS 0
Grace Klobafbe47c02009-05-14 17:31:45 -070076
77NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env, void *application_context)
78{
79 // Make sure we have a function table equal or larger than we are built against.
80 if (browserFuncs->size < sizeof(NPNetscapeFuncs)) {
81 return NPERR_GENERIC_ERROR;
82 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040083
Grace Klobafbe47c02009-05-14 17:31:45 -070084 // Copy the function table (structure)
85 browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs));
86 memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs));
Derek Sollenberger9119e7d2009-06-08 10:53:09 -040087
Grace Klobafbe47c02009-05-14 17:31:45 -070088 // Build the plugin function table
89 pluginFuncs->version = 11;
90 pluginFuncs->size = sizeof(pluginFuncs);
91 pluginFuncs->newp = NPP_New;
92 pluginFuncs->destroy = NPP_Destroy;
93 pluginFuncs->setwindow = NPP_SetWindow;
94 pluginFuncs->newstream = NPP_NewStream;
95 pluginFuncs->destroystream = NPP_DestroyStream;
96 pluginFuncs->asfile = NPP_StreamAsFile;
97 pluginFuncs->writeready = NPP_WriteReady;
98 pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
99 pluginFuncs->print = NPP_Print;
100 pluginFuncs->event = NPP_HandleEvent;
101 pluginFuncs->urlnotify = NPP_URLNotify;
102 pluginFuncs->getvalue = NPP_GetValue;
103 pluginFuncs->setvalue = NPP_SetValue;
104
105 static const struct {
106 NPNVariable v;
107 uint32_t size;
108 ANPInterface* i;
109 } gPairs[] = {
Mike Reed224adad2009-06-10 10:24:01 -0400110 { kBitmapInterfaceV0_ANPGetValue, sizeof(gBitmapI), &gBitmapI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700111 { kCanvasInterfaceV0_ANPGetValue, sizeof(gCanvasI), &gCanvasI },
Mike Reed224adad2009-06-10 10:24:01 -0400112 { kLogInterfaceV0_ANPGetValue, sizeof(gLogI), &gLogI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700113 { kPaintInterfaceV0_ANPGetValue, sizeof(gPaintI), &gPaintI },
114 { kPathInterfaceV0_ANPGetValue, sizeof(gPathI), &gPathI },
115 { kTypefaceInterfaceV0_ANPGetValue, sizeof(gPaintI), &gTypefaceI },
116 { kAudioTrackInterfaceV0_ANPGetValue, sizeof(gSoundI), &gSoundI },
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400117 { kWindowInterfaceV0_ANPGetValue, sizeof(gWindowI), &gWindowI },
Grace Klobafbe47c02009-05-14 17:31:45 -0700118 };
119 for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) {
120 gPairs[i].i->inSize = gPairs[i].size;
121 NPError err = browser->getvalue(NULL, gPairs[i].v, gPairs[i].i);
122 if (err) {
123 return err;
124 }
125 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400126
Grace Klobafbe47c02009-05-14 17:31:45 -0700127 return NPERR_NO_ERROR;
128}
129
130void NP_Shutdown(void)
131{
132
133}
134
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400135const char *NP_GetMIMEDescription(void)
Grace Klobafbe47c02009-05-14 17:31:45 -0700136{
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400137 return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
Grace Klobafbe47c02009-05-14 17:31:45 -0700138}
139
140NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
141 char* argn[], char* argv[], NPSavedData* saved)
142{
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400143
144 /* BEGIN: STANDARD PLUGIN FRAMEWORK */
Grace Klobafbe47c02009-05-14 17:31:45 -0700145 PluginObject *obj = NULL;
146
147 // Scripting functions appeared in NPAPI version 14
148 if (browser->version >= 14) {
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400149 instance->pdata = browser->createobject (instance, getPluginClass());
150 obj = static_cast<PluginObject*>(instance->pdata);
151 bzero(obj, sizeof(*obj));
Grace Klobafbe47c02009-05-14 17:31:45 -0700152 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400153 /* END: STANDARD PLUGIN FRAMEWORK */
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400154
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400155 // select the pluginType
156 for (int i = 0; i < argc; i++) {
157 if (!strcmp(argn[i], "PluginType")) {
158 if (!strcmp(argv[i], "Animation")) {
159 obj->pluginType = kAnimation_PluginType;
160 obj->activePlugin = new BallAnimation(instance);
161 }
162 else if (!strcmp(argv[i], "Audio")) {
163 obj->pluginType = kAudio_PluginType;
Derek Sollenbergerf42e2f42009-06-26 11:42:46 -0400164 obj->activePlugin = new AudioPlugin(instance);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400165 }
166 else if (!strcmp(argv[i], "Background")) {
167 obj->pluginType = kBackground_PluginType;
168 obj->activePlugin = new BackgroundPlugin(instance);
169 }
Derek Sollenbergerdb398a72009-06-29 13:53:04 -0400170 else if (!strcmp(argv[i], "Form")) {
171 obj->pluginType = kForm_PluginType;
172 obj->activePlugin = new FormPlugin(instance);
173 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400174 gLogI.log(instance, kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
175 break;
176 }
177 }
178
179 // if no pluginType is specified then default to Animation
180 if (!obj->pluginType) {
181 obj->pluginType = kAnimation_PluginType;
182 obj->activePlugin = new BallAnimation(instance);
183 }
184
Derek Sollenberger21f39912009-07-09 09:19:39 -0400185 // select the drawing model based on user input
186 ANPDrawingModel model = kBitmap_ANPDrawingModel;
187
188 for (int i = 0; i < argc; i++) {
189 if (!strcmp(argn[i], "DrawingModel")) {
190 if (!strcmp(argv[i], "Bitmap")) {
191 model = kBitmap_ANPDrawingModel;
192 }
193 else if (!strcmp(argv[i], "RasterSurface")) {
194 // model = kRasterSurface_ANPDrawingModel;
195 }
196 gLogI.log(instance, kDebug_ANPLogType, "------ %p DrawingModel is %d", instance, model);
197 break;
198 }
199 }
200
201 // check to ensure the pluginType supports the model
202 if (!obj->activePlugin->supportsDrawingModel(model)) {
203 gLogI.log(instance, kError_ANPLogType, "------ %p Unsupported DrawingModel (%d)", instance, model);
204 return NPERR_GENERIC_ERROR;
205 }
206
207 // notify the plugin API of the drawing model we wish to use
208 NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
209 reinterpret_cast<void*>(model));
210 if (err) {
211 gLogI.log(instance, kError_ANPLogType, "request model %d err %d", model, err);
212 return err;
213 }
214
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400215 return NPERR_NO_ERROR;
Grace Klobafbe47c02009-05-14 17:31:45 -0700216}
217
218NPError NPP_Destroy(NPP instance, NPSavedData** save)
219{
220 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400221 delete obj->activePlugin;
Grace Klobafbe47c02009-05-14 17:31:45 -0700222
223 return NPERR_NO_ERROR;
224}
225
Grace Klobafbe47c02009-05-14 17:31:45 -0700226NPError NPP_SetWindow(NPP instance, NPWindow* window)
227{
228 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400229
Grace Klobafbe47c02009-05-14 17:31:45 -0700230 // Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
231 if (obj != NULL) {
232 obj->window = window;
233 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400234
Grace Klobafbe47c02009-05-14 17:31:45 -0700235 browser->invalidaterect(instance, NULL);
236
237 return NPERR_NO_ERROR;
238}
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400239
Grace Klobafbe47c02009-05-14 17:31:45 -0700240NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
241{
242 *stype = NP_ASFILEONLY;
243 return NPERR_NO_ERROR;
244}
245
246NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
247{
248 return NPERR_NO_ERROR;
249}
250
251int32 NPP_WriteReady(NPP instance, NPStream* stream)
252{
253 return 0;
254}
255
256int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
257{
258 return 0;
259}
260
261void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
262{
263}
264
265void NPP_Print(NPP instance, NPPrint* platformPrint)
266{
Grace Klobafbe47c02009-05-14 17:31:45 -0700267}
268
Grace Klobafbe47c02009-05-14 17:31:45 -0700269int16 NPP_HandleEvent(NPP instance, void* event)
270{
271 PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
272 const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
273
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400274#if DEBUG_PLUGIN_EVENTS
Grace Klobafbe47c02009-05-14 17:31:45 -0700275 switch (evt->eventType) {
276 case kDraw_ANPEventType:
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400277
278 if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
279
280 static ANPBitmapFormat currentFormat = -1;
281 if (evt->data.draw.data.bitmap.format != currentFormat) {
282 currentFormat = evt->data.draw.data.bitmap.format;
283 gLogI.log(instance, kDebug_ANPLogType, "---- %p Draw (bitmap)"
284 " clip=%d,%d,%d,%d format=%d", instance,
285 evt->data.draw.clip.left,
286 evt->data.draw.clip.top,
287 evt->data.draw.clip.right,
288 evt->data.draw.clip.bottom,
289 evt->data.draw.data.bitmap.format);
290 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700291 }
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400292 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700293
294 case kKey_ANPEventType:
295 gLogI.log(instance, kDebug_ANPLogType, "---- %p Key action=%d"
296 " code=%d vcode=%d unichar=%d repeat=%d mods=%x", instance,
297 evt->data.key.action,
298 evt->data.key.nativeCode,
299 evt->data.key.virtualCode,
300 evt->data.key.unichar,
301 evt->data.key.repeatCount,
302 evt->data.key.modifiers);
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400303 break;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400304
305 case kLifecycle_ANPEventType:
306 gLogI.log(instance, kDebug_ANPLogType, "---- %p Lifecycle action=%d",
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400307 instance, evt->data.lifecycle.action);
Mike Reed1e7c3312009-05-26 16:37:45 -0400308 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700309
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400310 case kTouch_ANPEventType:
Grace Klobafbe47c02009-05-14 17:31:45 -0700311 gLogI.log(instance, kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
312 instance, evt->data.touch.action, evt->data.touch.x,
313 evt->data.touch.y);
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400314 break;
315
Derek Sollenbergerdb398a72009-06-29 13:53:04 -0400316 case kMouse_ANPEventType:
317 gLogI.log(instance, kDebug_ANPLogType, "---- %p Mouse action=%d [%d %d]",
318 instance, evt->data.mouse.action, evt->data.mouse.x,
319 evt->data.mouse.y);
320 break;
321
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400322 case kVisibleRect_ANPEventType:
323 gLogI.log(instance, kDebug_ANPLogType, "---- %p VisibleRect [%d %d %d %d]",
Derek Sollenbergerf42e2f42009-06-26 11:42:46 -0400324 instance, evt->data.visibleRect.rect.left, evt->data.visibleRect.rect.top,
325 evt->data.visibleRect.rect.right, evt->data.visibleRect.rect.bottom);
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400326 break;
Grace Klobafbe47c02009-05-14 17:31:45 -0700327
328 default:
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400329 gLogI.log(instance, kError_ANPLogType, "---- %p Unknown Event [%d]",
330 instance, evt->eventType);
Grace Klobafbe47c02009-05-14 17:31:45 -0700331 break;
332 }
Derek Sollenberger5b011e32009-06-22 11:39:40 -0400333#endif
Derek Sollenbergerd7ebf272009-06-18 11:19:41 -0400334
335 if(!obj->activePlugin) {
336 gLogI.log(instance, kError_ANPLogType, "the active plugin is null.");
337 return 0; // unknown or unhandled event
338 }
339 else {
340 return obj->activePlugin->handleEvent(evt);
341 }
Grace Klobafbe47c02009-05-14 17:31:45 -0700342}
343
344void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
345{
346
347}
348
349EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) {
350
351 if (variable == NPPVpluginNameString) {
352 const char **str = (const char **)value;
353 *str = "Test Plugin";
354 return NPERR_NO_ERROR;
355 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400356
Grace Klobafbe47c02009-05-14 17:31:45 -0700357 if (variable == NPPVpluginDescriptionString) {
358 const char **str = (const char **)value;
359 *str = "Description of Test Plugin";
360 return NPERR_NO_ERROR;
361 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400362
Grace Klobafbe47c02009-05-14 17:31:45 -0700363 return NPERR_GENERIC_ERROR;
364}
365
366NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
367{
368 if (variable == NPPVpluginScriptableNPObject) {
369 void **v = (void **)value;
370 PluginObject *obj = (PluginObject*) instance->pdata;
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400371
Grace Klobafbe47c02009-05-14 17:31:45 -0700372 if (obj)
373 browser->retainobject((NPObject*)obj);
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400374
Grace Klobafbe47c02009-05-14 17:31:45 -0700375 *v = obj;
376 return NPERR_NO_ERROR;
377 }
Derek Sollenberger9119e7d2009-06-08 10:53:09 -0400378
Grace Klobafbe47c02009-05-14 17:31:45 -0700379 return NPERR_GENERIC_ERROR;
380}
381
382NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
383{
384 return NPERR_GENERIC_ERROR;
385}
386