From b8947eee3405616e00b1e4b70ae8bb97ac0e1d17 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Mon, 5 Oct 2009 14:40:18 -0400 Subject: [PATCH] Adding a full screen video sample plugin. Also cleaned up surface plugins to use the provided JavaVM. --- samples/BrowserPlugin/jni/Android.mk | 2 + samples/BrowserPlugin/jni/PluginObject.h | 3 +- .../jni/background/BackgroundPlugin.cpp | 14 +- .../jni/background/BackgroundPlugin.h | 3 +- samples/BrowserPlugin/jni/hello-jni.cpp | 48 ------ samples/BrowserPlugin/jni/jni-bridge.cpp | 8 +- samples/BrowserPlugin/jni/main.cpp | 11 ++ samples/BrowserPlugin/jni/main.h | 1 + .../BrowserPlugin/jni/paint/PaintPlugin.cpp | 12 +- samples/BrowserPlugin/jni/paint/PaintPlugin.h | 3 +- .../BrowserPlugin/jni/video/VideoPlugin.cpp | 159 ++++++++++++++++++ samples/BrowserPlugin/jni/video/VideoPlugin.h | 48 ++++++ 12 files changed, 239 insertions(+), 73 deletions(-) delete mode 100644 samples/BrowserPlugin/jni/hello-jni.cpp create mode 100644 samples/BrowserPlugin/jni/video/VideoPlugin.cpp create mode 100644 samples/BrowserPlugin/jni/video/VideoPlugin.h diff --git a/samples/BrowserPlugin/jni/Android.mk b/samples/BrowserPlugin/jni/Android.mk index cbd8a157d..b93e4a61f 100644 --- a/samples/BrowserPlugin/jni/Android.mk +++ b/samples/BrowserPlugin/jni/Android.mk @@ -35,6 +35,7 @@ LOCAL_SRC_FILES := \ background/BackgroundPlugin.cpp \ form/FormPlugin.cpp \ paint/PaintPlugin.cpp \ + video/VideoPlugin.cpp \ jni-bridge.cpp \ LOCAL_C_INCLUDES += \ @@ -45,6 +46,7 @@ LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/background \ $(LOCAL_PATH)/form \ $(LOCAL_PATH)/paint \ + $(LOCAL_PATH)/video \ external/webkit/WebCore/bridge \ external/webkit/WebCore/plugins \ external/webkit/WebCore/platform/android/JavaVM \ diff --git a/samples/BrowserPlugin/jni/PluginObject.h b/samples/BrowserPlugin/jni/PluginObject.h index 61486d599..deb60eabc 100644 --- a/samples/BrowserPlugin/jni/PluginObject.h +++ b/samples/BrowserPlugin/jni/PluginObject.h @@ -55,7 +55,7 @@ public: SurfaceSubPlugin(NPP inst) : SubPlugin(inst) {} virtual ~SurfaceSubPlugin() {} virtual bool isFixedSurface() = 0; - virtual void surfaceCreated(JNIEnv*, jobject) = 0; + virtual void surfaceCreated(jobject) = 0; virtual void surfaceChanged(int format, int width, int height) = 0; virtual void surfaceDestroyed() = 0; }; @@ -67,6 +67,7 @@ enum PluginTypes { kForm_PluginType = 4, kText_PluginType = 5, kPaint_PluginType = 6, + kVideo_PluginType = 7, }; typedef uint32_t PluginType; diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp index 2a65b4f60..af518a9a8 100644 --- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp +++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp @@ -54,7 +54,6 @@ BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) { // initialize the drawing surface m_surface = NULL; - m_vm = NULL; //initialize bitmap transparency variables mFinishedStageOne = false; @@ -69,7 +68,9 @@ BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) { test_javascript(); } -BackgroundPlugin::~BackgroundPlugin() { } +BackgroundPlugin::~BackgroundPlugin() { + surfaceDestroyed(); +} bool BackgroundPlugin::supportsDrawingModel(ANPDrawingModel model) { return (model == kSurface_ANPDrawingModel); @@ -79,9 +80,8 @@ bool BackgroundPlugin::isFixedSurface() { return false; } -void BackgroundPlugin::surfaceCreated(JNIEnv* env, jobject surface) { - env->GetJavaVM(&m_vm); - m_surface = env->NewGlobalRef(surface); +void BackgroundPlugin::surfaceCreated(jobject surface) { + m_surface = surface; } void BackgroundPlugin::surfaceChanged(int format, int width, int height) { @@ -90,7 +90,7 @@ void BackgroundPlugin::surfaceChanged(int format, int width, int height) { void BackgroundPlugin::surfaceDestroyed() { JNIEnv* env = NULL; - if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { + if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { env->DeleteGlobalRef(m_surface); m_surface = NULL; } @@ -119,7 +119,7 @@ void BackgroundPlugin::drawPlugin(int surfaceWidth, int surfaceHeight) { // lock the surface ANPBitmap bitmap; JNIEnv* env = NULL; - if (!m_surface || m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK || + if (!m_surface || gVM->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()); return; diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h index 3b9c7baff..d37081095 100644 --- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h +++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h @@ -34,7 +34,7 @@ public: virtual ~BackgroundPlugin(); virtual bool supportsDrawingModel(ANPDrawingModel); virtual int16 handleEvent(const ANPEvent* evt); - virtual void surfaceCreated(JNIEnv* env, jobject surface); + virtual void surfaceCreated(jobject surface); virtual void surfaceChanged(int format, int width, int height); virtual void surfaceDestroyed(); virtual bool isFixedSurface(); @@ -55,7 +55,6 @@ private: void drawPlugin(int surfaceWidth, int surfaceHeight); jobject m_surface; - JavaVM* m_vm; void test_logging(); void test_timers(); diff --git a/samples/BrowserPlugin/jni/hello-jni.cpp b/samples/BrowserPlugin/jni/hello-jni.cpp deleted file mode 100644 index 0789b7e18..000000000 --- a/samples/BrowserPlugin/jni/hello-jni.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 -#include -#include -#include - -#define EXPORT __attribute__((visibility("default"))) - -static jstring stringFromJNI( JNIEnv* env, jobject thiz ) -{ - return env->NewStringUTF("Hello from JNI !"); -} - -/* - * JNI registration. - */ -static JNINativeMethod gJavaSamplePluginStubMethods[] = { - { "nativeStringFromJNI", "()Ljava/lang/String;", (void*) stringFromJNI }, -}; - -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; -} diff --git a/samples/BrowserPlugin/jni/jni-bridge.cpp b/samples/BrowserPlugin/jni/jni-bridge.cpp index 45ecd544c..22e76dab2 100644 --- a/samples/BrowserPlugin/jni/jni-bridge.cpp +++ b/samples/BrowserPlugin/jni/jni-bridge.cpp @@ -35,12 +35,8 @@ static SurfaceSubPlugin* getPluginObject(int npp) { 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); + jobject globalSurface = env->NewGlobalRef(surface); + obj->surfaceCreated(globalSurface); } static void surfaceChanged(JNIEnv* env, jobject thiz, jint npp, jint format, jint width, jint height) { diff --git a/samples/BrowserPlugin/jni/main.cpp b/samples/BrowserPlugin/jni/main.cpp index d00091faf..6f0ed96ab 100644 --- a/samples/BrowserPlugin/jni/main.cpp +++ b/samples/BrowserPlugin/jni/main.cpp @@ -33,8 +33,11 @@ #include "BackgroundPlugin.h" #include "FormPlugin.h" #include "PaintPlugin.h" +#include "VideoPlugin.h" NPNetscapeFuncs* browser; +JavaVM* gVM; + #define EXPORT __attribute__((visibility("default"))) NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, @@ -128,6 +131,10 @@ NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, } } + // store the JavaVM for the plugin + JNIEnv* env = (JNIEnv*)java_env; + env->GetJavaVM(&gVM); + return NPERR_NO_ERROR; } @@ -220,6 +227,10 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, obj->pluginType = kPaint_PluginType; obj->activePlugin = new PaintPlugin(instance); } + else if (!strcmp(argv[i], "Video")) { + obj->pluginType = kVideo_PluginType; + obj->activePlugin = new VideoPlugin(instance); + } gLogI.log(instance, kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType); break; } diff --git a/samples/BrowserPlugin/jni/main.h b/samples/BrowserPlugin/jni/main.h index 8ad2cce9b..5906b0b89 100644 --- a/samples/BrowserPlugin/jni/main.h +++ b/samples/BrowserPlugin/jni/main.h @@ -30,3 +30,4 @@ #include "ANPSurface_npapi.h" extern NPNetscapeFuncs* browser; +extern JavaVM* gVM; diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp index 5b00dbaed..11f00fee1 100644 --- a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp +++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp @@ -52,7 +52,6 @@ PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) { // initialize the drawing surface m_surface = NULL; - m_vm = NULL; // initialize the path m_touchPath = gPathI.newPath(); @@ -97,7 +96,7 @@ ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) { ANPBitmap bitmap; JNIEnv* env = NULL; - if (!m_surface || m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK || + if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK || !gSurfaceI.lock(env, m_surface, &bitmap, dirtyRect)) { return NULL; } @@ -132,7 +131,7 @@ ANPCanvas* PaintPlugin::getCanvas(ANPRectF* dirtyRect) { void PaintPlugin::releaseCanvas(ANPCanvas* canvas) { JNIEnv* env = NULL; - if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { + if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { gSurfaceI.unlock(env, m_surface); } gCanvasI.deleteCanvas(canvas); @@ -216,9 +215,8 @@ bool PaintPlugin::isFixedSurface() { return true; } -void PaintPlugin::surfaceCreated(JNIEnv* env, jobject surface) { - env->GetJavaVM(&m_vm); - m_surface = env->NewGlobalRef(surface); +void PaintPlugin::surfaceCreated(jobject surface) { + m_surface = surface; drawCleanPlugin(); } @@ -235,7 +233,7 @@ void PaintPlugin::surfaceChanged(int format, int width, int height) { } void PaintPlugin::surfaceDestroyed() { JNIEnv* env = NULL; - if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { + if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { env->DeleteGlobalRef(m_surface); m_surface = NULL; } diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.h b/samples/BrowserPlugin/jni/paint/PaintPlugin.h index 8ff561c49..a917ffb27 100644 --- a/samples/BrowserPlugin/jni/paint/PaintPlugin.h +++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.h @@ -35,7 +35,7 @@ public: virtual ~PaintPlugin(); virtual bool supportsDrawingModel(ANPDrawingModel); virtual int16 handleEvent(const ANPEvent* evt); - virtual void surfaceCreated(JNIEnv* env, jobject surface); + virtual void surfaceCreated(jobject surface); virtual void surfaceChanged(int format, int width, int height); virtual void surfaceDestroyed(); virtual bool isFixedSurface(); @@ -55,7 +55,6 @@ private: bool m_isTouchActive; bool m_isTouchCurrentInput; - JavaVM* m_vm; jobject m_surface; ANPPath* m_touchPath; diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp new file mode 100644 index 000000000..2609af67c --- /dev/null +++ b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp @@ -0,0 +1,159 @@ +/* + * 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 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 "VideoPlugin.h" +#include "android_npapi.h" + +#include +#include +#include +#include +#include + +extern NPNetscapeFuncs* browser; +extern ANPBitmapInterfaceV0 gBitmapI; +extern ANPCanvasInterfaceV0 gCanvasI; +extern ANPLogInterfaceV0 gLogI; +extern ANPPaintInterfaceV0 gPaintI; +extern ANPSurfaceInterfaceV0 gSurfaceI; +extern ANPTypefaceInterfaceV0 gTypefaceI; +extern ANPWindowInterfaceV0 gWindowI; + +/////////////////////////////////////////////////////////////////////////////// + +VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) { + + // initialize the drawing surface + m_surface = NULL; + + //register for touch events + ANPEventFlags flags = kTouch_ANPEventFlag; + NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags); + if (err != NPERR_NO_ERROR) { + gLogI.log(inst, kError_ANPLogType, "Error selecting input events."); + } +} + +VideoPlugin::~VideoPlugin() { + surfaceDestroyed(); +} + +bool VideoPlugin::supportsDrawingModel(ANPDrawingModel model) { + return (model == kSurface_ANPDrawingModel); +} + +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(inst(), kDebug_ANPLogType, "----%p SurfaceChanged Event: %d", + inst(), format); + drawPlugin(); +} + +void VideoPlugin::surfaceDestroyed() { + JNIEnv* env = NULL; + if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { + env->DeleteGlobalRef(m_surface); + m_surface = NULL; + } +} + +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(inst(), 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(inst(), 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 kDraw_ANPEventType: + gLogI.log(inst(), kError_ANPLogType, " ------ %p the plugin did not request draw events", inst()); + break; + case kTouch_ANPEventType: + if (kDown_ANPTouchAction == evt->data.touch.action) { + gLogI.log(inst(), kDebug_ANPLogType, " ------ %p requesting fullscreen mode", inst()); + gWindowI.requestFullScreen(inst()); + } + return 1; + case kKey_ANPEventType: + gLogI.log(inst(), kError_ANPLogType, " ------ %p the plugin did not request key events", inst()); + break; + default: + break; + } + return 0; // unknown or unhandled event +} diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.h b/samples/BrowserPlugin/jni/video/VideoPlugin.h new file mode 100644 index 000000000..dd6859d27 --- /dev/null +++ b/samples/BrowserPlugin/jni/video/VideoPlugin.h @@ -0,0 +1,48 @@ +/* + * 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 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 videoPlugin__DEFINED +#define videoPlugin__DEFINED + +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(); + +private: + void drawPlugin(); + + jobject m_surface; +}; + +#endif // videoPlugin__DEFINED