Merge change I11438c37 into eclair-mr2

* changes:
  Implement the full screen WebView plugin.
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 7eb42f2..fb369d3 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -108,8 +108,6 @@
     private static final int RECEIVED_TOUCH_ICON_URL             = 132;
     private static final int GET_VISITED_HISTORY                 = 133;
     private static final int OPEN_FILE_CHOOSER                   = 134;
-    private static final int SHOW_CUSTOM_VIEW                    = 135;
-    private static final int HIDE_CUSTOM_VIEW                    = 136;
 
     // Message triggered by the client to resume execution
     private static final int NOTIFY                              = 200;
@@ -681,23 +679,6 @@
                     mWebChromeClient.openFileChooser((UploadFile) msg.obj);
                 }
                 break;
-
-            case SHOW_CUSTOM_VIEW:
-                if (mWebChromeClient != null) {
-                    HashMap<String, Object> map =
-                            (HashMap<String, Object>) msg.obj;
-                    View view = (View) map.get("view");
-                    WebChromeClient.CustomViewCallback callback =
-                            (WebChromeClient.CustomViewCallback) map.get("callback");
-                    mWebChromeClient.onShowCustomView(view, callback);
-                }
-                break;
-
-            case HIDE_CUSTOM_VIEW:
-                if (mWebChromeClient != null) {
-                    mWebChromeClient.onHideCustomView();
-                }
-                break;
         }
     }
 
@@ -1404,24 +1385,4 @@
         }
         return uploadFile.getResult();
     }
-
-    /* package */ void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {
-        if (mWebChromeClient == null) {
-            return;
-        }
-        Message msg = obtainMessage(SHOW_CUSTOM_VIEW);
-        HashMap<String, Object> map = new HashMap<String, Object>();
-        map.put("view", view);
-        map.put("callback", callback);
-        msg.obj = map;
-        sendMessage(msg);
-    }
-
-    /* package */ void hideCustomView() {
-        if (mWebChromeClient == null) {
-            return;
-        }
-        Message msg = obtainMessage(HIDE_CUSTOM_VIEW);
-        sendMessage(msg);
-    }
 }
diff --git a/core/java/android/webkit/PluginFullScreenHolder.java b/core/java/android/webkit/PluginFullScreenHolder.java
new file mode 100644
index 0000000..6a0b145
--- /dev/null
+++ b/core/java/android/webkit/PluginFullScreenHolder.java
@@ -0,0 +1,120 @@
+/*
+ * 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 android.webkit;
+
+import android.app.Dialog;
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+
+class PluginFullScreenHolder extends Dialog {
+
+    private static final String LOGTAG = "FullScreenHolder";
+
+    private final WebView mWebView;
+    private final int mNpp;
+    private int mX;
+    private int mY;
+    private int mWidth;
+    private int mHeight;
+
+    PluginFullScreenHolder(WebView webView, int npp) {
+        super(webView.getContext(), android.R.style.Theme_NoTitleBar_Fullscreen);
+        mWebView = webView;
+        mNpp = npp;
+    }
+
+    Rect getBound() {
+        return new Rect(mX, mY, mWidth, mHeight);
+    }
+
+    /*
+     * x, y, width, height are in the caller's view coordinate system. (x, y) is
+     * relative to the top left corner of the caller's view.
+     */
+    void updateBound(int x, int y, int width, int height) {
+        mX = x;
+        mY = y;
+        mWidth = width;
+        mHeight = height;
+    }
+
+    @Override
+    public void onBackPressed() {
+        mWebView.mPrivateHandler.obtainMessage(WebView.HIDE_FULLSCREEN)
+                .sendToTarget();
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (event.isSystem()) {
+            return super.onKeyDown(keyCode, event);
+        }
+        mWebView.onKeyDown(keyCode, event);
+        // always return true as we are the handler
+        return true;
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        if (event.isSystem()) {
+            return super.onKeyUp(keyCode, event);
+        }
+        mWebView.onKeyUp(keyCode, event);
+        // always return true as we are the handler
+        return true;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        final float x = event.getX();
+        final float y = event.getY();
+        // TODO: find a way to know when the dialog size changed so that we can
+        // cache the ratio
+        final View decorView = getWindow().getDecorView();
+        event.setLocation(mX + x * mWidth / decorView.getWidth(),
+                mY + y * mHeight / decorView.getHeight());
+        mWebView.onTouchEvent(event);
+        // always return true as we are the handler
+        return true;
+    }
+
+    @Override
+    public boolean onTrackballEvent(MotionEvent event) {
+        mWebView.onTrackballEvent(event);
+        // always return true as we are the handler
+        return true;
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mWebView.getWebViewCore().sendMessage(
+                WebViewCore.EventHub.HIDE_FULLSCREEN, mNpp, 0);
+    }
+
+}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 7d49cb6a..d99f9f2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -301,6 +301,9 @@
     // Used by WebViewCore to create child views.
     /* package */ final ViewManager mViewManager;
 
+    // Used to display in full screen mode
+    PluginFullScreenHolder mFullScreenHolder;
+
     /**
      * Position of the last touch event.
      */
@@ -487,6 +490,8 @@
     static final int INVAL_RECT_MSG_ID                  = 26;
     static final int REQUEST_KEYBOARD                   = 27;
     static final int DO_MOTION_UP                       = 28;
+    static final int SHOW_FULLSCREEN                    = 29;
+    static final int HIDE_FULLSCREEN                    = 30;
 
     static final String[] HandlerDebugString = {
         "REMEMBER_PASSWORD", //              = 1;
@@ -516,7 +521,9 @@
         "WEBCORE_NEED_TOUCH_EVENTS", //      = 25;
         "INVAL_RECT_MSG_ID", //              = 26;
         "REQUEST_KEYBOARD", //               = 27;
-        "DO_MOTION_UP" //                    = 28;
+        "DO_MOTION_UP", //                   = 28;
+        "SHOW_FULLSCREEN", //                = 29;
+        "HIDE_FULLSCREEN" //                 = 30;
     };
 
     // If the site doesn't use the viewport meta tag to specify the viewport,
@@ -3993,6 +4000,11 @@
                             || mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
                         mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
                     }
+                    if (mFullScreenHolder != null) {
+                        // in full screen mode, the WebView can't be panned.
+                        mTouchMode = TOUCH_DONE_MODE;
+                        break;
+                    }
 
                     // if it starts nearly horizontal or vertical, enforce it
                     int ax = Math.abs(deltaX);
@@ -4147,7 +4159,7 @@
                             ted.mX = viewToContentX((int) x + mScrollX);
                             ted.mY = viewToContentY((int) y + mScrollY);
                             mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
-                        } else {
+                        } else if (mFullScreenHolder == null) {
                             doDoubleTap();
                         }
                         break;
@@ -4163,8 +4175,9 @@
                         if ((deltaX * deltaX + deltaY * deltaY) > mTouchSlopSquare) {
                             Log.w(LOGTAG, "Miss a drag as we are waiting for" +
                                     " WebCore's response for touch down.");
-                            if (computeHorizontalScrollExtent() < computeHorizontalScrollRange()
-                                    || computeVerticalScrollExtent() < computeVerticalScrollRange()) {
+                            if (mFullScreenHolder == null
+                                    && (computeHorizontalScrollExtent() < computeHorizontalScrollRange()
+                                    || computeVerticalScrollExtent() < computeVerticalScrollRange())) {
                                 // we will not rewrite drag code here, but we
                                 // will try fling if it applies.
                                 WebViewCore.pauseUpdate(mWebViewCore);
@@ -5115,7 +5128,7 @@
             // exclude INVAL_RECT_MSG_ID since it is frequently output
             if (DebugFlags.WEB_VIEW && msg.what != INVAL_RECT_MSG_ID) {
                 Log.v(LOGTAG, msg.what < REMEMBER_PASSWORD || msg.what
-                        > DO_MOTION_UP ? Integer.toString(msg.what)
+                        > HIDE_FULLSCREEN ? Integer.toString(msg.what)
                         : HandlerDebugString[msg.what - REMEMBER_PASSWORD]);
             }
             if (mWebViewCore == null) {
@@ -5146,7 +5159,9 @@
                         mPreventDoubleTap = false;
                     }
                     if (mTouchMode == TOUCH_INIT_MODE) {
-                        mTouchMode = TOUCH_SHORTPRESS_START_MODE;
+                        mTouchMode = mFullScreenHolder == null
+                                ? TOUCH_SHORTPRESS_START_MODE
+                                        : TOUCH_SHORTPRESS_MODE;
                         updateSelection();
                     } else if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
                         mTouchMode = TOUCH_DONE_MODE;
@@ -5164,8 +5179,10 @@
                         mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
                     } else if (mPreventDrag == PREVENT_DRAG_NO) {
                         mTouchMode = TOUCH_DONE_MODE;
-                        performLongClick();
-                        rebuildWebTextView();
+                        if (mFullScreenHolder == null) {
+                            performLongClick();
+                            rebuildWebTextView();
+                        }
                     }
                     break;
                 }
@@ -5466,6 +5483,35 @@
                     doMotionUp(msg.arg1, msg.arg2, (Boolean) msg.obj);
                     break;
 
+                case SHOW_FULLSCREEN:
+                    WebViewCore.PluginFullScreenData data
+                            = (WebViewCore.PluginFullScreenData) msg.obj;
+                    if (data.mNpp != 0 && data.mView != null) {
+                        if (mFullScreenHolder != null) {
+                            Log.w(LOGTAG,
+                                    "Should not have another full screen.");
+                            mFullScreenHolder.dismiss();
+                        }
+                        mFullScreenHolder = new PluginFullScreenHolder(
+                                WebView.this, data.mNpp);
+                        mFullScreenHolder.setContentView(data.mView);
+                        mFullScreenHolder.setCancelable(false);
+                        mFullScreenHolder.setCanceledOnTouchOutside(false);
+                    }
+                    mFullScreenHolder.updateBound(contentToViewX(data.mDocX)
+                            - mScrollX, contentToViewY(data.mDocY) - mScrollY,
+                            contentToViewDimension(data.mDocWidth),
+                            contentToViewDimension(data.mDocHeight));
+                    mFullScreenHolder.show();
+                    break;
+
+                case HIDE_FULLSCREEN:
+                    if (mFullScreenHolder != null) {
+                        mFullScreenHolder.dismiss();
+                        mFullScreenHolder = null;
+                    }
+                    break;
+
                 default:
                     super.handleMessage(msg);
                     break;
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index e198ee8..ce2637b 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -41,7 +41,6 @@
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
-import android.webkit.plugin.FullScreenDrawingModel;
 import android.webkit.plugin.SurfaceDrawingModel;
 import android.webkit.plugin.WebkitPlugin;
 
@@ -737,6 +736,15 @@
         boolean mRemember;
     }
 
+    static class PluginFullScreenData {
+        View mView;
+        int mNpp;
+        int mDocX;
+        int mDocY;
+        int mDocWidth;
+        int mDocHeight;
+    }
+
         static final String[] HandlerDebugString = {
             "UPDATE_FRAME_CACHE_IF_LOADING", // = 98
             "SCROLL_TEXT_INPUT", // = 99
@@ -870,6 +878,8 @@
 
         static final int POPULATE_VISITED_LINKS = 181;
 
+        static final int HIDE_FULLSCREEN = 182;
+
         // private message ids
         private static final int DESTROY =     200;
 
@@ -1313,6 +1323,10 @@
                                     message);
                             break;
                         }
+
+                        case HIDE_FULLSCREEN:
+                            nativeFullScreenPluginHidden(msg.arg1);
+                            break;
                     }
                 }
             };
@@ -2236,35 +2250,53 @@
 
     // called by JNI. PluginWidget function to launch a full-screen view using a
     // View object provided by the plugin class.
-    private void showFullScreenPlugin(WebkitPlugin webkitPlugin, final int npp) {
+    private void showFullScreenPlugin(WebkitPlugin webkitPlugin, final int npp,
+            int x, int y, int width, int height) {
         if (mWebView == null) {
             return;
         }
 
-        final FullScreenDrawingModel surface = webkitPlugin.getFullScreenSurface();
+        final SurfaceDrawingModel surface = webkitPlugin.getFullScreenSurface();
         if(surface == null) {
-            Log.e(LOGTAG, "Attempted to create an full-screen surface with a null drawing model");
+            Log.e(LOGTAG, "Attempted to create an full-screen surface with a " +
+                    "null drawing model");
             return;
         }
 
-        WebChromeClient.CustomViewCallback callback = new WebChromeClient.CustomViewCallback() {
-            public void onCustomViewHidden() {
-                if (surface != null) {
-                    surface.onSurfaceRemoved();
-                    nativeFullScreenPluginHidden(npp);
-                }
-            }
-        };
-
-        mCallbackProxy.showCustomView(surface.getSurface(), callback);
+        PluginFullScreenData data = new PluginFullScreenData();
+        data.mView = surface.getSurface();
+        data.mNpp = npp;
+        data.mDocX = x;
+        data.mDocY = y;
+        data.mDocWidth = width;
+        data.mDocHeight = height;
+        mWebView.mPrivateHandler.obtainMessage(WebView.SHOW_FULLSCREEN, data)
+                .sendToTarget();
     }
 
+    // called by JNI
     private void hideFullScreenPlugin() {
         if (mWebView == null) {
             return;
         }
+        mWebView.mPrivateHandler.obtainMessage(WebView.HIDE_FULLSCREEN)
+                .sendToTarget();
+    }
 
-        mCallbackProxy.hideCustomView();
+    // called by JNI
+    private void updateFullScreenPlugin(int x, int y, int width, int height) {
+        if (mWebView == null) {
+            return;
+        }
+
+        PluginFullScreenData data = new PluginFullScreenData();
+        data.mDocX = x;
+        data.mDocY = y;
+        data.mDocWidth = width;
+        data.mDocHeight = height;
+        // null mView and mNpp to indicate it is an update
+        mWebView.mPrivateHandler.obtainMessage(WebView.SHOW_FULLSCREEN, data)
+                .sendToTarget();
     }
 
     // called by JNI.  PluginWidget functions for creating an embedded View for
diff --git a/core/java/android/webkit/plugin/FullScreenDrawingModel.java b/core/java/android/webkit/plugin/FullScreenDrawingModel.java
deleted file mode 100644
index fe9d197..0000000
--- a/core/java/android/webkit/plugin/FullScreenDrawingModel.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 android.webkit.plugin;
-
-/**
- *
- * @hide pending API solidification
- */
-public interface FullScreenDrawingModel extends SurfaceDrawingModel {
-
-    public void onSurfaceRemoved();
-
-}
diff --git a/core/java/android/webkit/plugin/WebkitPlugin.java b/core/java/android/webkit/plugin/WebkitPlugin.java
index af02cdc..3d13c1c 100644
--- a/core/java/android/webkit/plugin/WebkitPlugin.java
+++ b/core/java/android/webkit/plugin/WebkitPlugin.java
@@ -30,7 +30,7 @@
  */
 public interface WebkitPlugin {
 
-    SurfaceDrawingModel    getEmbeddedSurface();
-    FullScreenDrawingModel getFullScreenSurface();
+    SurfaceDrawingModel getEmbeddedSurface();
+    SurfaceDrawingModel getFullScreenSurface();
 
 }