First pass at replacing native plugin views with java.

Change-Id: I6d1f45f31210c2353fa348cc37be8d91bcd5e887
diff --git a/api/current.xml b/api/current.xml
index 7562f2e..36d083d8 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -167285,6 +167285,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="NPP" type="int">
+</parameter>
 <parameter name="context" type="android.content.Context">
 </parameter>
 </method>
@@ -167438,24 +167440,13 @@
 </parameter>
 </method>
 </class>
-<class name="PluginStub"
- extends="java.lang.Object"
+<interface name="PluginStub"
  abstract="true"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="PluginStub"
- type="android.webkit.PluginStub"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="npp" type="int">
-</parameter>
-</constructor>
 <method name="getEmbeddedView"
  return="android.view.View"
  abstract="true"
@@ -167479,10 +167470,12 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="NPP" type="int">
+</parameter>
 <parameter name="context" type="android.content.Context">
 </parameter>
 </method>
-</class>
+</interface>
 <class name="SslErrorHandler"
  extends="android.os.Handler"
  abstract="false"
diff --git a/core/java/android/webkit/PluginActivity.java b/core/java/android/webkit/PluginActivity.java
index f9e3080..cda7b59 100644
--- a/core/java/android/webkit/PluginActivity.java
+++ b/core/java/android/webkit/PluginActivity.java
@@ -49,10 +49,10 @@
         final int npp = intent.getIntExtra(INTENT_EXTRA_NPP_INSTANCE, -1);
         // Retrieve the PluginStub implemented in packageName.className
         PluginStub stub =
-                PluginUtil.getPluginStub(this, packageName, className, npp);
+                PluginUtil.getPluginStub(this, packageName, className);
 
         if (stub != null) {
-            View pluginView = stub.getFullScreenView(this);
+            View pluginView = stub.getFullScreenView(npp, this);
             if (pluginView != null) {
                 setContentView(pluginView);
             } else {
diff --git a/core/java/android/webkit/PluginStub.java b/core/java/android/webkit/PluginStub.java
index c24da8d..cbb36aa 100644
--- a/core/java/android/webkit/PluginStub.java
+++ b/core/java/android/webkit/PluginStub.java
@@ -19,32 +19,29 @@
 import android.view.View;
 
 /**
- * This abstract class is used to implement plugins in a WebView. A plugin
+ * This interface is used to implement plugins in a WebView. A plugin
  * package may extend this class and implement the abstract functions to create
  * embedded or fullscreeen views displayed in a WebView. The PluginStub
  * implementation will be provided the same NPP instance that is created
  * through the native interface.
  */
-public abstract class PluginStub {
-    /**
-     * Construct a new PluginStub implementation for the given NPP instance.
-     * @param npp The native NPP instance.
-     */
-    public PluginStub(int npp) { }
+public interface PluginStub {
 
     /**
      * Return a custom embedded view to draw the plugin.
+     * @param npp The native NPP instance.
      * @param context The current application's Context.
      * @return A custom View that will be managed by WebView.
      */
-    public abstract View getEmbeddedView(Context context);
+    public abstract View getEmbeddedView(int NPP, Context context);
 
     /**
      * Return a custom full-screen view to be displayed when the user requests
      * a plugin display as full-screen. Note that the application may choose not
      * to display this View as completely full-screen.
+     * @param npp The native NPP instance.
      * @param context The current application's Context.
      * @return A custom View that will be managed by the application.
      */
-    public abstract View getFullScreenView(Context context);
+    public abstract View getFullScreenView(int NPP, Context context);
 }
diff --git a/core/java/android/webkit/PluginUtil.java b/core/java/android/webkit/PluginUtil.java
index c0a7375..8fdbd67 100644
--- a/core/java/android/webkit/PluginUtil.java
+++ b/core/java/android/webkit/PluginUtil.java
@@ -32,19 +32,16 @@
      * @param className the fully qualified name of a subclass of PluginStub
      */
     /* package */
-    static PluginStub getPluginStub(Context context, String packageName,
-            String className, int NPP) {
+    static PluginStub getPluginStub(Context context, String packageName, 
+            String className) {
         try {
             Context pluginContext = context.createPackageContext(packageName,
                     Context.CONTEXT_INCLUDE_CODE |
                     Context.CONTEXT_IGNORE_SECURITY);
             ClassLoader pluginCL = pluginContext.getClassLoader();
 
-            Class<?> stubClass =
-                    pluginCL.loadClass(className);
-            Constructor<?> stubConstructor =
-                    stubClass.getConstructor(int.class);
-            Object stubObject = stubConstructor.newInstance(NPP);
+            Class<?> stubClass = pluginCL.loadClass(className);
+            Object stubObject = stubClass.newInstance();
 
             if (stubObject instanceof PluginStub) {
                 return (PluginStub) stubObject;
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 5f2d65e..ac3334c 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -34,6 +34,7 @@
 import android.view.KeyEvent;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
+import android.view.View;
 
 import java.util.ArrayList;
 import java.util.Map;
@@ -2060,84 +2061,32 @@
         }
     }
 
-    // This class looks like a SurfaceView to native code. In java, we can
-    // assume the passed in SurfaceView is this class so we can talk to the
-    // ViewManager through the ChildView.
-    private class SurfaceViewProxy extends SurfaceView
-            implements SurfaceHolder.Callback {
-        private final ViewManager.ChildView mChildView;
-        private int mPointer;
-        private final boolean mIsFixedSize;
-        SurfaceViewProxy(Context context, ViewManager.ChildView childView,
-                int pointer, int pixelFormat, boolean isFixedSize) {
-            super(context);
-            setWillNotDraw(false); // this prevents the black box artifact
-            getHolder().addCallback(this);
-            getHolder().setFormat(pixelFormat);
-            mChildView = childView;
-            mChildView.mView = this;
-            mPointer = pointer;
-            mIsFixedSize = isFixedSize;
-        }
-        void destroy() {
-            mPointer = 0;
-            mChildView.removeView();
-        }
-        void attach(int x, int y, int width, int height) {
-            mChildView.attachView(x, y, width, height);
-
-            if (mIsFixedSize) {
-                getHolder().setFixedSize(width, height);
-            }
-        }
-
-        // SurfaceHolder.Callback methods
-        public void surfaceCreated(SurfaceHolder holder) {
-            if (mPointer != 0) {
-                nativeSurfaceChanged(mPointer, 0, 0, 0, 0);
-            }
-        }
-        public void surfaceChanged(SurfaceHolder holder, int format, int width,
-                int height) {
-            if (mPointer != 0) {
-                nativeSurfaceChanged(mPointer, 1, format, width, height);
-            }
-        }
-        public void surfaceDestroyed(SurfaceHolder holder) {
-            if (mPointer != 0) {
-                nativeSurfaceChanged(mPointer, 2, 0, 0, 0);
-            }
-        }
-    }
-
-    // PluginWidget functions for mainting SurfaceViews for the Surface drawing
+    // PluginWidget functions for creating SurfaceViews for the Surface drawing
     // model.
-    private SurfaceView createSurface(int nativePointer, int pixelFormat,
-                                      boolean isFixedSize) {
+    private ViewManager.ChildView createSurface(String packageName, String className,
+            int npp, int x, int y, int width, int height) {
         if (mWebView == null) {
             return null;
         }
-        return new SurfaceViewProxy(mContext, mWebView.mViewManager.createView(),
-                                    nativePointer, pixelFormat, isFixedSize);
+        PluginStub stub = PluginUtil.getPluginStub(mWebView.getContext(), packageName, className);
+        if (stub == null) {
+            Log.e(LOGTAG, "Unable to find plugin class (" + className + 
+                    ") in the apk (" + packageName + ")");
+            return null;
+        }
+        
+        View pluginView = stub.getEmbeddedView(npp, mWebView.getContext());
+        
+        ViewManager.ChildView view = mWebView.mViewManager.createView();
+        view.mView = pluginView;
+        view.attachView(x, y, width, height);
+        return view;
     }
-
-    private void destroySurface(SurfaceView surface) {
-        SurfaceViewProxy proxy = (SurfaceViewProxy) surface;
-        proxy.destroy();
+    
+    private void destroySurface(ViewManager.ChildView childView) {
+        childView.removeView();
     }
 
-    private void attachSurface(SurfaceView surface, int x, int y,
-            int width, int height) {
-        SurfaceViewProxy proxy = (SurfaceViewProxy) surface;
-        proxy.attach(x, y, width, height);
-    }
-
-    // Callback for the SurfaceHolder.Callback. Called for all the surface
-    // callbacks. The state parameter is one of Created(0), Changed(1),
-    // Destroyed(2).
-    private native void nativeSurfaceChanged(int pointer, int state, int format,
-            int width, int height);
-
     private native void nativePause();
     private native void nativeResume();
     private native void nativeFreeMemory();
diff --git a/tests/BrowserTestPlugin/jni/event/EventPlugin.cpp b/tests/BrowserTestPlugin/jni/event/EventPlugin.cpp
index 1263204..706c27e 100644
--- a/tests/BrowserTestPlugin/jni/event/EventPlugin.cpp
+++ b/tests/BrowserTestPlugin/jni/event/EventPlugin.cpp
@@ -36,27 +36,18 @@
 extern ANPCanvasInterfaceV0    gCanvasI;
 extern ANPLogInterfaceV0       gLogI;
 extern ANPPaintInterfaceV0     gPaintI;
-extern ANPSurfaceInterfaceV0   gSurfaceI;
 extern ANPTypefaceInterfaceV0  gTypefaceI;
 
 ///////////////////////////////////////////////////////////////////////////////
 
-EventPlugin::EventPlugin(NPP inst) : SubPlugin(inst) {
+EventPlugin::EventPlugin(NPP inst) : SubPlugin(inst) { }
 
-    // initialize the drawing surface
-    m_surfaceReady = false;
-    m_surface = gSurfaceI.newRasterSurface(inst, kRGB_565_ANPBitmapFormat, false);
-    if(!m_surface)
-        gLogI.log(inst, kError_ANPLogType, "----%p Unable to create Raster surface", inst);
-}
+EventPlugin::~EventPlugin() { }
 
-EventPlugin::~EventPlugin() {
-    gSurfaceI.deleteSurface(m_surface);
-}
+void EventPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
 
-void EventPlugin::drawPlugin(int surfaceWidth, int surfaceHeight) {
-
-    gLogI.log(inst(), kDebug_ANPLogType, " ------ %p drawing the plugin (%d,%d)", inst(), surfaceWidth, surfaceHeight);
+    gLogI.log(inst(), kDebug_ANPLogType, " ------ %p drawing the plugin (%d,%d)",
+              inst(), bitmap.width, bitmap.height);
 
     // get the plugin's dimensions according to the DOM
     PluginObject *obj = (PluginObject*) inst()->pdata;
@@ -64,8 +55,8 @@
     const int H = obj->window->height;
 
     // compute the current zoom level
-    const float zoomFactorW = static_cast<float>(surfaceWidth) / W;
-    const float zoomFactorH = static_cast<float>(surfaceHeight) / H;
+    const float zoomFactorW = static_cast<float>(bitmap.width) / W;
+    const float zoomFactorH = static_cast<float>(bitmap.height) / H;
 
     // check to make sure the zoom level is uniform
     if (zoomFactorW + .01 < zoomFactorH && zoomFactorW - .01 > zoomFactorH)
@@ -76,15 +67,16 @@
     const int fontSize = (int)(zoomFactorW * 16);
     const int leftMargin = (int)(zoomFactorW * 10);
 
-    // lock the surface
-    ANPBitmap bitmap;
-    if (!m_surfaceReady || !gSurfaceI.lock(m_surface, &bitmap, NULL)) {
-        gLogI.log(inst(), kError_ANPLogType, " ------ %p unable to lock the plugin", inst());
-        return;
-    }
-
-    // create a canvas
+    // create and clip a canvas
     ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
+
+    ANPRectF clipR;
+    clipR.left = clip.left;
+    clipR.top = clip.top;
+    clipR.right = clip.right;
+    clipR.bottom = clip.bottom;
+    gCanvasI.clipRect(canvas, &clipR);
+
     gCanvasI.drawColor(canvas, 0xFFFFFFFF);
 
     // configure the paint
@@ -106,10 +98,9 @@
     const char c[] = "Browser Test Plugin";
     gCanvasI.drawText(canvas, c, sizeof(c)-1, leftMargin, -fm.fTop, paint);
 
-    // clean up variables and unlock the surface
+    // clean up variables
     gPaintI.deletePaint(paint);
     gCanvasI.deleteCanvas(canvas);
-    gSurfaceI.unlock(m_surface);
 }
 
 void EventPlugin::printToDiv(const char* text, int length) {
@@ -149,23 +140,16 @@
 
 int16 EventPlugin::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 kSurface_ANPEventType:
-            switch (evt->data.surface.action) {
-                case kCreated_ANPSurfaceAction:
-                    m_surfaceReady = true;
+
+        case kDraw_ANPEventType: {
+            switch (evt->data.draw.model) {
+                case kBitmap_ANPDrawingModel:
+                    drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
                     return 1;
-                case kDestroyed_ANPSurfaceAction:
-                    m_surfaceReady = false;
-                    return 1;
-                case kChanged_ANPSurfaceAction:
-                    drawPlugin(evt->data.surface.data.changed.width,
-                               evt->data.surface.data.changed.height);
-                    return 1;
+                default:
+                    break;   // unknown drawing model
             }
-            break;
+        }
         case kLifecycle_ANPEventType:
             switch (evt->data.lifecycle.action) {
                 case kOnLoad_ANPLifecycleAction: {
diff --git a/tests/BrowserTestPlugin/jni/event/EventPlugin.h b/tests/BrowserTestPlugin/jni/event/EventPlugin.h
index 73dd6ea..88b7c9d 100644
--- a/tests/BrowserTestPlugin/jni/event/EventPlugin.h
+++ b/tests/BrowserTestPlugin/jni/event/EventPlugin.h
@@ -35,11 +35,8 @@
     virtual int16 handleEvent(const ANPEvent* evt);
 
 private:
-    void drawPlugin(int surfaceWidth, int surfaceHeight);
+    void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
     void printToDiv(const char* text, int length);
-
-    bool        m_surfaceReady;
-    ANPSurface* m_surface;
 };
 
 #endif // eventPlugin__DEFINED
diff --git a/tests/BrowserTestPlugin/jni/main.cpp b/tests/BrowserTestPlugin/jni/main.cpp
index 056ec4d..e3ad4a7 100644
--- a/tests/BrowserTestPlugin/jni/main.cpp
+++ b/tests/BrowserTestPlugin/jni/main.cpp
@@ -65,7 +65,6 @@
 ANPLogInterfaceV0           gLogI;
 ANPPaintInterfaceV0         gPaintI;
 ANPPathInterfaceV0          gPathI;
-ANPSurfaceInterfaceV0       gSurfaceI;
 ANPSystemInterfaceV0        gSystemI;
 ANPTypefaceInterfaceV0      gTypefaceI;
 ANPWindowInterfaceV0        gWindowI;
@@ -105,16 +104,10 @@
         uint32_t        size;
         ANPInterface*   i;
     } gPairs[] = {
-        { kAudioTrackInterfaceV0_ANPGetValue,   sizeof(gSoundI),    &gSoundI },
-        { kBitmapInterfaceV0_ANPGetValue,       sizeof(gBitmapI),   &gBitmapI },
         { kCanvasInterfaceV0_ANPGetValue,       sizeof(gCanvasI),   &gCanvasI },
         { kLogInterfaceV0_ANPGetValue,          sizeof(gLogI),      &gLogI },
         { kPaintInterfaceV0_ANPGetValue,        sizeof(gPaintI),    &gPaintI },
-        { kPathInterfaceV0_ANPGetValue,         sizeof(gPathI),     &gPathI },
-        { kSurfaceInterfaceV0_ANPGetValue,      sizeof(gSurfaceI),  &gSurfaceI },
-        { kSystemInterfaceV0_ANPGetValue,       sizeof(gSystemI),   &gSystemI },
         { kTypefaceInterfaceV0_ANPGetValue,     sizeof(gTypefaceI), &gTypefaceI },
-        { kWindowInterfaceV0_ANPGetValue,       sizeof(gWindowI),   &gWindowI },
     };
     for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) {
         gPairs[i].i->inSize = gPairs[i].size;
@@ -156,7 +149,7 @@
     }
 
     // select the drawing model
-    ANPDrawingModel model = kSurface_ANPDrawingModel;
+    ANPDrawingModel model = kBitmap_ANPDrawingModel;
 
     // notify the plugin API of the drawing model we wish to use. This must be
     // done prior to creating certain subPlugin objects (e.g. surfaceViews)