OSDN Git Service

Add Plugin APIs for creating and manipulating a Surface.
authorPatrick Scott <phanna@android.com>
Fri, 17 Jul 2009 20:40:38 +0000 (16:40 -0400)
committerPatrick Scott <phanna@android.com>
Mon, 20 Jul 2009 15:01:37 +0000 (11:01 -0400)
SurfaceCallback: An interface used to receive the surface change events. The
PluginSurface then sends those events to the actual plugin.

PluginSurface: A wrapper around the native Surface object obtained from the Java
SurfaceView. This object can lock and unlock the surface and takes care of
creating, positioning and destroying the Java SurfaceView.

Changed PluginWidgetAndroid to not use SkFlipPixelRef when the drawing model is
Surface.

WebKit/Android.mk
WebKit/android/jni/WebViewCore.cpp
WebKit/android/jni/WebViewCore.h
WebKit/android/plugins/ANPSurfaceInterface.cpp
WebKit/android/plugins/PluginSurface.cpp [new file with mode: 0644]
WebKit/android/plugins/PluginSurface.h [new file with mode: 0644]
WebKit/android/plugins/PluginWidgetAndroid.cpp
WebKit/android/plugins/PluginWidgetAndroid.h
WebKit/android/plugins/SurfaceCallback.h [new file with mode: 0644]
WebKit/android/plugins/android_npapi.h

index 4fff70e..5e79d5a 100644 (file)
@@ -62,8 +62,9 @@ LOCAL_SRC_FILES := \
        android/plugins/ANPPathInterface.cpp \
        android/plugins/ANPSoundInterface.cpp \
        android/plugins/ANPSurfaceInterface.cpp \
-        android/plugins/ANPTypefaceInterface.cpp \
+       android/plugins/ANPTypefaceInterface.cpp \
        android/plugins/ANPWindowInterface.cpp \
+       android/plugins/PluginSurface.cpp \
        android/plugins/PluginTimer.cpp \
        android/plugins/PluginViewBridgeAndroid.cpp \
        android/plugins/PluginWidgetAndroid.cpp \
index f88b1d2..d304e79 100644 (file)
@@ -88,6 +88,7 @@
 #include "SkCanvas.h"
 #include "SkPicture.h"
 #include "SkUtils.h"
+#include "SurfaceCallback.h"
 #include "StringImpl.h"
 #include "Text.h"
 #include "TypingCommand.h"
@@ -176,6 +177,9 @@ struct WebViewCore::JavaGlue {
     jmethodID   m_requestKeyboard;
     jmethodID   m_exceededDatabaseQuota;
     jmethodID   m_addMessageToConsole;
+    jmethodID   m_createSurface;
+    jmethodID   m_destroySurface;
+    jmethodID   m_attachSurface;
     AutoJObject object(JNIEnv* env) {
         return getRealObject(env, m_obj);
     }
@@ -241,6 +245,9 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
     m_javaGlue->m_requestKeyboard = GetJMethod(env, clazz, "requestKeyboard", "(Z)V");
     m_javaGlue->m_exceededDatabaseQuota = GetJMethod(env, clazz, "exceededDatabaseQuota", "(Ljava/lang/String;Ljava/lang/String;J)V");
     m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;)V");
+    m_javaGlue->m_createSurface = GetJMethod(env, clazz, "createSurface", "(I)Landroid/view/SurfaceView;");
+    m_javaGlue->m_destroySurface = GetJMethod(env, clazz, "destroySurface", "(Landroid/view/SurfaceView;)V");
+    m_javaGlue->m_attachSurface = GetJMethod(env, clazz, "attachSurface", "(Landroid/view/SurfaceView;IIII)V");
 
     env->SetIntField(javaWebViewCore, gWebViewCoreFields.m_nativeClass, (jint)this);
 
@@ -2021,6 +2028,32 @@ void WebViewCore::setBackgroundColor(SkColor c)
     view->setBaseBackgroundColor(bcolor);
 }
 
+jobject WebViewCore::createSurface(SurfaceCallback* cb)
+{
+    JNIEnv* env = JSC::Bindings::getJNIEnv();
+    jobject surface = env->CallObjectMethod(m_javaGlue->object(env).get(),
+            m_javaGlue->m_createSurface, (int) cb);
+    checkException(env);
+    return surface;
+}
+
+void WebViewCore::destroySurface(jobject surface)
+{
+    JNIEnv* env = JSC::Bindings::getJNIEnv();
+    env->CallVoidMethod(m_javaGlue->object(env).get(),
+            m_javaGlue->m_destroySurface, surface);
+    checkException(env);
+}
+
+void WebViewCore::attachSurface(jobject surface, int x, int y, int width,
+        int height)
+{
+    JNIEnv* env = JSC::Bindings::getJNIEnv();
+    env->CallVoidMethod(m_javaGlue->object(env).get(),
+            m_javaGlue->m_attachSurface, surface, x, y, width, height);
+    checkException(env);
+}
+
 //----------------------------------------------------------------------
 // Native JNI methods
 //----------------------------------------------------------------------
@@ -2503,6 +2536,28 @@ static void UpdatePluginState(JNIEnv* env, jobject obj, jint framePtr, jint node
                                 (PluginState) state);
 }
 
+static void SurfaceChanged(JNIEnv* env, jobject obj, jint pointer, jint state,
+        jint format, jint width, jint height)
+{
+    // Be safe and check for a valid callback
+    if (!pointer)
+        return;
+    SurfaceCallback* cb = reinterpret_cast<SurfaceCallback*>(pointer);
+    switch (state) {
+        case 0:
+            cb->surfaceCreated();
+            break;
+        case 1:
+            cb->surfaceChanged(format, width, height);
+            break;
+        case 2:
+            cb->surfaceDestroyed();
+            break;
+        default:
+            break;
+    }
+}
+
 static void Pause(JNIEnv* env, jobject obj)
 {
     ANPEvent event;
@@ -2607,6 +2662,8 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
         (void*) DumpNavTree },
     { "nativeSetDatabaseQuota", "(J)V",
         (void*) SetDatabaseQuota },
+    { "nativeSurfaceChanged", "(IIIII)V",
+        (void*) SurfaceChanged },
     { "nativePause", "()V", (void*) Pause },
     { "nativeResume", "()V", (void*) Resume },
     { "nativeFreeMemory", "()V", (void*) FreeMemory },
index 2af849f..62189bd 100644 (file)
@@ -67,6 +67,7 @@ namespace android {
 
     class CachedRoot;
     class ListBoxReply;
+    class SurfaceCallback;
 
     class WebCoreReply : public WebCoreRefObject {
     public:
@@ -313,6 +314,15 @@ namespace android {
         // Notify the Java side that webkit is requesting a keyboard
         void requestKeyboard(bool);
 
+        // Creates a SurfaceView for a plugin
+        jobject createSurface(SurfaceCallback* cb);
+
+        // Destroys the SurfaceView after removing from the view system.
+        void destroySurface(jobject surface);
+
+        // Positions the SurfaceView at x,y with dimensions width x height
+        void attachSurface(jobject surface, int x, int y, int width, int height);
+
         // other public functions
     public:
         // reset the picture set to empty
index a64af1e..835f45a 100644 (file)
 
 // must include config.h first for webkit to fiddle with new/delete
 #include "config.h"
+
+#include "PluginSurface.h"
+#include "PluginView.h"
+#include "PluginWidgetAndroid.h"
 #include "SkANP.h"
 
-static ANPSurface* anp_newSurface(NPP instance, ANPSurfaceType) {
+using namespace WebCore;
+
+static ANPSurface* anp_newSurface(NPP instance, ANPSurfaceType type) {
+    if (instance && instance->ndata) {
+        PluginView* view = static_cast<PluginView*>(instance->ndata);
+        PluginWidgetAndroid* widget = view->platformPluginWidget();
+        return widget->createSurface(type);
+    }
     return NULL;
 }
 
 static void anp_deleteSurface(ANPSurface* surface) {
-
+    if (surface) {
+        if (surface->data) {
+            android::PluginSurface* s =
+                    static_cast<android::PluginSurface*>(surface->data);
+            s->destroy();
+        }
+        delete surface;
+    }
 }
 
 static bool anp_lock(ANPSurface* surface, ANPBitmap* bitmap,
                      ANPRectI* dirtyRect) {
+    if (bitmap && surface && surface->data) {
+        android::PluginSurface* s =
+                static_cast<android::PluginSurface*>(surface->data);
+        SkBitmap src;
+        bool res = false;
+        if (dirtyRect) {
+            SkIRect rect;
+            res = s->lock(SkANP::SetRect(&rect, *dirtyRect), &src);
+        } else {
+            res = s->lock(NULL, &src);
+        }
+        if (res) {
+            res &= SkANP::SetBitmap(bitmap, src);
+        }
+        return res;
+    }
     return false;
 }
 
 static void anp_unlock(ANPSurface* surface) {
-
+    if (surface && surface->data) {
+        android::PluginSurface* s =
+                static_cast<android::PluginSurface*>(surface->data);
+        s->unlock();
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/WebKit/android/plugins/PluginSurface.cpp b/WebKit/android/plugins/PluginSurface.cpp
new file mode 100644 (file)
index 0000000..e57ecbc
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * 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 "config.h"
+
+#include "PluginSurface.h"
+
+#include "android_graphics.h"
+#include "PluginWidgetAndroid.h"
+#include "WebViewCore.h"
+#include "jni_utility.h"
+
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <ui/Surface.h>
+
+namespace android {
+
+// jni field offset for the native surface pointer.
+static jfieldID  gSurfaceField;
+static jmethodID gGetHolder;
+static jmethodID gGetSurface;
+
+static void initFields(JNIEnv* env) {
+    if (gSurfaceField)
+        return;
+
+    jclass clazz = env->FindClass("android/view/Surface");
+    gSurfaceField = env->GetFieldID(clazz, "mSurface", "I");
+
+    clazz = env->FindClass("android/view/SurfaceView");
+    gGetHolder = env->GetMethodID(clazz, "getHolder", "()Landroid/view/SurfaceHolder;");
+
+    clazz = env->FindClass("android/view/SurfaceHolder");
+    gGetSurface = env->GetMethodID(clazz, "getSurface", "()Landroid/view/Surface;");
+}
+
+static inline sp<Surface> getSurface(jobject view) {
+    if (!view) {
+        return NULL;
+    }
+    JNIEnv* env = JSC::Bindings::getJNIEnv();
+    initFields(env);
+    jobject holder = env->CallObjectMethod(view, gGetHolder);
+    jobject surface = env->CallObjectMethod(holder, gGetSurface);
+    return sp<Surface>((Surface*) env->GetIntField(surface, gSurfaceField));
+}
+
+static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
+    switch (format) {
+        case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;
+        case PIXEL_FORMAT_RGBA_4444:    return SkBitmap::kARGB_4444_Config;
+        case PIXEL_FORMAT_RGB_565:      return SkBitmap::kRGB_565_Config;
+        case PIXEL_FORMAT_A_8:          return SkBitmap::kA8_Config;
+        default:                        return SkBitmap::kNo_Config;
+    }
+}
+
+PluginSurface::PluginSurface(PluginWidgetAndroid* widget)
+        : m_jSurfaceView(0)
+        , m_widget(widget) {
+    // Create our java SurfaceView.
+    jobject obj = widget->webViewCore()->createSurface(this);
+    if (obj) {
+        JNIEnv* env = JSC::Bindings::getJNIEnv();
+        m_jSurfaceView = env->NewGlobalRef(obj);
+        env->DeleteLocalRef(obj);
+    }
+}
+
+void PluginSurface::attach(int x, int y, int width, int height) {
+    if (m_jSurfaceView) {
+        m_widget->webViewCore()->attachSurface(m_jSurfaceView, x, y, width,
+                height);
+    }
+}
+
+void PluginSurface::destroy() {
+    m_surface.clear();
+    if (m_jSurfaceView) {
+        m_widget->webViewCore()->destroySurface(m_jSurfaceView);
+        JNIEnv* env = JSC::Bindings::getJNIEnv();
+        env->DeleteGlobalRef(m_jSurfaceView);
+        m_jSurfaceView = 0;
+    }
+}
+
+bool PluginSurface::lock(SkIRect* dirty, SkBitmap* bitmap) {
+    if (!bitmap || !Surface::isValid(m_surface)) {
+        return false;
+    }
+
+    Region dirtyRegion;
+    if (dirty) {
+        Rect rect(dirty->fLeft, dirty->fTop, dirty->fRight, dirty->fBottom);
+        if (!rect.isEmpty()) {
+            dirtyRegion.set(rect);
+        }
+    } else {
+        dirtyRegion.set(Rect(0x3FFF, 0x3FFF));
+    }
+
+    Surface::SurfaceInfo info;
+    status_t err = m_surface->lock(&info, &dirtyRegion);
+    if (err < 0) {
+        return false;
+    }
+
+    ssize_t bpr = info.s * bytesPerPixel(info.format);
+    bitmap->setConfig(convertPixelFormat(info.format), info.w, info.h, bpr);
+    if (info.w > 0 && info.h > 0) {
+        bitmap->setPixels(info.bits);
+    } else {
+        bitmap->setPixels(NULL);
+    }
+
+    return true;
+}
+
+void PluginSurface::unlock() {
+    if (!Surface::isValid(m_surface)) {
+        return;
+    }
+
+    m_surface->unlockAndPost();
+}
+
+static void sendSurfaceEvent(PluginWidgetAndroid* widget,
+        ANPSurfaceAction action, int format = 0, int width = 0,
+        int height = 0) {
+    ANPEvent event;
+    SkANP::InitEvent(&event, kSurface_ANPEventType);
+
+    event.data.surface.action = action;
+    if (action == kChanged_ANPSurfaceAction) {
+        event.data.surface.data.changed.format = format;
+        event.data.surface.data.changed.width = width;
+        event.data.surface.data.changed.height = height;
+    }
+
+    widget->sendEvent(event);
+}
+
+// SurfaceCallback methods
+void PluginSurface::surfaceCreated() {
+    m_surface = getSurface(m_jSurfaceView);
+    // Not sure what values for format, width, and height should be here.
+    sendSurfaceEvent(m_widget, kCreated_ANPSurfaceAction);
+}
+
+void PluginSurface::surfaceChanged(int format, int width, int height) {
+    m_surface = getSurface(m_jSurfaceView);
+    sendSurfaceEvent(m_widget, kChanged_ANPSurfaceAction, format, width,
+            height);
+}
+
+void PluginSurface::surfaceDestroyed() {
+    m_surface = getSurface(m_jSurfaceView);
+    // Not sure what values for format, width, and height should be here.
+    sendSurfaceEvent(m_widget, kDestroyed_ANPSurfaceAction);
+}
+
+} // namespace android
diff --git a/WebKit/android/plugins/PluginSurface.h b/WebKit/android/plugins/PluginSurface.h
new file mode 100644 (file)
index 0000000..b8cbac9
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ * Copyright (C) 2008 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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 APPLE COMPUTER, INC. ``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.
+ */
+
+#ifndef PluginSurface_H
+#define PluginSurface_H
+
+#include "android_npapi.h"
+#include "SkANP.h"
+#include "SurfaceCallback.h"
+
+#include <jni.h>
+#include <ui/Surface.h>
+#include <utils/RefBase.h>
+
+struct PluginWidgetAndroid;
+class  SkBitmap;
+struct SkIRect;
+
+struct ANPSurface {
+    void*           data;
+    ANPSurfaceType  type;
+};
+
+namespace android {
+
+class Surface;
+
+class PluginSurface : public SurfaceCallback {
+public:
+    PluginSurface(PluginWidgetAndroid* widget);
+    virtual ~PluginSurface() {
+        destroy();
+    }
+
+    void attach(int x, int y, int width, int height);
+    void destroy();
+    bool lock(SkIRect* dirty, SkBitmap* bitmap);
+    void unlock();
+
+    virtual void surfaceCreated();
+    virtual void surfaceChanged(int format, int width, int height);
+    virtual void surfaceDestroyed();
+
+private:
+    jobject              m_jSurfaceView;
+    sp<Surface>          m_surface;
+    PluginWidgetAndroid* m_widget;
+};
+
+} // namespace android
+
+#endif
index 7566d63..bf9b1bf 100644 (file)
@@ -29,6 +29,7 @@
 #include "Element.h"
 #include "Frame.h"
 #include "PluginPackage.h"
+#include "PluginSurface.h"
 #include "PluginView.h"
 #include "PluginWidgetAndroid.h"
 #include "SkANP.h"
@@ -65,9 +66,16 @@ void PluginWidgetAndroid::setWindow(int x, int y, int width, int height,
                                     bool isTransparent) {
     m_x = x;
     m_y = y;
-    m_flipPixelRef->safeUnref();
-    m_flipPixelRef = new SkFlipPixelRef(computeConfig(isTransparent),
-                                        width, height);
+
+    if (m_drawingModel == kSurface_ANPDrawingModel) {
+        if (m_surface) {
+            m_surface->attach(x, y, width, height);
+        }
+    } else {
+        m_flipPixelRef->safeUnref();
+        m_flipPixelRef = new SkFlipPixelRef(computeConfig(isTransparent),
+                                            width, height);
+    }
 }
 
 bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) {
@@ -98,7 +106,8 @@ bool PluginWidgetAndroid::isDirty(SkIRect* rect) const {
 
 void PluginWidgetAndroid::inval(const WebCore::IntRect& rect,
                                 bool signalRedraw) {
-    // nothing to do if we haven't had setWindow() called yet
+    // nothing to do if we haven't had setWindow() called yet. m_flipPixelRef
+    // will also be null if this is a Surface model.
     if (NULL == m_flipPixelRef) {
         return;
     }
@@ -182,3 +191,14 @@ void PluginWidgetAndroid::updateEventFlags(ANPEventFlags flags) {
 bool PluginWidgetAndroid::isAcceptingEvent(ANPEventFlag flag) {
     return m_eventFlags & flag;
 }
+
+ANPSurface* PluginWidgetAndroid::createSurface(ANPSurfaceType ignored) {
+    if (m_drawingModel != kSurface_ANPDrawingModel) {
+        return NULL;
+    }
+    m_surface.set(new android::PluginSurface(this));
+    ANPSurface* surface = new ANPSurface;
+    surface->data = m_surface.get();
+    surface->type = ignored;
+    return surface;
+}
index c8d1ffe..84ac729 100644 (file)
 
 #include "android_npapi.h"
 
+#include <wtf/OwnPtr.h>
+
 namespace WebCore {
     class PluginView;
 }
 
 namespace android {
+    class PluginSurface;
     class WebViewCore;
 }
 
@@ -52,6 +55,9 @@ struct PluginWidgetAndroid {
 
     WebCore::PluginView* pluginView() const { return m_pluginView; }
 
+    // Needed by PluginSurface to manage the java SurfaceView.
+    android::WebViewCore* webViewCore() const { return m_core; }
+
     /*  Can't determine our core at construction time, so PluginView calls this
         as soon as it has a parent.
      */
@@ -101,6 +107,12 @@ struct PluginWidgetAndroid {
      */
     bool isAcceptingEvent(ANPEventFlag);
 
+    /*  Create an ANPSurface that the plugin may draw in to. The drawing model
+        must be kSurface_ANPDrawingModel for this call to succeed. The type
+        specifies what kind of pixel access will be available.
+     */
+    ANPSurface* createSurface(ANPSurfaceType type);
+
 private:
     WebCore::PluginView*    m_pluginView;
     android::WebViewCore*   m_core;
@@ -109,6 +121,7 @@ private:
     ANPEventFlags           m_eventFlags;
     int                     m_x;
     int                     m_y;
+    OwnPtr<android::PluginSurface> m_surface;
 };
 
 #endif
diff --git a/WebKit/android/plugins/SurfaceCallback.h b/WebKit/android/plugins/SurfaceCallback.h
new file mode 100644 (file)
index 0000000..fb2e015
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ * Copyright (C) 2008 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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 APPLE COMPUTER, INC. ``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.
+ */
+
+#ifndef SurfaceCallback_H
+#define SurfaceCallback_H
+
+namespace android {
+
+    class SurfaceCallback {
+    public:
+        virtual ~SurfaceCallback() {}
+        virtual void surfaceCreated() = 0;
+        virtual void surfaceChanged(int format, int width, int height) = 0;
+        virtual void surfaceDestroyed() = 0;
+    };
+
+} // namespace android
+
+#endif
index 41c1080..2d86b9c 100644 (file)
@@ -200,11 +200,6 @@ struct ANPBitmapInterfaceV0 : ANPInterface {
     bool (*getPixelPacking)(ANPBitmapFormat, ANPPixelPacking* packing);
 };
 
-/** The ANPSurface acts as a handle between the plugin and the native libraries
-    that render the surface to the screen.
- */
-struct ANPSurface;
-
 /** The surfaceType is the mechanism by which the plugin informs the native
     libraries which type of surface view it wishes to use.
  */
@@ -213,6 +208,11 @@ enum ANPSurfaceTypes {
 };
 typedef int32_t ANPSurfaceType;
 
+/** The ANPSurface acts as a handle between the plugin and the native libraries
+    that render the surface to the screen.
+ */
+struct ANPSurface;
+
 struct ANPSurfaceInterfaceV0 : ANPInterface {
     /** Creates a new surface handle based on the given surface type. If the
         given surface type is not supported then NULL is returned.
@@ -717,6 +717,7 @@ enum ANPEventTypes {
     kDraw_ANPEventType          = 4,
     kLifecycle_ANPEventType     = 5,
     kVisibleRect_ANPEventType   = 6,
+    kSurface_ANPEventType       = 7,
 };
 typedef int32_t ANPEventType;
 
@@ -759,6 +760,23 @@ enum ANPLifecycleActions {
 };
 typedef uint32_t ANPLifecycleAction;
 
+enum ANPSurfaceActions {
+    /** The surface has been created and is ready to be used. Any calls to
+        lock/unlock before this action will fail.
+     */
+    kCreated_ANPSurfaceAction    = 0,
+    /** The surface has changed format or dimensions.
+     */
+    kChanged_ANPSurfaceAction    = 1,
+    /** The surface has been destroyed. This happens when the view system has
+        remove the surface (possibly due to the plugin being offscreen). Calls
+        to lock/unlock will fail after this action and before
+        kCreate_ANPSurfaceAction.
+     */
+    kDestroyed_ANPSurfaceAction  = 2,
+};
+typedef uint32_t ANPSurfaceAction;
+
 /* This is what is passed to NPP_HandleEvent() */
 struct ANPEvent {
     uint32_t        inSize;  // size of this struct in bytes
@@ -800,6 +818,23 @@ struct ANPEvent {
             ANPRectI    rect;       // in global document coordinates
             float       zoomScale;  // 1.0 means no zoom scale
         } visibleRect;
+        struct {
+            ANPSurfaceAction action;
+            /** This union is based on the value of action and contains data
+                specific to the given action.
+             */
+            union {
+                /** This struct is filled in only during the
+                    kChanged_ANPSurfaceAction action. For all other actions,
+                    this struct is undefined.
+                  */
+                struct {
+                    int32_t format;
+                    int32_t width;
+                    int32_t height;
+                } changed;
+            } data;
+        } surface;
         int32_t         other[8];
     } data;
 };