Merge change I11438c37 into eclair-mr2

* changes:
  Implement the full screen WebView plugin.
This commit is contained in:
Android (Google) Code Review
2009-12-16 14:11:34 -08:00
6 changed files with 223 additions and 99 deletions

View File

@@ -108,8 +108,6 @@ class CallbackProxy extends Handler {
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 @@ class CallbackProxy extends Handler {
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 @@ class CallbackProxy extends Handler {
}
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);
}
}

View File

@@ -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);
}
}

View File

@@ -301,6 +301,9 @@ public class WebView extends AbsoluteLayout
// 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 @@ public class WebView extends AbsoluteLayout
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 @@ public class WebView extends AbsoluteLayout
"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 @@ public class WebView extends AbsoluteLayout
|| 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 @@ public class WebView extends AbsoluteLayout
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 @@ public class WebView extends AbsoluteLayout
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 @@ public class WebView extends AbsoluteLayout
// 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 @@ public class WebView extends AbsoluteLayout
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 @@ public class WebView extends AbsoluteLayout
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 @@ public class WebView extends AbsoluteLayout
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;

View File

@@ -41,7 +41,6 @@ import android.view.KeyEvent;
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 @@ final class WebViewCore {
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 @@ final class WebViewCore {
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 @@ final class WebViewCore {
message);
break;
}
case HIDE_FULLSCREEN:
nativeFullScreenPluginHidden(msg.arg1);
break;
}
}
};
@@ -2236,35 +2250,53 @@ final class WebViewCore {
// 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

View File

@@ -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();
}

View File

@@ -30,7 +30,7 @@ package android.webkit.plugin;
*/
public interface WebkitPlugin {
SurfaceDrawingModel getEmbeddedSurface();
FullScreenDrawingModel getFullScreenSurface();
SurfaceDrawingModel getEmbeddedSurface();
SurfaceDrawingModel getFullScreenSurface();
}