Merge change I11438c37 into eclair-mr2
* changes: Implement the full screen WebView plugin.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
120
core/java/android/webkit/PluginFullScreenHolder.java
Normal file
120
core/java/android/webkit/PluginFullScreenHolder.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -30,7 +30,7 @@ package android.webkit.plugin;
|
||||
*/
|
||||
public interface WebkitPlugin {
|
||||
|
||||
SurfaceDrawingModel getEmbeddedSurface();
|
||||
FullScreenDrawingModel getFullScreenSurface();
|
||||
SurfaceDrawingModel getEmbeddedSurface();
|
||||
SurfaceDrawingModel getFullScreenSurface();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user