Restructuring the sample plugin and adding more tests.

This commit is contained in:
Derek Sollenberger
2009-06-18 11:19:41 -04:00
parent 246ad9119a
commit d7ebf27ff4
16 changed files with 595 additions and 253 deletions

View File

@@ -30,10 +30,13 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
main.cpp \
PluginObject.cpp \
pluginGraphics.cpp
animation/AnimationPlugin.cpp \
background/BackgroundPlugin.cpp
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(LOCAL_PATH)/animation \
$(LOCAL_PATH)/background \
external/webkit/WebCore/bridge \
external/webkit/WebCore/plugins \
external/webkit/WebCore/platform/android/JavaVM \

View File

@@ -1,33 +1,33 @@
/*
IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
consideration of your agreement to the following terms, and your use, installation,
modification or redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use, install, modify or
consideration of your agreement to the following terms, and your use, installation,
modification or redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject to these
terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in
this original Apple software (the "Apple Software"), to use, reproduce, modify and
redistribute the Apple Software, with or without modifications, in source and/or binary
forms; provided that if you redistribute the Apple Software in its entirety and without
modifications, you must retain this notice and the following text and disclaimers in all
such redistributions of the Apple Software. Neither the name, trademarks, service marks
or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
In consideration of your agreement to abide by the following terms, and subject to these
terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in
this original Apple software (the "Apple Software"), to use, reproduce, modify and
redistribute the Apple Software, with or without modifications, in source and/or binary
forms; provided that if you redistribute the Apple Software in its entirety and without
modifications, you must retain this notice and the following text and disclaimers in all
such redistributions of the Apple Software. Neither the name, trademarks, service marks
or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
the Apple Software without specific prior written permission from Apple. Except as expressly
stated in this notice, no other rights or licenses, express or implied, are granted by Apple
herein, including but not limited to any patent rights that may be infringed by your
herein, including but not limited to any patent rights that may be infringed by your
derivative works or by other works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -49,10 +49,10 @@ static bool pluginEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *cou
static NPClass pluginClass = {
static NPClass pluginClass = {
NP_CLASS_STRUCT_VERSION,
pluginAllocate,
pluginDeallocate,
pluginAllocate,
pluginDeallocate,
pluginInvalidate,
pluginHasMethod,
pluginInvoke,
@@ -63,7 +63,7 @@ static NPClass pluginClass = {
pluginRemoveProperty,
pluginEnumerate
};
NPClass *getPluginClass(void)
{
return &pluginClass;
@@ -150,18 +150,18 @@ static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
PluginObject *newInstance = (PluginObject*) malloc(sizeof(PluginObject));
newInstance->header._class = theClass;
newInstance->header.referenceCount = 1;
if (!identifiersInitialized) {
identifiersInitialized = true;
initializeIdentifiers();
}
newInstance->npp = npp;
return &newInstance->header;
}
static void pluginDeallocate(NPObject *obj)
static void pluginDeallocate(NPObject *obj)
{
free(obj);
}
@@ -175,4 +175,3 @@ static bool pluginEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *cou
{
return false;
}

View File

@@ -1,68 +1,76 @@
/*
IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
consideration of your agreement to the following terms, and your use, installation,
modification or redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use, install, modify or
consideration of your agreement to the following terms, and your use, installation,
modification or redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject to these
terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in
this original Apple software (the "Apple Software"), to use, reproduce, modify and
redistribute the Apple Software, with or without modifications, in source and/or binary
forms; provided that if you redistribute the Apple Software in its entirety and without
modifications, you must retain this notice and the following text and disclaimers in all
such redistributions of the Apple Software. Neither the name, trademarks, service marks
or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
In consideration of your agreement to abide by the following terms, and subject to these
terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in
this original Apple software (the "Apple Software"), to use, reproduce, modify and
redistribute the Apple Software, with or without modifications, in source and/or binary
forms; provided that if you redistribute the Apple Software in its entirety and without
modifications, you must retain this notice and the following text and disclaimers in all
such redistributions of the Apple Software. Neither the name, trademarks, service marks
or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
the Apple Software without specific prior written permission from Apple. Except as expressly
stated in this notice, no other rights or licenses, express or implied, are granted by Apple
herein, including but not limited to any patent rights that may be infringed by your
herein, including but not limited to any patent rights that may be infringed by your
derivative works or by other works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PluginObject__DEFINED
#define PluginObject__DEFINED
#include "npapi.h"
#include "main.h"
struct ANPEvent;
struct ANPCanvas;
struct ANPAudioTrack;
class Animation {
class SubPlugin {
public:
Animation(NPP inst) : m_inst(inst) {}
virtual ~Animation() {}
SubPlugin(NPP inst) : m_inst(inst) {}
virtual ~SubPlugin() {}
virtual void draw(ANPCanvas*) = 0;
virtual int16 handleEvent(const ANPEvent* evt) = 0;
NPP inst() const { return m_inst; }
private:
NPP m_inst;
};
enum PluginTypes {
kBackground_PluginType = 1,
kAnimation_PluginType = 2,
kAudio_PluginType = 3,
kText_PluginType = 4,
kPaint_PluginType = 5
};
typedef uint32_t PluginType;
typedef struct PluginObject {
NPObject header;
NPP npp;
NPWindow* window;
Animation* anim;
PluginType pluginType;
SubPlugin* activePlugin;
ANPAudioTrack* track;
int32_t mUnichar;
bool mTestTimers;
uint32_t mStartTime;
uint32_t mPrevTime;
int mTimerCount;
} PluginObject;
NPClass *getPluginClass(void);

View File

@@ -22,10 +22,9 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "pluginGraphics.h"
#include "android_npapi.h"
#include "AnimationPlugin.h"
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
@@ -63,6 +62,20 @@ static void inval(NPP instance, const ANPRectF& r, bool doAA) {
browser->invalidaterect(instance, &inval);
}
static void drawPlugin(SubPlugin* plugin, const ANPBitmap& bitmap, const ANPRectI& clip) {
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
ANPRectF clipR;
clipR.left = clip.left;
clipR.top = clip.top;
clipR.right = clip.right;
clipR.bottom = clip.bottom;
gCanvasI.clipRect(canvas, &clipR);
plugin->draw(canvas);
gCanvasI.deleteCanvas(canvas);
}
uint32_t getMSecs() {
struct timeval tv;
gettimeofday(&tv, NULL);
@@ -71,38 +84,28 @@ uint32_t getMSecs() {
///////////////////////////////////////////////////////////////////////////////
class BallAnimation : public Animation {
public:
BallAnimation(NPP inst);
virtual ~BallAnimation();
virtual void draw(ANPCanvas*);
private:
float m_x;
float m_y;
float m_dx;
float m_dy;
ANPRectF m_oval;
ANPPaint* m_paint;
static const float SCALE = 0.1;
};
BallAnimation::BallAnimation(NPP inst) : Animation(inst) {
BallAnimation::BallAnimation(NPP inst) : SubPlugin(inst) {
m_x = m_y = 0;
m_dx = 7 * SCALE;
m_dy = 5 * SCALE;
memset(&m_oval, 0, sizeof(m_oval));
m_paint = gPaintI.newPaint();
gPaintI.setFlags(m_paint, gPaintI.getFlags(m_paint) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paint, 0xFFFF0000);
gPaintI.setTextSize(m_paint, 24);
ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
gPaintI.setTypeface(m_paint, tf);
gTypefaceI.unref(tf);
//register for key and touch events
ANPEventFlags flags = kKey_ANPEventFlag | kTouch_ANPEventFlag;
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
if (err != NPERR_NO_ERROR) {
gLogI.log(inst, kError_ANPLogType, "Error selecting input events.");
}
}
BallAnimation::~BallAnimation() {
@@ -166,45 +169,46 @@ void BallAnimation::draw(ANPCanvas* canvas) {
#endif
gPathI.deletePath(path);
}
gPaintI.setColor(m_paint, 0xFFFF0000);
gCanvasI.drawOval(canvas, &m_oval, m_paint);
bounce(&m_x, &m_dx, obj->window->width - OW);
bounce(&m_y, &m_dy, obj->window->height - OH);
if (obj->mUnichar) {
if (mUnichar) {
ANPFontMetrics fm;
gPaintI.getFontMetrics(m_paint, &fm);
gPaintI.setColor(m_paint, 0xFF0000FF);
char c = static_cast<char>(obj->mUnichar);
char c = static_cast<char>(mUnichar);
gCanvasI.drawText(canvas, &c, 1, 10, -fm.fTop, m_paint);
}
}
///////////////////////////////////////////////////////////////////////////////
int16 BallAnimation::handleEvent(const ANPEvent* evt) {
NPP instance = this->inst();
void drawPlugin(NPP instance, const ANPBitmap& bitmap, const ANPRectI& clip) {
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
ANPRectF clipR;
clipR.left = clip.left;
clipR.top = clip.top;
clipR.right = clip.right;
clipR.bottom = clip.bottom;
gCanvasI.clipRect(canvas, &clipR);
drawPlugin(instance, canvas);
gCanvasI.deleteCanvas(canvas);
}
switch (evt->eventType) {
case kDraw_ANPEventType:
switch (evt->data.draw.model) {
case kBitmap_ANPDrawingModel:
drawPlugin(this, evt->data.draw.data.bitmap, evt->data.draw.clip);
return 1;
default:
break; // unknown drawing model
}
void drawPlugin(NPP instance, ANPCanvas* canvas) {
PluginObject *obj = (PluginObject*) instance->pdata;
if (obj->anim == NULL) {
obj->anim = new BallAnimation(instance);
case kKey_ANPEventType:
if (evt->data.key.action == kDown_ANPKeyAction) {
mUnichar = evt->data.key.unichar;
gLogI.log(instance, kDebug_ANPLogType, "ball downkey event");
browser->invalidaterect(instance, NULL);
}
return 1;
default:
break;
}
obj->anim->draw(canvas);
return 0; // unknown or unhandled event
}

View File

@@ -22,19 +22,33 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "main.h" // for NPAPI definitions
#include "PluginObject.h"
#include "android_npapi.h"
#ifndef pluginGraphics__DEFINED
#define pluginGraphics__DEFINED
struct ANPBitmap;
struct ANPCanvas;
struct ANPRectI;
class BallAnimation : public SubPlugin {
public:
BallAnimation(NPP inst);
virtual ~BallAnimation();
virtual void draw(ANPCanvas*);
virtual int16 handleEvent(const ANPEvent* evt);
private:
float m_x;
float m_y;
float m_dx;
float m_dy;
int32_t mUnichar;
ANPRectF m_oval;
ANPPaint* m_paint;
static const float SCALE = 0.1;
};
void drawPlugin(NPP instance, const ANPBitmap& bitmap, const ANPRectI& clip);
void drawPlugin(NPP instance, ANPCanvas*);
uint32_t getMSecs();
#endif // pluginGraphics__DEFINED

View File

@@ -0,0 +1,307 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "BackgroundPlugin.h"
#include "android_npapi.h"
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>
#include <string.h>
extern NPNetscapeFuncs* browser;
extern ANPBitmapInterfaceV0 gBitmapI;
extern ANPLogInterfaceV0 gLogI;
extern ANPCanvasInterfaceV0 gCanvasI;
extern ANPPaintInterfaceV0 gPaintI;
extern ANPPathInterfaceV0 gPathI;
extern ANPTypefaceInterfaceV0 gTypefaceI;
extern uint32_t getMSecs();
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
//#define LOG_ERROR(inst, string, params...) gLogI.log(inst, kError_ANPLogType, (log_prefix + string), inst, params)
///////////////////////////////////////////////////////////////////////////////
BackgroundPlugin::BackgroundPlugin(NPP inst) : SubPlugin(inst) {
m_paint = gPaintI.newPaint();
gPaintI.setFlags(m_paint, gPaintI.getFlags(m_paint) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paint, 0xFFFF0000);
gPaintI.setTextSize(m_paint, 16);
ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
gPaintI.setTypeface(m_paint, tf);
gTypefaceI.unref(tf);
//initialize variables
mFinishedStageOne = false;
mFinishedStageTwo = false;
mFinishedStageThree = false;
// test basic plugin functionality
test_logging(); // android logging
test_timers(); // plugin timers
test_bitmaps(); // android bitmaps
}
BackgroundPlugin::~BackgroundPlugin() {
}
void BackgroundPlugin::draw(ANPCanvas* canvas) {
gCanvasI.drawColor(canvas, 0xFFFFFFFF);
ANPFontMetrics fm;
gPaintI.getFontMetrics(m_paint, &fm);
gPaintI.setColor(m_paint, 0xFF0000FF);
const char c[] = "This is a background plugin.";
gCanvasI.drawText(canvas, c, sizeof(c)-1, 10, -fm.fTop, m_paint);
}
static void drawPlugin(SubPlugin* plugin, const ANPBitmap& bitmap, const ANPRectI& clip) {
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
ANPRectF clipR;
clipR.left = clip.left;
clipR.top = clip.top;
clipR.right = clip.right;
clipR.bottom = clip.bottom;
gCanvasI.clipRect(canvas, &clipR);
plugin->draw(canvas);
gCanvasI.deleteCanvas(canvas);
}
int16 BackgroundPlugin::handleEvent(const ANPEvent* evt) {
NPP instance = this->inst();
switch (evt->eventType) {
case kDraw_ANPEventType:
switch (evt->data.draw.model) {
case kBitmap_ANPDrawingModel:
test_bitmap_transparency(evt);
drawPlugin(this, evt->data.draw.data.bitmap, evt->data.draw.clip);
return 1;
default:
break; // unknown drawing model
}
case kTouch_ANPEventType:
gLogI.log(instance, kError_ANPLogType, " ------ %p the plugin did not request touch events", instance);
case kKey_ANPEventType:
gLogI.log(instance, kError_ANPLogType, " ------ %p the plugin did not request key events", instance);
default:
break;
}
return 0; // unknown or unhandled event
}
///////////////////////////////////////////////////////////////////////////////
// LOGGING TESTS
///////////////////////////////////////////////////////////////////////////////
void BackgroundPlugin::test_logging() {
NPP instance = this->inst();
//LOG_ERROR(instance, " ------ %p Testing Log Error", instance);
gLogI.log(instance, kError_ANPLogType, " ------ %p Testing Log Error", instance);
gLogI.log(instance, kWarning_ANPLogType, " ------ %p Testing Log Warning", instance);
gLogI.log(instance, kDebug_ANPLogType, " ------ %p Testing Log Debug", instance);
}
///////////////////////////////////////////////////////////////////////////////
// TIMER TESTS
///////////////////////////////////////////////////////////////////////////////
#define TIMER_INTERVAL 50
static void timer_oneshot(NPP instance, uint32 timerID);
static void timer_repeat(NPP instance, uint32 timerID);
static void timer_neverfires(NPP instance, uint32 timerID);
static void timer_latency(NPP instance, uint32 timerID);
void BackgroundPlugin::test_timers() {
NPP instance = this->inst();
//Setup the testing counters
mTimerRepeatCount = 5;
mTimerLatencyCount = 5;
// test for bogus timerID
browser->unscheduletimer(instance, 999999);
// test one-shot
browser->scheduletimer(instance, 100, false, timer_oneshot);
// test repeat
browser->scheduletimer(instance, 50, true, timer_repeat);
// test timer latency
browser->scheduletimer(instance, TIMER_INTERVAL, true, timer_latency);
mStartTime = mPrevTime = getMSecs();
// test unschedule immediately
uint32 id = browser->scheduletimer(instance, 100, false, timer_neverfires);
browser->unscheduletimer(instance, id);
// test double unschedule (should be no-op)
browser->unscheduletimer(instance, id);
}
static void timer_oneshot(NPP instance, uint32 timerID) {
gLogI.log(instance, kDebug_ANPLogType, "-------- oneshot timer\n");
}
static void timer_repeat(NPP instance, uint32 timerID) {
BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
gLogI.log(instance, kDebug_ANPLogType, "-------- repeat timer %d\n",
obj->mTimerRepeatCount);
if (--obj->mTimerRepeatCount == 0) {
browser->unscheduletimer(instance, timerID);
}
}
static void timer_neverfires(NPP instance, uint32 timerID) {
gLogI.log(instance, kError_ANPLogType, "-------- timer_neverfires!!!\n");
}
static void timer_latency(NPP instance, uint32 timerID) {
BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
obj->mTimerLatencyCurrentCount += 1;
uint32_t now = getMSecs();
uint32_t interval = now - obj->mPrevTime;
uint32_t dur = now - obj->mStartTime;
uint32_t expectedDur = obj->mTimerLatencyCurrentCount * TIMER_INTERVAL;
int32_t drift = dur - expectedDur;
int32_t avgDrift = drift / obj->mTimerLatencyCurrentCount;
obj->mPrevTime = now;
gLogI.log(instance, kDebug_ANPLogType,
"-------- latency test: [%3d] interval %d expected %d, total %d expected %d, drift %d avg %d\n",
obj->mTimerLatencyCurrentCount, interval, TIMER_INTERVAL, dur,
expectedDur, drift, avgDrift);
if (--obj->mTimerLatencyCount == 0) {
browser->unscheduletimer(instance, timerID);
}
}
///////////////////////////////////////////////////////////////////////////////
// BITMAP TESTS
///////////////////////////////////////////////////////////////////////////////
static void test_formats(NPP instance);
void BackgroundPlugin::test_bitmaps() {
test_formats(this->inst());
}
static void test_formats(NPP instance) {
// TODO pull names from enum in npapi instead of hardcoding them
static const struct {
ANPBitmapFormat fFormat;
const char* fName;
} gRecs[] = {
{ kUnknown_ANPBitmapFormat, "unknown" },
{ kRGBA_8888_ANPBitmapFormat, "8888" },
{ kRGB_565_ANPBitmapFormat, "565" },
};
ANPPixelPacking packing;
for (size_t i = 0; i < ARRAY_COUNT(gRecs); i++) {
if (gBitmapI.getPixelPacking(gRecs[i].fFormat, &packing)) {
gLogI.log(instance, kDebug_ANPLogType,
"pixel format [%d] %s has packing ARGB [%d %d] [%d %d] [%d %d] [%d %d]\n",
gRecs[i].fFormat, gRecs[i].fName,
packing.AShift, packing.ABits,
packing.RShift, packing.RBits,
packing.GShift, packing.GBits,
packing.BShift, packing.BBits);
} else {
gLogI.log(instance, kDebug_ANPLogType,
"pixel format [%d] %s has no packing\n",
gRecs[i].fFormat, gRecs[i].fName);
}
}
}
void BackgroundPlugin::test_bitmap_transparency(const ANPEvent* evt) {
NPP instance = this->inst();
// check default & set transparent
if (!mFinishedStageOne) {
gLogI.log(instance, kDebug_ANPLogType, "BEGIN: testing bitmap transparency");
//check to make sure it is not transparent
if (evt->data.draw.data.bitmap.format == kRGBA_8888_ANPBitmapFormat) {
gLogI.log(instance, kError_ANPLogType, "bitmap default format is transparent");
}
//make it transparent (any non-null value will set it to true)
bool value = true;
NPError err = browser->setvalue(instance, NPPVpluginTransparentBool, &value);
if (err != NPERR_NO_ERROR) {
gLogI.log(instance, kError_ANPLogType, "Error setting transparency.");
}
mFinishedStageOne = true;
browser->invalidaterect(instance, NULL);
}
// check transparent & set opaque
else if (!mFinishedStageTwo) {
//check to make sure it is transparent
if (evt->data.draw.data.bitmap.format != kRGBA_8888_ANPBitmapFormat) {
gLogI.log(instance, kError_ANPLogType, "bitmap did not change to transparent format");
}
//make it opaque
NPError err = browser->setvalue(instance, NPPVpluginTransparentBool, NULL);
if (err != NPERR_NO_ERROR) {
gLogI.log(instance, kError_ANPLogType, "Error setting transparency.");
}
mFinishedStageTwo = true;
}
// check opaque
else if (!mFinishedStageThree) {
//check to make sure it is not transparent
if (evt->data.draw.data.bitmap.format == kRGBA_8888_ANPBitmapFormat) {
gLogI.log(instance, kError_ANPLogType, "bitmap default format is transparent");
}
gLogI.log(instance, kDebug_ANPLogType, "END: testing bitmap transparency");
mFinishedStageThree = true;
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PluginObject.h"
#ifndef backgroundPlugin__DEFINED
#define backgroundPlugin__DEFINED
struct ANPCanvas;
struct ANPEvent;
struct ANPPaint;
class BackgroundPlugin : public SubPlugin {
public:
BackgroundPlugin(NPP inst);
virtual ~BackgroundPlugin();
virtual void draw(ANPCanvas*);
virtual int16 handleEvent(const ANPEvent* evt);
// Timer Testing Variables
uint32_t mStartTime;
uint32_t mPrevTime;
int mTimerRepeatCount;
int mTimerLatencyCount;
int mTimerLatencyCurrentCount;
// Bitmap Transparency Variables
bool mFinishedStageOne; // check default & set transparent
bool mFinishedStageTwo; // check transparent & set opaque
bool mFinishedStageThree; // check opaque
private:
ANPPaint* m_paint;
void test_logging();
void test_timers();
void test_bitmaps();
void test_bitmap_transparency(const ANPEvent* evt);
};
#endif // backgroundPlugin__DEFINED

View File

@@ -28,7 +28,8 @@
#include <stdio.h>
#include "main.h"
#include "PluginObject.h"
#include "pluginGraphics.h"
#include "AnimationPlugin.h"
#include "BackgroundPlugin.h"
#include "android_npapi.h"
NPNetscapeFuncs* browser;
@@ -128,103 +129,86 @@ void NP_Shutdown(void)
const char *NP_GetMIMEDescription(void)
{
return "application/x-testplugin:tst:Test plugin mimetype is application/x-testplugin";
return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
}
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
char* argn[], char* argv[], NPSavedData* saved)
{
/* BEGIN: STANDARD PLUGIN FRAMEWORK */
PluginObject *obj = NULL;
// Scripting functions appeared in NPAPI version 14
if (browser->version >= 14) {
instance->pdata = browser->createobject (instance, getPluginClass());
obj = static_cast<PluginObject*>(instance->pdata);
bzero(obj, sizeof(*obj));
}
uint32_t bits;
NPError err = browser->getvalue(instance, kSupportedDrawingModel_ANPGetValue, &bits);
if (err) {
gLogI.log(instance, kError_ANPLogType, "supported model err %d", err);
return err;
instance->pdata = browser->createobject (instance, getPluginClass());
obj = static_cast<PluginObject*>(instance->pdata);
bzero(obj, sizeof(*obj));
}
/* END: STANDARD PLUGIN FRAMEWORK */
// select the drawing model based on user input
ANPDrawingModel model = kBitmap_ANPDrawingModel;
int count = argc;
for (int i = 0; i < count; i++) {
for (int i = 0; i < argc; i++) {
if (!strcmp(argn[i], "DrawingModel")) {
if (!strcmp(argv[i], "Bitmap")) {
model = kBitmap_ANPDrawingModel;
}
if (!strcmp(argv[i], "Canvas")) {
// obj->mTestTimers = true;
//TODO support drawing on canvas instead of bitmap
}
gLogI.log(instance, kDebug_ANPLogType, "------ %p DrawingModel is %d", instance, model);
break;
}
}
// comment this out to draw via bitmaps (the default)
err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
// comment this out to use the default model (bitmaps)
NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
reinterpret_cast<void*>(model));
if (err) {
gLogI.log(instance, kError_ANPLogType, "request model %d err %d", model, err);
return err;
}
return err;
// select the pluginType
for (int i = 0; i < argc; i++) {
if (!strcmp(argn[i], "PluginType")) {
if (!strcmp(argv[i], "Animation")) {
obj->pluginType = kAnimation_PluginType;
obj->activePlugin = new BallAnimation(instance);
}
else if (!strcmp(argv[i], "Audio")) {
obj->pluginType = kAudio_PluginType;
//TODO add audio here
}
else if (!strcmp(argv[i], "Background")) {
obj->pluginType = kBackground_PluginType;
obj->activePlugin = new BackgroundPlugin(instance);
}
gLogI.log(instance, kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
break;
}
}
// if no pluginType is specified then default to Animation
if (!obj->pluginType) {
obj->pluginType = kAnimation_PluginType;
obj->activePlugin = new BallAnimation(instance);
}
return NPERR_NO_ERROR;
}
NPError NPP_Destroy(NPP instance, NPSavedData** save)
{
PluginObject *obj = (PluginObject*) instance->pdata;
delete obj->anim;
delete obj->activePlugin;
gSoundI.deleteTrack(obj->track);
return NPERR_NO_ERROR;
}
static void timer_oneshot(NPP instance, uint32 timerID) {
gLogI.log(instance, kDebug_ANPLogType, "-------- oneshot timer\n");
}
static int gTimerRepeatCount;
static void timer_repeat(NPP instance, uint32 timerID) {
gLogI.log(instance, kDebug_ANPLogType, "-------- repeat timer %d\n",
gTimerRepeatCount);
if (--gTimerRepeatCount == 0) {
browser->unscheduletimer(instance, timerID);
}
}
static void timer_neverfires(NPP instance, uint32 timerID) {
gLogI.log(instance, kError_ANPLogType, "-------- timer_neverfires!!!\n");
}
#define TIMER_INTERVAL 50
static void timer_latency(NPP instance, uint32 timerID) {
PluginObject *obj = (PluginObject*) instance->pdata;
obj->mTimerCount += 1;
uint32_t now = getMSecs();
uint32_t interval = now - obj->mPrevTime;
uint32_t dur = now - obj->mStartTime;
uint32_t expectedDur = obj->mTimerCount * TIMER_INTERVAL;
int32_t drift = dur - expectedDur;
int32_t aveDrift = drift / obj->mTimerCount;
obj->mPrevTime = now;
gLogI.log(instance, kDebug_ANPLogType,
"-------- latency test: [%3d] interval %d expected %d, total %d expected %d, drift %d ave %d\n",
obj->mTimerCount, interval, TIMER_INTERVAL, dur, expectedDur,
drift, aveDrift);
}
NPError NPP_SetWindow(NPP instance, NPWindow* window)
{
PluginObject *obj = (PluginObject*) instance->pdata;
@@ -234,63 +218,11 @@ NPError NPP_SetWindow(NPP instance, NPWindow* window)
obj->window = window;
}
static bool gTestTimers;
if (!gTestTimers) {
gTestTimers = true;
// test for bogus timerID
browser->unscheduletimer(instance, 999999);
// test oneshot
browser->scheduletimer(instance, 100, false, timer_oneshot);
// test repeat
gTimerRepeatCount = 10;
browser->scheduletimer(instance, 50, true, timer_repeat);
// test unschedule immediately
uint32 id = browser->scheduletimer(instance, 100, false, timer_neverfires);
browser->unscheduletimer(instance, id);
// test double unschedlue (should be no-op)
browser->unscheduletimer(instance, id);
}
if (obj->mTestTimers) {
browser->scheduletimer(instance, TIMER_INTERVAL, true, timer_latency);
obj->mStartTime = obj->mPrevTime = getMSecs();
obj->mTestTimers = false;
}
if (true) {
static const struct {
ANPBitmapFormat fFormat;
const char* fName;
} gRecs[] = {
{ kUnknown_ANPBitmapFormat, "unknown" },
{ kRGBA_8888_ANPBitmapFormat, "8888" },
{ kRGB_565_ANPBitmapFormat, "565" },
};
ANPPixelPacking packing;
for (size_t i = 0; i < ARRAY_COUNT(gRecs); i++) {
if (gBitmapI.getPixelPacking(gRecs[i].fFormat, &packing)) {
gLogI.log(instance, kDebug_ANPLogType,
"pixel format [%d] %s has packing ARGB [%d %d] [%d %d] [%d %d] [%d %d]\n",
gRecs[i].fFormat, gRecs[i].fName,
packing.AShift, packing.ABits,
packing.RShift, packing.RBits,
packing.GShift, packing.GBits,
packing.BShift, packing.BBits);
} else {
gLogI.log(instance, kDebug_ANPLogType,
"pixel format [%d] %s has no packing\n",
gRecs[i].fFormat, gRecs[i].fName);
}
}
}
browser->invalidaterect(instance, NULL);
return NPERR_NO_ERROR;
}
NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
{
*stype = NP_ASFILEONLY;
@@ -318,7 +250,6 @@ void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
void NPP_Print(NPP instance, NPPrint* platformPrint)
{
}
struct SoundPlay {
@@ -370,14 +301,22 @@ int16 NPP_HandleEvent(NPP instance, void* event)
switch (evt->eventType) {
case kDraw_ANPEventType:
switch (evt->data.draw.model) {
case kBitmap_ANPDrawingModel:
drawPlugin(instance, evt->data.draw.data.bitmap,
evt->data.draw.clip);
return 1;
default:
break; // unknown drawing model
if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
static ANPBitmapFormat currentFormat = -1;
if (evt->data.draw.data.bitmap.format != currentFormat) {
currentFormat = evt->data.draw.data.bitmap.format;
gLogI.log(instance, kDebug_ANPLogType, "---- %p Draw (bitmap)"
" clip=%d,%d,%d,%d format=%d", instance,
evt->data.draw.clip.left,
evt->data.draw.clip.top,
evt->data.draw.clip.right,
evt->data.draw.clip.bottom,
evt->data.draw.data.bitmap.format);
}
}
break;
case kKey_ANPEventType:
gLogI.log(instance, kDebug_ANPLogType, "---- %p Key action=%d"
@@ -388,18 +327,14 @@ int16 NPP_HandleEvent(NPP instance, void* event)
evt->data.key.unichar,
evt->data.key.repeatCount,
evt->data.key.modifiers);
if (evt->data.key.action == kDown_ANPKeyAction) {
obj->mUnichar = evt->data.key.unichar;
browser->invalidaterect(instance, NULL);
}
return 1;
break;
case kLifecycle_ANPEventType:
gLogI.log(instance, kDebug_ANPLogType, "---- %p Lifecycle action=%d",
instance, evt->data.lifecycle.action);
instance, evt->data.lifecycle.action);
break;
case kTouch_ANPEventType:
case kTouch_ANPEventType:
gLogI.log(instance, kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
instance, evt->data.touch.action, evt->data.touch.x,
evt->data.touch.y);
@@ -422,7 +357,14 @@ int16 NPP_HandleEvent(NPP instance, void* event)
default:
break;
}
return 0; // unknown or unhandled event
if(!obj->activePlugin) {
gLogI.log(instance, kError_ANPLogType, "the active plugin is null.");
return 0; // unknown or unhandled event
}
else {
return obj->activePlugin->handleEvent(evt);
}
}
void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB