Updating samplePlugin to use java surface views.

Change-Id: I1b925ce3a6aeb0bd5464a7d5711449029944d7de
This commit is contained in:
Derek Sollenberger
2009-09-08 18:36:29 -04:00
parent 16ce3cdcac
commit 08581f1c06
10 changed files with 239 additions and 83 deletions

View File

@@ -35,7 +35,7 @@ LOCAL_SRC_FILES := \
background/BackgroundPlugin.cpp \ background/BackgroundPlugin.cpp \
form/FormPlugin.cpp \ form/FormPlugin.cpp \
paint/PaintPlugin.cpp \ paint/PaintPlugin.cpp \
hello-jni.cpp \ jni-bridge.cpp \
LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \ $(JNI_H_INCLUDE) \

View File

@@ -35,6 +35,7 @@
#define PluginObject__DEFINED #define PluginObject__DEFINED
#include "main.h" #include "main.h"
#include <jni.h>
class SubPlugin { class SubPlugin {
public: public:
@@ -49,6 +50,16 @@ private:
NPP m_inst; NPP m_inst;
}; };
class SurfaceSubPlugin : public SubPlugin {
public:
SurfaceSubPlugin(NPP inst) : SubPlugin(inst) {}
virtual ~SurfaceSubPlugin() {}
virtual bool isFixedSurface() = 0;
virtual void surfaceCreated(JNIEnv*, jobject) = 0;
virtual void surfaceChanged(int format, int width, int height) = 0;
virtual void surfaceDestroyed() = 0;
};
enum PluginTypes { enum PluginTypes {
kAnimation_PluginType = 1, kAnimation_PluginType = 1,
kAudio_PluginType = 2, kAudio_PluginType = 2,

View File

@@ -50,13 +50,11 @@ static uint32_t getMSecs() {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
BackgroundPlugin::BackgroundPlugin(NPP inst) : SubPlugin(inst) { BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) {
// initialize the drawing surface // initialize the drawing surface
m_surfaceReady = false; m_surface = NULL;
m_surface = gSurfaceI.newRasterSurface(inst, kRGB_565_ANPBitmapFormat, false); m_vm = NULL;
if(!m_surface)
gLogI.log(inst, kError_ANPLogType, "----%p Unable to create RGBA surface", inst);
//initialize bitmap transparency variables //initialize bitmap transparency variables
mFinishedStageOne = false; mFinishedStageOne = false;
@@ -71,14 +69,33 @@ BackgroundPlugin::BackgroundPlugin(NPP inst) : SubPlugin(inst) {
test_javascript(); test_javascript();
} }
BackgroundPlugin::~BackgroundPlugin() { BackgroundPlugin::~BackgroundPlugin() { }
gSurfaceI.deleteSurface(m_surface);
}
bool BackgroundPlugin::supportsDrawingModel(ANPDrawingModel model) { bool BackgroundPlugin::supportsDrawingModel(ANPDrawingModel model) {
return (model == kSurface_ANPDrawingModel); return (model == kSurface_ANPDrawingModel);
} }
bool BackgroundPlugin::isFixedSurface() {
return false;
}
void BackgroundPlugin::surfaceCreated(JNIEnv* env, jobject surface) {
env->GetJavaVM(&m_vm);
m_surface = env->NewGlobalRef(surface);
}
void BackgroundPlugin::surfaceChanged(int format, int width, int height) {
drawPlugin(width, height);
}
void BackgroundPlugin::surfaceDestroyed() {
JNIEnv* env = NULL;
if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
env->DeleteGlobalRef(m_surface);
m_surface = NULL;
}
}
void BackgroundPlugin::drawPlugin(int surfaceWidth, int surfaceHeight) { void BackgroundPlugin::drawPlugin(int surfaceWidth, int surfaceHeight) {
// get the plugin's dimensions according to the DOM // get the plugin's dimensions according to the DOM
@@ -101,7 +118,9 @@ void BackgroundPlugin::drawPlugin(int surfaceWidth, int surfaceHeight) {
// lock the surface // lock the surface
ANPBitmap bitmap; ANPBitmap bitmap;
if (!m_surfaceReady || !gSurfaceI.lock(m_surface, &bitmap, NULL)) { JNIEnv* env = NULL;
if (!m_surface || m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
!gSurfaceI.lock(env, m_surface, &bitmap, NULL)) {
gLogI.log(inst(), kError_ANPLogType, " ------ %p unable to lock the plugin", inst()); gLogI.log(inst(), kError_ANPLogType, " ------ %p unable to lock the plugin", inst());
return; return;
} }
@@ -129,7 +148,7 @@ void BackgroundPlugin::drawPlugin(int surfaceWidth, int surfaceHeight) {
// clean up variables and unlock the surface // clean up variables and unlock the surface
gPaintI.deletePaint(paint); gPaintI.deletePaint(paint);
gCanvasI.deleteCanvas(canvas); gCanvasI.deleteCanvas(canvas);
gSurfaceI.unlock(m_surface); gSurfaceI.unlock(env, m_surface);
} }
int16 BackgroundPlugin::handleEvent(const ANPEvent* evt) { int16 BackgroundPlugin::handleEvent(const ANPEvent* evt) {
@@ -137,20 +156,6 @@ int16 BackgroundPlugin::handleEvent(const ANPEvent* evt) {
case kDraw_ANPEventType: case kDraw_ANPEventType:
gLogI.log(inst(), kError_ANPLogType, " ------ %p the plugin did not request draw events", inst()); gLogI.log(inst(), kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
break; break;
case kSurface_ANPEventType:
switch (evt->data.surface.action) {
case kCreated_ANPSurfaceAction:
m_surfaceReady = true;
return 1;
case kDestroyed_ANPSurfaceAction:
m_surfaceReady = false;
return 1;
case kChanged_ANPSurfaceAction:
drawPlugin(evt->data.surface.data.changed.width,
evt->data.surface.data.changed.height);
return 1;
}
break;
case kLifecycle_ANPEventType: case kLifecycle_ANPEventType:
if (evt->data.lifecycle.action == kOnLoad_ANPLifecycleAction) { if (evt->data.lifecycle.action == kOnLoad_ANPLifecycleAction) {
gLogI.log(inst(), kDebug_ANPLogType, " ------ %p the plugin received an onLoad event", inst()); gLogI.log(inst(), kDebug_ANPLogType, " ------ %p the plugin received an onLoad event", inst());

View File

@@ -28,12 +28,16 @@
#ifndef backgroundPlugin__DEFINED #ifndef backgroundPlugin__DEFINED
#define backgroundPlugin__DEFINED #define backgroundPlugin__DEFINED
class BackgroundPlugin : public SubPlugin { class BackgroundPlugin : public SurfaceSubPlugin {
public: public:
BackgroundPlugin(NPP inst); BackgroundPlugin(NPP inst);
virtual ~BackgroundPlugin(); virtual ~BackgroundPlugin();
virtual bool supportsDrawingModel(ANPDrawingModel); virtual bool supportsDrawingModel(ANPDrawingModel);
virtual int16 handleEvent(const ANPEvent* evt); virtual int16 handleEvent(const ANPEvent* evt);
virtual void surfaceCreated(JNIEnv* env, jobject surface);
virtual void surfaceChanged(int format, int width, int height);
virtual void surfaceDestroyed();
virtual bool isFixedSurface();
// Timer Testing Variables // Timer Testing Variables
uint32_t mStartTime; uint32_t mStartTime;
@@ -50,8 +54,8 @@ public:
private: private:
void drawPlugin(int surfaceWidth, int surfaceHeight); void drawPlugin(int surfaceWidth, int surfaceHeight);
bool m_surfaceReady; jobject m_surface;
ANPSurface* m_surface; JavaVM* m_vm;
void test_logging(); void test_logging();
void test_timers(); void test_timers();

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <string.h>
#include <jni.h>
#include <JNIHelp.h>
#include <utils/Log.h>
#include "PluginObject.h"
#define EXPORT __attribute__((visibility("default")))
static SurfaceSubPlugin* getPluginObject(int npp) {
NPP instance = (NPP)npp;
PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
if (obj && obj->activePlugin
&& obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)) {
return static_cast<SurfaceSubPlugin*>(obj->activePlugin);
}
return NULL;
}
static void surfaceCreated(JNIEnv* env, jobject thiz, jint npp, jobject surface) {
SurfaceSubPlugin* obj = getPluginObject(npp);
//TODO why is this VM different from the one in NP_INIT...
JavaVM* vm = NULL;
env->GetJavaVM(&vm);
obj->surfaceCreated(env, surface);
}
static void surfaceChanged(JNIEnv* env, jobject thiz, jint npp, jint format, jint width, jint height) {
SurfaceSubPlugin* obj = getPluginObject(npp);
obj->surfaceChanged(format, width, height);
}
static void surfaceDestroyed(JNIEnv* env, jobject thiz, jint npp) {
SurfaceSubPlugin* obj = getPluginObject(npp);
if (obj) {
obj->surfaceDestroyed();
}
}
static jboolean isFixedSurface(JNIEnv* env, jobject thiz, jint npp) {
SurfaceSubPlugin* obj = getPluginObject(npp);
return obj->isFixedSurface();
}
/*
* JNI registration.
*/
static JNINativeMethod gJavaSamplePluginStubMethods[] = {
{ "nativeSurfaceCreated", "(ILandroid/view/View;)V", (void*) surfaceCreated },
{ "nativeSurfaceChanged", "(IIII)V", (void*) surfaceChanged },
{ "nativeSurfaceDestroyed", "(I)V", (void*) surfaceDestroyed },
{ "nativeIsFixedSurface", "(I)Z", (void*) isFixedSurface },
};
EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
jniRegisterNativeMethods(env, "com/android/sampleplugin/SamplePluginStub",
gJavaSamplePluginStubMethods, NELEM(gJavaSamplePluginStubMethods));
return JNI_VERSION_1_4;
}

View File

@@ -33,7 +33,6 @@
#include "BackgroundPlugin.h" #include "BackgroundPlugin.h"
#include "FormPlugin.h" #include "FormPlugin.h"
#include "PaintPlugin.h" #include "PaintPlugin.h"
#include "android_npapi.h"
NPNetscapeFuncs* browser; NPNetscapeFuncs* browser;
#define EXPORT __attribute__((visibility("default"))) #define EXPORT __attribute__((visibility("default")))
@@ -173,6 +172,15 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
} }
} }
// notify the plugin API of the location of the java interface
char* className = "com.android.sampleplugin.SamplePluginStub";
NPError npErr = browser->setvalue(instance, kSetJavaClassName_ANPSetValue,
reinterpret_cast<void*>(className));
if (npErr) {
gLogI.log(instance, kError_ANPLogType, "set class err %d", npErr);
return npErr;
}
// notify the plugin API of the drawing model we wish to use. This must be // notify the plugin API of the drawing model we wish to use. This must be
// done prior to creating certain subPlugin objects (e.g. surfaceViews) // done prior to creating certain subPlugin objects (e.g. surfaceViews)
NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue, NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,

View File

@@ -27,5 +27,6 @@
#include <npfunctions.h> #include <npfunctions.h>
#include <npruntime.h> #include <npruntime.h>
#include "android_npapi.h" #include "android_npapi.h"
#include "ANPSurface_npapi.h"
extern NPNetscapeFuncs* browser; extern NPNetscapeFuncs* browser;

View File

@@ -39,7 +39,7 @@ extern ANPTypefaceInterfaceV0 gTypefaceI;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
PaintPlugin::PaintPlugin(NPP inst) : SubPlugin(inst) { PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) {
m_isTouchActive = false; m_isTouchActive = false;
m_isTouchCurrentInput = true; m_isTouchCurrentInput = true;
@@ -51,10 +51,8 @@ PaintPlugin::PaintPlugin(NPP inst) : SubPlugin(inst) {
memset(&m_clearSurface, 0, sizeof(m_clearSurface)); memset(&m_clearSurface, 0, sizeof(m_clearSurface));
// initialize the drawing surface // initialize the drawing surface
m_surfaceReady = false; m_surface = NULL;
m_surface = gSurfaceI.newRasterSurface(inst, kRGBA_8888_ANPBitmapFormat, true); m_vm = NULL;
if(!m_surface)
gLogI.log(inst, kError_ANPLogType, "----%p Unable to create RGBA surface", inst);
// initialize the path // initialize the path
m_touchPath = gPathI.newPath(); m_touchPath = gPathI.newPath();
@@ -85,10 +83,10 @@ PaintPlugin::PaintPlugin(NPP inst) : SubPlugin(inst) {
} }
PaintPlugin::~PaintPlugin() { PaintPlugin::~PaintPlugin() {
gSurfaceI.deleteSurface(m_surface);
gPathI.deletePath(m_touchPath); gPathI.deletePath(m_touchPath);
gPaintI.deletePaint(m_paintSurface); gPaintI.deletePaint(m_paintSurface);
gPaintI.deletePaint(m_paintButton); gPaintI.deletePaint(m_paintButton);
surfaceDestroyed();
} }
bool PaintPlugin::supportsDrawingModel(ANPDrawingModel model) { bool PaintPlugin::supportsDrawingModel(ANPDrawingModel model) {
@@ -98,8 +96,11 @@ bool PaintPlugin::supportsDrawingModel(ANPDrawingModel model) {
ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) { ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) {
ANPBitmap bitmap; ANPBitmap bitmap;
if (!m_surfaceReady || !gSurfaceI.lock(m_surface, &bitmap, dirtyRect)) JNIEnv* env = NULL;
if (!m_surface || m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
!gSurfaceI.lock(env, m_surface, &bitmap, dirtyRect)) {
return NULL; return NULL;
}
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap); ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
@@ -130,7 +131,10 @@ ANPCanvas* PaintPlugin::getCanvas(ANPRectF* dirtyRect) {
} }
void PaintPlugin::releaseCanvas(ANPCanvas* canvas) { void PaintPlugin::releaseCanvas(ANPCanvas* canvas) {
gSurfaceI.unlock(m_surface); JNIEnv* env = NULL;
if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
gSurfaceI.unlock(env, m_surface);
}
gCanvasI.deleteCanvas(canvas); gCanvasI.deleteCanvas(canvas);
} }
@@ -208,33 +212,37 @@ const char* PaintPlugin::getColorText() {
return "Red"; return "Red";
} }
int16 PaintPlugin::handleEvent(const ANPEvent* evt) { bool PaintPlugin::isFixedSurface() {
switch (evt->eventType) { return true;
case kSurface_ANPEventType: }
switch (evt->data.surface.action) {
case kCreated_ANPSurfaceAction: void PaintPlugin::surfaceCreated(JNIEnv* env, jobject surface) {
m_surfaceReady = true; env->GetJavaVM(&m_vm);
m_surface = env->NewGlobalRef(surface);
drawCleanPlugin(); drawCleanPlugin();
return 1; }
case kDestroyed_ANPSurfaceAction:
m_surfaceReady = false; void PaintPlugin::surfaceChanged(int format, int width, int height) {
return 1;
case kChanged_ANPSurfaceAction:
// get the plugin's dimensions according to the DOM // get the plugin's dimensions according to the DOM
PluginObject *obj = (PluginObject*) inst()->pdata; PluginObject *obj = (PluginObject*) inst()->pdata;
const int pW = obj->window->width; const int pW = obj->window->width;
const int pH = obj->window->height; const int pH = obj->window->height;
// get the plugin's surface dimensions // compare to the plugin's surface dimensions
const int sW = evt->data.surface.data.changed.width; if (pW != width || pH != height)
const int sH = evt->data.surface.data.changed.height;
if (pW != sW || pH != sH)
gLogI.log(inst(), kError_ANPLogType, gLogI.log(inst(), kError_ANPLogType,
"----%p Invalid Surface Dimensions (%d,%d):(%d,%d)", "----%p Invalid Surface Dimensions (%d,%d):(%d,%d)",
inst(), pW, pH, sW, sH); inst(), pW, pH, width, height);
return 1; }
void PaintPlugin::surfaceDestroyed() {
JNIEnv* env = NULL;
if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
env->DeleteGlobalRef(m_surface);
m_surface = NULL;
} }
break; }
int16 PaintPlugin::handleEvent(const ANPEvent* evt) {
switch (evt->eventType) {
case kTouch_ANPEventType: { case kTouch_ANPEventType: {
float x = (float) evt->data.touch.x; float x = (float) evt->data.touch.x;
float y = (float) evt->data.touch.y; float y = (float) evt->data.touch.y;

View File

@@ -29,12 +29,17 @@
#ifndef paintPlugin__DEFINED #ifndef paintPlugin__DEFINED
#define paintPlugin__DEFINED #define paintPlugin__DEFINED
class PaintPlugin : public SubPlugin { class PaintPlugin : public SurfaceSubPlugin {
public: public:
PaintPlugin(NPP inst); PaintPlugin(NPP inst);
virtual ~PaintPlugin(); virtual ~PaintPlugin();
virtual bool supportsDrawingModel(ANPDrawingModel); virtual bool supportsDrawingModel(ANPDrawingModel);
virtual int16 handleEvent(const ANPEvent* evt); virtual int16 handleEvent(const ANPEvent* evt);
virtual void surfaceCreated(JNIEnv* env, jobject surface);
virtual void surfaceChanged(int format, int width, int height);
virtual void surfaceDestroyed();
virtual bool isFixedSurface();
private: private:
void drawCleanPlugin(ANPCanvas* canvas = NULL); void drawCleanPlugin(ANPCanvas* canvas = NULL);
ANPCanvas* getCanvas(ANPRectI* dirtyRect = NULL); ANPCanvas* getCanvas(ANPRectI* dirtyRect = NULL);
@@ -49,9 +54,9 @@ private:
bool m_isTouchActive; bool m_isTouchActive;
bool m_isTouchCurrentInput; bool m_isTouchCurrentInput;
bool m_surfaceReady;
ANPSurface* m_surface; JavaVM* m_vm;
jobject m_surface;
ANPPath* m_touchPath; ANPPath* m_touchPath;
ANPRectF m_drawingSurface; ANPRectF m_drawingSurface;

View File

@@ -19,8 +19,11 @@ package com.android.sampleplugin;
import android.content.Context; import android.content.Context;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import android.webkit.PluginStub; import android.webkit.PluginStub;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@@ -28,29 +31,53 @@ import android.widget.MediaController;
import android.widget.VideoView; import android.widget.VideoView;
import com.android.sampleplugin.graphics.CubeRenderer; import com.android.sampleplugin.graphics.CubeRenderer;
public class SamplePluginStub extends PluginStub { public class SamplePluginStub implements PluginStub {
private int npp; static {
//needed for jni calls
public SamplePluginStub(int npp) { System.loadLibrary("sampleplugin");
super(npp);
this.npp = npp;
} }
public View getEmbeddedView(Context context) { public View getEmbeddedView(final int npp, Context context) {
// TODO Auto-generated method stub
return null; final SurfaceView view = new SurfaceView(context);
/* You can do all sorts of interesting operations on the surface view
* here. We illustrate a few of the important operations below.
*/
//TODO get pixel format from the subplugin (via jni)
view.getHolder().setFormat(PixelFormat.RGBA_8888);
view.getHolder().addCallback(new Callback() {
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
nativeSurfaceChanged(npp, format, width, height);
} }
public View getFullScreenView(Context context) { public void surfaceCreated(SurfaceHolder holder) {
nativeSurfaceCreated(npp, view);
}
public void surfaceDestroyed(SurfaceHolder holder) {
nativeSurfaceDestroyed(npp);
}
});
if (nativeIsFixedSurface(npp)) {
//TODO get the fixed dimensions from the plugin
//view.getHolder().setFixedSize(width, height);
}
return view;
}
public View getFullScreenView(int npp, Context context) {
/* TODO make this aware of the plugin instance and get the video file /* TODO make this aware of the plugin instance and get the video file
* from the plugin. * from the plugin.
*/ */
//needed for jni calls
System.loadLibrary("sampleplugin");
FrameLayout layout = new FrameLayout(context); FrameLayout layout = new FrameLayout(context);
LayoutParams fp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); LayoutParams fp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
layout.setLayoutParams(fp); layout.setLayoutParams(fp);
@@ -84,6 +111,8 @@ public class SamplePluginStub extends PluginStub {
return layout; return layout;
} }
public native String nativeStringFromJNI(); private native void nativeSurfaceCreated(int npp, View surfaceView);
private native void nativeSurfaceChanged(int npp, int format, int width, int height);
private native void nativeSurfaceDestroyed(int npp);
private native boolean nativeIsFixedSurface(int npp);
} }