Removed dependence on java interfaces and use only one surface for both embedded and fullscreen surfaces.
diff --git a/samples/BrowserPlugin/jni/PluginObject.cpp b/samples/BrowserPlugin/jni/PluginObject.cpp
index 94b0cfa..dd0fbac 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 @@
     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 691234f..e8084ef 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 <jni.h>
 
+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 @@
 
 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 699fa4d..578fe6d 100644
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
@@ -54,9 +54,6 @@
 
 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() {
-    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, "<init>", "(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 @@
         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 0e8f6f7..ebd77d1 100644
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
@@ -32,12 +32,8 @@
 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 @@
 
 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 02f768b..9ba8a32 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<PluginObject*>(instance->pdata);
-    if (obj && obj->activePlugin
-            && obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)) {
-        return static_cast<SurfaceSubPlugin*>(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 @@
         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 85632e4..35dd5d6 100644
--- a/samples/BrowserPlugin/jni/main.cpp
+++ b/samples/BrowserPlugin/jni/main.cpp
@@ -68,6 +68,7 @@
 ANPAudioTrackInterfaceV0    gSoundI;
 ANPBitmapInterfaceV0        gBitmapI;
 ANPCanvasInterfaceV0        gCanvasI;
+ANPEventInterfaceV0         gEventI;
 ANPLogInterfaceV0           gLogI;
 ANPPaintInterfaceV0         gPaintI;
 ANPPathInterfaceV0          gPathI;
@@ -115,6 +116,7 @@
         { 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 @@
         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<SurfaceSubPlugin*>(obj->activePlugin);
+
+        jobject context;
+        NPError err = browser->getvalue(instance, kJavaContext_ANPGetValue,
+                                        static_cast<void*>(&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 @@
     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 @@
         return NPERR_NO_ERROR;
     }
 
+    if (variable == kJavaSurface_ANPGetValue) {
+        //get the surface sub-plugin
+        PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
+        if (obj && obj->activePlugin) {
+
+            if(obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)) {
+                SurfaceSubPlugin* plugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
+                jobject* surface = static_cast<jobject*>(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 4222222..e478897 100644
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
@@ -35,6 +35,7 @@
 extern ANPPaintInterfaceV0      gPaintI;
 extern ANPPathInterfaceV0       gPathI;
 extern ANPSurfaceInterfaceV0    gSurfaceI;
+extern ANPSystemInterfaceV0     gSystemI;
 extern ANPTypefaceInterfaceV0   gTypefaceI;
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -50,9 +51,6 @@
     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 @@
     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 @@
         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;
+    }
 
-void PaintPlugin::surfaceChanged(int format, int width, int height) {
-    // get the plugin's dimensions according to the DOM
+    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;
+    }
+
     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, "<init>", "(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 @@
             }
             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 a917ffb..4867a70 100644
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.h
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.h
@@ -33,18 +33,15 @@
 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 f6608d6..f24295b 100644
--- a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
@@ -38,6 +38,7 @@
 extern ANPLogInterfaceV0       gLogI;
 extern ANPPaintInterfaceV0     gPaintI;
 extern ANPSurfaceInterfaceV0   gSurfaceI;
+extern ANPSystemInterfaceV0    gSystemI;
 extern ANPTypefaceInterfaceV0  gTypefaceI;
 extern ANPWindowInterfaceV0    gWindowI;
 
@@ -45,9 +46,6 @@
 
 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() {
-    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, "<init>", "(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::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 dd6859d..701e2d0 100644
--- a/samples/BrowserPlugin/jni/video/VideoPlugin.h
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.h
@@ -32,15 +32,11 @@
 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 0000000..5af8c8e
--- /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 0000000..9582bcc
--- /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 2cfb525..5bec1c6 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 0000000..a3c80cf
--- /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);
+    }
+}