From d53b56d1806161bd26c2d97b9af67ef0e41f6e25 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Mon, 11 Jan 2010 12:31:49 -0500 Subject: [PATCH] Removed dependence on java interfaces and use only one surface for both embedded and fullscreen surfaces. --- samples/BrowserPlugin/jni/PluginObject.cpp | 33 ++-- samples/BrowserPlugin/jni/PluginObject.h | 21 ++- .../jni/background/BackgroundPlugin.cpp | 58 +++--- .../jni/background/BackgroundPlugin.h | 7 +- samples/BrowserPlugin/jni/jni-bridge.cpp | 80 +++------ samples/BrowserPlugin/jni/main.cpp | 38 +++- .../BrowserPlugin/jni/paint/PaintPlugin.cpp | 92 +++++++--- samples/BrowserPlugin/jni/paint/PaintPlugin.h | 7 +- .../BrowserPlugin/jni/video/VideoPlugin.cpp | 120 +++++-------- samples/BrowserPlugin/jni/video/VideoPlugin.h | 8 +- .../sampleplugin/BackgroundSurface.java | 19 ++ .../android/sampleplugin/PaintSurface.java | 95 ++++++++++ .../android/sampleplugin/SamplePlugin.java | 165 +----------------- .../android/sampleplugin/VideoSurface.java | 67 +++++++ 14 files changed, 444 insertions(+), 366 deletions(-) create mode 100644 samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundSurface.java create mode 100644 samples/BrowserPlugin/src/com/android/sampleplugin/PaintSurface.java create mode 100644 samples/BrowserPlugin/src/com/android/sampleplugin/VideoSurface.java diff --git a/samples/BrowserPlugin/jni/PluginObject.cpp b/samples/BrowserPlugin/jni/PluginObject.cpp index 94b0cfad1..dd0fbac57 100644 --- a/samples/BrowserPlugin/jni/PluginObject.cpp +++ b/samples/BrowserPlugin/jni/PluginObject.cpp @@ -6,7 +6,7 @@ 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 + 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 @@ -45,25 +45,28 @@ int SubPlugin::getPluginHeight() { return obj->window->height; } -void SurfaceSubPlugin::setJavaInterface(jobject javaInterface) { +bool SurfaceSubPlugin::supportsDrawingModel(ANPDrawingModel model) { + return (model == kSurface_ANPDrawingModel); +} - // if one exists then free its reference and notify the object that it is no - // longer attached to the native instance +void SurfaceSubPlugin::setContext(jobject context) { JNIEnv* env = NULL; - if (m_javaInterface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { + if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { - // detach the native code from the object - jclass javaClass = env->GetObjectClass(m_javaInterface); - jmethodID invalMethod = env->GetMethodID(javaClass, "invalidateNPP", "()V"); - env->CallVoidMethod(m_javaInterface, invalMethod); + // if one exists then free its global reference + if (m_context) { + env->DeleteGlobalRef(m_context); + m_context = NULL; + } - // delete the reference - env->DeleteGlobalRef(m_javaInterface); - m_javaInterface = NULL; + // create a new global ref + if (context) { + context = env->NewGlobalRef(context); + } + + // set the value + m_context = context; } - - //set the value - m_javaInterface = javaInterface; } static void pluginInvalidate(NPObject *obj); diff --git a/samples/BrowserPlugin/jni/PluginObject.h b/samples/BrowserPlugin/jni/PluginObject.h index 691234f1e..e8084ef06 100644 --- a/samples/BrowserPlugin/jni/PluginObject.h +++ b/samples/BrowserPlugin/jni/PluginObject.h @@ -6,7 +6,7 @@ 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 + 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 @@ -37,6 +37,13 @@ #include "main.h" #include +enum CustomEventTypes { + kSurfaceCreated_CustomEvent = 0, + kSurfaceChanged_CustomEvent = 1, + kSurfaceDestroyed_CustomEvent = 2, +}; +typedef int32_t CustomEventType; + class SubPlugin { public: SubPlugin(NPP inst) : m_inst(inst) {} @@ -55,16 +62,14 @@ private: class SurfaceSubPlugin : public SubPlugin { public: - SurfaceSubPlugin(NPP inst) : SubPlugin(inst) {} + SurfaceSubPlugin(NPP inst) : SubPlugin(inst) { m_context = NULL; } virtual ~SurfaceSubPlugin() {} - virtual bool isFixedSurface() = 0; - virtual void surfaceCreated(jobject) = 0; - virtual void surfaceChanged(int format, int width, int height) = 0; - virtual void surfaceDestroyed() = 0; + virtual jobject getSurface() = 0; + virtual bool supportsDrawingModel(ANPDrawingModel); - void setJavaInterface(jobject); + void setContext(jobject context); - jobject m_javaInterface; + jobject m_context; }; enum PluginTypes { diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp index 699fa4da3..578fe6d3e 100644 --- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp +++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp @@ -54,9 +54,6 @@ static uint32_t getMSecs() { BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) { - // initialize the java interface - m_javaInterface = NULL; - // initialize the drawing surface m_surface = NULL; @@ -82,27 +79,44 @@ BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) { } BackgroundPlugin::~BackgroundPlugin() { - setJavaInterface(NULL); - surfaceDestroyed(); + setContext(NULL); + destroySurface(); } -bool BackgroundPlugin::supportsDrawingModel(ANPDrawingModel model) { - return (model == kSurface_ANPDrawingModel); +jobject BackgroundPlugin::getSurface() { + + if (m_surface) { + return m_surface; + } + + // load the appropriate java class and instantiate it + JNIEnv* env = NULL; + if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { + gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env"); + return NULL; + } + + const char* className = "com.android.sampleplugin.BackgroundSurface"; + jclass backgroundClass = gSystemI.loadJavaClass(inst(), className); + + if(!backgroundClass) { + gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class"); + return NULL; + } + + jmethodID constructor = env->GetMethodID(backgroundClass, "", "(Landroid/content/Context;)V"); + jobject backgroundSurface = env->NewObject(backgroundClass, constructor, m_context); + + if(!backgroundSurface) { + gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object"); + return NULL; + } + + m_surface = env->NewGlobalRef(backgroundSurface); + return m_surface; } -bool BackgroundPlugin::isFixedSurface() { - return false; -} - -void BackgroundPlugin::surfaceCreated(jobject surface) { - m_surface = surface; -} - -void BackgroundPlugin::surfaceChanged(int format, int width, int height) { - drawPlugin(width, height); -} - -void BackgroundPlugin::surfaceDestroyed() { +void BackgroundPlugin::destroySurface() { JNIEnv* env = NULL; if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { env->DeleteGlobalRef(m_surface); @@ -179,8 +193,10 @@ int16 BackgroundPlugin::handleEvent(const ANPEvent* evt) { case kTouch_ANPEventType: if (kDown_ANPTouchAction == evt->data.touch.action) return kHandleLongPress_ANPTouchResult | kHandleDoubleTap_ANPTouchResult; - else if (kLongPress_ANPTouchAction == evt->data.touch.action) + else if (kLongPress_ANPTouchAction == evt->data.touch.action) { browser->geturl(inst(), "javascript:alert('Detected long press event.')", 0); + gWindowI.requestFullScreen(inst()); + } else if (kDoubleTap_ANPTouchAction == evt->data.touch.action) browser->geturl(inst(), "javascript:alert('Detected double tap event.')", 0); break; diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h index 0e8f6f7c0..ebd77d16d 100644 --- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h +++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h @@ -32,12 +32,8 @@ class BackgroundPlugin : public SurfaceSubPlugin { public: BackgroundPlugin(NPP inst); virtual ~BackgroundPlugin(); - virtual bool supportsDrawingModel(ANPDrawingModel); virtual int16 handleEvent(const ANPEvent* evt); - virtual void surfaceCreated(jobject surface); - virtual void surfaceChanged(int format, int width, int height); - virtual void surfaceDestroyed(); - virtual bool isFixedSurface(); + virtual jobject getSurface(); // Timer Testing Variables uint32_t mStartTime; @@ -53,6 +49,7 @@ public: private: void drawPlugin(int surfaceWidth, int surfaceHeight); + void destroySurface(); jobject m_surface; diff --git a/samples/BrowserPlugin/jni/jni-bridge.cpp b/samples/BrowserPlugin/jni/jni-bridge.cpp index 02f768b34..9ba8a3215 100644 --- a/samples/BrowserPlugin/jni/jni-bridge.cpp +++ b/samples/BrowserPlugin/jni/jni-bridge.cpp @@ -23,72 +23,48 @@ #define EXPORT __attribute__((visibility("default"))) -static SurfaceSubPlugin* getPluginObject(int npp) { - NPP instance = (NPP)npp; - PluginObject* obj = static_cast(instance->pdata); - if (obj && obj->activePlugin - && obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)) { - return static_cast(obj->activePlugin); - } - return NULL; -} - -static jboolean javaInit(JNIEnv* env, jobject thiz, jint npp) { - SurfaceSubPlugin* obj = getPluginObject(npp); - - if (obj) { - jobject globalObject = env->NewGlobalRef(thiz); - obj->setJavaInterface(globalObject); - return true; - } else { - return false; - } -} +extern ANPEventInterfaceV0 gEventI; static void surfaceCreated(JNIEnv* env, jobject thiz, jint npp, jobject surface) { - SurfaceSubPlugin* obj = getPluginObject(npp); - jobject globalSurface = env->NewGlobalRef(surface); - obj->surfaceCreated(globalSurface); + + // send custom event + ANPEvent event; + event.inSize = sizeof(ANPEvent); + event.eventType = kCustom_ANPEventType; + event.data.other[0] = kSurfaceCreated_CustomEvent; + + gEventI.postEvent((NPP)npp, &event); } static void surfaceChanged(JNIEnv* env, jobject thiz, jint npp, jint format, jint width, jint height) { - SurfaceSubPlugin* obj = getPluginObject(npp); - obj->surfaceChanged(format, width, height); + // send custom event + ANPEvent event; + event.inSize = sizeof(ANPEvent); + event.eventType = kCustom_ANPEventType; + event.data.other[0] = kSurfaceChanged_CustomEvent; + event.data.other[1] = width; + event.data.other[2] = height; + + gEventI.postEvent((NPP)npp, &event); } static void surfaceDestroyed(JNIEnv* env, jobject thiz, jint npp) { - SurfaceSubPlugin* obj = getPluginObject(npp); - if (obj) { - obj->surfaceDestroyed(); - } -} + // send custom event + ANPEvent event; + event.inSize = sizeof(ANPEvent); + event.eventType = kCustom_ANPEventType; + event.data.other[0] = kSurfaceDestroyed_CustomEvent; -static jint getSurfaceWidth(JNIEnv* env, jobject thiz, jint npp) { - SurfaceSubPlugin* obj = getPluginObject(npp); - return obj->getPluginWidth(); -} - -static jint getSurfaceHeight(JNIEnv* env, jobject thiz, jint npp) { - SurfaceSubPlugin* obj = getPluginObject(npp); - return obj->getPluginHeight(); -} - -static jboolean isFixedSurface(JNIEnv* env, jobject thiz, jint npp) { - SurfaceSubPlugin* obj = getPluginObject(npp); - return obj->isFixedSurface(); + gEventI.postEvent((NPP)npp, &event); } /* * JNI registration. */ -static JNINativeMethod gJavaSamplePluginMethods[] = { - { "nativeJavaInit", "(I)Z", (void*) javaInit }, - { "nativeSurfaceCreated", "(ILandroid/view/View;)V", (void*) surfaceCreated }, +static JNINativeMethod gPaintSurfaceMethods[] = { + { "nativeSurfaceCreated", "(I)V", (void*) surfaceCreated }, { "nativeSurfaceChanged", "(IIII)V", (void*) surfaceChanged }, { "nativeSurfaceDestroyed", "(I)V", (void*) surfaceDestroyed }, - { "nativeGetSurfaceWidth", "(I)I", (void*) getSurfaceWidth }, - { "nativeGetSurfaceHeight", "(I)I", (void*) getSurfaceHeight }, - { "nativeIsFixedSurface", "(I)Z", (void*) isFixedSurface }, }; EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { @@ -99,8 +75,8 @@ EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { return -1; } - jniRegisterNativeMethods(env, "com/android/sampleplugin/SamplePlugin", - gJavaSamplePluginMethods, NELEM(gJavaSamplePluginMethods)); + jniRegisterNativeMethods(env, "com/android/sampleplugin/PaintSurface", + gPaintSurfaceMethods, NELEM(gPaintSurfaceMethods)); return JNI_VERSION_1_4; } diff --git a/samples/BrowserPlugin/jni/main.cpp b/samples/BrowserPlugin/jni/main.cpp index 85632e45d..35dd5d65a 100644 --- a/samples/BrowserPlugin/jni/main.cpp +++ b/samples/BrowserPlugin/jni/main.cpp @@ -68,6 +68,7 @@ EXPORT void NP_Shutdown(void); ANPAudioTrackInterfaceV0 gSoundI; ANPBitmapInterfaceV0 gBitmapI; ANPCanvasInterfaceV0 gCanvasI; +ANPEventInterfaceV0 gEventI; ANPLogInterfaceV0 gLogI; ANPPaintInterfaceV0 gPaintI; ANPPathInterfaceV0 gPathI; @@ -115,6 +116,7 @@ NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, { kAudioTrackInterfaceV0_ANPGetValue, sizeof(gSoundI), &gSoundI }, { kBitmapInterfaceV0_ANPGetValue, sizeof(gBitmapI), &gBitmapI }, { kCanvasInterfaceV0_ANPGetValue, sizeof(gCanvasI), &gCanvasI }, + { kEventInterfaceV0_ANPGetValue, sizeof(gEventI), &gEventI }, { kLogInterfaceV0_ANPGetValue, sizeof(gLogI), &gLogI }, { kPaintInterfaceV0_ANPGetValue, sizeof(gPaintI), &gPaintI }, { kPathInterfaceV0_ANPGetValue, sizeof(gPathI), &gPathI }, @@ -239,6 +241,22 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, return NPERR_GENERIC_ERROR; } + // if the plugin uses the surface drawing model then set the java context + if (model == kSurface_ANPDrawingModel) { + SurfaceSubPlugin* surfacePlugin = static_cast(obj->activePlugin); + + jobject context; + NPError err = browser->getvalue(instance, kJavaContext_ANPGetValue, + static_cast(&context)); + if (err) { + gLogI.log(kError_ANPLogType, "request context err: %d", err); + return err; + } + + surfacePlugin->setContext(context); + } + + return NPERR_NO_ERROR; } @@ -393,7 +411,7 @@ EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) { return NPERR_GENERIC_ERROR; } -NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) +NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value) { if (variable == NPPVpluginScriptableNPObject) { void **v = (void **)value; @@ -406,6 +424,24 @@ NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) return NPERR_NO_ERROR; } + if (variable == kJavaSurface_ANPGetValue) { + //get the surface sub-plugin + PluginObject* obj = static_cast(instance->pdata); + if (obj && obj->activePlugin) { + + if(obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)) { + SurfaceSubPlugin* plugin = static_cast(obj->activePlugin); + jobject* surface = static_cast(value); + *surface = plugin->getSurface(); + return NPERR_NO_ERROR; + } else { + gLogI.log(kError_ANPLogType, + "-- %p Tried to retrieve surface for non-surface plugin", + instance); + } + } + } + return NPERR_GENERIC_ERROR; } diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp index 42222228a..e478897d0 100644 --- a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp +++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp @@ -35,6 +35,7 @@ extern ANPCanvasInterfaceV0 gCanvasI; extern ANPPaintInterfaceV0 gPaintI; extern ANPPathInterfaceV0 gPathI; extern ANPSurfaceInterfaceV0 gSurfaceI; +extern ANPSystemInterfaceV0 gSystemI; extern ANPTypefaceInterfaceV0 gTypefaceI; /////////////////////////////////////////////////////////////////////////////// @@ -50,9 +51,6 @@ PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) { memset(&m_colorToggle, 0, sizeof(m_colorToggle)); memset(&m_clearSurface, 0, sizeof(m_clearSurface)); - // initialize the java interface - m_javaInterface = NULL; - // initialize the drawing surface m_surface = NULL; @@ -88,12 +86,9 @@ PaintPlugin::~PaintPlugin() { gPathI.deletePath(m_touchPath); gPaintI.deletePaint(m_paintSurface); gPaintI.deletePaint(m_paintButton); - setJavaInterface(NULL); - surfaceDestroyed(); -} -bool PaintPlugin::supportsDrawingModel(ANPDrawingModel model) { - return (model == kSurface_ANPDrawingModel); + setContext(NULL); + destroySurface(); } ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) { @@ -215,29 +210,51 @@ const char* PaintPlugin::getColorText() { return "Red"; } -bool PaintPlugin::isFixedSurface() { - return true; -} +jobject PaintPlugin::getSurface() { + if (m_surface) { + return m_surface; + } -void PaintPlugin::surfaceCreated(jobject surface) { - m_surface = surface; - drawCleanPlugin(); -} + // load the appropriate java class and instantiate it + JNIEnv* env = NULL; + if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { + gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env"); + return NULL; + } + + const char* className = "com.android.sampleplugin.PaintSurface"; + jclass paintClass = gSystemI.loadJavaClass(inst(), className); + + if(!paintClass) { + gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class"); + return NULL; + } -void PaintPlugin::surfaceChanged(int format, int width, int height) { - // get the plugin's dimensions according to the DOM PluginObject *obj = (PluginObject*) inst()->pdata; const int pW = obj->window->width; const int pH = obj->window->height; - // compare to the plugin's surface dimensions - if (pW != width || pH != height) - gLogI.log(kError_ANPLogType, - "----%p Invalid Surface Dimensions (%d,%d):(%d,%d)", - inst(), pW, pH, width, height); + + jmethodID constructor = env->GetMethodID(paintClass, "", "(Landroid/content/Context;III)V"); + jobject paintSurface = env->NewObject(paintClass, constructor, m_context, (int)inst(), pW, pH); + + if(!paintSurface) { + gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object"); + return NULL; + } + + m_surface = env->NewGlobalRef(paintSurface); + return m_surface; } -void PaintPlugin::surfaceDestroyed() { + +void PaintPlugin::destroySurface() { JNIEnv* env = NULL; if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { + + // detach the native code from the object + jclass javaClass = env->GetObjectClass(m_surface); + jmethodID invalMethod = env->GetMethodID(javaClass, "invalidateNPP", "()V"); + env->CallVoidMethod(m_surface, invalMethod); + env->DeleteGlobalRef(m_surface); m_surface = NULL; } @@ -294,6 +311,35 @@ int16 PaintPlugin::handleEvent(const ANPEvent* evt) { } return 1; } + case kCustom_ANPEventType: { + + switch (evt->data.other[0]) { + case kSurfaceCreated_CustomEvent: + gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceCreated"); + drawCleanPlugin(); + break; + case kSurfaceChanged_CustomEvent: { + gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceChanged"); + + int width = evt->data.other[1]; + int height = evt->data.other[2]; + + PluginObject *obj = (PluginObject*) inst()->pdata; + const int pW = obj->window->width; + const int pH = obj->window->height; + // compare to the plugin's surface dimensions + if (pW != width || pH != height) + gLogI.log(kError_ANPLogType, + "----%p Invalid Surface Dimensions (%d,%d):(%d,%d)", + inst(), pW, pH, width, height); + break; + } + case kSurfaceDestroyed_CustomEvent: + gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceDestroyed"); + break; + } + break; // end KCustom_ANPEventType + } default: break; } diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.h b/samples/BrowserPlugin/jni/paint/PaintPlugin.h index a917ffb27..4867a706a 100644 --- a/samples/BrowserPlugin/jni/paint/PaintPlugin.h +++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.h @@ -33,18 +33,15 @@ class PaintPlugin : public SurfaceSubPlugin { public: PaintPlugin(NPP inst); virtual ~PaintPlugin(); - virtual bool supportsDrawingModel(ANPDrawingModel); virtual int16 handleEvent(const ANPEvent* evt); - virtual void surfaceCreated(jobject surface); - virtual void surfaceChanged(int format, int width, int height); - virtual void surfaceDestroyed(); - virtual bool isFixedSurface(); + virtual jobject getSurface(); private: void drawCleanPlugin(ANPCanvas* canvas = NULL); ANPCanvas* getCanvas(ANPRectI* dirtyRect = NULL); ANPCanvas* getCanvas(ANPRectF* dirtyRect); const char* getColorText(); + void destroySurface(); void paintMouse(int x, int y); void paintTouch(); void releaseCanvas(ANPCanvas*); diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp index f6608d6b0..f24295ba7 100644 --- a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp +++ b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp @@ -38,6 +38,7 @@ extern ANPCanvasInterfaceV0 gCanvasI; extern ANPLogInterfaceV0 gLogI; extern ANPPaintInterfaceV0 gPaintI; extern ANPSurfaceInterfaceV0 gSurfaceI; +extern ANPSystemInterfaceV0 gSystemI; extern ANPTypefaceInterfaceV0 gTypefaceI; extern ANPWindowInterfaceV0 gWindowI; @@ -45,9 +46,6 @@ extern ANPWindowInterfaceV0 gWindowI; VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) { - // initialize the java interface - m_javaInterface = NULL; - // initialize the drawing surface m_surface = NULL; @@ -60,30 +58,44 @@ VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) { } VideoPlugin::~VideoPlugin() { - setJavaInterface(NULL); - surfaceDestroyed(); + setContext(NULL); + destroySurface(); } -bool VideoPlugin::supportsDrawingModel(ANPDrawingModel model) { - return (model == kSurface_ANPDrawingModel); +jobject VideoPlugin::getSurface() { + + if (m_surface) { + return m_surface; + } + + // load the appropriate java class and instantiate it + JNIEnv* env = NULL; + if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { + gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env"); + return NULL; + } + + const char* className = "com.android.sampleplugin.VideoSurface"; + jclass videoClass = gSystemI.loadJavaClass(inst(), className); + + if(!videoClass) { + gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class"); + return NULL; + } + + jmethodID constructor = env->GetMethodID(videoClass, "", "(Landroid/content/Context;)V"); + jobject videoSurface = env->NewObject(videoClass, constructor, m_context); + + if(!videoSurface) { + gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object"); + return NULL; + } + + m_surface = env->NewGlobalRef(videoSurface); + return m_surface; } -bool VideoPlugin::isFixedSurface() { - return true; -} - -void VideoPlugin::surfaceCreated(jobject surface) { - m_surface = surface; - drawPlugin(); -} - -void VideoPlugin::surfaceChanged(int format, int width, int height) { - gLogI.log(kDebug_ANPLogType, "----%p SurfaceChanged Event: %d", - inst(), format); - drawPlugin(); -} - -void VideoPlugin::surfaceDestroyed() { +void VideoPlugin::destroySurface() { JNIEnv* env = NULL; if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { env->DeleteGlobalRef(m_surface); @@ -91,59 +103,19 @@ void VideoPlugin::surfaceDestroyed() { } } -void VideoPlugin::drawPlugin() { - - ANPBitmap bitmap; - JNIEnv* env = NULL; - if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK || - !gSurfaceI.lock(env, m_surface, &bitmap, NULL)) { - gLogI.log(kError_ANPLogType, "----%p Unable to Lock Surface", inst()); - return; - } - - ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap); - - // get the plugin's dimensions according to the DOM - PluginObject *obj = (PluginObject*) inst()->pdata; - const int pW = obj->window->width; - const int pH = obj->window->height; - - // compare DOM dimensions to the plugin's surface dimensions - if (pW != bitmap.width || pH != bitmap.height) - gLogI.log(kError_ANPLogType, - "----%p Invalid Surface Dimensions (%d,%d):(%d,%d)", - inst(), pW, pH, bitmap.width, bitmap.height); - - // set constants - const int fontSize = 16; - const int leftMargin = 10; - - gCanvasI.drawColor(canvas, 0xFFCDCDCD); - - ANPPaint* paint = gPaintI.newPaint(); - gPaintI.setFlags(paint, gPaintI.getFlags(paint) | kAntiAlias_ANPPaintFlag); - gPaintI.setColor(paint, 0xFFFF0000); - gPaintI.setTextSize(paint, fontSize); - - ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle); - gPaintI.setTypeface(paint, tf); - gTypefaceI.unref(tf); - - ANPFontMetrics fm; - gPaintI.getFontMetrics(paint, &fm); - - gPaintI.setColor(paint, 0xFF0000FF); - const char c[] = "Touch anywhere on the plugin to begin video playback!"; - gCanvasI.drawText(canvas, c, sizeof(c)-1, leftMargin, -fm.fTop, paint); - - // clean up variables and unlock the surface - gPaintI.deletePaint(paint); - gCanvasI.deleteCanvas(canvas); - gSurfaceI.unlock(env, m_surface); -} - int16 VideoPlugin::handleEvent(const ANPEvent* evt) { switch (evt->eventType) { + case kLifecycle_ANPEventType: { + switch (evt->data.lifecycle.action) { + case kEnterFullScreen_ANPLifecycleAction: + gLogI.log(kDebug_ANPLogType, " ---- %p entering fullscreen", inst()); + break; + case kExitFullScreen_ANPLifecycleAction: + gLogI.log(kDebug_ANPLogType, " ---- %p exiting fullscreen", inst()); + break; + } + break; // end kLifecycle_ANPEventType + } case kDraw_ANPEventType: gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request draw events", inst()); break; diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.h b/samples/BrowserPlugin/jni/video/VideoPlugin.h index dd6859d27..701e2d0c8 100644 --- a/samples/BrowserPlugin/jni/video/VideoPlugin.h +++ b/samples/BrowserPlugin/jni/video/VideoPlugin.h @@ -32,15 +32,11 @@ class VideoPlugin : public SurfaceSubPlugin { public: VideoPlugin(NPP inst); virtual ~VideoPlugin(); - virtual bool supportsDrawingModel(ANPDrawingModel); virtual int16 handleEvent(const ANPEvent* evt); - virtual void surfaceCreated(jobject surface); - virtual void surfaceChanged(int format, int width, int height); - virtual void surfaceDestroyed(); - virtual bool isFixedSurface(); + virtual jobject getSurface(); private: - void drawPlugin(); + void destroySurface(); jobject m_surface; }; diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundSurface.java b/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundSurface.java new file mode 100644 index 000000000..5af8c8e24 --- /dev/null +++ b/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundSurface.java @@ -0,0 +1,19 @@ +package com.android.sampleplugin; + +import android.content.Context; +import android.graphics.Color; +import android.widget.TextView; + +public class BackgroundSurface extends TextView { + + public BackgroundSurface(Context context) { + super(context); + + this.setBackgroundColor(Color.BLACK); + this.setTextColor(Color.WHITE); + this.setText("This is a java background plugin"); + + // ensure that the view system is aware that we will be drawing + this.setWillNotDraw(false); + } +} diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/PaintSurface.java b/samples/BrowserPlugin/src/com/android/sampleplugin/PaintSurface.java new file mode 100644 index 000000000..9582bccd9 --- /dev/null +++ b/samples/BrowserPlugin/src/com/android/sampleplugin/PaintSurface.java @@ -0,0 +1,95 @@ +/* + * Copyright 2009, 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 THE COPYRIGHT OWNER 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. + */ +package com.android.sampleplugin; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.SurfaceHolder.Callback; + +public class PaintSurface extends SurfaceView { + + static { + //needed for jni calls + System.loadLibrary("sampleplugin"); + } + + private final int npp; + + private boolean validNPP = true; + private Object nppLock = new Object(); + + public PaintSurface(Context context, int NPP, int width, int height) { + super(context); + + this.npp = NPP; + + this.getHolder().setFormat(PixelFormat.RGBA_8888); + this.getHolder().addCallback(new Callback() { + + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + synchronized (nppLock) { + if (validNPP) { + nativeSurfaceChanged(npp, format, width, height); + } + } + } + + public void surfaceCreated(SurfaceHolder holder) { + synchronized (nppLock) { + if (validNPP) { + nativeSurfaceCreated(npp); + } + } + } + + public void surfaceDestroyed(SurfaceHolder holder) { + synchronized (nppLock) { + if (validNPP) { + nativeSurfaceDestroyed(npp); + } + } + } + }); + + // sets the plugin's surface to a fixed size + this.getHolder().setFixedSize(width, height); + + // ensure that the view system is aware that we will be drawing + this.setWillNotDraw(false); + } + + // called by JNI + private void invalidateNPP() { + synchronized (nppLock) { + validNPP = false; + } + } + + private native void nativeSurfaceCreated(int npp); + private native void nativeSurfaceChanged(int npp, int format, int width, int height); + private native void nativeSurfaceDestroyed(int npp); +} diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java b/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java index 2cfb5255b..5bec1c6ac 100644 --- a/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java +++ b/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java @@ -24,161 +24,14 @@ */ package com.android.sampleplugin; -import com.android.sampleplugin.graphics.CubeRenderer; +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; -import android.content.Context; -import android.graphics.PixelFormat; -import android.opengl.GLSurfaceView; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.View; -import android.view.WindowManager; -import android.view.SurfaceHolder.Callback; -import android.view.ViewGroup.LayoutParams; -import android.webkit.plugin.NativePlugin; -import android.webkit.plugin.SurfaceDrawingModel; -import android.widget.FrameLayout; -import android.widget.MediaController; -import android.widget.VideoView; +public class SamplePlugin extends Service { -public class SamplePlugin implements NativePlugin { - - static { - //needed for jni calls - System.loadLibrary("sampleplugin"); - } - - private int npp; - private Context context; - - private SurfaceDrawingModel embeddedSurface; - private SurfaceDrawingModel fullScreenSurface; - - private boolean validNPP = false; - private Object nppLock = new Object(); - - public void initializePlugin(int npp, Context context) { - this.npp = npp; - this.context = context; - this.validNPP = nativeJavaInit(npp); - } - - public SurfaceDrawingModel getEmbeddedSurface() { - if (embeddedSurface == null) { - embeddedSurface = new EmbeddedSurface(); - } - return embeddedSurface; - } - - public SurfaceDrawingModel getFullScreenSurface() { - if (fullScreenSurface == null) { - fullScreenSurface = new FullScreenSurface(); - } - return fullScreenSurface; - } - - // called by JNI - private void invalidateNPP() { - synchronized (nppLock) { - validNPP = false; - } - } - - private native boolean nativeJavaInit(int npp); - 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 int nativeGetSurfaceWidth(int npp); - private native int nativeGetSurfaceHeight(int npp); - private native boolean nativeIsFixedSurface(int npp); - - private class EmbeddedSurface implements SurfaceDrawingModel { - - public View getSurface() { - 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) { - synchronized (nppLock) { - if (validNPP) { - nativeSurfaceChanged(npp, format, width, height); - } - } - } - - public void surfaceCreated(SurfaceHolder holder) { - synchronized (nppLock) { - if (validNPP) { - nativeSurfaceCreated(npp, view); - } - } - } - - public void surfaceDestroyed(SurfaceHolder holder) { - synchronized (nppLock) { - if (validNPP) { - nativeSurfaceDestroyed(npp); - } - } - } - }); - - // TODO provide way for native plugin code to reset the size - if (nativeIsFixedSurface(npp)) { - int width = nativeGetSurfaceWidth(npp); - int height = nativeGetSurfaceHeight(npp); - view.getHolder().setFixedSize(width, height); - } - - // ensure that the view system is aware that we will be drawing - view.setWillNotDraw(false); - - return view; - } - } - - private class FullScreenSurface implements SurfaceDrawingModel { - - public View getSurface() { - /* TODO make this aware of the plugin instance and get the video file - * from the plugin. - */ - - FrameLayout layout = new FrameLayout(context); - LayoutParams fp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); - layout.setLayoutParams(fp); - -// VideoView video = new VideoView(context); -// LayoutParams vp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); -// layout.setLayoutParams(vp); - - GLSurfaceView gl = new GLSurfaceView(context); - LayoutParams gp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); - layout.setLayoutParams(gp); - - layout.addView(gl); -// layout.addView(video); - - // Tell the cube renderer that we want to render a translucent version - // of the cube: - gl.setRenderer(new CubeRenderer(false)); - gl.setWindowType(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY); - -// video.setVideoPath("/sdcard/test_video.3gp"); -// video.setMediaController(new MediaController(context)); -// video.requestFocus(); - - // ensure that the view system is aware that we will be drawing - layout.setWillNotDraw(false); - - return layout; - } - } -} + @Override + public IBinder onBind(Intent intent) { + // TODO Auto-generated method stub + return null; + }} diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/VideoSurface.java b/samples/BrowserPlugin/src/com/android/sampleplugin/VideoSurface.java new file mode 100644 index 000000000..a3c80cfa7 --- /dev/null +++ b/samples/BrowserPlugin/src/com/android/sampleplugin/VideoSurface.java @@ -0,0 +1,67 @@ +/* + * Copyright 2009, 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 THE COPYRIGHT OWNER 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. + */ +package com.android.sampleplugin; + +import com.android.sampleplugin.graphics.CubeRenderer; + +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.view.WindowManager; +import android.widget.FrameLayout; +import android.widget.MediaController; +import android.widget.VideoView; + +public class VideoSurface extends FrameLayout { + + public VideoSurface(Context context) { + super(context); + + LayoutParams fp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); + this.setLayoutParams(fp); + +// VideoView video = new VideoView(context); +// LayoutParams vp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); +// vp.setLayoutParams(vp); + + GLSurfaceView gl = new GLSurfaceView(context); + LayoutParams gp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); + gl.setLayoutParams(gp); + + this.addView(gl); +// this.addView(video); + + // Tell the cube renderer that we want to render a translucent version + // of the cube: + gl.setRenderer(new CubeRenderer(false)); + gl.setWindowType(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY); + +// video.setVideoPath("/sdcard/test_video.3gp"); +// video.setMediaController(new MediaController(context)); +// video.requestFocus(); + + // ensure that the view system is aware that we will be drawing + this.setWillNotDraw(false); + } +}