summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Dixon <joth@google.com>2012-02-28 18:45:06 +0000
committerJonathan Dixon <joth@google.com>2012-03-02 11:17:47 +0000
commit3c90952036a5ff7ddb2946c643f1a0bf1c31d53a (patch)
tree974ef2a94c60a2c72b8fbd804613792480a9c3e5
parent0dc0da67d9775b2364a38d015e0610492708a02e (diff)
downloadframeworks_base-3c90952036a5ff7ddb2946c643f1a0bf1c31d53a.zip
frameworks_base-3c90952036a5ff7ddb2946c643f1a0bf1c31d53a.tar.gz
frameworks_base-3c90952036a5ff7ddb2946c643f1a0bf1c31d53a.tar.bz2
Refactor WebView to be a thin proxy class
Splits interface and implementation; all client calls are forwarded to an abstract WebViewProvider interface, and the existing implementation moved into the WebViewClassic implementor of this interface. Originally taken from a snapshot from the development branch, by: git diff HEAD 9a4c328a54cc05e5 | git apply - but then rebased to keep up to date with master Interdepends on webkit and Browser changes: https://android-git.corp.google.com/g/158979 https://android-git.corp.google.com/g/167911 Change-Id: I91403f32654ff308934e95c832d17b292a7d9b2e
-rw-r--r--core/java/android/webkit/AccessibilityInjector.java12
-rw-r--r--core/java/android/webkit/BrowserFrame.java4
-rw-r--r--core/java/android/webkit/CallbackProxy.java68
-rw-r--r--core/java/android/webkit/FindActionModeCallback.java8
-rwxr-xr-xcore/java/android/webkit/GeolocationService.java1
-rw-r--r--core/java/android/webkit/HTML5Audio.java2
-rw-r--r--core/java/android/webkit/HTML5VideoFullScreen.java2
-rw-r--r--core/java/android/webkit/HTML5VideoView.java2
-rw-r--r--core/java/android/webkit/HTML5VideoViewProxy.java12
-rw-r--r--core/java/android/webkit/JWebCoreJavaBridge.java14
-rw-r--r--core/java/android/webkit/OverScrollGlow.java8
-rw-r--r--core/java/android/webkit/PluginFullScreenHolder.java6
-rw-r--r--core/java/android/webkit/PluginManager.java2
-rw-r--r--core/java/android/webkit/SelectActionModeCallback.java4
-rw-r--r--core/java/android/webkit/ViewManager.java14
-rw-r--r--core/java/android/webkit/ViewStateSerializer.java4
-rw-r--r--core/java/android/webkit/WebSettings.java1127
-rw-r--r--core/java/android/webkit/WebSettingsClassic.java597
-rw-r--r--core/java/android/webkit/WebTextView.java10
-rw-r--r--core/java/android/webkit/WebView.java9418
-rw-r--r--core/java/android/webkit/WebViewClassic.java736
-rw-r--r--core/java/android/webkit/WebViewCore.java118
-rw-r--r--core/java/android/webkit/WebViewFactoryProvider.java56
-rw-r--r--core/java/android/webkit/WebViewProvider.java372
-rw-r--r--core/java/android/webkit/ZoomControlEmbedded.java8
-rw-r--r--core/java/android/webkit/ZoomControlExternal.java4
-rw-r--r--core/java/android/webkit/ZoomManager.java26
-rw-r--r--core/tests/coretests/src/android/webkit/ZoomManagerTest.java5
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java29
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java24
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java3
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java52
32 files changed, 1714 insertions, 11034 deletions
diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java
index db66305..11bd815 100644
--- a/core/java/android/webkit/AccessibilityInjector.java
+++ b/core/java/android/webkit/AccessibilityInjector.java
@@ -79,8 +79,8 @@ class AccessibilityInjector {
private static ArrayList<AccessibilityWebContentKeyBinding> sBindings =
new ArrayList<AccessibilityWebContentKeyBinding>();
- // handle to the WebView this injector is associated with.
- private final WebView mWebView;
+ // handle to the WebViewClassic this injector is associated with.
+ private final WebViewClassic mWebView;
// events scheduled for sending as soon as we receive the selected text
private final Stack<AccessibilityEvent> mScheduledEventStack = new Stack<AccessibilityEvent>();
@@ -98,11 +98,11 @@ class AccessibilityInjector {
private int mLastDirection;
/**
- * Creates a new injector associated with a given {@link WebView}.
+ * Creates a new injector associated with a given {@link WebViewClassic}.
*
- * @param webView The associated WebView.
+ * @param webView The associated WebViewClassic.
*/
- public AccessibilityInjector(WebView webView) {
+ public AccessibilityInjector(WebViewClassic webView) {
mWebView = webView;
ensureWebContentKeyBindings();
}
@@ -327,7 +327,7 @@ class AccessibilityInjector {
AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_SELECTED);
event.setClassName(mWebView.getClass().getName());
event.setPackageName(mWebView.getContext().getPackageName());
- event.setEnabled(mWebView.isEnabled());
+ event.setEnabled(mWebView.getWebView().isEnabled());
return event;
}
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 8ccc59c7..f09e29d 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -70,7 +70,7 @@ class BrowserFrame extends Handler {
private final static int MAX_OUTSTANDING_REQUESTS = 300;
private final CallbackProxy mCallbackProxy;
- private final WebSettings mSettings;
+ private final WebSettingsClassic mSettings;
private final Context mContext;
private final WebViewDatabase mDatabase;
private final WebViewCore mWebViewCore;
@@ -200,7 +200,7 @@ class BrowserFrame extends Handler {
* XXX: Called by WebCore thread.
*/
public BrowserFrame(Context context, WebViewCore w, CallbackProxy proxy,
- WebSettings settings, Map<String, Object> javascriptInterfaces) {
+ WebSettingsClassic settings, Map<String, Object> javascriptInterfaces) {
Context appContext = context.getApplicationContext();
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 3a05bca..484c449 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -61,8 +61,8 @@ class CallbackProxy extends Handler {
private volatile WebViewClient mWebViewClient;
// Instance of WebChromeClient for handling all chrome functions.
private volatile WebChromeClient mWebChromeClient;
- // Instance of WebView for handling UI requests.
- private final WebView mWebView;
+ // Instance of WebViewClassic for handling UI requests.
+ private final WebViewClassic mWebView;
// Client registered callback listener for download events
private volatile DownloadListener mDownloadListener;
// Keep track of multiple progress updates.
@@ -148,7 +148,7 @@ class CallbackProxy extends Handler {
/**
* Construct a new CallbackProxy.
*/
- public CallbackProxy(Context context, WebView w) {
+ public CallbackProxy(Context context, WebViewClassic w) {
// Used to start a default activity.
mContext = context;
mWebView = w;
@@ -221,7 +221,7 @@ class CallbackProxy extends Handler {
}
boolean override = false;
if (mWebViewClient != null) {
- override = mWebViewClient.shouldOverrideUrlLoading(mWebView,
+ override = mWebViewClient.shouldOverrideUrlLoading(mWebView.getWebView(),
overrideUrl);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW,
@@ -248,7 +248,7 @@ class CallbackProxy extends Handler {
*/
public boolean uiOverrideKeyEvent(KeyEvent event) {
if (mWebViewClient != null) {
- return mWebViewClient.shouldOverrideKeyEvent(mWebView, event);
+ return mWebViewClient.shouldOverrideKeyEvent(mWebView.getWebView(), event);
}
return false;
}
@@ -264,7 +264,8 @@ class CallbackProxy extends Handler {
String startedUrl = msg.getData().getString("url");
mWebView.onPageStarted(startedUrl);
if (mWebViewClient != null) {
- mWebViewClient.onPageStarted(mWebView, startedUrl, (Bitmap) msg.obj);
+ mWebViewClient.onPageStarted(mWebView.getWebView(), startedUrl,
+ (Bitmap) msg.obj);
}
break;
@@ -272,26 +273,26 @@ class CallbackProxy extends Handler {
String finishedUrl = (String) msg.obj;
mWebView.onPageFinished(finishedUrl);
if (mWebViewClient != null) {
- mWebViewClient.onPageFinished(mWebView, finishedUrl);
+ mWebViewClient.onPageFinished(mWebView.getWebView(), finishedUrl);
}
break;
case RECEIVED_ICON:
if (mWebChromeClient != null) {
- mWebChromeClient.onReceivedIcon(mWebView, (Bitmap) msg.obj);
+ mWebChromeClient.onReceivedIcon(mWebView.getWebView(), (Bitmap) msg.obj);
}
break;
case RECEIVED_TOUCH_ICON_URL:
if (mWebChromeClient != null) {
- mWebChromeClient.onReceivedTouchIconUrl(mWebView,
+ mWebChromeClient.onReceivedTouchIconUrl(mWebView.getWebView(),
(String) msg.obj, msg.arg1 == 1);
}
break;
case RECEIVED_TITLE:
if (mWebChromeClient != null) {
- mWebChromeClient.onReceivedTitle(mWebView,
+ mWebChromeClient.onReceivedTitle(mWebView.getWebView(),
(String) msg.obj);
}
break;
@@ -301,7 +302,7 @@ class CallbackProxy extends Handler {
int reasonCode = msg.arg1;
final String description = msg.getData().getString("description");
final String failUrl = msg.getData().getString("failingUrl");
- mWebViewClient.onReceivedError(mWebView, reasonCode,
+ mWebViewClient.onReceivedError(mWebView.getWebView(), reasonCode,
description, failUrl);
}
break;
@@ -312,7 +313,7 @@ class CallbackProxy extends Handler {
Message dontResend =
(Message) msg.getData().getParcelable("dontResend");
if (mWebViewClient != null) {
- mWebViewClient.onFormResubmission(mWebView, dontResend,
+ mWebViewClient.onFormResubmission(mWebView.getWebView(), dontResend,
resend);
} else {
dontResend.sendToTarget();
@@ -335,7 +336,7 @@ class CallbackProxy extends Handler {
HttpAuthHandler handler = (HttpAuthHandler) msg.obj;
String host = msg.getData().getString("host");
String realm = msg.getData().getString("realm");
- mWebViewClient.onReceivedHttpAuthRequest(mWebView, handler,
+ mWebViewClient.onReceivedHttpAuthRequest(mWebView.getWebView(), handler,
host, realm);
}
break;
@@ -344,7 +345,7 @@ class CallbackProxy extends Handler {
if (mWebViewClient != null) {
HashMap<String, Object> map =
(HashMap<String, Object>) msg.obj;
- mWebViewClient.onReceivedSslError(mWebView,
+ mWebViewClient.onReceivedSslError(mWebView.getWebView(),
(SslErrorHandler) map.get("handler"),
(SslError) map.get("error"));
}
@@ -352,7 +353,7 @@ class CallbackProxy extends Handler {
case PROCEEDED_AFTER_SSL_ERROR:
if (mWebViewClient != null) {
- mWebViewClient.onProceededAfterSslError(mWebView,
+ mWebViewClient.onProceededAfterSslError(mWebView.getWebView(),
(SslError) msg.obj);
}
break;
@@ -361,7 +362,7 @@ class CallbackProxy extends Handler {
if (mWebViewClient != null) {
HashMap<String, Object> map =
(HashMap<String, Object>) msg.obj;
- mWebViewClient.onReceivedClientCertRequest(mWebView,
+ mWebViewClient.onReceivedClientCertRequest(mWebView.getWebView(),
(ClientCertRequestHandler) map.get("handler"),
(String) map.get("host_and_port"));
}
@@ -373,7 +374,7 @@ class CallbackProxy extends Handler {
// changed.
synchronized (this) {
if (mWebChromeClient != null) {
- mWebChromeClient.onProgressChanged(mWebView,
+ mWebChromeClient.onProgressChanged(mWebView.getWebView(),
mLatestProgress);
}
mProgressUpdatePending = false;
@@ -382,14 +383,14 @@ class CallbackProxy extends Handler {
case UPDATE_VISITED:
if (mWebViewClient != null) {
- mWebViewClient.doUpdateVisitedHistory(mWebView,
+ mWebViewClient.doUpdateVisitedHistory(mWebView.getWebView(),
(String) msg.obj, msg.arg1 != 0);
}
break;
case LOAD_RESOURCE:
if (mWebViewClient != null) {
- mWebViewClient.onLoadResource(mWebView, (String) msg.obj);
+ mWebViewClient.onLoadResource(mWebView.getWebView(), (String) msg.obj);
}
break;
@@ -409,7 +410,7 @@ class CallbackProxy extends Handler {
case CREATE_WINDOW:
if (mWebChromeClient != null) {
- if (!mWebChromeClient.onCreateWindow(mWebView,
+ if (!mWebChromeClient.onCreateWindow(mWebView.getWebView(),
msg.arg1 == 1, msg.arg2 == 1,
(Message) msg.obj)) {
synchronized (this) {
@@ -422,13 +423,13 @@ class CallbackProxy extends Handler {
case REQUEST_FOCUS:
if (mWebChromeClient != null) {
- mWebChromeClient.onRequestFocus(mWebView);
+ mWebChromeClient.onRequestFocus(mWebView.getWebView());
}
break;
case CLOSE_WINDOW:
if (mWebChromeClient != null) {
- mWebChromeClient.onCloseWindow((WebView) msg.obj);
+ mWebChromeClient.onCloseWindow(((WebViewClassic) msg.obj).getWebView());
}
break;
@@ -449,7 +450,7 @@ class CallbackProxy extends Handler {
case ASYNC_KEYEVENTS:
if (mWebViewClient != null) {
- mWebViewClient.onUnhandledKeyEvent(mWebView,
+ mWebViewClient.onUnhandledKeyEvent(mWebView.getWebView(),
(KeyEvent) msg.obj);
}
break;
@@ -516,7 +517,7 @@ class CallbackProxy extends Handler {
final JsResult res = (JsResult) msg.obj;
String message = msg.getData().getString("message");
String url = msg.getData().getString("url");
- if (!mWebChromeClient.onJsAlert(mWebView, url, message,
+ if (!mWebChromeClient.onJsAlert(mWebView.getWebView(), url, message,
res)) {
if (!canShowAlertDialog()) {
res.cancel();
@@ -552,7 +553,7 @@ class CallbackProxy extends Handler {
final JsResult res = (JsResult) msg.obj;
String message = msg.getData().getString("message");
String url = msg.getData().getString("url");
- if (!mWebChromeClient.onJsConfirm(mWebView, url, message,
+ if (!mWebChromeClient.onJsConfirm(mWebView.getWebView(), url, message,
res)) {
if (!canShowAlertDialog()) {
res.cancel();
@@ -597,7 +598,7 @@ class CallbackProxy extends Handler {
String message = msg.getData().getString("message");
String defaultVal = msg.getData().getString("default");
String url = msg.getData().getString("url");
- if (!mWebChromeClient.onJsPrompt(mWebView, url, message,
+ if (!mWebChromeClient.onJsPrompt(mWebView.getWebView(), url, message,
defaultVal, res)) {
if (!canShowAlertDialog()) {
res.cancel();
@@ -653,7 +654,7 @@ class CallbackProxy extends Handler {
final JsResult res = (JsResult) msg.obj;
String message = msg.getData().getString("message");
String url = msg.getData().getString("url");
- if (!mWebChromeClient.onJsBeforeUnload(mWebView, url,
+ if (!mWebChromeClient.onJsBeforeUnload(mWebView.getWebView(), url,
message, res)) {
if (!canShowAlertDialog()) {
res.cancel();
@@ -710,7 +711,7 @@ class CallbackProxy extends Handler {
case SCALE_CHANGED:
if (mWebViewClient != null) {
- mWebViewClient.onScaleChanged(mWebView, msg.getData()
+ mWebViewClient.onScaleChanged(mWebView.getWebView(), msg.getData()
.getFloat("old"), msg.getData().getFloat("new"));
}
break;
@@ -817,7 +818,7 @@ class CallbackProxy extends Handler {
String realm = msg.getData().getString("realm");
String account = msg.getData().getString("account");
String args = msg.getData().getString("args");
- mWebViewClient.onReceivedLoginRequest(mWebView, realm,
+ mWebViewClient.onReceivedLoginRequest(mWebView.getWebView(), realm,
account, args);
}
break;
@@ -1074,7 +1075,7 @@ class CallbackProxy extends Handler {
}
// Note: This method does _not_ send a message.
WebResourceResponse r =
- mWebViewClient.shouldInterceptRequest(mWebView, url);
+ mWebViewClient.shouldInterceptRequest(mWebView.getWebView(), url);
if (r == null) {
sendMessage(obtainMessage(LOAD_RESOURCE, url));
}
@@ -1219,7 +1220,8 @@ class CallbackProxy extends Handler {
return null;
}
- WebView.WebViewTransport transport = mWebView.new WebViewTransport();
+ WebView.WebViewTransport transport =
+ mWebView.getWebView().new WebViewTransport();
final Message msg = obtainMessage(NOTIFY);
msg.obj = transport;
synchronized (this) {
@@ -1234,7 +1236,7 @@ class CallbackProxy extends Handler {
}
}
- WebView w = transport.getWebView();
+ WebViewClassic w = WebViewClassic.fromWebView(transport.getWebView());
if (w != null) {
WebViewCore core = w.getWebViewCore();
// If WebView.destroy() has been called, core may be null. Skip
@@ -1257,7 +1259,7 @@ class CallbackProxy extends Handler {
sendEmptyMessage(REQUEST_FOCUS);
}
- public void onCloseWindow(WebView window) {
+ public void onCloseWindow(WebViewClassic window) {
// Do an unsynchronized quick check to avoid posting if no callback has
// been set.
if (mWebChromeClient == null) {
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
index 10b0885..964cf3e 100644
--- a/core/java/android/webkit/FindActionModeCallback.java
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -38,7 +38,7 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
private View mCustomView;
private EditText mEditText;
private TextView mMatches;
- private WebView mWebView;
+ private WebViewClassic mWebView;
private InputMethodManager mInput;
private Resources mResources;
private boolean mMatchesFound;
@@ -90,7 +90,7 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
* Set the WebView to search. Must be non null, and set before calling
* startActionMode.
*/
- void setWebView(WebView webView) {
+ void setWebView(WebViewClassic webView) {
if (null == webView) {
throw new AssertionError("WebView supplied to "
+ "FindActionModeCallback cannot be null");
@@ -218,7 +218,7 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
mWebView.notifyFindDialogDismissed();
- mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
+ mInput.hideSoftInputFromWindow(mWebView.getWebView().getWindowToken(), 0);
}
@Override
@@ -232,7 +232,7 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
throw new AssertionError(
"No WebView for FindActionModeCallback::onActionItemClicked");
}
- mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
+ mInput.hideSoftInputFromWindow(mWebView.getWebView().getWindowToken(), 0);
switch(item.getItemId()) {
case com.android.internal.R.id.find_prev:
findNext(false);
diff --git a/core/java/android/webkit/GeolocationService.java b/core/java/android/webkit/GeolocationService.java
index 91de1d8..225053b 100755
--- a/core/java/android/webkit/GeolocationService.java
+++ b/core/java/android/webkit/GeolocationService.java
@@ -24,7 +24,6 @@ import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
-import android.webkit.WebView;
import android.webkit.WebViewCore;
diff --git a/core/java/android/webkit/HTML5Audio.java b/core/java/android/webkit/HTML5Audio.java
index aedecf0..8e1f573 100644
--- a/core/java/android/webkit/HTML5Audio.java
+++ b/core/java/android/webkit/HTML5Audio.java
@@ -92,7 +92,7 @@ class HTML5Audio extends Handler
private class IsPrivateBrowsingEnabledGetter {
private boolean mIsReady;
private boolean mIsPrivateBrowsingEnabled;
- IsPrivateBrowsingEnabledGetter(Looper uiThreadLooper, final WebView webView) {
+ IsPrivateBrowsingEnabledGetter(Looper uiThreadLooper, final WebViewClassic webView) {
new Handler(uiThreadLooper).post(new Runnable() {
@Override
public void run() {
diff --git a/core/java/android/webkit/HTML5VideoFullScreen.java b/core/java/android/webkit/HTML5VideoFullScreen.java
index bc0557e..fac549d 100644
--- a/core/java/android/webkit/HTML5VideoFullScreen.java
+++ b/core/java/android/webkit/HTML5VideoFullScreen.java
@@ -236,7 +236,7 @@ public class HTML5VideoFullScreen extends HTML5VideoView
@Override
public void enterFullScreenVideoState(int layerId,
- HTML5VideoViewProxy proxy, WebView webView) {
+ HTML5VideoViewProxy proxy, WebViewClassic webView) {
mFullScreenMode = FULLSCREEN_SURFACECREATING;
mCurrentBufferPercentage = 0;
mPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
diff --git a/core/java/android/webkit/HTML5VideoView.java b/core/java/android/webkit/HTML5VideoView.java
index 73166cb..0d3b755 100644
--- a/core/java/android/webkit/HTML5VideoView.java
+++ b/core/java/android/webkit/HTML5VideoView.java
@@ -280,7 +280,7 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
// screen mode. Some are specific to one type, but currently are called
// directly from the proxy.
public void enterFullScreenVideoState(int layerId,
- HTML5VideoViewProxy proxy, WebView webView) {
+ HTML5VideoViewProxy proxy, WebViewClassic webView) {
}
public boolean isFullScreenMode() {
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index d306c86..1644b06 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -75,8 +75,8 @@ class HTML5VideoViewProxy extends Handler
int mNativePointer;
// The handler for WebCore thread messages;
private Handler mWebCoreHandler;
- // The WebView instance that created this view.
- private WebView mWebView;
+ // The WebViewClassic instance that created this view.
+ private WebViewClassic mWebView;
// The poster image to be shown when the video is not playing.
// This ref prevents the bitmap from being GC'ed.
private Bitmap mPoster;
@@ -142,7 +142,7 @@ class HTML5VideoViewProxy extends Handler
}
public static void enterFullScreenVideo(int layerId, String url,
- HTML5VideoViewProxy proxy, WebView webView) {
+ HTML5VideoViewProxy proxy, WebViewClassic webView) {
// Save the inline video info and inherit it in the full screen
int savePosition = 0;
if (mHTML5VideoView != null) {
@@ -163,7 +163,7 @@ class HTML5VideoViewProxy extends Handler
}
public static void exitFullScreenVideo(HTML5VideoViewProxy proxy,
- WebView webView) {
+ WebViewClassic webView) {
if (!mHTML5VideoView.fullScreenExited() && mHTML5VideoView.isFullScreenMode()) {
WebChromeClient client = webView.getWebChromeClient();
if (client != null) {
@@ -551,7 +551,7 @@ class HTML5VideoViewProxy extends Handler
* @param webView is the WebView that hosts the video.
* @param nativePtr is the C++ pointer to the MediaPlayerPrivate object.
*/
- private HTML5VideoViewProxy(WebView webView, int nativePtr) {
+ private HTML5VideoViewProxy(WebViewClassic webView, int nativePtr) {
// This handler is for the main (UI) thread.
super(Looper.getMainLooper());
// Save the WebView object.
@@ -721,7 +721,7 @@ class HTML5VideoViewProxy extends Handler
return new HTML5VideoViewProxy(webViewCore.getWebView(), nativePtr);
}
- /* package */ WebView getWebView() {
+ /* package */ WebViewClassic getWebView() {
return mWebView;
}
diff --git a/core/java/android/webkit/JWebCoreJavaBridge.java b/core/java/android/webkit/JWebCoreJavaBridge.java
index b498435..e6eaa14 100644
--- a/core/java/android/webkit/JWebCoreJavaBridge.java
+++ b/core/java/android/webkit/JWebCoreJavaBridge.java
@@ -43,10 +43,10 @@ final class JWebCoreJavaBridge extends Handler {
private boolean mTimerPaused;
private boolean mHasDeferredTimers;
- // keep track of the main WebView attached to the current window so that we
+ // keep track of the main WebViewClassic attached to the current window so that we
// can get the proper Context.
- private static WeakReference<WebView> sCurrentMainWebView =
- new WeakReference<WebView>(null);
+ private static WeakReference<WebViewClassic> sCurrentMainWebView =
+ new WeakReference<WebViewClassic>(null);
/* package */
static final int REFRESH_PLUGINS = 100;
@@ -67,15 +67,15 @@ final class JWebCoreJavaBridge extends Handler {
nativeFinalize();
}
- static synchronized void setActiveWebView(WebView webview) {
+ static synchronized void setActiveWebView(WebViewClassic webview) {
if (sCurrentMainWebView.get() != null) {
// it is possible if there is a sub-WebView. Do nothing.
return;
}
- sCurrentMainWebView = new WeakReference<WebView>(webview);
+ sCurrentMainWebView = new WeakReference<WebViewClassic>(webview);
}
- static synchronized void removeActiveWebView(WebView webview) {
+ static synchronized void removeActiveWebView(WebViewClassic webview) {
if (sCurrentMainWebView.get() != webview) {
// it is possible if there is a sub-WebView. Do nothing.
return;
@@ -259,7 +259,7 @@ final class JWebCoreJavaBridge extends Handler {
synchronized private String getSignedPublicKey(int index, String challenge,
String url) {
- WebView current = sCurrentMainWebView.get();
+ WebViewClassic current = sCurrentMainWebView.get();
if (current != null) {
// generateKeyPair expects organizations which we don't have. Ignore
// url.
diff --git a/core/java/android/webkit/OverScrollGlow.java b/core/java/android/webkit/OverScrollGlow.java
index e906f7f..d91f860 100644
--- a/core/java/android/webkit/OverScrollGlow.java
+++ b/core/java/android/webkit/OverScrollGlow.java
@@ -29,7 +29,7 @@ import android.widget.EdgeEffect;
* @hide
*/
public class OverScrollGlow {
- private WebView mHostView;
+ private WebViewClassic mHostView;
private EdgeEffect mEdgeGlowTop;
private EdgeEffect mEdgeGlowBottom;
@@ -39,7 +39,7 @@ public class OverScrollGlow {
private int mOverScrollDeltaX;
private int mOverScrollDeltaY;
- public OverScrollGlow(WebView host) {
+ public OverScrollGlow(WebViewClassic host) {
mHostView = host;
Context context = host.getContext();
mEdgeGlowTop = new EdgeEffect(context);
@@ -80,7 +80,7 @@ public class OverScrollGlow {
mOverScrollDeltaX = 0;
}
- if (maxY > 0 || mHostView.getOverScrollMode() == View.OVER_SCROLL_ALWAYS) {
+ if (maxY > 0 || mHostView.getWebView().getOverScrollMode() == View.OVER_SCROLL_ALWAYS) {
final int pulledToY = oldY + mOverScrollDeltaY;
if (pulledToY < 0) {
mEdgeGlowTop.onPull((float) mOverScrollDeltaY / mHostView.getHeight());
@@ -120,7 +120,7 @@ public class OverScrollGlow {
* @param rangeY Maximum range for vertical scrolling
*/
public void absorbGlow(int x, int y, int oldX, int oldY, int rangeX, int rangeY) {
- if (rangeY > 0 || mHostView.getOverScrollMode() == View.OVER_SCROLL_ALWAYS) {
+ if (rangeY > 0 || mHostView.getWebView().getOverScrollMode() == View.OVER_SCROLL_ALWAYS) {
if (y < 0 && oldY >= 0) {
mEdgeGlowTop.onAbsorb((int) mHostView.mScroller.getCurrVelocity());
if (!mEdgeGlowBottom.isFinished()) {
diff --git a/core/java/android/webkit/PluginFullScreenHolder.java b/core/java/android/webkit/PluginFullScreenHolder.java
index 42ba7c9..665cd9d 100644
--- a/core/java/android/webkit/PluginFullScreenHolder.java
+++ b/core/java/android/webkit/PluginFullScreenHolder.java
@@ -35,7 +35,7 @@ import android.widget.FrameLayout;
class PluginFullScreenHolder {
- private final WebView mWebView;
+ private final WebViewClassic mWebView;
private final int mNpp;
private final int mOrientation;
@@ -44,7 +44,7 @@ class PluginFullScreenHolder {
private View mContentView;
- PluginFullScreenHolder(WebView webView, int orientation, int npp) {
+ PluginFullScreenHolder(WebViewClassic webView, int orientation, int npp) {
mWebView = webView;
mNpp = npp;
mOrientation = orientation;
@@ -134,7 +134,7 @@ class PluginFullScreenHolder {
new WebChromeClient.CustomViewCallback() {
public void onCustomViewHidden() {
- mWebView.mPrivateHandler.obtainMessage(WebView.HIDE_FULLSCREEN)
+ mWebView.mPrivateHandler.obtainMessage(WebViewClassic.HIDE_FULLSCREEN)
.sendToTarget();
mWebView.getWebViewCore().sendMessage(
diff --git a/core/java/android/webkit/PluginManager.java b/core/java/android/webkit/PluginManager.java
index ab3b6d5..fe40156 100644
--- a/core/java/android/webkit/PluginManager.java
+++ b/core/java/android/webkit/PluginManager.java
@@ -34,7 +34,7 @@ import android.os.SystemProperties;
import android.util.Log;
/**
- * Class for managing the relationship between the {@link WebView} and installed
+ * Class for managing the relationship between the {@link WebViewClassic} and installed
* plugins in the system. You can find this class through
* {@link PluginManager#getInstance}.
*
diff --git a/core/java/android/webkit/SelectActionModeCallback.java b/core/java/android/webkit/SelectActionModeCallback.java
index 2a770f5..57628d3 100644
--- a/core/java/android/webkit/SelectActionModeCallback.java
+++ b/core/java/android/webkit/SelectActionModeCallback.java
@@ -26,11 +26,11 @@ import android.view.Menu;
import android.view.MenuItem;
class SelectActionModeCallback implements ActionMode.Callback {
- private WebView mWebView;
+ private WebViewClassic mWebView;
private ActionMode mActionMode;
private boolean mIsTextSelected = true;
- void setWebView(WebView webView) {
+ void setWebView(WebViewClassic webView) {
mWebView = webView;
}
diff --git a/core/java/android/webkit/ViewManager.java b/core/java/android/webkit/ViewManager.java
index 153c1c2..34065a1 100644
--- a/core/java/android/webkit/ViewManager.java
+++ b/core/java/android/webkit/ViewManager.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.util.DisplayMetrics;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
@@ -24,7 +25,7 @@ import android.widget.AbsoluteLayout;
import java.util.ArrayList;
class ViewManager {
- private final WebView mWebView;
+ private final WebViewClassic mWebView;
private final ArrayList<ChildView> mChildren = new ArrayList<ChildView>();
private boolean mHidden;
private boolean mReadyToDraw;
@@ -74,7 +75,7 @@ class ViewManager {
}
private void attachViewOnUIThread() {
- mWebView.addView(mView);
+ mWebView.getWebView().addView(mView);
mChildren.add(this);
if (!mReadyToDraw) {
mView.setVisibility(View.GONE);
@@ -93,16 +94,15 @@ class ViewManager {
}
private void removeViewOnUIThread() {
- mWebView.removeView(mView);
+ mWebView.getWebView().removeView(mView);
mChildren.remove(this);
}
}
- ViewManager(WebView w) {
+ ViewManager(WebViewClassic w) {
mWebView = w;
-
- int pixelArea = w.getResources().getDisplayMetrics().widthPixels *
- w.getResources().getDisplayMetrics().heightPixels;
+ DisplayMetrics metrics = w.getWebView().getResources().getDisplayMetrics();
+ int pixelArea = metrics.widthPixels * metrics.heightPixels;
/* set the threshold to be 275% larger than the screen size. The
percentage is simply an estimation and is not based on anything but
basic trial-and-error tests run on multiple devices.
diff --git a/core/java/android/webkit/ViewStateSerializer.java b/core/java/android/webkit/ViewStateSerializer.java
index 5f91ed3..a22fc26 100644
--- a/core/java/android/webkit/ViewStateSerializer.java
+++ b/core/java/android/webkit/ViewStateSerializer.java
@@ -34,7 +34,7 @@ class ViewStateSerializer {
static final int VERSION = 1;
- static boolean serializeViewState(OutputStream stream, WebView web)
+ static boolean serializeViewState(OutputStream stream, WebViewClassic web)
throws IOException {
int baseLayer = web.getBaseLayer();
if (baseLayer == 0) {
@@ -48,7 +48,7 @@ class ViewStateSerializer {
new byte[WORKING_STREAM_STORAGE]);
}
- static DrawData deserializeViewState(InputStream stream, WebView web)
+ static DrawData deserializeViewState(InputStream stream, WebViewClassic web)
throws IOException {
DataInputStream dis = new DataInputStream(stream);
int version = dis.readInt();
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index c463b40..cddd7ab 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -16,16 +16,7 @@
package android.webkit;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Handler;
import android.os.Message;
-import android.util.DisplayMetrics;
-import android.util.EventLog;
-
-import java.util.Locale;
/**
* Manages settings state for a WebView. When a WebView is first created, it
@@ -35,7 +26,18 @@ import java.util.Locale;
* been destroyed, any method call on WebSettings will throw an
* IllegalStateException.
*/
+// This is (effectively) an abstract base class; concrete WebViewProviders must
+// create a class derived from this, and return an instance of it in the
+// WebViewProvider.getWebSettingsProvider() method implementation.
public class WebSettings {
+ // TODO: Remove MustOverrideException and make all methods throwing it abstract instead;
+ // needs API file update.
+ private static class MustOverrideException extends RuntimeException {
+ MustOverrideException() {
+ super("abstract function called: must be overriden!");
+ }
+ }
+
/**
* Enum for controlling the layout of html.
* NORMAL means no rendering changes.
@@ -141,379 +143,12 @@ public class WebSettings {
OFF
}
- // TODO: Keep this up to date
- private static final String PREVIOUS_VERSION = "4.0.3";
-
- // WebView associated with this WebSettings.
- private WebView mWebView;
- // BrowserFrame used to access the native frame pointer.
- private BrowserFrame mBrowserFrame;
- // Flag to prevent multiple SYNC messages at one time.
- private boolean mSyncPending = false;
- // Custom handler that queues messages until the WebCore thread is active.
- private final EventHandler mEventHandler;
-
- // Private settings so we don't have to go into native code to
- // retrieve the values. After setXXX, postSync() needs to be called.
- //
- // The default values need to match those in WebSettings.cpp
- // If the defaults change, please also update the JavaDocs so developers
- // know what they are.
- private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
- private Context mContext;
- private int mTextSize = 100;
- private String mStandardFontFamily = "sans-serif";
- private String mFixedFontFamily = "monospace";
- private String mSansSerifFontFamily = "sans-serif";
- private String mSerifFontFamily = "serif";
- private String mCursiveFontFamily = "cursive";
- private String mFantasyFontFamily = "fantasy";
- private String mDefaultTextEncoding;
- private String mUserAgent;
- private boolean mUseDefaultUserAgent;
- private String mAcceptLanguage;
- private int mMinimumFontSize = 8;
- private int mMinimumLogicalFontSize = 8;
- private int mDefaultFontSize = 16;
- private int mDefaultFixedFontSize = 13;
- private int mPageCacheCapacity = 0;
- private boolean mLoadsImagesAutomatically = true;
- private boolean mBlockNetworkImage = false;
- private boolean mBlockNetworkLoads;
- private boolean mJavaScriptEnabled = false;
- private boolean mHardwareAccelSkia = false;
- private boolean mShowVisualIndicator = false;
- private PluginState mPluginState = PluginState.OFF;
- private boolean mJavaScriptCanOpenWindowsAutomatically = false;
- private boolean mUseDoubleTree = false;
- private boolean mUseWideViewport = false;
- private boolean mSupportMultipleWindows = false;
- private boolean mShrinksStandaloneImagesToFit = false;
- private long mMaximumDecodedImageSize = 0; // 0 means default
- private boolean mPrivateBrowsingEnabled = false;
- private boolean mSyntheticLinksEnabled = true;
- // HTML5 API flags
- private boolean mAppCacheEnabled = false;
- private boolean mDatabaseEnabled = false;
- private boolean mDomStorageEnabled = false;
- private boolean mWorkersEnabled = false; // only affects V8.
- private boolean mGeolocationEnabled = true;
- private boolean mXSSAuditorEnabled = false;
- // HTML5 configuration parameters
- private long mAppCacheMaxSize = Long.MAX_VALUE;
- private String mAppCachePath = null;
- private String mDatabasePath = "";
- // The WebCore DatabaseTracker only allows the database path to be set
- // once. Keep track of when the path has been set.
- private boolean mDatabasePathHasBeenSet = false;
- private String mGeolocationDatabasePath = "";
- // Don't need to synchronize the get/set methods as they
- // are basic types, also none of these values are used in
- // native WebCore code.
- private ZoomDensity mDefaultZoom = ZoomDensity.MEDIUM;
- private RenderPriority mRenderPriority = RenderPriority.NORMAL;
- private int mOverrideCacheMode = LOAD_DEFAULT;
- private int mDoubleTapZoom = 100;
- private boolean mSaveFormData = true;
- private boolean mAutoFillEnabled = false;
- private boolean mSavePassword = true;
- private boolean mLightTouchEnabled = false;
- private boolean mNeedInitialFocus = true;
- private boolean mNavDump = false;
- private boolean mSupportZoom = true;
- private boolean mBuiltInZoomControls = false;
- private boolean mDisplayZoomControls = true;
- private boolean mAllowFileAccess = true;
- private boolean mAllowContentAccess = true;
- private boolean mLoadWithOverviewMode = false;
- private boolean mEnableSmoothTransition = false;
- private boolean mForceUserScalable = false;
-
- // AutoFill Profile data
- /**
- * @hide for now, pending API council approval.
- */
- public static class AutoFillProfile {
- private int mUniqueId;
- private String mFullName;
- private String mEmailAddress;
- private String mCompanyName;
- private String mAddressLine1;
- private String mAddressLine2;
- private String mCity;
- private String mState;
- private String mZipCode;
- private String mCountry;
- private String mPhoneNumber;
-
- public AutoFillProfile(int uniqueId, String fullName, String email,
- String companyName, String addressLine1, String addressLine2,
- String city, String state, String zipCode, String country,
- String phoneNumber) {
- mUniqueId = uniqueId;
- mFullName = fullName;
- mEmailAddress = email;
- mCompanyName = companyName;
- mAddressLine1 = addressLine1;
- mAddressLine2 = addressLine2;
- mCity = city;
- mState = state;
- mZipCode = zipCode;
- mCountry = country;
- mPhoneNumber = phoneNumber;
- }
-
- public int getUniqueId() { return mUniqueId; }
- public String getFullName() { return mFullName; }
- public String getEmailAddress() { return mEmailAddress; }
- public String getCompanyName() { return mCompanyName; }
- public String getAddressLine1() { return mAddressLine1; }
- public String getAddressLine2() { return mAddressLine2; }
- public String getCity() { return mCity; }
- public String getState() { return mState; }
- public String getZipCode() { return mZipCode; }
- public String getCountry() { return mCountry; }
- public String getPhoneNumber() { return mPhoneNumber; }
- }
-
-
- private AutoFillProfile mAutoFillProfile;
-
- private boolean mUseWebViewBackgroundForOverscroll = true;
-
- // private WebSettings, not accessible by the host activity
- static private int mDoubleTapToastCount = 3;
-
- private static final String PREF_FILE = "WebViewSettings";
- private static final String DOUBLE_TAP_TOAST_COUNT = "double_tap_toast_count";
-
- // Class to handle messages before WebCore is ready.
- private class EventHandler {
- // Message id for syncing
- static final int SYNC = 0;
- // Message id for setting priority
- static final int PRIORITY = 1;
- // Message id for writing double-tap toast count
- static final int SET_DOUBLE_TAP_TOAST_COUNT = 2;
- // Actual WebCore thread handler
- private Handler mHandler;
-
- private synchronized void createHandler() {
- // as mRenderPriority can be set before thread is running, sync up
- setRenderPriority();
-
- // create a new handler
- mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case SYNC:
- synchronized (WebSettings.this) {
- if (mBrowserFrame.mNativeFrame != 0) {
- nativeSync(mBrowserFrame.mNativeFrame);
- }
- mSyncPending = false;
- }
- break;
-
- case PRIORITY: {
- setRenderPriority();
- break;
- }
-
- case SET_DOUBLE_TAP_TOAST_COUNT: {
- SharedPreferences.Editor editor = mContext
- .getSharedPreferences(PREF_FILE,
- Context.MODE_PRIVATE).edit();
- editor.putInt(DOUBLE_TAP_TOAST_COUNT,
- mDoubleTapToastCount);
- editor.commit();
- break;
- }
- }
- }
- };
- }
-
- private void setRenderPriority() {
- synchronized (WebSettings.this) {
- if (mRenderPriority == RenderPriority.NORMAL) {
- android.os.Process.setThreadPriority(
- android.os.Process.THREAD_PRIORITY_DEFAULT);
- } else if (mRenderPriority == RenderPriority.HIGH) {
- android.os.Process.setThreadPriority(
- android.os.Process.THREAD_PRIORITY_FOREGROUND +
- android.os.Process.THREAD_PRIORITY_LESS_FAVORABLE);
- } else if (mRenderPriority == RenderPriority.LOW) {
- android.os.Process.setThreadPriority(
- android.os.Process.THREAD_PRIORITY_BACKGROUND);
- }
- }
- }
-
- /**
- * Send a message to the private queue or handler.
- */
- private synchronized boolean sendMessage(Message msg) {
- if (mHandler != null) {
- mHandler.sendMessage(msg);
- return true;
- } else {
- return false;
- }
- }
- }
-
- // User agent strings.
- private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (X11; " +
- "Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) " +
- "Chrome/11.0.696.34 Safari/534.24";
- private static final String IPHONE_USERAGENT =
- "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us)"
- + " AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0"
- + " Mobile/7A341 Safari/528.16";
- private static Locale sLocale;
- private static Object sLockForLocaleSettings;
-
- /**
- * Package constructor to prevent clients from creating a new settings
- * instance.
- */
- WebSettings(Context context, WebView webview) {
- mEventHandler = new EventHandler();
- mContext = context;
- mWebView = webview;
- mDefaultTextEncoding = context.getString(com.android.internal.
- R.string.default_text_encoding);
-
- if (sLockForLocaleSettings == null) {
- sLockForLocaleSettings = new Object();
- sLocale = Locale.getDefault();
- }
- mAcceptLanguage = getCurrentAcceptLanguage();
- mUserAgent = getCurrentUserAgent();
- mUseDefaultUserAgent = true;
-
- mBlockNetworkLoads = mContext.checkPermission(
- "android.permission.INTERNET", android.os.Process.myPid(),
- android.os.Process.myUid()) != PackageManager.PERMISSION_GRANTED;
- }
-
- private static final String ACCEPT_LANG_FOR_US_LOCALE = "en-US";
-
- /**
- * Looks at sLocale and returns current AcceptLanguage String.
- * @return Current AcceptLanguage String.
- */
- private String getCurrentAcceptLanguage() {
- Locale locale;
- synchronized(sLockForLocaleSettings) {
- locale = sLocale;
- }
- StringBuilder buffer = new StringBuilder();
- addLocaleToHttpAcceptLanguage(buffer, locale);
-
- if (!Locale.US.equals(locale)) {
- if (buffer.length() > 0) {
- buffer.append(", ");
- }
- buffer.append(ACCEPT_LANG_FOR_US_LOCALE);
- }
-
- return buffer.toString();
- }
-
/**
- * Convert obsolete language codes, including Hebrew/Indonesian/Yiddish,
- * to new standard.
+ * Hidden constructor to prevent clients from creating a new settings
+ * instance or deriving the class.
+ * @hide
*/
- private static String convertObsoleteLanguageCodeToNew(String langCode) {
- if (langCode == null) {
- return null;
- }
- if ("iw".equals(langCode)) {
- // Hebrew
- return "he";
- } else if ("in".equals(langCode)) {
- // Indonesian
- return "id";
- } else if ("ji".equals(langCode)) {
- // Yiddish
- return "yi";
- }
- return langCode;
- }
-
- private static void addLocaleToHttpAcceptLanguage(StringBuilder builder,
- Locale locale) {
- String language = convertObsoleteLanguageCodeToNew(locale.getLanguage());
- if (language != null) {
- builder.append(language);
- String country = locale.getCountry();
- if (country != null) {
- builder.append("-");
- builder.append(country);
- }
- }
- }
-
- /**
- * Looks at sLocale and mContext and returns current UserAgent String.
- * @return Current UserAgent String.
- */
- private synchronized String getCurrentUserAgent() {
- Locale locale;
- synchronized(sLockForLocaleSettings) {
- locale = sLocale;
- }
- StringBuffer buffer = new StringBuffer();
- // Add version
- final String version = Build.VERSION.RELEASE;
- if (version.length() > 0) {
- if (Character.isDigit(version.charAt(0))) {
- // Release is a version, eg "3.1"
- buffer.append(version);
- } else {
- // Release is a codename, eg "Honeycomb"
- // In this case, use the previous release's version
- buffer.append(PREVIOUS_VERSION);
- }
- } else {
- // default to "1.0"
- buffer.append("1.0");
- }
- buffer.append("; ");
- final String language = locale.getLanguage();
- if (language != null) {
- buffer.append(convertObsoleteLanguageCodeToNew(language));
- final String country = locale.getCountry();
- if (country != null) {
- buffer.append("-");
- buffer.append(country.toLowerCase());
- }
- } else {
- // default to "en"
- buffer.append("en");
- }
- buffer.append(";");
- // add the model for the release build
- if ("REL".equals(Build.VERSION.CODENAME)) {
- final String model = Build.MODEL;
- if (model.length() > 0) {
- buffer.append(" ");
- buffer.append(model);
- }
- }
- final String id = Build.ID;
- if (id.length() > 0) {
- buffer.append(" Build/");
- buffer.append(id);
- }
- String mobile = mContext.getResources().getText(
- com.android.internal.R.string.web_user_agent_target_content).toString();
- final String base = mContext.getResources().getText(
- com.android.internal.R.string.web_user_agent).toString();
- return String.format(base, buffer, mobile);
+ protected WebSettings() {
}
/**
@@ -522,7 +157,7 @@ public class WebSettings {
*/
@Deprecated
public void setNavDump(boolean enabled) {
- mNavDump = enabled;
+ throw new MustOverrideException();
}
/**
@@ -531,37 +166,35 @@ public class WebSettings {
*/
@Deprecated
public boolean getNavDump() {
- return mNavDump;
+ throw new MustOverrideException();
}
/**
* Set whether the WebView supports zoom
*/
public void setSupportZoom(boolean support) {
- mSupportZoom = support;
- mWebView.updateMultiTouchSupport(mContext);
+ throw new MustOverrideException();
}
/**
* Returns whether the WebView supports zoom
*/
public boolean supportZoom() {
- return mSupportZoom;
+ throw new MustOverrideException();
}
/**
* Sets whether the zoom mechanism built into WebView is used.
*/
public void setBuiltInZoomControls(boolean enabled) {
- mBuiltInZoomControls = enabled;
- mWebView.updateMultiTouchSupport(mContext);
+ throw new MustOverrideException();
}
/**
* Returns true if the zoom mechanism built into WebView is being used.
*/
public boolean getBuiltInZoomControls() {
- return mBuiltInZoomControls;
+ throw new MustOverrideException();
}
/**
@@ -571,15 +204,14 @@ public class WebSettings {
* to work without the on screen controls
*/
public void setDisplayZoomControls(boolean enabled) {
- mDisplayZoomControls = enabled;
- mWebView.updateMultiTouchSupport(mContext);
+ throw new MustOverrideException();
}
/**
* Returns true if the on screen zoom buttons are being used.
*/
public boolean getDisplayZoomControls() {
- return mDisplayZoomControls;
+ throw new MustOverrideException();
}
/**
@@ -589,14 +221,14 @@ public class WebSettings {
* file:///android_res.
*/
public void setAllowFileAccess(boolean allow) {
- mAllowFileAccess = allow;
+ throw new MustOverrideException();
}
/**
* Returns true if this WebView supports file access.
*/
public boolean getAllowFileAccess() {
- return mAllowFileAccess;
+ throw new MustOverrideException();
}
/**
@@ -605,28 +237,28 @@ public class WebSettings {
* system. The default is enabled.
*/
public void setAllowContentAccess(boolean allow) {
- mAllowContentAccess = allow;
+ throw new MustOverrideException();
}
/**
* Returns true if this WebView supports content url access.
*/
public boolean getAllowContentAccess() {
- return mAllowContentAccess;
+ throw new MustOverrideException();
}
/**
* Set whether the WebView loads a page with overview mode.
*/
public void setLoadWithOverviewMode(boolean overview) {
- mLoadWithOverviewMode = overview;
+ throw new MustOverrideException();
}
/**
* Returns true if this WebView loads page with overview mode
*/
public boolean getLoadWithOverviewMode() {
- return mLoadWithOverviewMode;
+ throw new MustOverrideException();
}
/**
@@ -637,15 +269,14 @@ public class WebSettings {
* If it is false, WebView will keep its fidelity. The default value is false.
*/
public void setEnableSmoothTransition(boolean enable) {
- mEnableSmoothTransition = enable;
+ throw new MustOverrideException();
}
-
/**
* Returns true if the WebView enables smooth transition while panning or
* zooming.
*/
public boolean enableSmoothTransition() {
- return mEnableSmoothTransition;
+ throw new MustOverrideException();
}
/**
@@ -656,7 +287,7 @@ public class WebSettings {
*/
@Deprecated
public void setUseWebViewBackgroundForOverscrollBackground(boolean view) {
- mUseWebViewBackgroundForOverscroll = view;
+ throw new MustOverrideException();
}
/**
@@ -666,14 +297,14 @@ public class WebSettings {
*/
@Deprecated
public boolean getUseWebViewBackgroundForOverscrollBackground() {
- return mUseWebViewBackgroundForOverscroll;
+ throw new MustOverrideException();
}
/**
* Store whether the WebView is saving form data.
*/
public void setSaveFormData(boolean save) {
- mSaveFormData = save;
+ throw new MustOverrideException();
}
/**
@@ -681,21 +312,21 @@ public class WebSettings {
* entries/autofill++. Always false in private browsing mode.
*/
public boolean getSaveFormData() {
- return mSaveFormData && !mPrivateBrowsingEnabled;
+ throw new MustOverrideException();
}
/**
* Store whether the WebView is saving password.
*/
public void setSavePassword(boolean save) {
- mSavePassword = save;
+ throw new MustOverrideException();
}
/**
* Return whether the WebView is saving password.
*/
public boolean getSavePassword() {
- return mSavePassword;
+ throw new MustOverrideException();
}
/**
@@ -703,14 +334,7 @@ public class WebSettings {
* @param textZoom A percent value for increasing or decreasing the text.
*/
public synchronized void setTextZoom(int textZoom) {
- if (mTextSize != textZoom) {
- if (WebView.mLogEvent) {
- EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE,
- mTextSize, textZoom);
- }
- mTextSize = textZoom;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -719,7 +343,7 @@ public class WebSettings {
* @see setTextSizeZoom
*/
public synchronized int getTextZoom() {
- return mTextSize;
+ throw new MustOverrideException();
}
/**
@@ -729,7 +353,7 @@ public class WebSettings {
* @deprecated Use {@link #setTextZoom(int)} instead
*/
public synchronized void setTextSize(TextSize t) {
- setTextZoom(t.value);
+ throw new MustOverrideException();
}
/**
@@ -741,40 +365,7 @@ public class WebSettings {
* @deprecated Use {@link #getTextZoom()} instead
*/
public synchronized TextSize getTextSize() {
- TextSize closestSize = null;
- int smallestDelta = Integer.MAX_VALUE;
- for (TextSize size : TextSize.values()) {
- int delta = Math.abs(mTextSize - size.value);
- if (delta == 0) {
- return size;
- }
- if (delta < smallestDelta) {
- smallestDelta = delta;
- closestSize = size;
- }
- }
- return closestSize != null ? closestSize : TextSize.NORMAL;
- }
-
- /**
- * Set the double-tap zoom of the page in percent. Default is 100.
- * @param doubleTapZoom A percent value for increasing or decreasing the double-tap zoom.
- * @hide
- */
- public void setDoubleTapZoom(int doubleTapZoom) {
- if (mDoubleTapZoom != doubleTapZoom) {
- mDoubleTapZoom = doubleTapZoom;
- mWebView.updateDoubleTapZoom(doubleTapZoom);
- }
- }
-
- /**
- * Get the double-tap zoom of the page in percent.
- * @return A percent value describing the double-tap zoom.
- * @hide
- */
- public int getDoubleTapZoom() {
- return mDoubleTapZoom;
+ throw new MustOverrideException();
}
/**
@@ -784,10 +375,7 @@ public class WebSettings {
* @see WebSettings.ZoomDensity
*/
public void setDefaultZoom(ZoomDensity zoom) {
- if (mDefaultZoom != zoom) {
- mDefaultZoom = zoom;
- mWebView.adjustDefaultZoomDensity(zoom.value);
- }
+ throw new MustOverrideException();
}
/**
@@ -797,21 +385,21 @@ public class WebSettings {
* @see WebSettings.ZoomDensity
*/
public ZoomDensity getDefaultZoom() {
- return mDefaultZoom;
+ throw new MustOverrideException();
}
/**
* Enables using light touches to make a selection and activate mouseovers.
*/
public void setLightTouchEnabled(boolean enabled) {
- mLightTouchEnabled = enabled;
+ throw new MustOverrideException();
}
/**
* Returns true if light touches are enabled.
*/
public boolean getLightTouchEnabled() {
- return mLightTouchEnabled;
+ throw new MustOverrideException();
}
/**
@@ -820,7 +408,7 @@ public class WebSettings {
*/
@Deprecated
public synchronized void setUseDoubleTree(boolean use) {
- return;
+ // Specified to do nothing, so no need for derived classes to override.
}
/**
@@ -829,6 +417,7 @@ public class WebSettings {
*/
@Deprecated
public synchronized boolean getUseDoubleTree() {
+ // Returns false unconditionally, so no need for derived classes to override.
return false;
}
@@ -841,23 +430,7 @@ public class WebSettings {
*/
@Deprecated
public synchronized void setUserAgent(int ua) {
- String uaString = null;
- if (ua == 1) {
- if (DESKTOP_USERAGENT.equals(mUserAgent)) {
- return; // do nothing
- } else {
- uaString = DESKTOP_USERAGENT;
- }
- } else if (ua == 2) {
- if (IPHONE_USERAGENT.equals(mUserAgent)) {
- return; // do nothing
- } else {
- uaString = IPHONE_USERAGENT;
- }
- } else if (ua != 0) {
- return; // do nothing
- }
- setUserAgentString(uaString);
+ throw new MustOverrideException();
}
/**
@@ -870,31 +443,21 @@ public class WebSettings {
*/
@Deprecated
public synchronized int getUserAgent() {
- if (DESKTOP_USERAGENT.equals(mUserAgent)) {
- return 1;
- } else if (IPHONE_USERAGENT.equals(mUserAgent)) {
- return 2;
- } else if (mUseDefaultUserAgent) {
- return 0;
- }
- return -1;
+ throw new MustOverrideException();
}
/**
* Tell the WebView to use the wide viewport
*/
public synchronized void setUseWideViewPort(boolean use) {
- if (mUseWideViewport != use) {
- mUseWideViewport = use;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
* @return True if the WebView is using a wide viewport
*/
public synchronized boolean getUseWideViewPort() {
- return mUseWideViewport;
+ throw new MustOverrideException();
}
/**
@@ -903,10 +466,7 @@ public class WebSettings {
* boolean, Message)} is implemented by the host application.
*/
public synchronized void setSupportMultipleWindows(boolean support) {
- if (mSupportMultipleWindows != support) {
- mSupportMultipleWindows = support;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -915,7 +475,7 @@ public class WebSettings {
* boolean, Message)} is implemented by the host application.
*/
public synchronized boolean supportMultipleWindows() {
- return mSupportMultipleWindows;
+ throw new MustOverrideException();
}
/**
@@ -925,12 +485,7 @@ public class WebSettings {
* @see WebSettings.LayoutAlgorithm
*/
public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) {
- // XXX: This will only be affective if libwebcore was built with
- // ANDROID_LAYOUT defined.
- if (mLayoutAlgorithm != l) {
- mLayoutAlgorithm = l;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -940,7 +495,7 @@ public class WebSettings {
* @see WebSettings.LayoutAlgorithm
*/
public synchronized LayoutAlgorithm getLayoutAlgorithm() {
- return mLayoutAlgorithm;
+ throw new MustOverrideException();
}
/**
@@ -948,10 +503,7 @@ public class WebSettings {
* @param font A font family name.
*/
public synchronized void setStandardFontFamily(String font) {
- if (font != null && !font.equals(mStandardFontFamily)) {
- mStandardFontFamily = font;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -959,7 +511,7 @@ public class WebSettings {
* @return The standard font family name as a string.
*/
public synchronized String getStandardFontFamily() {
- return mStandardFontFamily;
+ throw new MustOverrideException();
}
/**
@@ -967,10 +519,7 @@ public class WebSettings {
* @param font A font family name.
*/
public synchronized void setFixedFontFamily(String font) {
- if (font != null && !font.equals(mFixedFontFamily)) {
- mFixedFontFamily = font;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -978,7 +527,7 @@ public class WebSettings {
* @return The fixed font family name as a string.
*/
public synchronized String getFixedFontFamily() {
- return mFixedFontFamily;
+ throw new MustOverrideException();
}
/**
@@ -986,10 +535,7 @@ public class WebSettings {
* @param font A font family name.
*/
public synchronized void setSansSerifFontFamily(String font) {
- if (font != null && !font.equals(mSansSerifFontFamily)) {
- mSansSerifFontFamily = font;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -997,7 +543,7 @@ public class WebSettings {
* @return The sans-serif font family name as a string.
*/
public synchronized String getSansSerifFontFamily() {
- return mSansSerifFontFamily;
+ throw new MustOverrideException();
}
/**
@@ -1005,10 +551,7 @@ public class WebSettings {
* @param font A font family name.
*/
public synchronized void setSerifFontFamily(String font) {
- if (font != null && !font.equals(mSerifFontFamily)) {
- mSerifFontFamily = font;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1016,7 +559,7 @@ public class WebSettings {
* @return The serif font family name as a string.
*/
public synchronized String getSerifFontFamily() {
- return mSerifFontFamily;
+ throw new MustOverrideException();
}
/**
@@ -1024,10 +567,7 @@ public class WebSettings {
* @param font A font family name.
*/
public synchronized void setCursiveFontFamily(String font) {
- if (font != null && !font.equals(mCursiveFontFamily)) {
- mCursiveFontFamily = font;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1035,7 +575,7 @@ public class WebSettings {
* @return The cursive font family name as a string.
*/
public synchronized String getCursiveFontFamily() {
- return mCursiveFontFamily;
+ throw new MustOverrideException();
}
/**
@@ -1043,10 +583,7 @@ public class WebSettings {
* @param font A font family name.
*/
public synchronized void setFantasyFontFamily(String font) {
- if (font != null && !font.equals(mFantasyFontFamily)) {
- mFantasyFontFamily = font;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1054,7 +591,7 @@ public class WebSettings {
* @return The fantasy font family name as a string.
*/
public synchronized String getFantasyFontFamily() {
- return mFantasyFontFamily;
+ throw new MustOverrideException();
}
/**
@@ -1063,11 +600,7 @@ public class WebSettings {
* Any number outside the specified range will be pinned.
*/
public synchronized void setMinimumFontSize(int size) {
- size = pin(size);
- if (mMinimumFontSize != size) {
- mMinimumFontSize = size;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1075,7 +608,7 @@ public class WebSettings {
* @return A non-negative integer between 1 and 72.
*/
public synchronized int getMinimumFontSize() {
- return mMinimumFontSize;
+ throw new MustOverrideException();
}
/**
@@ -1084,11 +617,7 @@ public class WebSettings {
* Any number outside the specified range will be pinned.
*/
public synchronized void setMinimumLogicalFontSize(int size) {
- size = pin(size);
- if (mMinimumLogicalFontSize != size) {
- mMinimumLogicalFontSize = size;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1096,7 +625,7 @@ public class WebSettings {
* @return A non-negative integer between 1 and 72.
*/
public synchronized int getMinimumLogicalFontSize() {
- return mMinimumLogicalFontSize;
+ throw new MustOverrideException();
}
/**
@@ -1105,11 +634,7 @@ public class WebSettings {
* Any number outside the specified range will be pinned.
*/
public synchronized void setDefaultFontSize(int size) {
- size = pin(size);
- if (mDefaultFontSize != size) {
- mDefaultFontSize = size;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1117,7 +642,7 @@ public class WebSettings {
* @return A non-negative integer between 1 and 72.
*/
public synchronized int getDefaultFontSize() {
- return mDefaultFontSize;
+ throw new MustOverrideException();
}
/**
@@ -1126,11 +651,7 @@ public class WebSettings {
* Any number outside the specified range will be pinned.
*/
public synchronized void setDefaultFixedFontSize(int size) {
- size = pin(size);
- if (mDefaultFixedFontSize != size) {
- mDefaultFixedFontSize = size;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1138,21 +659,7 @@ public class WebSettings {
* @return A non-negative integer between 1 and 72.
*/
public synchronized int getDefaultFixedFontSize() {
- return mDefaultFixedFontSize;
- }
-
- /**
- * Set the number of pages cached by the WebKit for the history navigation.
- * @param size A non-negative integer between 0 (no cache) and 20 (max).
- * @hide
- */
- public synchronized void setPageCacheCapacity(int size) {
- if (size < 0) size = 0;
- if (size > 20) size = 20;
- if (mPageCacheCapacity != size) {
- mPageCacheCapacity = size;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1165,10 +672,7 @@ public class WebSettings {
* @param flag Whether the WebView should load image resources.
*/
public synchronized void setLoadsImagesAutomatically(boolean flag) {
- if (mLoadsImagesAutomatically != flag) {
- mLoadsImagesAutomatically = flag;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1177,7 +681,7 @@ public class WebSettings {
* @return True if the WebView loads image resources.
*/
public synchronized boolean getLoadsImagesAutomatically() {
- return mLoadsImagesAutomatically;
+ throw new MustOverrideException();
}
/**
@@ -1195,10 +699,7 @@ public class WebSettings {
* @see #setBlockNetworkLoads
*/
public synchronized void setBlockNetworkImage(boolean flag) {
- if (mBlockNetworkImage != flag) {
- mBlockNetworkImage = flag;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1207,7 +708,7 @@ public class WebSettings {
* @return True if the WebView does not load image resources from the network.
*/
public synchronized boolean getBlockNetworkImage() {
- return mBlockNetworkImage;
+ throw new MustOverrideException();
}
/**
@@ -1226,11 +727,7 @@ public class WebSettings {
* @see android.webkit.WebView#reload
*/
public synchronized void setBlockNetworkLoads(boolean flag) {
- if (mBlockNetworkLoads != flag) {
- mBlockNetworkLoads = flag;
- verifyNetworkAccess();
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1241,20 +738,7 @@ public class WebSettings {
* @return True if the WebView does not load any resources from the network.
*/
public synchronized boolean getBlockNetworkLoads() {
- return mBlockNetworkLoads;
- }
-
-
- private void verifyNetworkAccess() {
- if (!mBlockNetworkLoads) {
- if (mContext.checkPermission("android.permission.INTERNET",
- android.os.Process.myPid(), android.os.Process.myUid()) !=
- PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException
- ("Permission denied - " +
- "application missing INTERNET permission");
- }
- }
+ throw new MustOverrideException();
}
/**
@@ -1262,50 +746,7 @@ public class WebSettings {
* @param flag True if the WebView should execute javascript.
*/
public synchronized void setJavaScriptEnabled(boolean flag) {
- if (mJavaScriptEnabled != flag) {
- mJavaScriptEnabled = flag;
- postSync();
- }
- }
-
- /**
- * Tell the WebView to use Skia's hardware accelerated rendering path
- * @param flag True if the WebView should use Skia's hw-accel path
- * @hide
- */
- public synchronized void setHardwareAccelSkiaEnabled(boolean flag) {
- if (mHardwareAccelSkia != flag) {
- mHardwareAccelSkia = flag;
- postSync();
- }
- }
-
- /**
- * @return True if the WebView is using hardware accelerated skia
- * @hide
- */
- public synchronized boolean getHardwareAccelSkiaEnabled() {
- return mHardwareAccelSkia;
- }
-
- /**
- * Tell the WebView to show the visual indicator
- * @param flag True if the WebView should show the visual indicator
- * @hide
- */
- public synchronized void setShowVisualIndicator(boolean flag) {
- if (mShowVisualIndicator != flag) {
- mShowVisualIndicator = flag;
- postSync();
- }
- }
-
- /**
- * @return True if the WebView is showing the visual indicator
- * @hide
- */
- public synchronized boolean getShowVisualIndicator() {
- return mShowVisualIndicator;
+ throw new MustOverrideException();
}
/**
@@ -1316,7 +757,7 @@ public class WebSettings {
*/
@Deprecated
public synchronized void setPluginsEnabled(boolean flag) {
- setPluginState(flag ? PluginState.ON : PluginState.OFF);
+ throw new MustOverrideException();
}
/**
@@ -1327,10 +768,7 @@ public class WebSettings {
* @param state One of the PluginState values.
*/
public synchronized void setPluginState(PluginState state) {
- if (mPluginState != state) {
- mPluginState = state;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1342,6 +780,7 @@ public class WebSettings {
*/
@Deprecated
public synchronized void setPluginsPath(String pluginsPath) {
+ // Specified to do nothing, so no need for derived classes to override.
}
/**
@@ -1352,11 +791,7 @@ public class WebSettings {
* be saved. May be the empty string but should never be null.
*/
public synchronized void setDatabasePath(String databasePath) {
- if (databasePath != null && !mDatabasePathHasBeenSet) {
- mDatabasePath = databasePath;
- mDatabasePathHasBeenSet = true;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1367,40 +802,26 @@ public class WebSettings {
* should never be null.
*/
public synchronized void setGeolocationDatabasePath(String databasePath) {
- if (databasePath != null
- && !databasePath.equals(mGeolocationDatabasePath)) {
- mGeolocationDatabasePath = databasePath;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
- * Enable or disable the Application Cache API.
- * @param flag Whether to enable the Application Cache API.
+ * Tell the WebView to enable Application Caches API.
+ * @param flag True if the WebView should enable Application Caches.
*/
public synchronized void setAppCacheEnabled(boolean flag) {
- if (mAppCacheEnabled != flag) {
- mAppCacheEnabled = flag;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
- * Set the path used by the Application Cache API to store files. This
- * setting is applied to all WebViews in the application. In order for the
- * Application Cache API to function, this method must be called with a
- * path which exists and is writable by the application. This method may
- * only be called once: repeated calls are ignored.
- * @param path Path to the directory that should be used to store Application
- * Cache files.
+ * Set a custom path to the Application Caches files. The client
+ * must ensure it exists before this call.
+ * @param appCachePath String path to the directory containing Application
+ * Caches files. The appCache path can be the empty string but should not
+ * be null. Passing null for this parameter will result in a no-op.
*/
- public synchronized void setAppCachePath(String path) {
- // We test for a valid path and for repeated setting on the native
- // side, but we can avoid syncing in some simple cases.
- if (mAppCachePath == null && path != null && !path.isEmpty()) {
- mAppCachePath = path;
- postSync();
- }
+ public synchronized void setAppCachePath(String appCachePath) {
+ throw new MustOverrideException();
}
/**
@@ -1408,10 +829,7 @@ public class WebSettings {
* @param appCacheMaxSize the maximum size in bytes.
*/
public synchronized void setAppCacheMaxSize(long appCacheMaxSize) {
- if (appCacheMaxSize != mAppCacheMaxSize) {
- mAppCacheMaxSize = appCacheMaxSize;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1420,10 +838,7 @@ public class WebSettings {
* API.
*/
public synchronized void setDatabaseEnabled(boolean flag) {
- if (mDatabaseEnabled != flag) {
- mDatabaseEnabled = flag;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1432,10 +847,7 @@ public class WebSettings {
* API.
*/
public synchronized void setDomStorageEnabled(boolean flag) {
- if (mDomStorageEnabled != flag) {
- mDomStorageEnabled = flag;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1443,16 +855,15 @@ public class WebSettings {
* @return True if the DOM Storage API's are enabled.
*/
public synchronized boolean getDomStorageEnabled() {
- return mDomStorageEnabled;
+ throw new MustOverrideException();
}
-
/**
* Return the path to where database storage API databases are saved for
* the current WebView.
* @return the String path to the database storage API databases.
*/
public synchronized String getDatabasePath() {
- return mDatabasePath;
+ throw new MustOverrideException();
}
/**
@@ -1460,21 +871,7 @@ public class WebSettings {
* @return True if the database storage API is enabled.
*/
public synchronized boolean getDatabaseEnabled() {
- return mDatabaseEnabled;
- }
-
- /**
- * Tell the WebView to enable WebWorkers API.
- * @param flag True if the WebView should enable WebWorkers.
- * Note that this flag only affects V8. JSC does not have
- * an equivalent setting.
- * @hide
- */
- public synchronized void setWorkersEnabled(boolean flag) {
- if (mWorkersEnabled != flag) {
- mWorkersEnabled = flag;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1482,22 +879,7 @@ public class WebSettings {
* @param flag Whether Geolocation should be enabled.
*/
public synchronized void setGeolocationEnabled(boolean flag) {
- if (mGeolocationEnabled != flag) {
- mGeolocationEnabled = flag;
- postSync();
- }
- }
-
- /**
- * Sets whether XSS Auditor is enabled.
- * @param flag Whether XSS Auditor should be enabled.
- * @hide Only used by LayoutTestController.
- */
- public synchronized void setXSSAuditorEnabled(boolean flag) {
- if (mXSSAuditorEnabled != flag) {
- mXSSAuditorEnabled = flag;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1505,7 +887,7 @@ public class WebSettings {
* @return True if javascript is enabled.
*/
public synchronized boolean getJavaScriptEnabled() {
- return mJavaScriptEnabled;
+ throw new MustOverrideException();
}
/**
@@ -1515,7 +897,7 @@ public class WebSettings {
*/
@Deprecated
public synchronized boolean getPluginsEnabled() {
- return mPluginState == PluginState.ON;
+ throw new MustOverrideException();
}
/**
@@ -1523,7 +905,7 @@ public class WebSettings {
* @return A value corresponding to the enum PluginState.
*/
public synchronized PluginState getPluginState() {
- return mPluginState;
+ throw new MustOverrideException();
}
/**
@@ -1535,6 +917,7 @@ public class WebSettings {
*/
@Deprecated
public synchronized String getPluginsPath() {
+ // Unconditionally returns empty string, so no need for derived classes to override.
return "";
}
@@ -1543,12 +926,8 @@ public class WebSettings {
* javascript function window.open().
* @param flag True if javascript can open windows automatically.
*/
- public synchronized void setJavaScriptCanOpenWindowsAutomatically(
- boolean flag) {
- if (mJavaScriptCanOpenWindowsAutomatically != flag) {
- mJavaScriptCanOpenWindowsAutomatically = flag;
- postSync();
- }
+ public synchronized void setJavaScriptCanOpenWindowsAutomatically(boolean flag) {
+ throw new MustOverrideException();
}
/**
@@ -1558,18 +937,14 @@ public class WebSettings {
* window.open().
*/
public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() {
- return mJavaScriptCanOpenWindowsAutomatically;
+ throw new MustOverrideException();
}
-
/**
* Set the default text encoding name to use when decoding html pages.
* @param encoding The text encoding name.
*/
public synchronized void setDefaultTextEncodingName(String encoding) {
- if (encoding != null && !encoding.equals(mDefaultTextEncoding)) {
- mDefaultTextEncoding = encoding;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1577,7 +952,7 @@ public class WebSettings {
* @return The default text encoding name as a string.
*/
public synchronized String getDefaultTextEncodingName() {
- return mDefaultTextEncoding;
+ throw new MustOverrideException();
}
/**
@@ -1585,66 +960,14 @@ public class WebSettings {
* it will use the system default user-agent string.
*/
public synchronized void setUserAgentString(String ua) {
- if (ua == null || ua.length() == 0) {
- synchronized(sLockForLocaleSettings) {
- Locale currentLocale = Locale.getDefault();
- if (!sLocale.equals(currentLocale)) {
- sLocale = currentLocale;
- mAcceptLanguage = getCurrentAcceptLanguage();
- }
- }
- ua = getCurrentUserAgent();
- mUseDefaultUserAgent = true;
- } else {
- mUseDefaultUserAgent = false;
- }
-
- if (!ua.equals(mUserAgent)) {
- mUserAgent = ua;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
* Return the WebView's user-agent string.
*/
public synchronized String getUserAgentString() {
- if (DESKTOP_USERAGENT.equals(mUserAgent) ||
- IPHONE_USERAGENT.equals(mUserAgent) ||
- !mUseDefaultUserAgent) {
- return mUserAgent;
- }
-
- boolean doPostSync = false;
- synchronized(sLockForLocaleSettings) {
- Locale currentLocale = Locale.getDefault();
- if (!sLocale.equals(currentLocale)) {
- sLocale = currentLocale;
- mUserAgent = getCurrentUserAgent();
- mAcceptLanguage = getCurrentAcceptLanguage();
- doPostSync = true;
- }
- }
- if (doPostSync) {
- postSync();
- }
- return mUserAgent;
- }
-
- /* package api to grab the Accept Language string. */
- /*package*/ synchronized String getAcceptLanguage() {
- synchronized(sLockForLocaleSettings) {
- Locale currentLocale = Locale.getDefault();
- if (!sLocale.equals(currentLocale)) {
- sLocale = currentLocale;
- mAcceptLanguage = getCurrentAcceptLanguage();
- }
- }
- return mAcceptLanguage;
- }
-
- /* package */ boolean isNarrowColumnLayout() {
- return getLayoutAlgorithm() == LayoutAlgorithm.NARROW_COLUMNS;
+ throw new MustOverrideException();
}
/**
@@ -1654,14 +977,7 @@ public class WebSettings {
* @param flag
*/
public void setNeedInitialFocus(boolean flag) {
- if (mNeedInitialFocus != flag) {
- mNeedInitialFocus = flag;
- }
- }
-
- /* Package api to get the choice whether it needs to set initial focus. */
- /* package */ boolean getNeedInitialFocus() {
- return mNeedInitialFocus;
+ throw new MustOverrideException();
}
/**
@@ -1671,11 +987,7 @@ public class WebSettings {
* @param priority RenderPriority, can be normal, high or low.
*/
public synchronized void setRenderPriority(RenderPriority priority) {
- if (mRenderPriority != priority) {
- mRenderPriority = priority;
- mEventHandler.sendMessage(Message.obtain(null,
- EventHandler.PRIORITY));
- }
+ throw new MustOverrideException();
}
/**
@@ -1687,10 +999,7 @@ public class WebSettings {
* @param mode One of the LOAD_ values.
*/
public void setCacheMode(int mode) {
- if (mode != mOverrideCacheMode) {
- mOverrideCacheMode = mode;
- postSync();
- }
+ throw new MustOverrideException();
}
/**
@@ -1698,204 +1007,6 @@ public class WebSettings {
* description, see the {@link #setCacheMode(int)} function.
*/
public int getCacheMode() {
- return mOverrideCacheMode;
+ throw new MustOverrideException();
}
-
- /**
- * If set, webkit alternately shrinks and expands images viewed outside
- * of an HTML page to fit the screen. This conflicts with attempts by
- * the UI to zoom in and out of an image, so it is set false by default.
- * @param shrink Set true to let webkit shrink the standalone image to fit.
- * {@hide}
- */
- public void setShrinksStandaloneImagesToFit(boolean shrink) {
- if (mShrinksStandaloneImagesToFit != shrink) {
- mShrinksStandaloneImagesToFit = shrink;
- postSync();
- }
- }
-
- /**
- * Specify the maximum decoded image size. The default is
- * 2 megs for small memory devices and 8 megs for large memory devices.
- * @param size The maximum decoded size, or zero to set to the default.
- * @hide
- */
- public void setMaximumDecodedImageSize(long size) {
- if (mMaximumDecodedImageSize != size) {
- mMaximumDecodedImageSize = size;
- postSync();
- }
- }
-
- /**
- * Returns whether to use fixed viewport. Use fixed viewport
- * whenever wide viewport is on.
- */
- /* package */ boolean getUseFixedViewport() {
- return getUseWideViewPort();
- }
-
- /**
- * Returns whether private browsing is enabled.
- */
- /* package */ boolean isPrivateBrowsingEnabled() {
- return mPrivateBrowsingEnabled;
- }
-
- /**
- * Sets whether private browsing is enabled.
- * @param flag Whether private browsing should be enabled.
- */
- /* package */ synchronized void setPrivateBrowsingEnabled(boolean flag) {
- if (mPrivateBrowsingEnabled != flag) {
- mPrivateBrowsingEnabled = flag;
-
- // AutoFill is dependant on private browsing being enabled so
- // reset it to take account of the new value of mPrivateBrowsingEnabled.
- setAutoFillEnabled(mAutoFillEnabled);
-
- postSync();
- }
- }
-
- /**
- * Returns whether the viewport metatag can disable zooming
- * @hide
- */
- public boolean forceUserScalable() {
- return mForceUserScalable;
- }
-
- /**
- * Sets whether viewport metatag can disable zooming.
- * @param flag Whether or not to forceably enable user scalable.
- * @hide
- */
- public synchronized void setForceUserScalable(boolean flag) {
- mForceUserScalable = flag;
- }
-
- synchronized void setSyntheticLinksEnabled(boolean flag) {
- if (mSyntheticLinksEnabled != flag) {
- mSyntheticLinksEnabled = flag;
- postSync();
- }
- }
-
- /**
- * @hide
- */
- public synchronized void setAutoFillEnabled(boolean enabled) {
- // AutoFill is always disabled in private browsing mode.
- boolean autoFillEnabled = enabled && !mPrivateBrowsingEnabled;
- if (mAutoFillEnabled != autoFillEnabled) {
- mAutoFillEnabled = autoFillEnabled;
- postSync();
- }
- }
-
- /**
- * @hide
- */
- public synchronized boolean getAutoFillEnabled() {
- return mAutoFillEnabled;
- }
-
- /**
- * @hide
- */
- public synchronized void setAutoFillProfile(AutoFillProfile profile) {
- if (mAutoFillProfile != profile) {
- mAutoFillProfile = profile;
- postSync();
- }
- }
-
- /**
- * @hide
- */
- public synchronized AutoFillProfile getAutoFillProfile() {
- return mAutoFillProfile;
- }
-
- int getDoubleTapToastCount() {
- return mDoubleTapToastCount;
- }
-
- void setDoubleTapToastCount(int count) {
- if (mDoubleTapToastCount != count) {
- mDoubleTapToastCount = count;
- // write the settings in the non-UI thread
- mEventHandler.sendMessage(Message.obtain(null,
- EventHandler.SET_DOUBLE_TAP_TOAST_COUNT));
- }
- }
-
- /**
- * @hide
- */
- public void setProperty(String key, String value) {
- if (mWebView.nativeSetProperty(key, value)) {
- mWebView.contentInvalidateAll();
- }
- }
-
- /**
- * @hide
- */
- public String getProperty(String key) {
- return mWebView.nativeGetProperty(key);
- }
-
- /**
- * Transfer messages from the queue to the new WebCoreThread. Called from
- * WebCore thread.
- */
- /*package*/
- synchronized void syncSettingsAndCreateHandler(BrowserFrame frame) {
- mBrowserFrame = frame;
- if (DebugFlags.WEB_SETTINGS) {
- junit.framework.Assert.assertTrue(frame.mNativeFrame != 0);
- }
-
- SharedPreferences sp = mContext.getSharedPreferences(PREF_FILE,
- Context.MODE_PRIVATE);
- if (mDoubleTapToastCount > 0) {
- mDoubleTapToastCount = sp.getInt(DOUBLE_TAP_TOAST_COUNT,
- mDoubleTapToastCount);
- }
- nativeSync(frame.mNativeFrame);
- mSyncPending = false;
- mEventHandler.createHandler();
- }
-
- /**
- * Let the Settings object know that our owner is being destroyed.
- */
- /*package*/
- synchronized void onDestroyed() {
- }
-
- private int pin(int size) {
- // FIXME: 72 is just an arbitrary max text size value.
- if (size < 1) {
- return 1;
- } else if (size > 72) {
- return 72;
- }
- return size;
- }
-
- /* Post a SYNC message to handle syncing the native settings. */
- private synchronized void postSync() {
- // Only post if a sync is not pending
- if (!mSyncPending) {
- mSyncPending = mEventHandler.sendMessage(
- Message.obtain(null, EventHandler.SYNC));
- }
- }
-
- // Synchronize the native and java settings.
- private native void nativeSync(int nativeFrame);
}
diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java
index c463b40..6850eea 100644
--- a/core/java/android/webkit/WebSettingsClassic.java
+++ b/core/java/android/webkit/WebSettingsClassic.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,124 +28,15 @@ import android.util.EventLog;
import java.util.Locale;
/**
- * Manages settings state for a WebView. When a WebView is first created, it
- * obtains a set of default settings. These default settings will be returned
- * from any getter call. A WebSettings object obtained from
- * WebView.getSettings() is tied to the life of the WebView. If a WebView has
- * been destroyed, any method call on WebSettings will throw an
- * IllegalStateException.
+ * WebSettings implementation for the WebViewClassic implementation of WebView.
+ * @hide
*/
-public class WebSettings {
- /**
- * Enum for controlling the layout of html.
- * NORMAL means no rendering changes.
- * SINGLE_COLUMN moves all content into one column that is the width of the
- * view.
- * NARROW_COLUMNS makes all columns no wider than the screen if possible.
- */
- // XXX: These must match LayoutAlgorithm in Settings.h in WebCore.
- public enum LayoutAlgorithm {
- NORMAL,
- /**
- * @deprecated This algorithm is now obsolete.
- */
- @Deprecated
- SINGLE_COLUMN,
- NARROW_COLUMNS
- }
-
- /**
- * Enum for specifying the text size.
- * SMALLEST is 50%
- * SMALLER is 75%
- * NORMAL is 100%
- * LARGER is 150%
- * LARGEST is 200%
- * @deprecated Use {@link WebSettings#setTextZoom(int)} and {@link WebSettings#getTextZoom()} instead.
- */
- public enum TextSize {
- SMALLEST(50),
- SMALLER(75),
- NORMAL(100),
- LARGER(150),
- LARGEST(200);
- TextSize(int size) {
- value = size;
- }
- int value;
- }
-
- /**
- * Enum for specifying the WebView's desired density.
- * FAR makes 100% looking like in 240dpi
- * MEDIUM makes 100% looking like in 160dpi
- * CLOSE makes 100% looking like in 120dpi
- */
- public enum ZoomDensity {
- FAR(150), // 240dpi
- MEDIUM(100), // 160dpi
- CLOSE(75); // 120dpi
- ZoomDensity(int size) {
- value = size;
- }
- int value;
- }
-
- /**
- * Default cache usage pattern Use with {@link #setCacheMode}.
- */
- public static final int LOAD_DEFAULT = -1;
-
- /**
- * Normal cache usage pattern Use with {@link #setCacheMode}.
- */
- public static final int LOAD_NORMAL = 0;
-
- /**
- * Use cache if content is there, even if expired (eg, history nav)
- * If it is not in the cache, load from network.
- * Use with {@link #setCacheMode}.
- */
- public static final int LOAD_CACHE_ELSE_NETWORK = 1;
-
- /**
- * Don't use the cache, load from network
- * Use with {@link #setCacheMode}.
- */
- public static final int LOAD_NO_CACHE = 2;
-
- /**
- * Don't use the network, load from cache only.
- * Use with {@link #setCacheMode}.
- */
- public static final int LOAD_CACHE_ONLY = 3;
-
- public enum RenderPriority {
- NORMAL,
- HIGH,
- LOW
- }
-
- /**
- * The plugin state effects how plugins are treated on a page. ON means
- * that any object will be loaded even if a plugin does not exist to handle
- * the content. ON_DEMAND means that if there is a plugin installed that
- * can handle the content, a placeholder is shown until the user clicks on
- * the placeholder. Once clicked, the plugin will be enabled on the page.
- * OFF means that all plugins will be turned off and any fallback content
- * will be used.
- */
- public enum PluginState {
- ON,
- ON_DEMAND,
- OFF
- }
-
+public class WebSettingsClassic extends WebSettings {
// TODO: Keep this up to date
private static final String PREVIOUS_VERSION = "4.0.3";
// WebView associated with this WebSettings.
- private WebView mWebView;
+ private WebViewClassic mWebView;
// BrowserFrame used to access the native frame pointer.
private BrowserFrame mBrowserFrame;
// Flag to prevent multiple SYNC messages at one time.
@@ -308,7 +199,7 @@ public class WebSettings {
public void handleMessage(Message msg) {
switch (msg.what) {
case SYNC:
- synchronized (WebSettings.this) {
+ synchronized (WebSettingsClassic.this) {
if (mBrowserFrame.mNativeFrame != 0) {
nativeSync(mBrowserFrame.mNativeFrame);
}
@@ -336,7 +227,7 @@ public class WebSettings {
}
private void setRenderPriority() {
- synchronized (WebSettings.this) {
+ synchronized (WebSettingsClassic.this) {
if (mRenderPriority == RenderPriority.NORMAL) {
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_DEFAULT);
@@ -379,7 +270,7 @@ public class WebSettings {
* Package constructor to prevent clients from creating a new settings
* instance.
*/
- WebSettings(Context context, WebView webview) {
+ WebSettingsClassic(Context context, WebViewClassic webview) {
mEventHandler = new EventHandler();
mContext = context;
mWebView = webview;
@@ -517,194 +408,195 @@ public class WebSettings {
}
/**
- * Enables dumping the pages navigation cache to a text file.
- * @deprecated This method is now obsolete.
+ * @see android.webkit.WebSettings#setNavDump(boolean)
*/
+ @Override
@Deprecated
public void setNavDump(boolean enabled) {
mNavDump = enabled;
}
/**
- * Returns true if dumping the navigation cache is enabled.
- * @deprecated This method is now obsolete.
+ * @see android.webkit.WebSettings#getNavDump()
*/
+ @Override
@Deprecated
public boolean getNavDump() {
return mNavDump;
}
/**
- * Set whether the WebView supports zoom
+ * @see android.webkit.WebSettings#setSupportZoom(boolean)
*/
+ @Override
public void setSupportZoom(boolean support) {
mSupportZoom = support;
mWebView.updateMultiTouchSupport(mContext);
}
/**
- * Returns whether the WebView supports zoom
+ * @see android.webkit.WebSettings#supportZoom()
*/
+ @Override
public boolean supportZoom() {
return mSupportZoom;
}
/**
- * Sets whether the zoom mechanism built into WebView is used.
+ * @see android.webkit.WebSettings#setBuiltInZoomControls(boolean)
*/
+ @Override
public void setBuiltInZoomControls(boolean enabled) {
mBuiltInZoomControls = enabled;
mWebView.updateMultiTouchSupport(mContext);
}
/**
- * Returns true if the zoom mechanism built into WebView is being used.
+ * @see android.webkit.WebSettings#getBuiltInZoomControls()
*/
+ @Override
public boolean getBuiltInZoomControls() {
return mBuiltInZoomControls;
}
/**
- * Sets whether the on screen zoom buttons are used.
- * A combination of built in zoom controls enabled
- * and on screen zoom controls disabled allows for pinch to zoom
- * to work without the on screen controls
+ * @see android.webkit.WebSettings#setDisplayZoomControls(boolean)
*/
+ @Override
public void setDisplayZoomControls(boolean enabled) {
mDisplayZoomControls = enabled;
mWebView.updateMultiTouchSupport(mContext);
}
/**
- * Returns true if the on screen zoom buttons are being used.
+ * @see android.webkit.WebSettings#getDisplayZoomControls()
*/
+ @Override
public boolean getDisplayZoomControls() {
return mDisplayZoomControls;
}
/**
- * Enable or disable file access within WebView. File access is enabled by
- * default. Note that this enables or disables file system access only.
- * Assets and resources are still accessible using file:///android_asset and
- * file:///android_res.
+ * @see android.webkit.WebSettings#setAllowFileAccess(boolean)
*/
+ @Override
public void setAllowFileAccess(boolean allow) {
mAllowFileAccess = allow;
}
/**
- * Returns true if this WebView supports file access.
+ * @see android.webkit.WebSettings#getAllowFileAccess()
*/
+ @Override
public boolean getAllowFileAccess() {
return mAllowFileAccess;
}
/**
- * Enable or disable content url access within WebView. Content url access
- * allows WebView to load content from a content provider installed in the
- * system. The default is enabled.
+ * @see android.webkit.WebSettings#setAllowContentAccess(boolean)
*/
+ @Override
public void setAllowContentAccess(boolean allow) {
mAllowContentAccess = allow;
}
/**
- * Returns true if this WebView supports content url access.
+ * @see android.webkit.WebSettings#getAllowContentAccess()
*/
+ @Override
public boolean getAllowContentAccess() {
return mAllowContentAccess;
}
/**
- * Set whether the WebView loads a page with overview mode.
+ * @see android.webkit.WebSettings#setLoadWithOverviewMode(boolean)
*/
+ @Override
public void setLoadWithOverviewMode(boolean overview) {
mLoadWithOverviewMode = overview;
}
/**
- * Returns true if this WebView loads page with overview mode
+ * @see android.webkit.WebSettings#getLoadWithOverviewMode()
*/
+ @Override
public boolean getLoadWithOverviewMode() {
return mLoadWithOverviewMode;
}
/**
- * Set whether the WebView will enable smooth transition while panning or
- * zooming or while the window hosting the WebView does not have focus.
- * If it is true, WebView will choose a solution to maximize the performance.
- * e.g. the WebView's content may not be updated during the transition.
- * If it is false, WebView will keep its fidelity. The default value is false.
+ * @see android.webkit.WebSettings#setEnableSmoothTransition(boolean)
*/
+ @Override
public void setEnableSmoothTransition(boolean enable) {
mEnableSmoothTransition = enable;
}
/**
- * Returns true if the WebView enables smooth transition while panning or
- * zooming.
+ * @see android.webkit.WebSettings#enableSmoothTransition()
*/
+ @Override
public boolean enableSmoothTransition() {
return mEnableSmoothTransition;
}
/**
- * Set whether the WebView uses its background for over scroll background.
- * If true, it will use the WebView's background. If false, it will use an
- * internal pattern. Default is true.
- * @deprecated This method is now obsolete.
+ * @see android.webkit.WebSettings#setUseWebViewBackgroundForOverscrollBackground(boolean)
*/
+ @Override
@Deprecated
public void setUseWebViewBackgroundForOverscrollBackground(boolean view) {
mUseWebViewBackgroundForOverscroll = view;
}
/**
- * Returns true if this WebView uses WebView's background instead of
- * internal pattern for over scroll background.
- * @deprecated This method is now obsolete.
+ * @see android.webkit.WebSettings#getUseWebViewBackgroundForOverscrollBackground()
*/
+ @Override
@Deprecated
public boolean getUseWebViewBackgroundForOverscrollBackground() {
return mUseWebViewBackgroundForOverscroll;
}
/**
- * Store whether the WebView is saving form data.
+ * @see android.webkit.WebSettings#setSaveFormData(boolean)
*/
+ @Override
public void setSaveFormData(boolean save) {
mSaveFormData = save;
}
/**
- * Return whether the WebView is saving form data and displaying prior
- * entries/autofill++. Always false in private browsing mode.
+ * @see android.webkit.WebSettings#getSaveFormData()
*/
+ @Override
public boolean getSaveFormData() {
return mSaveFormData && !mPrivateBrowsingEnabled;
}
/**
- * Store whether the WebView is saving password.
+ * @see android.webkit.WebSettings#setSavePassword(boolean)
*/
+ @Override
public void setSavePassword(boolean save) {
mSavePassword = save;
}
/**
- * Return whether the WebView is saving password.
+ * @see android.webkit.WebSettings#getSavePassword()
*/
+ @Override
public boolean getSavePassword() {
return mSavePassword;
}
/**
- * Set the text zoom of the page in percent. Default is 100.
- * @param textZoom A percent value for increasing or decreasing the text.
+ * @see android.webkit.WebSettings#setTextZoom(int)
*/
+ @Override
public synchronized void setTextZoom(int textZoom) {
if (mTextSize != textZoom) {
- if (WebView.mLogEvent) {
+ if (WebViewClassic.mLogEvent) {
EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE,
mTextSize, textZoom);
}
@@ -714,32 +606,25 @@ public class WebSettings {
}
/**
- * Get the text zoom of the page in percent.
- * @return A percent value describing the text zoom.
- * @see setTextSizeZoom
+ * @see android.webkit.WebSettings#getTextZoom()
*/
+ @Override
public synchronized int getTextZoom() {
return mTextSize;
}
/**
- * Set the text size of the page.
- * @param t A TextSize value for increasing or decreasing the text.
- * @see WebSettings.TextSize
- * @deprecated Use {@link #setTextZoom(int)} instead
+ * @see android.webkit.WebSettings#setTextSize(android.webkit.WebSettingsClassic.TextSize)
*/
+ @Override
public synchronized void setTextSize(TextSize t) {
setTextZoom(t.value);
}
/**
- * Get the text size of the page. If the text size was previously specified
- * in percent using {@link #setTextZoom(int)}, this will return
- * the closest matching {@link TextSize}.
- * @return A TextSize enum value describing the text size.
- * @see WebSettings.TextSize
- * @deprecated Use {@link #getTextZoom()} instead
+ * @see android.webkit.WebSettings#getTextSize()
*/
+ @Override
public synchronized TextSize getTextSize() {
TextSize closestSize = null;
int smallestDelta = Integer.MAX_VALUE;
@@ -778,11 +663,9 @@ public class WebSettings {
}
/**
- * Set the default zoom density of the page. This should be called from UI
- * thread.
- * @param zoom A ZoomDensity value
- * @see WebSettings.ZoomDensity
+ * @see android.webkit.WebSettings#setDefaultZoom(android.webkit.WebSettingsClassic.ZoomDensity)
*/
+ @Override
public void setDefaultZoom(ZoomDensity zoom) {
if (mDefaultZoom != zoom) {
mDefaultZoom = zoom;
@@ -791,54 +674,51 @@ public class WebSettings {
}
/**
- * Get the default zoom density of the page. This should be called from UI
- * thread.
- * @return A ZoomDensity value
- * @see WebSettings.ZoomDensity
+ * @see android.webkit.WebSettings#getDefaultZoom()
*/
+ @Override
public ZoomDensity getDefaultZoom() {
return mDefaultZoom;
}
/**
- * Enables using light touches to make a selection and activate mouseovers.
+ * @see android.webkit.WebSettings#setLightTouchEnabled(boolean)
*/
+ @Override
public void setLightTouchEnabled(boolean enabled) {
mLightTouchEnabled = enabled;
}
/**
- * Returns true if light touches are enabled.
+ * @see android.webkit.WebSettings#getLightTouchEnabled()
*/
+ @Override
public boolean getLightTouchEnabled() {
return mLightTouchEnabled;
}
/**
- * @deprecated This setting controlled a rendering optimization
- * that is no longer present. Setting it now has no effect.
+ * @see android.webkit.WebSettings#setUseDoubleTree(boolean)
*/
+ @Override
@Deprecated
public synchronized void setUseDoubleTree(boolean use) {
return;
}
/**
- * @deprecated This setting controlled a rendering optimization
- * that is no longer present. Setting it now has no effect.
+ * @see android.webkit.WebSettings#getUseDoubleTree()
*/
+ @Override
@Deprecated
public synchronized boolean getUseDoubleTree() {
return false;
}
/**
- * Tell the WebView about user-agent string.
- * @param ua 0 if the WebView should use an Android user-agent string,
- * 1 if the WebView should use a desktop user-agent string.
- *
- * @deprecated Please use setUserAgentString instead.
+ * @see android.webkit.WebSettings#setUserAgent(int)
*/
+ @Override
@Deprecated
public synchronized void setUserAgent(int ua) {
String uaString = null;
@@ -861,13 +741,9 @@ public class WebSettings {
}
/**
- * Return user-agent as int
- * @return int 0 if the WebView is using an Android user-agent string.
- * 1 if the WebView is using a desktop user-agent string.
- * -1 if the WebView is using user defined user-agent string.
- *
- * @deprecated Please use getUserAgentString instead.
+ * @see android.webkit.WebSettings#getUserAgent()
*/
+ @Override
@Deprecated
public synchronized int getUserAgent() {
if (DESKTOP_USERAGENT.equals(mUserAgent)) {
@@ -881,8 +757,9 @@ public class WebSettings {
}
/**
- * Tell the WebView to use the wide viewport
+ * @see android.webkit.WebSettings#setUseWideViewPort(boolean)
*/
+ @Override
public synchronized void setUseWideViewPort(boolean use) {
if (mUseWideViewport != use) {
mUseWideViewport = use;
@@ -891,17 +768,17 @@ public class WebSettings {
}
/**
- * @return True if the WebView is using a wide viewport
+ * @see android.webkit.WebSettings#getUseWideViewPort()
*/
+ @Override
public synchronized boolean getUseWideViewPort() {
return mUseWideViewport;
}
/**
- * Tell the WebView whether it supports multiple windows. TRUE means
- * that {@link WebChromeClient#onCreateWindow(WebView, boolean,
- * boolean, Message)} is implemented by the host application.
+ * @see android.webkit.WebSettings#setSupportMultipleWindows(boolean)
*/
+ @Override
public synchronized void setSupportMultipleWindows(boolean support) {
if (mSupportMultipleWindows != support) {
mSupportMultipleWindows = support;
@@ -910,20 +787,17 @@ public class WebSettings {
}
/**
- * @return True if the WebView is supporting multiple windows. This means
- * that {@link WebChromeClient#onCreateWindow(WebView, boolean,
- * boolean, Message)} is implemented by the host application.
+ * @see android.webkit.WebSettings#supportMultipleWindows()
*/
+ @Override
public synchronized boolean supportMultipleWindows() {
return mSupportMultipleWindows;
}
/**
- * Set the underlying layout algorithm. This will cause a relayout of the
- * WebView.
- * @param l A LayoutAlgorithm enum specifying the algorithm to use.
- * @see WebSettings.LayoutAlgorithm
+ * @see android.webkit.WebSettings#setLayoutAlgorithm(android.webkit.WebSettingsClassic.LayoutAlgorithm)
*/
+ @Override
public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) {
// XXX: This will only be affective if libwebcore was built with
// ANDROID_LAYOUT defined.
@@ -934,19 +808,17 @@ public class WebSettings {
}
/**
- * Return the current layout algorithm. The default is NARROW_COLUMNS.
- * @return LayoutAlgorithm enum value describing the layout algorithm
- * being used.
- * @see WebSettings.LayoutAlgorithm
+ * @see android.webkit.WebSettings#getLayoutAlgorithm()
*/
+ @Override
public synchronized LayoutAlgorithm getLayoutAlgorithm() {
return mLayoutAlgorithm;
}
/**
- * Set the standard font family name.
- * @param font A font family name.
+ * @see android.webkit.WebSettings#setStandardFontFamily(java.lang.String)
*/
+ @Override
public synchronized void setStandardFontFamily(String font) {
if (font != null && !font.equals(mStandardFontFamily)) {
mStandardFontFamily = font;
@@ -955,17 +827,17 @@ public class WebSettings {
}
/**
- * Get the standard font family name. The default is "sans-serif".
- * @return The standard font family name as a string.
+ * @see android.webkit.WebSettings#getStandardFontFamily()
*/
+ @Override
public synchronized String getStandardFontFamily() {
return mStandardFontFamily;
}
/**
- * Set the fixed font family name.
- * @param font A font family name.
+ * @see android.webkit.WebSettings#setFixedFontFamily(java.lang.String)
*/
+ @Override
public synchronized void setFixedFontFamily(String font) {
if (font != null && !font.equals(mFixedFontFamily)) {
mFixedFontFamily = font;
@@ -974,17 +846,17 @@ public class WebSettings {
}
/**
- * Get the fixed font family name. The default is "monospace".
- * @return The fixed font family name as a string.
+ * @see android.webkit.WebSettings#getFixedFontFamily()
*/
+ @Override
public synchronized String getFixedFontFamily() {
return mFixedFontFamily;
}
/**
- * Set the sans-serif font family name.
- * @param font A font family name.
+ * @see android.webkit.WebSettings#setSansSerifFontFamily(java.lang.String)
*/
+ @Override
public synchronized void setSansSerifFontFamily(String font) {
if (font != null && !font.equals(mSansSerifFontFamily)) {
mSansSerifFontFamily = font;
@@ -993,17 +865,17 @@ public class WebSettings {
}
/**
- * Get the sans-serif font family name.
- * @return The sans-serif font family name as a string.
+ * @see android.webkit.WebSettings#getSansSerifFontFamily()
*/
+ @Override
public synchronized String getSansSerifFontFamily() {
return mSansSerifFontFamily;
}
/**
- * Set the serif font family name. The default is "sans-serif".
- * @param font A font family name.
+ * @see android.webkit.WebSettings#setSerifFontFamily(java.lang.String)
*/
+ @Override
public synchronized void setSerifFontFamily(String font) {
if (font != null && !font.equals(mSerifFontFamily)) {
mSerifFontFamily = font;
@@ -1012,17 +884,17 @@ public class WebSettings {
}
/**
- * Get the serif font family name. The default is "serif".
- * @return The serif font family name as a string.
+ * @see android.webkit.WebSettings#getSerifFontFamily()
*/
+ @Override
public synchronized String getSerifFontFamily() {
return mSerifFontFamily;
}
/**
- * Set the cursive font family name.
- * @param font A font family name.
+ * @see android.webkit.WebSettings#setCursiveFontFamily(java.lang.String)
*/
+ @Override
public synchronized void setCursiveFontFamily(String font) {
if (font != null && !font.equals(mCursiveFontFamily)) {
mCursiveFontFamily = font;
@@ -1031,17 +903,17 @@ public class WebSettings {
}
/**
- * Get the cursive font family name. The default is "cursive".
- * @return The cursive font family name as a string.
+ * @see android.webkit.WebSettings#getCursiveFontFamily()
*/
+ @Override
public synchronized String getCursiveFontFamily() {
return mCursiveFontFamily;
}
/**
- * Set the fantasy font family name.
- * @param font A font family name.
+ * @see android.webkit.WebSettings#setFantasyFontFamily(java.lang.String)
*/
+ @Override
public synchronized void setFantasyFontFamily(String font) {
if (font != null && !font.equals(mFantasyFontFamily)) {
mFantasyFontFamily = font;
@@ -1050,18 +922,17 @@ public class WebSettings {
}
/**
- * Get the fantasy font family name. The default is "fantasy".
- * @return The fantasy font family name as a string.
+ * @see android.webkit.WebSettings#getFantasyFontFamily()
*/
+ @Override
public synchronized String getFantasyFontFamily() {
return mFantasyFontFamily;
}
/**
- * Set the minimum font size.
- * @param size A non-negative integer between 1 and 72.
- * Any number outside the specified range will be pinned.
+ * @see android.webkit.WebSettings#setMinimumFontSize(int)
*/
+ @Override
public synchronized void setMinimumFontSize(int size) {
size = pin(size);
if (mMinimumFontSize != size) {
@@ -1071,18 +942,17 @@ public class WebSettings {
}
/**
- * Get the minimum font size. The default is 8.
- * @return A non-negative integer between 1 and 72.
+ * @see android.webkit.WebSettings#getMinimumFontSize()
*/
+ @Override
public synchronized int getMinimumFontSize() {
return mMinimumFontSize;
}
/**
- * Set the minimum logical font size.
- * @param size A non-negative integer between 1 and 72.
- * Any number outside the specified range will be pinned.
+ * @see android.webkit.WebSettings#setMinimumLogicalFontSize(int)
*/
+ @Override
public synchronized void setMinimumLogicalFontSize(int size) {
size = pin(size);
if (mMinimumLogicalFontSize != size) {
@@ -1092,18 +962,17 @@ public class WebSettings {
}
/**
- * Get the minimum logical font size. The default is 8.
- * @return A non-negative integer between 1 and 72.
+ * @see android.webkit.WebSettings#getMinimumLogicalFontSize()
*/
+ @Override
public synchronized int getMinimumLogicalFontSize() {
return mMinimumLogicalFontSize;
}
/**
- * Set the default font size.
- * @param size A non-negative integer between 1 and 72.
- * Any number outside the specified range will be pinned.
+ * @see android.webkit.WebSettings#setDefaultFontSize(int)
*/
+ @Override
public synchronized void setDefaultFontSize(int size) {
size = pin(size);
if (mDefaultFontSize != size) {
@@ -1113,18 +982,17 @@ public class WebSettings {
}
/**
- * Get the default font size. The default is 16.
- * @return A non-negative integer between 1 and 72.
+ * @see android.webkit.WebSettings#getDefaultFontSize()
*/
+ @Override
public synchronized int getDefaultFontSize() {
return mDefaultFontSize;
}
/**
- * Set the default fixed font size.
- * @param size A non-negative integer between 1 and 72.
- * Any number outside the specified range will be pinned.
+ * @see android.webkit.WebSettings#setDefaultFixedFontSize(int)
*/
+ @Override
public synchronized void setDefaultFixedFontSize(int size) {
size = pin(size);
if (mDefaultFixedFontSize != size) {
@@ -1134,9 +1002,9 @@ public class WebSettings {
}
/**
- * Get the default fixed font size. The default is 16.
- * @return A non-negative integer between 1 and 72.
+ * @see android.webkit.WebSettings#getDefaultFixedFontSize()
*/
+ @Override
public synchronized int getDefaultFixedFontSize() {
return mDefaultFixedFontSize;
}
@@ -1156,14 +1024,9 @@ public class WebSettings {
}
/**
- * Sets whether the WebView should load image resources. Note that this method
- * controls loading of all images, including those embedded using the data
- * URI scheme. Use {@link #setBlockNetworkImage} to control loading only
- * of images specified using network URI schemes. Note that if the value of this
- * setting is changed from false to true, all images resources referenced
- * by content currently displayed by the WebView are loaded automatically.
- * @param flag Whether the WebView should load image resources.
+ * @see android.webkit.WebSettings#setLoadsImagesAutomatically(boolean)
*/
+ @Override
public synchronized void setLoadsImagesAutomatically(boolean flag) {
if (mLoadsImagesAutomatically != flag) {
mLoadsImagesAutomatically = flag;
@@ -1172,28 +1035,17 @@ public class WebSettings {
}
/**
- * Returns true if the WebView loads image resources. This includes
- * images embedded using the data URI scheme. The default is true.
- * @return True if the WebView loads image resources.
+ * @see android.webkit.WebSettings#getLoadsImagesAutomatically()
*/
+ @Override
public synchronized boolean getLoadsImagesAutomatically() {
return mLoadsImagesAutomatically;
}
/**
- * Sets whether the WebView should not load image resources from the
- * network (resources accessed via http and https URI schemes). Note
- * that this method has no effect unless
- * {@link #getLoadsImagesAutomatically} returns true. Also note that
- * disabling all network loads using {@link #setBlockNetworkLoads}
- * will also prevent network images from loading, even if this flag is set
- * to false. When the value of this setting is changed from true to false,
- * network images resources referenced by content currently displayed by
- * the WebView are fetched automatically.
- * @param flag Whether the WebView should not load image resources from
- * the network.
- * @see #setBlockNetworkLoads
+ * @see android.webkit.WebSettings#setBlockNetworkImage(boolean)
*/
+ @Override
public synchronized void setBlockNetworkImage(boolean flag) {
if (mBlockNetworkImage != flag) {
mBlockNetworkImage = flag;
@@ -1202,29 +1054,17 @@ public class WebSettings {
}
/**
- * Returns true if the WebView does not load image resources from the network.
- * The default is false.
- * @return True if the WebView does not load image resources from the network.
+ * @see android.webkit.WebSettings#getBlockNetworkImage()
*/
+ @Override
public synchronized boolean getBlockNetworkImage() {
return mBlockNetworkImage;
}
/**
- * Sets whether the WebView should not load resources from the network.
- * Use {@link #setBlockNetworkImage} to only avoid loading
- * image resources. Note that if the value of this setting is
- * changed from true to false, network resources referenced by content
- * currently displayed by the WebView are not fetched until
- * {@link android.webkit.WebView#reload} is called.
- * If the application does not have the
- * {@link android.Manifest.permission#INTERNET} permission, attempts to set
- * a value of false will cause a {@link java.lang.SecurityException}
- * to be thrown.
- * @param flag Whether the WebView should not load any resources
- * from the network.
- * @see android.webkit.WebView#reload
+ * @see android.webkit.WebSettings#setBlockNetworkLoads(boolean)
*/
+ @Override
public synchronized void setBlockNetworkLoads(boolean flag) {
if (mBlockNetworkLoads != flag) {
mBlockNetworkLoads = flag;
@@ -1234,12 +1074,9 @@ public class WebSettings {
}
/**
- * Returns true if the WebView does not load any resources from the network.
- * The default value is false if the application has the
- * {@link android.Manifest.permission#INTERNET} permission, otherwise it is
- * true.
- * @return True if the WebView does not load any resources from the network.
+ * @see android.webkit.WebSettings#getBlockNetworkLoads()
*/
+ @Override
public synchronized boolean getBlockNetworkLoads() {
return mBlockNetworkLoads;
}
@@ -1258,9 +1095,9 @@ public class WebSettings {
}
/**
- * Tell the WebView to enable javascript execution.
- * @param flag True if the WebView should execute javascript.
+ * @see android.webkit.WebSettings#setJavaScriptEnabled(boolean)
*/
+ @Override
public synchronized void setJavaScriptEnabled(boolean flag) {
if (mJavaScriptEnabled != flag) {
mJavaScriptEnabled = flag;
@@ -1309,23 +1146,18 @@ public class WebSettings {
}
/**
- * Tell the WebView to enable plugins.
- * @param flag True if the WebView should load plugins.
- * @deprecated This method has been deprecated in favor of
- * {@link #setPluginState}
+ * @see android.webkit.WebSettings#setPluginsEnabled(boolean)
*/
+ @Override
@Deprecated
public synchronized void setPluginsEnabled(boolean flag) {
setPluginState(flag ? PluginState.ON : PluginState.OFF);
}
/**
- * Tell the WebView to enable, disable, or have plugins on demand. On
- * demand mode means that if a plugin exists that can handle the embedded
- * content, a placeholder icon will be shown instead of the plugin. When
- * the placeholder is clicked, the plugin will be enabled.
- * @param state One of the PluginState values.
+ * @see android.webkit.WebSettings#setPluginState(android.webkit.WebSettingsClassic.PluginState)
*/
+ @Override
public synchronized void setPluginState(PluginState state) {
if (mPluginState != state) {
mPluginState = state;
@@ -1334,23 +1166,17 @@ public class WebSettings {
}
/**
- * Set a custom path to plugins used by the WebView. This method is
- * obsolete since each plugin is now loaded from its own package.
- * @param pluginsPath String path to the directory containing plugins.
- * @deprecated This method is no longer used as plugins are loaded from
- * their own APK via the system's package manager.
+ * @see android.webkit.WebSettings#setPluginsPath(java.lang.String)
*/
+ @Override
@Deprecated
public synchronized void setPluginsPath(String pluginsPath) {
}
/**
- * Set the path to where database storage API databases should be saved.
- * Nota that the WebCore Database Tracker only allows the path to be set once.
- * This will update WebCore when the Sync runs in the C++ side.
- * @param databasePath String path to the directory where databases should
- * be saved. May be the empty string but should never be null.
+ * @see android.webkit.WebSettings#setDatabasePath(java.lang.String)
*/
+ @Override
public synchronized void setDatabasePath(String databasePath) {
if (databasePath != null && !mDatabasePathHasBeenSet) {
mDatabasePath = databasePath;
@@ -1360,12 +1186,9 @@ public class WebSettings {
}
/**
- * Set the path where the Geolocation permissions database should be saved.
- * This will update WebCore when the Sync runs in the C++ side.
- * @param databasePath String path to the directory where the Geolocation
- * permissions database should be saved. May be the empty string but
- * should never be null.
+ * @see android.webkit.WebSettings#setGeolocationDatabasePath(java.lang.String)
*/
+ @Override
public synchronized void setGeolocationDatabasePath(String databasePath) {
if (databasePath != null
&& !databasePath.equals(mGeolocationDatabasePath)) {
@@ -1375,9 +1198,9 @@ public class WebSettings {
}
/**
- * Enable or disable the Application Cache API.
- * @param flag Whether to enable the Application Cache API.
+ * @see android.webkit.WebSettings#setAppCacheEnabled(boolean)
*/
+ @Override
public synchronized void setAppCacheEnabled(boolean flag) {
if (mAppCacheEnabled != flag) {
mAppCacheEnabled = flag;
@@ -1386,14 +1209,9 @@ public class WebSettings {
}
/**
- * Set the path used by the Application Cache API to store files. This
- * setting is applied to all WebViews in the application. In order for the
- * Application Cache API to function, this method must be called with a
- * path which exists and is writable by the application. This method may
- * only be called once: repeated calls are ignored.
- * @param path Path to the directory that should be used to store Application
- * Cache files.
+ * @see android.webkit.WebSettings#setAppCachePath(java.lang.String)
*/
+ @Override
public synchronized void setAppCachePath(String path) {
// We test for a valid path and for repeated setting on the native
// side, but we can avoid syncing in some simple cases.
@@ -1404,9 +1222,9 @@ public class WebSettings {
}
/**
- * Set the maximum size for the Application Caches content.
- * @param appCacheMaxSize the maximum size in bytes.
+ * @see android.webkit.WebSettings#setAppCacheMaxSize(long)
*/
+ @Override
public synchronized void setAppCacheMaxSize(long appCacheMaxSize) {
if (appCacheMaxSize != mAppCacheMaxSize) {
mAppCacheMaxSize = appCacheMaxSize;
@@ -1415,10 +1233,9 @@ public class WebSettings {
}
/**
- * Set whether the database storage API is enabled.
- * @param flag boolean True if the WebView should use the database storage
- * API.
+ * @see android.webkit.WebSettings#setDatabaseEnabled(boolean)
*/
+ @Override
public synchronized void setDatabaseEnabled(boolean flag) {
if (mDatabaseEnabled != flag) {
mDatabaseEnabled = flag;
@@ -1427,10 +1244,9 @@ public class WebSettings {
}
/**
- * Set whether the DOM storage API is enabled.
- * @param flag boolean True if the WebView should use the DOM storage
- * API.
+ * @see android.webkit.WebSettings#setDomStorageEnabled(boolean)
*/
+ @Override
public synchronized void setDomStorageEnabled(boolean flag) {
if (mDomStorageEnabled != flag) {
mDomStorageEnabled = flag;
@@ -1439,26 +1255,25 @@ public class WebSettings {
}
/**
- * Returns true if the DOM Storage API's are enabled.
- * @return True if the DOM Storage API's are enabled.
+ * @see android.webkit.WebSettings#getDomStorageEnabled()
*/
+ @Override
public synchronized boolean getDomStorageEnabled() {
return mDomStorageEnabled;
}
/**
- * Return the path to where database storage API databases are saved for
- * the current WebView.
- * @return the String path to the database storage API databases.
+ * @see android.webkit.WebSettings#getDatabasePath()
*/
+ @Override
public synchronized String getDatabasePath() {
return mDatabasePath;
}
/**
- * Returns true if database storage API is enabled.
- * @return True if the database storage API is enabled.
+ * @see android.webkit.WebSettings#getDatabaseEnabled()
*/
+ @Override
public synchronized boolean getDatabaseEnabled() {
return mDatabaseEnabled;
}
@@ -1478,9 +1293,9 @@ public class WebSettings {
}
/**
- * Sets whether Geolocation is enabled.
- * @param flag Whether Geolocation should be enabled.
+ * @see android.webkit.WebSettings#setGeolocationEnabled(boolean)
*/
+ @Override
public synchronized void setGeolocationEnabled(boolean flag) {
if (mGeolocationEnabled != flag) {
mGeolocationEnabled = flag;
@@ -1501,48 +1316,43 @@ public class WebSettings {
}
/**
- * Return true if javascript is enabled. <b>Note: The default is false.</b>
- * @return True if javascript is enabled.
+ * @see android.webkit.WebSettings#getJavaScriptEnabled()
*/
+ @Override
public synchronized boolean getJavaScriptEnabled() {
return mJavaScriptEnabled;
}
/**
- * Return true if plugins are enabled.
- * @return True if plugins are enabled.
- * @deprecated This method has been replaced by {@link #getPluginState}
+ * @see android.webkit.WebSettings#getPluginsEnabled()
*/
+ @Override
@Deprecated
public synchronized boolean getPluginsEnabled() {
return mPluginState == PluginState.ON;
}
/**
- * Return the current plugin state.
- * @return A value corresponding to the enum PluginState.
+ * @see android.webkit.WebSettings#getPluginState()
*/
+ @Override
public synchronized PluginState getPluginState() {
return mPluginState;
}
/**
- * Returns the directory that contains the plugin libraries. This method is
- * obsolete since each plugin is now loaded from its own package.
- * @return An empty string.
- * @deprecated This method is no longer used as plugins are loaded from
- * their own APK via the system's package manager.
+ * @see android.webkit.WebSettings#getPluginsPath()
*/
+ @Override
@Deprecated
public synchronized String getPluginsPath() {
return "";
}
/**
- * Tell javascript to open windows automatically. This applies to the
- * javascript function window.open().
- * @param flag True if javascript can open windows automatically.
+ * @see android.webkit.WebSettings#setJavaScriptCanOpenWindowsAutomatically(boolean)
*/
+ @Override
public synchronized void setJavaScriptCanOpenWindowsAutomatically(
boolean flag) {
if (mJavaScriptCanOpenWindowsAutomatically != flag) {
@@ -1552,19 +1362,17 @@ public class WebSettings {
}
/**
- * Return true if javascript can open windows automatically. The default
- * is false.
- * @return True if javascript can open windows automatically during
- * window.open().
+ * @see android.webkit.WebSettings#getJavaScriptCanOpenWindowsAutomatically()
*/
+ @Override
public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() {
return mJavaScriptCanOpenWindowsAutomatically;
}
/**
- * Set the default text encoding name to use when decoding html pages.
- * @param encoding The text encoding name.
+ * @see android.webkit.WebSettings#setDefaultTextEncodingName(java.lang.String)
*/
+ @Override
public synchronized void setDefaultTextEncodingName(String encoding) {
if (encoding != null && !encoding.equals(mDefaultTextEncoding)) {
mDefaultTextEncoding = encoding;
@@ -1573,17 +1381,17 @@ public class WebSettings {
}
/**
- * Get the default text encoding name. The default is "Latin-1".
- * @return The default text encoding name as a string.
+ * @see android.webkit.WebSettings#getDefaultTextEncodingName()
*/
+ @Override
public synchronized String getDefaultTextEncodingName() {
return mDefaultTextEncoding;
}
/**
- * Set the WebView's user-agent string. If the string "ua" is null or empty,
- * it will use the system default user-agent string.
+ * @see android.webkit.WebSettings#setUserAgentString(java.lang.String)
*/
+ @Override
public synchronized void setUserAgentString(String ua) {
if (ua == null || ua.length() == 0) {
synchronized(sLockForLocaleSettings) {
@@ -1606,8 +1414,9 @@ public class WebSettings {
}
/**
- * Return the WebView's user-agent string.
+ * @see android.webkit.WebSettings#getUserAgentString()
*/
+ @Override
public synchronized String getUserAgentString() {
if (DESKTOP_USERAGENT.equals(mUserAgent) ||
IPHONE_USERAGENT.equals(mUserAgent) ||
@@ -1648,11 +1457,9 @@ public class WebSettings {
}
/**
- * Tell the WebView whether it needs to set a node to have focus when
- * {@link WebView#requestFocus(int, android.graphics.Rect)} is called.
- *
- * @param flag
+ * @see android.webkit.WebSettings#setNeedInitialFocus(boolean)
*/
+ @Override
public void setNeedInitialFocus(boolean flag) {
if (mNeedInitialFocus != flag) {
mNeedInitialFocus = flag;
@@ -1665,11 +1472,9 @@ public class WebSettings {
}
/**
- * Set the priority of the Render thread. Unlike the other settings, this
- * one only needs to be called once per process. The default is NORMAL.
- *
- * @param priority RenderPriority, can be normal, high or low.
+ * @see android.webkit.WebSettings#setRenderPriority(android.webkit.WebSettingsClassic.RenderPriority)
*/
+ @Override
public synchronized void setRenderPriority(RenderPriority priority) {
if (mRenderPriority != priority) {
mRenderPriority = priority;
@@ -1679,13 +1484,9 @@ public class WebSettings {
}
/**
- * Override the way the cache is used. The way the cache is used is based
- * on the navigation option. For a normal page load, the cache is checked
- * and content is re-validated as needed. When navigating back, content is
- * not revalidated, instead the content is just pulled from the cache.
- * This function allows the client to override this behavior.
- * @param mode One of the LOAD_ values.
+ * @see android.webkit.WebSettings#setCacheMode(int)
*/
+ @Override
public void setCacheMode(int mode) {
if (mode != mOverrideCacheMode) {
mOverrideCacheMode = mode;
@@ -1694,9 +1495,9 @@ public class WebSettings {
}
/**
- * Return the current setting for overriding the cache mode. For a full
- * description, see the {@link #setCacheMode(int)} function.
+ * @see android.webkit.WebSettings#getCacheMode()
*/
+ @Override
public int getCacheMode() {
return mOverrideCacheMode;
}
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 510c168..a01c42d 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -78,7 +78,7 @@ import java.util.ArrayList;
private int mRingInset;
- private WebView mWebView;
+ private WebViewClassic mWebView;
private boolean mSingle;
private int mWidthSpec;
private int mHeightSpec;
@@ -177,7 +177,7 @@ import java.util.ArrayList;
* @param context The Context for this WebTextView.
* @param webView The WebView that created this.
*/
- /* package */ WebTextView(Context context, WebView webView, int autoFillQueryId) {
+ /* package */ WebTextView(Context context, WebViewClassic webView, int autoFillQueryId) {
super(context, null, com.android.internal.R.attr.webTextViewStyle);
mWebView = webView;
mMaxLength = -1;
@@ -833,9 +833,9 @@ import java.util.ArrayList;
}
mInsideRemove = true;
boolean isFocused = hasFocus();
- mWebView.removeView(this);
+ mWebView.getWebView().removeView(this);
if (isFocused) {
- mWebView.requestFocus();
+ mWebView.getWebView().requestFocus();
}
mInsideRemove = false;
mHandler.removeCallbacksAndMessages(null);
@@ -997,7 +997,7 @@ import java.util.ArrayList;
}
if (getParent() == null) {
// Insert the view so that it's drawn first (at index 0)
- mWebView.addView(this, 0, lp);
+ mWebView.getWebView().addView(this, 0, lp);
} else if (needsUpdate) {
setLayoutParams(lp);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index a850379..a561577 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -16,126 +16,35 @@
package android.webkit;
-import android.animation.ObjectAnimator;
import android.annotation.Widget;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.content.BroadcastReceiver;
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.ComponentCallbacks2;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
import android.content.res.Configuration;
-import android.database.DataSetObserver;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapShader;
import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.DrawFilter;
-import android.graphics.Paint;
-import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Picture;
-import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.RegionIterator;
-import android.graphics.Shader;
import android.graphics.drawable.Drawable;
-import android.net.Proxy;
-import android.net.ProxyProperties;
-import android.net.Uri;
import android.net.http.SslCertificate;
-import android.os.AsyncTask;
import android.os.Bundle;
-import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.StrictMode;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.security.KeyChain;
-import android.speech.tts.TextToSpeech;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.Selection;
-import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.EventLog;
import android.util.Log;
-import android.view.Display;
-import android.view.Gravity;
-import android.view.HapticFeedbackConstants;
-import android.view.HardwareCanvas;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-import android.view.SoundEffectConstants;
-import android.view.VelocityTracker;
import android.view.View;
-import android.view.ViewConfiguration;
import android.view.ViewGroup;
-import android.view.ViewParent;
+import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
-import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputMethodManager;
-import android.webkit.HTML5VideoInline;
-import android.webkit.WebTextView.AutoCompleteAdapter;
-import android.webkit.WebViewCore.DrawData;
-import android.webkit.WebViewCore.EventHub;
-import android.webkit.WebViewCore.TextFieldInitData;
-import android.webkit.WebViewCore.TouchEventData;
-import android.webkit.WebViewCore.TouchHighlightData;
-import android.webkit.WebViewCore.WebKitHitTest;
import android.widget.AbsoluteLayout;
-import android.widget.Adapter;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.CheckedTextView;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.OverScroller;
-import android.widget.PopupWindow;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import junit.framework.Assert;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
-import java.util.Vector;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
/**
* <p>A View that displays web pages. This class is the basis upon which you
@@ -345,452 +254,25 @@ import java.util.regex.Pattern;
*
*
*/
+/*
+ * Implementation notes.
+ * The WebView is a thin API class that delegates its public API to a backend WebViewProvider
+ * class instance. WebView extends {@link AbsoluteLayout} for backward compatibility reasons.
+ * Methods are delegated to the provider implementation: all public API methods introduced in this
+ * file are fully delegated, whereas public and protected methods from the View base classes are
+ * only delegated where a specific need exists for them to do so.
+ */
@Widget
public class WebView extends AbsoluteLayout
implements ViewTreeObserver.OnGlobalFocusChangeListener,
ViewGroup.OnHierarchyChangeListener {
- private class InnerGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
- @Override
- public void onGlobalLayout() {
- if (isShown()) {
- setGLRectViewport();
- }
- }
- }
-
- private class InnerScrollChangedListener implements ViewTreeObserver.OnScrollChangedListener {
- @Override
- public void onScrollChanged() {
- if (isShown()) {
- setGLRectViewport();
- }
- }
- }
-
- /**
- * InputConnection used for ContentEditable. This captures changes
- * to the text and sends them either as key strokes or text changes.
- */
- private class WebViewInputConnection extends BaseInputConnection {
- // Used for mapping characters to keys typed.
- private KeyCharacterMap mKeyCharacterMap;
- private boolean mIsKeySentByMe;
- private int mInputType;
- private int mImeOptions;
- private String mHint;
- private int mMaxLength;
-
- public WebViewInputConnection() {
- super(WebView.this, true);
- }
-
- @Override
- public boolean sendKeyEvent(KeyEvent event) {
- // Some IMEs send key events directly using sendKeyEvents.
- // WebViewInputConnection should treat these as text changes.
- if (!mIsKeySentByMe) {
- if (event.getAction() == KeyEvent.ACTION_UP) {
- if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
- return deleteSurroundingText(1, 0);
- } else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) {
- return deleteSurroundingText(0, 1);
- } else if (event.getUnicodeChar() != 0){
- String newComposingText =
- Character.toString((char)event.getUnicodeChar());
- return commitText(newComposingText, 1);
- }
- } else if (event.getAction() == KeyEvent.ACTION_DOWN &&
- (event.getKeyCode() == KeyEvent.KEYCODE_DEL
- || event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL
- || event.getUnicodeChar() != 0)) {
- return true; // only act on action_down
- }
- }
- return super.sendKeyEvent(event);
- }
-
- public void setTextAndKeepSelection(CharSequence text) {
- Editable editable = getEditable();
- int selectionStart = Selection.getSelectionStart(editable);
- int selectionEnd = Selection.getSelectionEnd(editable);
- text = limitReplaceTextByMaxLength(text, editable.length());
- editable.replace(0, editable.length(), text);
- restartInput();
- // Keep the previous selection.
- selectionStart = Math.min(selectionStart, editable.length());
- selectionEnd = Math.min(selectionEnd, editable.length());
- setSelection(selectionStart, selectionEnd);
- }
-
- public void replaceSelection(CharSequence text) {
- Editable editable = getEditable();
- int selectionStart = Selection.getSelectionStart(editable);
- int selectionEnd = Selection.getSelectionEnd(editable);
- text = limitReplaceTextByMaxLength(text, selectionEnd - selectionStart);
- setNewText(selectionStart, selectionEnd, text);
- editable.replace(selectionStart, selectionEnd, text);
- restartInput();
- // Move caret to the end of the new text
- int newCaret = selectionStart + text.length();
- setSelection(newCaret, newCaret);
- }
-
- @Override
- public boolean setComposingText(CharSequence text, int newCursorPosition) {
- Editable editable = getEditable();
- int start = getComposingSpanStart(editable);
- int end = getComposingSpanEnd(editable);
- if (start < 0 || end < 0) {
- start = Selection.getSelectionStart(editable);
- end = Selection.getSelectionEnd(editable);
- }
- if (end < start) {
- int temp = end;
- end = start;
- start = temp;
- }
- CharSequence limitedText = limitReplaceTextByMaxLength(text, end - start);
- setNewText(start, end, limitedText);
- if (limitedText != text) {
- newCursorPosition -= text.length() - limitedText.length();
- }
- super.setComposingText(limitedText, newCursorPosition);
- if (limitedText != text) {
- restartInput();
- int lastCaret = start + limitedText.length();
- finishComposingText();
- setSelection(lastCaret, lastCaret);
- }
- return true;
- }
-
- @Override
- public boolean commitText(CharSequence text, int newCursorPosition) {
- setComposingText(text, newCursorPosition);
- int cursorPosition = Selection.getSelectionEnd(getEditable());
- setComposingRegion(cursorPosition, cursorPosition);
- return true;
- }
-
- @Override
- public boolean deleteSurroundingText(int leftLength, int rightLength) {
- Editable editable = getEditable();
- int cursorPosition = Selection.getSelectionEnd(editable);
- int startDelete = Math.max(0, cursorPosition - leftLength);
- int endDelete = Math.min(editable.length(),
- cursorPosition + rightLength);
- setNewText(startDelete, endDelete, "");
- return super.deleteSurroundingText(leftLength, rightLength);
- }
-
- @Override
- public boolean performEditorAction(int editorAction) {
-
- boolean handled = true;
- switch (editorAction) {
- case EditorInfo.IME_ACTION_NEXT:
- WebView.this.requestFocus(FOCUS_FORWARD);
- break;
- case EditorInfo.IME_ACTION_PREVIOUS:
- WebView.this.requestFocus(FOCUS_BACKWARD);
- break;
- case EditorInfo.IME_ACTION_DONE:
- WebView.this.hideSoftKeyboard();
- break;
- case EditorInfo.IME_ACTION_GO:
- case EditorInfo.IME_ACTION_SEARCH:
- WebView.this.hideSoftKeyboard();
- String text = getEditable().toString();
- passToJavaScript(text, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_ENTER));
- passToJavaScript(text, new KeyEvent(KeyEvent.ACTION_UP,
- KeyEvent.KEYCODE_ENTER));
- break;
-
- default:
- handled = super.performEditorAction(editorAction);
- break;
- }
-
- return handled;
- }
-
- public void initEditorInfo(WebViewCore.TextFieldInitData initData) {
- int type = initData.mType;
- int inputType = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
- int imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
- | EditorInfo.IME_FLAG_NO_FULLSCREEN;
- if (!initData.mIsSpellCheckEnabled) {
- inputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
- }
- if (WebTextView.TEXT_AREA != type
- && initData.mIsTextFieldNext) {
- imeOptions |= EditorInfo.IME_FLAG_NAVIGATE_NEXT;
- }
- switch (type) {
- case WebTextView.NORMAL_TEXT_FIELD:
- imeOptions |= EditorInfo.IME_ACTION_GO;
- break;
- case WebTextView.TEXT_AREA:
- inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE
- | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
- | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
- imeOptions |= EditorInfo.IME_ACTION_NONE;
- break;
- case WebTextView.PASSWORD:
- inputType |= EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD;
- imeOptions |= EditorInfo.IME_ACTION_GO;
- break;
- case WebTextView.SEARCH:
- imeOptions |= EditorInfo.IME_ACTION_SEARCH;
- break;
- case WebTextView.EMAIL:
- // inputType needs to be overwritten because of the different text variation.
- inputType = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
- imeOptions |= EditorInfo.IME_ACTION_GO;
- break;
- case WebTextView.NUMBER:
- // inputType needs to be overwritten because of the different class.
- inputType = InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_NORMAL
- | InputType.TYPE_NUMBER_FLAG_SIGNED | InputType.TYPE_NUMBER_FLAG_DECIMAL;
- // Number and telephone do not have both a Tab key and an
- // action, so set the action to NEXT
- imeOptions |= EditorInfo.IME_ACTION_NEXT;
- break;
- case WebTextView.TELEPHONE:
- // inputType needs to be overwritten because of the different class.
- inputType = InputType.TYPE_CLASS_PHONE;
- imeOptions |= EditorInfo.IME_ACTION_NEXT;
- break;
- case WebTextView.URL:
- // TYPE_TEXT_VARIATION_URI prevents Tab key from showing, so
- // exclude it for now.
- imeOptions |= EditorInfo.IME_ACTION_GO;
- inputType |= InputType.TYPE_TEXT_VARIATION_URI;
- break;
- default:
- imeOptions |= EditorInfo.IME_ACTION_GO;
- break;
- }
- mHint = initData.mLabel;
- mInputType = inputType;
- mImeOptions = imeOptions;
- mMaxLength = initData.mMaxLength;
- }
-
- public void setupEditorInfo(EditorInfo outAttrs) {
- outAttrs.inputType = mInputType;
- outAttrs.imeOptions = mImeOptions;
- outAttrs.hintText = mHint;
- outAttrs.initialCapsMode = getCursorCapsMode(InputType.TYPE_CLASS_TEXT);
- }
-
- /**
- * Sends a text change to webkit indirectly. If it is a single-
- * character add or delete, it sends it as a key stroke. If it cannot
- * be represented as a key stroke, it sends it as a field change.
- * @param start The start offset (inclusive) of the text being changed.
- * @param end The end offset (exclusive) of the text being changed.
- * @param text The new text to replace the changed text.
- */
- private void setNewText(int start, int end, CharSequence text) {
- mIsKeySentByMe = true;
- Editable editable = getEditable();
- CharSequence original = editable.subSequence(start, end);
- boolean isCharacterAdd = false;
- boolean isCharacterDelete = false;
- int textLength = text.length();
- int originalLength = original.length();
- if (textLength > originalLength) {
- isCharacterAdd = (textLength == originalLength + 1)
- && TextUtils.regionMatches(text, 0, original, 0,
- originalLength);
- } else if (originalLength > textLength) {
- isCharacterDelete = (textLength == originalLength - 1)
- && TextUtils.regionMatches(text, 0, original, 0,
- textLength);
- }
- if (isCharacterAdd) {
- sendCharacter(text.charAt(textLength - 1));
- } else if (isCharacterDelete) {
- sendKey(KeyEvent.KEYCODE_DEL);
- } else if ((textLength != originalLength) ||
- !TextUtils.regionMatches(text, 0, original, 0,
- textLength)) {
- // Send a message so that key strokes and text replacement
- // do not come out of order.
- Message replaceMessage = mPrivateHandler.obtainMessage(
- REPLACE_TEXT, start, end, text.toString());
- mPrivateHandler.sendMessage(replaceMessage);
- }
- mIsKeySentByMe = false;
- }
-
- /**
- * Send a single character to the WebView as a key down and up event.
- * @param c The character to be sent.
- */
- private void sendCharacter(char c) {
- if (mKeyCharacterMap == null) {
- mKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
- }
- char[] chars = new char[1];
- chars[0] = c;
- KeyEvent[] events = mKeyCharacterMap.getEvents(chars);
- if (events != null) {
- for (KeyEvent event : events) {
- sendKeyEvent(event);
- }
- } else {
- Message msg = mPrivateHandler.obtainMessage(KEY_PRESS, (int) c, 0);
- mPrivateHandler.sendMessage(msg);
- }
- }
-
- /**
- * Send a key event for a specific key code, not a standard
- * unicode character.
- * @param keyCode The key code to send.
- */
- private void sendKey(int keyCode) {
- long eventTime = SystemClock.uptimeMillis();
- sendKeyEvent(new KeyEvent(eventTime, eventTime,
- KeyEvent.ACTION_DOWN, keyCode, 0, 0,
- KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
- KeyEvent.FLAG_SOFT_KEYBOARD));
- sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
- KeyEvent.ACTION_UP, keyCode, 0, 0,
- KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
- KeyEvent.FLAG_SOFT_KEYBOARD));
- }
-
- private CharSequence limitReplaceTextByMaxLength(CharSequence text,
- int numReplaced) {
- if (mMaxLength > 0) {
- Editable editable = getEditable();
- int maxReplace = mMaxLength - editable.length() + numReplaced;
- if (maxReplace < text.length()) {
- maxReplace = Math.max(maxReplace, 0);
- // New length is greater than the maximum. trim it down.
- text = text.subSequence(0, maxReplace);
- }
- }
- return text;
- }
-
- private void restartInput() {
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null) {
- // Since the text has changed, do not allow the IME to replace the
- // existing text as though it were a completion.
- imm.restartInput(WebView.this);
- }
- }
- }
-
- private class PastePopupWindow extends PopupWindow implements OnClickListener {
- private ViewGroup mContentView;
- private TextView mPasteTextView;
-
- public PastePopupWindow() {
- super(WebView.this.mContext, null,
- com.android.internal.R.attr.textSelectHandleWindowStyle);
- setClippingEnabled(true);
- LinearLayout linearLayout = new LinearLayout(WebView.this.getContext());
- linearLayout.setOrientation(LinearLayout.HORIZONTAL);
- mContentView = linearLayout;
- mContentView.setBackgroundResource(
- com.android.internal.R.drawable.text_edit_paste_window);
-
- LayoutInflater inflater = (LayoutInflater)WebView.this.mContext.
- getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- ViewGroup.LayoutParams wrapContent = new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-
- mPasteTextView = (TextView) inflater.inflate(
- com.android.internal.R.layout.text_edit_action_popup_text, null);
- mPasteTextView.setLayoutParams(wrapContent);
- mContentView.addView(mPasteTextView);
- mPasteTextView.setText(com.android.internal.R.string.paste);
- mPasteTextView.setOnClickListener(this);
- this.setContentView(mContentView);
- }
-
- public void show(Rect cursorRect, int windowLeft, int windowTop) {
- measureContent();
-
- int width = mContentView.getMeasuredWidth();
- int height = mContentView.getMeasuredHeight();
- int y = cursorRect.top - height;
- if (y < windowTop) {
- // There's not enough room vertically, move it below the
- // handle.
- // The selection handle is vertically offset by 1/4 of the
- // line height.
- y = cursorRect.bottom - (cursorRect.height() / 4) +
- mSelectHandleCenter.getIntrinsicHeight();
- }
- int x = cursorRect.centerX() - (width / 2);
- if (x < windowLeft) {
- x = windowLeft;
- }
- if (!isShowing()) {
- showAtLocation(WebView.this, Gravity.NO_GRAVITY, x, y);
- }
- update(x, y, width, height);
- }
-
- public void hide() {
- dismiss();
- }
-
- @Override
- public void onClick(View view) {
- pasteFromClipboard();
- selectionDone();
- }
-
- protected void measureContent() {
- final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
- mContentView.measure(
- View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels,
- View.MeasureSpec.AT_MOST),
- View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels,
- View.MeasureSpec.AT_MOST));
- }
- }
-
- // The listener to capture global layout change event.
- private InnerGlobalLayoutListener mGlobalLayoutListener = null;
-
- // The listener to capture scroll event.
- private InnerScrollChangedListener mScrollChangedListener = null;
+ // Default Provider factory class name.
+ private static final String DEFAULT_WEB_VIEW_FACTORY = "android.webkit.WebViewClassic$Factory";
- // if AUTO_REDRAW_HACK is true, then the CALL key will toggle redrawing
- // the screen all-the-time. Good for profiling our drawing code
- static private final boolean AUTO_REDRAW_HACK = false;
- // true means redraw the screen all-the-time. Only with AUTO_REDRAW_HACK
- private boolean mAutoRedraw;
-
- // Reference to the AlertDialog displayed by InvokeListBox.
- // It's used to dismiss the dialog in destroy if not done before.
- private AlertDialog mListBoxDialog = null;
-
- static final String LOGTAG = "webview";
-
- private ZoomManager mZoomManager;
-
- private final Rect mGLRectViewport = new Rect();
- private final Rect mViewRectViewport = new Rect();
- private final RectF mVisibleContentRect = new RectF();
- private boolean mGLViewportEmpty = false;
- WebViewInputConnection mInputConnection = null;
- private int mFieldPointer;
- private PastePopupWindow mPasteWindow;
+ private static final String LOGTAG = "webview_proxy";
+ // TODO: flip DEBUG to always be disabled.
+ private static final boolean DEBUG = true;
/**
* Transportation object for returning WebView across thread boundaries.
@@ -815,531 +297,6 @@ public class WebView extends AbsoluteLayout
}
}
- private static class OnTrimMemoryListener implements ComponentCallbacks2 {
- private static OnTrimMemoryListener sInstance = null;
-
- static void init(Context c) {
- if (sInstance == null) {
- sInstance = new OnTrimMemoryListener(c.getApplicationContext());
- }
- }
-
- private OnTrimMemoryListener(Context c) {
- c.registerComponentCallbacks(this);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- // Ignore
- }
-
- @Override
- public void onLowMemory() {
- // Ignore
- }
-
- @Override
- public void onTrimMemory(int level) {
- if (DebugFlags.WEB_VIEW) {
- Log.d("WebView", "onTrimMemory: " + level);
- }
- // When framework reset EGL context during high memory pressure, all
- // the existing GL resources for the html5 video will be destroyed
- // at native side.
- // Here we just need to clean up the Surface Texture which is static.
- HTML5VideoInline.cleanupSurfaceTexture();
- WebView.nativeOnTrimMemory(level);
- }
-
- }
-
- // A final CallbackProxy shared by WebViewCore and BrowserFrame.
- private final CallbackProxy mCallbackProxy;
-
- private final WebViewDatabase mDatabase;
-
- // SSL certificate for the main top-level page (if secure)
- private SslCertificate mCertificate;
-
- // Native WebView pointer that is 0 until the native object has been
- // created.
- private int mNativeClass;
- // This would be final but it needs to be set to null when the WebView is
- // destroyed.
- private WebViewCore mWebViewCore;
- // Handler for dispatching UI messages.
- /* package */ final Handler mPrivateHandler = new PrivateHandler();
- private WebTextView mWebTextView;
- // Used to ignore changes to webkit text that arrives to the UI side after
- // more key events.
- private int mTextGeneration;
-
- /* package */ void incrementTextGeneration() { mTextGeneration++; }
-
- // 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 in pixels.
- * Use integer to prevent loss of dragging delta calculation accuracy;
- * which was done in float and converted to integer, and resulted in gradual
- * and compounding touch position and view dragging mismatch.
- */
- private int mLastTouchX;
- private int mLastTouchY;
- private int mStartTouchX;
- private int mStartTouchY;
- private float mAverageAngle;
-
- /**
- * Time of the last touch event.
- */
- private long mLastTouchTime;
-
- /**
- * Time of the last time sending touch event to WebViewCore
- */
- private long mLastSentTouchTime;
-
- /**
- * The minimum elapsed time before sending another ACTION_MOVE event to
- * WebViewCore. This really should be tuned for each type of the devices.
- * For example in Google Map api test case, it takes Dream device at least
- * 150ms to do a full cycle in the WebViewCore by processing a touch event,
- * triggering the layout and drawing the picture. While the same process
- * takes 60+ms on the current high speed device. If we make
- * TOUCH_SENT_INTERVAL too small, there will be multiple touch events sent
- * to WebViewCore queue and the real layout and draw events will be pushed
- * to further, which slows down the refresh rate. Choose 50 to favor the
- * current high speed devices. For Dream like devices, 100 is a better
- * choice. Maybe make this in the buildspec later.
- * (Update 12/14/2010: changed to 0 since current device should be able to
- * handle the raw events and Map team voted to have the raw events too.
- */
- private static final int TOUCH_SENT_INTERVAL = 0;
- private int mCurrentTouchInterval = TOUCH_SENT_INTERVAL;
-
- /**
- * Helper class to get velocity for fling
- */
- VelocityTracker mVelocityTracker;
- private int mMaximumFling;
- private float mLastVelocity;
- private float mLastVelX;
- private float mLastVelY;
-
- // The id of the native layer being scrolled.
- private int mCurrentScrollingLayerId;
- private Rect mScrollingLayerRect = new Rect();
-
- // only trigger accelerated fling if the new velocity is at least
- // MINIMUM_VELOCITY_RATIO_FOR_ACCELERATION times of the previous velocity
- private static final float MINIMUM_VELOCITY_RATIO_FOR_ACCELERATION = 0.2f;
-
- /**
- * Touch mode
- */
- private int mTouchMode = TOUCH_DONE_MODE;
- private static final int TOUCH_INIT_MODE = 1;
- private static final int TOUCH_DRAG_START_MODE = 2;
- private static final int TOUCH_DRAG_MODE = 3;
- private static final int TOUCH_SHORTPRESS_START_MODE = 4;
- private static final int TOUCH_SHORTPRESS_MODE = 5;
- private static final int TOUCH_DOUBLE_TAP_MODE = 6;
- private static final int TOUCH_DONE_MODE = 7;
- private static final int TOUCH_PINCH_DRAG = 8;
- private static final int TOUCH_DRAG_LAYER_MODE = 9;
-
- // Whether to forward the touch events to WebCore
- // Can only be set by WebKit via JNI.
- private boolean mForwardTouchEvents = false;
-
- // Whether to prevent default during touch. The initial value depends on
- // mForwardTouchEvents. If WebCore wants all the touch events, it says yes
- // for touch down. Otherwise UI will wait for the answer of the first
- // confirmed move before taking over the control.
- private static final int PREVENT_DEFAULT_NO = 0;
- private static final int PREVENT_DEFAULT_MAYBE_YES = 1;
- private static final int PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN = 2;
- private static final int PREVENT_DEFAULT_YES = 3;
- private static final int PREVENT_DEFAULT_IGNORE = 4;
- private int mPreventDefault = PREVENT_DEFAULT_IGNORE;
-
- // true when the touch movement exceeds the slop
- private boolean mConfirmMove;
-
- // if true, touch events will be first processed by WebCore, if prevent
- // default is not set, the UI will continue handle them.
- private boolean mDeferTouchProcess;
-
- // to avoid interfering with the current touch events, track them
- // separately. Currently no snapping or fling in the deferred process mode
- private int mDeferTouchMode = TOUCH_DONE_MODE;
- private float mLastDeferTouchX;
- private float mLastDeferTouchY;
-
- // To keep track of whether the current drag was initiated by a WebTextView,
- // so that we know not to hide the cursor
- boolean mDragFromTextInput;
-
- // Whether or not to draw the cursor ring.
- private boolean mDrawCursorRing = true;
-
- // true if onPause has been called (and not onResume)
- private boolean mIsPaused;
-
- private HitTestResult mInitialHitTestResult;
- private WebKitHitTest mFocusedNode;
-
- /**
- * Customizable constant
- */
- // pre-computed square of ViewConfiguration.getScaledTouchSlop()
- private int mTouchSlopSquare;
- // pre-computed square of ViewConfiguration.getScaledDoubleTapSlop()
- private int mDoubleTapSlopSquare;
- // pre-computed density adjusted navigation slop
- private int mNavSlop;
- // This should be ViewConfiguration.getTapTimeout()
- // But system time out is 100ms, which is too short for the browser.
- // In the browser, if it switches out of tap too soon, jump tap won't work.
- // In addition, a double tap on a trackpad will always have a duration of
- // 300ms, so this value must be at least that (otherwise we will timeout the
- // first tap and convert it to a long press).
- private static final int TAP_TIMEOUT = 300;
- // This should be ViewConfiguration.getLongPressTimeout()
- // But system time out is 500ms, which is too short for the browser.
- // With a short timeout, it's difficult to treat trigger a short press.
- private static final int LONG_PRESS_TIMEOUT = 1000;
- // needed to avoid flinging after a pause of no movement
- private static final int MIN_FLING_TIME = 250;
- // draw unfiltered after drag is held without movement
- private static final int MOTIONLESS_TIME = 100;
- // The amount of content to overlap between two screens when going through
- // pages with the space bar, in pixels.
- private static final int PAGE_SCROLL_OVERLAP = 24;
-
- /**
- * These prevent calling requestLayout if either dimension is fixed. This
- * depends on the layout parameters and the measure specs.
- */
- boolean mWidthCanMeasure;
- boolean mHeightCanMeasure;
-
- // Remember the last dimensions we sent to the native side so we can avoid
- // sending the same dimensions more than once.
- int mLastWidthSent;
- int mLastHeightSent;
- // Since view height sent to webkit could be fixed to avoid relayout, this
- // value records the last sent actual view height.
- int mLastActualHeightSent;
-
- private int mContentWidth; // cache of value from WebViewCore
- private int mContentHeight; // cache of value from WebViewCore
-
- // Need to have the separate control for horizontal and vertical scrollbar
- // style than the View's single scrollbar style
- private boolean mOverlayHorizontalScrollbar = true;
- private boolean mOverlayVerticalScrollbar = false;
-
- // our standard speed. this way small distances will be traversed in less
- // time than large distances, but we cap the duration, so that very large
- // distances won't take too long to get there.
- private static final int STD_SPEED = 480; // pixels per second
- // time for the longest scroll animation
- private static final int MAX_DURATION = 750; // milliseconds
- private static final int SLIDE_TITLE_DURATION = 500; // milliseconds
-
- // Used by OverScrollGlow
- OverScroller mScroller;
-
- private boolean mInOverScrollMode = false;
- private static Paint mOverScrollBackground;
- private static Paint mOverScrollBorder;
-
- private boolean mWrapContent;
- private static final int MOTIONLESS_FALSE = 0;
- private static final int MOTIONLESS_PENDING = 1;
- private static final int MOTIONLESS_TRUE = 2;
- private static final int MOTIONLESS_IGNORE = 3;
- private int mHeldMotionless;
-
- // An instance for injecting accessibility in WebViews with disabled
- // JavaScript or ones for which no accessibility script exists
- private AccessibilityInjector mAccessibilityInjector;
-
- // flag indicating if accessibility script is injected so we
- // know to handle Shift and arrows natively first
- private boolean mAccessibilityScriptInjected;
-
-
- /**
- * How long the caret handle will last without being touched.
- */
- private static final long CARET_HANDLE_STAMINA_MS = 3000;
-
- private Drawable mSelectHandleLeft;
- private Drawable mSelectHandleRight;
- private Drawable mSelectHandleCenter;
- private Rect mSelectCursorBase = new Rect();
- private int mSelectCursorBaseLayerId;
- private Rect mSelectCursorExtent = new Rect();
- private int mSelectCursorExtentLayerId;
- private Rect mSelectDraggingCursor;
- private Point mSelectDraggingOffset = new Point();
- private boolean mIsCaretSelection;
- static final int HANDLE_ID_START = 0;
- static final int HANDLE_ID_END = 1;
- static final int HANDLE_ID_BASE = 2;
- static final int HANDLE_ID_EXTENT = 3;
-
- static boolean sDisableNavcache = false;
- static boolean sEnableWebTextView = false;
- // the color used to highlight the touch rectangles
- static final int HIGHLIGHT_COLOR = 0x6633b5e5;
- // the region indicating where the user touched on the screen
- private Region mTouchHighlightRegion = new Region();
- // the paint for the touch highlight
- private Paint mTouchHightlightPaint = new Paint();
- // debug only
- private static final boolean DEBUG_TOUCH_HIGHLIGHT = true;
- private static final int TOUCH_HIGHLIGHT_ELAPSE_TIME = 2000;
- private Paint mTouchCrossHairColor;
- private int mTouchHighlightX;
- private int mTouchHighlightY;
- private long mTouchHighlightRequested;
-
- // Basically this proxy is used to tell the Video to update layer tree at
- // SetBaseLayer time and to pause when WebView paused.
- private HTML5VideoViewProxy mHTML5VideoViewProxy;
-
- // If we are using a set picture, don't send view updates to webkit
- private boolean mBlockWebkitViewMessages = false;
-
- // cached value used to determine if we need to switch drawing models
- private boolean mHardwareAccelSkia = false;
-
- /*
- * Private message ids
- */
- private static final int REMEMBER_PASSWORD = 1;
- private static final int NEVER_REMEMBER_PASSWORD = 2;
- private static final int SWITCH_TO_SHORTPRESS = 3;
- private static final int SWITCH_TO_LONGPRESS = 4;
- private static final int RELEASE_SINGLE_TAP = 5;
- private static final int REQUEST_FORM_DATA = 6;
- private static final int DRAG_HELD_MOTIONLESS = 8;
- private static final int AWAKEN_SCROLL_BARS = 9;
- private static final int PREVENT_DEFAULT_TIMEOUT = 10;
- private static final int SCROLL_SELECT_TEXT = 11;
-
-
- private static final int FIRST_PRIVATE_MSG_ID = REMEMBER_PASSWORD;
- private static final int LAST_PRIVATE_MSG_ID = SCROLL_SELECT_TEXT;
-
- /*
- * Package message ids
- */
- static final int SCROLL_TO_MSG_ID = 101;
- static final int NEW_PICTURE_MSG_ID = 105;
- static final int UPDATE_TEXT_ENTRY_MSG_ID = 106;
- static final int WEBCORE_INITIALIZED_MSG_ID = 107;
- static final int UPDATE_TEXTFIELD_TEXT_MSG_ID = 108;
- static final int UPDATE_ZOOM_RANGE = 109;
- static final int UNHANDLED_NAV_KEY = 110;
- static final int CLEAR_TEXT_ENTRY = 111;
- static final int UPDATE_TEXT_SELECTION_MSG_ID = 112;
- static final int SHOW_RECT_MSG_ID = 113;
- static final int LONG_PRESS_CENTER = 114;
- static final int PREVENT_TOUCH_ID = 115;
- static final int WEBCORE_NEED_TOUCH_EVENTS = 116;
- // obj=Rect in doc coordinates
- static final int INVAL_RECT_MSG_ID = 117;
- static final int REQUEST_KEYBOARD = 118;
- static final int DO_MOTION_UP = 119;
- static final int SHOW_FULLSCREEN = 120;
- static final int HIDE_FULLSCREEN = 121;
- static final int DOM_FOCUS_CHANGED = 122;
- static final int REPLACE_BASE_CONTENT = 123;
- static final int FORM_DID_BLUR = 124;
- static final int RETURN_LABEL = 125;
- static final int UPDATE_MATCH_COUNT = 126;
- static final int CENTER_FIT_RECT = 127;
- static final int REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID = 128;
- static final int SET_SCROLLBAR_MODES = 129;
- static final int SELECTION_STRING_CHANGED = 130;
- static final int HIT_TEST_RESULT = 131;
- static final int SAVE_WEBARCHIVE_FINISHED = 132;
-
- static final int SET_AUTOFILLABLE = 133;
- static final int AUTOFILL_COMPLETE = 134;
-
- static final int SELECT_AT = 135;
- static final int SCREEN_ON = 136;
- static final int ENTER_FULLSCREEN_VIDEO = 137;
- static final int UPDATE_SELECTION = 138;
- static final int UPDATE_ZOOM_DENSITY = 139;
- static final int EXIT_FULLSCREEN_VIDEO = 140;
-
- static final int COPY_TO_CLIPBOARD = 141;
- static final int INIT_EDIT_FIELD = 142;
- static final int REPLACE_TEXT = 143;
- static final int CLEAR_CARET_HANDLE = 144;
- static final int KEY_PRESS = 145;
-
- private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
- private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT;
-
- static final String[] HandlerPrivateDebugString = {
- "REMEMBER_PASSWORD", // = 1;
- "NEVER_REMEMBER_PASSWORD", // = 2;
- "SWITCH_TO_SHORTPRESS", // = 3;
- "SWITCH_TO_LONGPRESS", // = 4;
- "RELEASE_SINGLE_TAP", // = 5;
- "REQUEST_FORM_DATA", // = 6;
- "RESUME_WEBCORE_PRIORITY", // = 7;
- "DRAG_HELD_MOTIONLESS", // = 8;
- "AWAKEN_SCROLL_BARS", // = 9;
- "PREVENT_DEFAULT_TIMEOUT", // = 10;
- "SCROLL_SELECT_TEXT" // = 11;
- };
-
- static final String[] HandlerPackageDebugString = {
- "SCROLL_TO_MSG_ID", // = 101;
- "102", // = 102;
- "103", // = 103;
- "104", // = 104;
- "NEW_PICTURE_MSG_ID", // = 105;
- "UPDATE_TEXT_ENTRY_MSG_ID", // = 106;
- "WEBCORE_INITIALIZED_MSG_ID", // = 107;
- "UPDATE_TEXTFIELD_TEXT_MSG_ID", // = 108;
- "UPDATE_ZOOM_RANGE", // = 109;
- "UNHANDLED_NAV_KEY", // = 110;
- "CLEAR_TEXT_ENTRY", // = 111;
- "UPDATE_TEXT_SELECTION_MSG_ID", // = 112;
- "SHOW_RECT_MSG_ID", // = 113;
- "LONG_PRESS_CENTER", // = 114;
- "PREVENT_TOUCH_ID", // = 115;
- "WEBCORE_NEED_TOUCH_EVENTS", // = 116;
- "INVAL_RECT_MSG_ID", // = 117;
- "REQUEST_KEYBOARD", // = 118;
- "DO_MOTION_UP", // = 119;
- "SHOW_FULLSCREEN", // = 120;
- "HIDE_FULLSCREEN", // = 121;
- "DOM_FOCUS_CHANGED", // = 122;
- "REPLACE_BASE_CONTENT", // = 123;
- "FORM_DID_BLUR", // = 124;
- "RETURN_LABEL", // = 125;
- "UPDATE_MATCH_COUNT", // = 126;
- "CENTER_FIT_RECT", // = 127;
- "REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID", // = 128;
- "SET_SCROLLBAR_MODES", // = 129;
- "SELECTION_STRING_CHANGED", // = 130;
- "SET_TOUCH_HIGHLIGHT_RECTS", // = 131;
- "SAVE_WEBARCHIVE_FINISHED", // = 132;
- "SET_AUTOFILLABLE", // = 133;
- "AUTOFILL_COMPLETE", // = 134;
- "SELECT_AT", // = 135;
- "SCREEN_ON", // = 136;
- "ENTER_FULLSCREEN_VIDEO", // = 137;
- "UPDATE_SELECTION", // = 138;
- "UPDATE_ZOOM_DENSITY" // = 139;
- };
-
- // If the site doesn't use the viewport meta tag to specify the viewport,
- // use DEFAULT_VIEWPORT_WIDTH as the default viewport width
- static final int DEFAULT_VIEWPORT_WIDTH = 980;
-
- // normally we try to fit the content to the minimum preferred width
- // calculated by the Webkit. To avoid the bad behavior when some site's
- // minimum preferred width keeps growing when changing the viewport width or
- // the minimum preferred width is huge, an upper limit is needed.
- static int sMaxViewportWidth = DEFAULT_VIEWPORT_WIDTH;
-
- // initial scale in percent. 0 means using default.
- private int mInitialScaleInPercent = 0;
-
- // Whether or not a scroll event should be sent to webkit. This is only set
- // to false when restoring the scroll position.
- private boolean mSendScrollEvent = true;
-
- private int mSnapScrollMode = SNAP_NONE;
- private static final int SNAP_NONE = 0;
- private static final int SNAP_LOCK = 1; // not a separate state
- private static final int SNAP_X = 2; // may be combined with SNAP_LOCK
- private static final int SNAP_Y = 4; // may be combined with SNAP_LOCK
- private boolean mSnapPositive;
-
- // keep these in sync with their counterparts in WebView.cpp
- private static final int DRAW_EXTRAS_NONE = 0;
- private static final int DRAW_EXTRAS_SELECTION = 1;
- private static final int DRAW_EXTRAS_CURSOR_RING = 2;
-
- // keep this in sync with WebCore:ScrollbarMode in WebKit
- private static final int SCROLLBAR_AUTO = 0;
- private static final int SCROLLBAR_ALWAYSOFF = 1;
- // as we auto fade scrollbar, this is ignored.
- private static final int SCROLLBAR_ALWAYSON = 2;
- private int mHorizontalScrollBarMode = SCROLLBAR_AUTO;
- private int mVerticalScrollBarMode = SCROLLBAR_AUTO;
-
- // constants for determining script injection strategy
- private static final int ACCESSIBILITY_SCRIPT_INJECTION_UNDEFINED = -1;
- private static final int ACCESSIBILITY_SCRIPT_INJECTION_OPTED_OUT = 0;
- private static final int ACCESSIBILITY_SCRIPT_INJECTION_PROVIDED = 1;
-
- // the alias via which accessibility JavaScript interface is exposed
- private static final String ALIAS_ACCESSIBILITY_JS_INTERFACE = "accessibility";
-
- // Template for JavaScript that injects a screen-reader.
- private static final String ACCESSIBILITY_SCREEN_READER_JAVASCRIPT_TEMPLATE =
- "javascript:(function() {" +
- " var chooser = document.createElement('script');" +
- " chooser.type = 'text/javascript';" +
- " chooser.src = '%1s';" +
- " document.getElementsByTagName('head')[0].appendChild(chooser);" +
- " })();";
-
- // Regular expression that matches the "axs" URL parameter.
- // The value of 0 means the accessibility script is opted out
- // The value of 1 means the accessibility script is already injected
- private static final String PATTERN_MATCH_AXS_URL_PARAMETER = "(\\?axs=(0|1))|(&axs=(0|1))";
-
- // TextToSpeech instance exposed to JavaScript to the injected screenreader.
- private TextToSpeech mTextToSpeech;
-
- // variable to cache the above pattern in case accessibility is enabled.
- private Pattern mMatchAxsUrlParameterPattern;
-
- /**
- * Max distance to overscroll by in pixels.
- * This how far content can be pulled beyond its normal bounds by the user.
- */
- private int mOverscrollDistance;
-
- /**
- * Max distance to overfling by in pixels.
- * This is how far flinged content can move beyond the end of its normal bounds.
- */
- private int mOverflingDistance;
-
- private OverScrollGlow mOverScrollGlow;
-
- // Used to match key downs and key ups
- private Vector<Integer> mKeysPressed;
-
- /* package */ static boolean mLogEvent = true;
-
- // for event log
- private long mLastTouchUpTime = 0;
-
- private WebViewCore.AutoFillData mAutoFillData;
-
- private static boolean sNotificationsEnabled = true;
-
/**
* URI scheme for telephone number
*/
@@ -1353,26 +310,6 @@ public class WebView extends AbsoluteLayout
*/
public static final String SCHEME_GEO = "geo:0,0?q=";
- private int mBackgroundColor = Color.WHITE;
-
- private static final long SELECT_SCROLL_INTERVAL = 1000 / 60; // 60 / second
- private int mAutoScrollX = 0;
- private int mAutoScrollY = 0;
- private int mMinAutoScrollX = 0;
- private int mMaxAutoScrollX = 0;
- private int mMinAutoScrollY = 0;
- private int mMaxAutoScrollY = 0;
- private Rect mScrollingLayerBounds = new Rect();
- private boolean mSentAutoScrollMessage = false;
-
- // used for serializing asynchronously handled touch events.
- private final TouchEventQueue mTouchEventQueue = new TouchEventQueue();
-
- // Used to track whether picture updating was paused due to a window focus change.
- private boolean mPictureUpdatePausedForFocusChange = false;
-
- // Used to notify listeners of a new picture.
- private PictureListener mPictureListener;
/**
* Interface to listen for new pictures as they change.
* @deprecated This interface is now obsolete.
@@ -1440,15 +377,24 @@ public class WebView extends AbsoluteLayout
private int mType;
private String mExtra;
- HitTestResult() {
+ /**
+ * @hide Only for use by WebViewProvider implementations
+ */
+ public HitTestResult() {
mType = UNKNOWN_TYPE;
}
- private void setType(int type) {
+ /**
+ * @hide Only for use by WebViewProvider implementations
+ */
+ public void setType(int type) {
mType = type;
}
- private void setExtra(String extra) {
+ /**
+ * @hide Only for use by WebViewProvider implementations
+ */
+ public void setExtra(String extra) {
mExtra = extra;
}
@@ -1471,15 +417,6 @@ public class WebView extends AbsoluteLayout
}
/**
- * Refer to {@link WebView#requestFocusNodeHref(Message)} for more information
- */
- static class FocusNodeHref {
- static final String TITLE = "title";
- static final String URL = "url";
- static final String SRC = "src";
- }
-
- /**
* Construct a new WebView with a Context object.
* @param context A Context object used to access application assets.
*/
@@ -1529,418 +466,20 @@ public class WebView extends AbsoluteLayout
* @param javaScriptInterfaces is a Map of interface names, as keys, and
* object implementing those interfaces, as values.
* @param privateBrowsing If true the web view will be initialized in private mode.
- * @hide This is an implementation detail.
+ * @hide This is used internally by dumprendertree, as it requires the javaScript interfaces to
+ * be added synchronously, before a subsequent loadUrl call takes effect.
*/
+ @SuppressWarnings("deprecation") // for super() call into deprecated base class constructor.
protected WebView(Context context, AttributeSet attrs, int defStyle,
Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
super(context, attrs, defStyle);
- checkThread();
-
if (context == null) {
throw new IllegalArgumentException("Invalid context argument");
}
+ checkThread();
- // Used by the chrome stack to find application paths
- JniUtil.setContext(context);
-
- mCallbackProxy = new CallbackProxy(context, this);
- mViewManager = new ViewManager(this);
- L10nUtils.setApplicationContext(context.getApplicationContext());
- mWebViewCore = new WebViewCore(context, this, mCallbackProxy, javaScriptInterfaces);
- mDatabase = WebViewDatabase.getInstance(context);
- mScroller = new OverScroller(context, null, 0, 0, false); //TODO Use OverScroller's flywheel
- mZoomManager = new ZoomManager(this, mCallbackProxy);
-
- /* The init method must follow the creation of certain member variables,
- * such as the mZoomManager.
- */
- init();
- setupPackageListener(context);
- setupProxyListener(context);
- setupTrustStorageListener(context);
- updateMultiTouchSupport(context);
-
- if (privateBrowsing) {
- startPrivateBrowsing();
- }
-
- mAutoFillData = new WebViewCore.AutoFillData();
- }
-
- private static class TrustStorageListener extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
- handleCertTrustChanged();
- }
- }
- }
- private static TrustStorageListener sTrustStorageListener;
-
- /**
- * Handles update to the trust storage.
- */
- private static void handleCertTrustChanged() {
- // send a message for indicating trust storage change
- WebViewCore.sendStaticMessage(EventHub.TRUST_STORAGE_UPDATED, null);
- }
-
- /*
- * @param context This method expects this to be a valid context.
- */
- private static void setupTrustStorageListener(Context context) {
- if (sTrustStorageListener != null ) {
- return;
- }
- IntentFilter filter = new IntentFilter();
- filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
- sTrustStorageListener = new TrustStorageListener();
- Intent current =
- context.getApplicationContext().registerReceiver(sTrustStorageListener, filter);
- if (current != null) {
- handleCertTrustChanged();
- }
- }
-
- private static class ProxyReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) {
- handleProxyBroadcast(intent);
- }
- }
- }
-
- /*
- * Receiver for PROXY_CHANGE_ACTION, will be null when it is not added handling broadcasts.
- */
- private static ProxyReceiver sProxyReceiver;
-
- /*
- * @param context This method expects this to be a valid context
- */
- private static synchronized void setupProxyListener(Context context) {
- if (sProxyReceiver != null || sNotificationsEnabled == false) {
- return;
- }
- IntentFilter filter = new IntentFilter();
- filter.addAction(Proxy.PROXY_CHANGE_ACTION);
- sProxyReceiver = new ProxyReceiver();
- Intent currentProxy = context.getApplicationContext().registerReceiver(
- sProxyReceiver, filter);
- if (currentProxy != null) {
- handleProxyBroadcast(currentProxy);
- }
- }
-
- /*
- * @param context This method expects this to be a valid context
- */
- private static synchronized void disableProxyListener(Context context) {
- if (sProxyReceiver == null)
- return;
-
- context.getApplicationContext().unregisterReceiver(sProxyReceiver);
- sProxyReceiver = null;
- }
-
- private static void handleProxyBroadcast(Intent intent) {
- ProxyProperties proxyProperties = (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
- if (proxyProperties == null || proxyProperties.getHost() == null) {
- WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, null);
- return;
- }
- WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, proxyProperties);
- }
-
- /*
- * A variable to track if there is a receiver added for ACTION_PACKAGE_ADDED
- * or ACTION_PACKAGE_REMOVED.
- */
- private static boolean sPackageInstallationReceiverAdded = false;
-
- /*
- * A set of Google packages we monitor for the
- * navigator.isApplicationInstalled() API. Add additional packages as
- * needed.
- */
- private static Set<String> sGoogleApps;
- static {
- sGoogleApps = new HashSet<String>();
- sGoogleApps.add("com.google.android.youtube");
- }
-
- private static class PackageListener extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- final String packageName = intent.getData().getSchemeSpecificPart();
- final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
- if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
- // if it is replacing, refreshPlugins() when adding
- return;
- }
-
- if (sGoogleApps.contains(packageName)) {
- if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
- WebViewCore.sendStaticMessage(EventHub.ADD_PACKAGE_NAME, packageName);
- } else {
- WebViewCore.sendStaticMessage(EventHub.REMOVE_PACKAGE_NAME, packageName);
- }
- }
-
- PluginManager pm = PluginManager.getInstance(context);
- if (pm.containsPluginPermissionAndSignatures(packageName)) {
- pm.refreshPlugins(Intent.ACTION_PACKAGE_ADDED.equals(action));
- }
- }
- }
-
- private void setupPackageListener(Context context) {
-
- /*
- * we must synchronize the instance check and the creation of the
- * receiver to ensure that only ONE receiver exists for all WebView
- * instances.
- */
- synchronized (WebView.class) {
-
- // if the receiver already exists then we do not need to register it
- // again
- if (sPackageInstallationReceiverAdded) {
- return;
- }
-
- IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addDataScheme("package");
- BroadcastReceiver packageListener = new PackageListener();
- context.getApplicationContext().registerReceiver(packageListener, filter);
- sPackageInstallationReceiverAdded = true;
- }
-
- // check if any of the monitored apps are already installed
- AsyncTask<Void, Void, Set<String>> task = new AsyncTask<Void, Void, Set<String>>() {
-
- @Override
- protected Set<String> doInBackground(Void... unused) {
- Set<String> installedPackages = new HashSet<String>();
- PackageManager pm = mContext.getPackageManager();
- for (String name : sGoogleApps) {
- try {
- pm.getPackageInfo(name,
- PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES);
- installedPackages.add(name);
- } catch (PackageManager.NameNotFoundException e) {
- // package not found
- }
- }
- return installedPackages;
- }
-
- // Executes on the UI thread
- @Override
- protected void onPostExecute(Set<String> installedPackages) {
- if (mWebViewCore != null) {
- mWebViewCore.sendMessage(EventHub.ADD_PACKAGE_NAMES, installedPackages);
- }
- }
- };
- task.execute();
- }
-
- void updateMultiTouchSupport(Context context) {
- mZoomManager.updateMultiTouchSupport(context);
- }
-
- private void init() {
- OnTrimMemoryListener.init(getContext());
- sDisableNavcache = nativeDisableNavcache();
- setWillNotDraw(false);
- setFocusable(true);
- setFocusableInTouchMode(true);
- setClickable(true);
- setLongClickable(true);
-
- final ViewConfiguration configuration = ViewConfiguration.get(getContext());
- int slop = configuration.getScaledTouchSlop();
- mTouchSlopSquare = slop * slop;
- slop = configuration.getScaledDoubleTapSlop();
- mDoubleTapSlopSquare = slop * slop;
- final float density = getContext().getResources().getDisplayMetrics().density;
- // use one line height, 16 based on our current default font, for how
- // far we allow a touch be away from the edge of a link
- mNavSlop = (int) (16 * density);
- mZoomManager.init(density);
- mMaximumFling = configuration.getScaledMaximumFlingVelocity();
-
- // Compute the inverse of the density squared.
- DRAG_LAYER_INVERSE_DENSITY_SQUARED = 1 / (density * density);
-
- mOverscrollDistance = configuration.getScaledOverscrollDistance();
- mOverflingDistance = configuration.getScaledOverflingDistance();
-
- setScrollBarStyle(super.getScrollBarStyle());
- // Initially use a size of two, since the user is likely to only hold
- // down two keys at a time (shift + another key)
- mKeysPressed = new Vector<Integer>(2);
- mHTML5VideoViewProxy = null ;
- }
-
- @Override
- public boolean shouldDelayChildPressedState() {
- return true;
- }
-
- /**
- * Adds accessibility APIs to JavaScript.
- *
- * Note: This method is responsible to performing the necessary
- * check if the accessibility APIs should be exposed.
- */
- private void addAccessibilityApisToJavaScript() {
- if (AccessibilityManager.getInstance(mContext).isEnabled()
- && getSettings().getJavaScriptEnabled()) {
- // exposing the TTS for now ...
- final Context ctx = getContext();
- if (ctx != null) {
- final String packageName = ctx.getPackageName();
- if (packageName != null) {
- mTextToSpeech = new TextToSpeech(getContext(), null, null,
- packageName + ".**webview**", true);
- addJavascriptInterface(mTextToSpeech, ALIAS_ACCESSIBILITY_JS_INTERFACE);
- }
- }
- }
- }
-
- /**
- * Removes accessibility APIs from JavaScript.
- */
- private void removeAccessibilityApisFromJavaScript() {
- // exposing the TTS for now ...
- if (mTextToSpeech != null) {
- removeJavascriptInterface(ALIAS_ACCESSIBILITY_JS_INTERFACE);
- mTextToSpeech.shutdown();
- mTextToSpeech = null;
- }
- }
-
- @Override
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
- info.setScrollable(isScrollableForAccessibility());
- }
-
- @Override
- public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
- super.onInitializeAccessibilityEvent(event);
- event.setScrollable(isScrollableForAccessibility());
- event.setScrollX(mScrollX);
- event.setScrollY(mScrollY);
- final int convertedContentWidth = contentToViewX(getContentWidth());
- final int adjustedViewWidth = getWidth() - mPaddingLeft - mPaddingRight;
- event.setMaxScrollX(Math.max(convertedContentWidth - adjustedViewWidth, 0));
- final int convertedContentHeight = contentToViewY(getContentHeight());
- final int adjustedViewHeight = getHeight() - mPaddingTop - mPaddingBottom;
- event.setMaxScrollY(Math.max(convertedContentHeight - adjustedViewHeight, 0));
- }
-
- private boolean isScrollableForAccessibility() {
- return (contentToViewX(getContentWidth()) > getWidth() - mPaddingLeft - mPaddingRight
- || contentToViewY(getContentHeight()) > getHeight() - mPaddingTop - mPaddingBottom);
- }
-
- @Override
- public void setOverScrollMode(int mode) {
- super.setOverScrollMode(mode);
- if (mode != OVER_SCROLL_NEVER) {
- if (mOverScrollGlow == null) {
- mOverScrollGlow = new OverScrollGlow(this);
- }
- } else {
- mOverScrollGlow = null;
- }
- }
-
- /* package */ void adjustDefaultZoomDensity(int zoomDensity) {
- final float density = mContext.getResources().getDisplayMetrics().density
- * 100 / zoomDensity;
- updateDefaultZoomDensity(density);
- }
-
- /* package */ void updateDefaultZoomDensity(float density) {
- mNavSlop = (int) (16 * density);
- mZoomManager.updateDefaultZoomDensity(density);
- }
-
- /* package */ boolean onSavePassword(String schemePlusHost, String username,
- String password, final Message resumeMsg) {
- boolean rVal = false;
- if (resumeMsg == null) {
- // null resumeMsg implies saving password silently
- mDatabase.setUsernamePassword(schemePlusHost, username, password);
- } else {
- final Message remember = mPrivateHandler.obtainMessage(
- REMEMBER_PASSWORD);
- remember.getData().putString("host", schemePlusHost);
- remember.getData().putString("username", username);
- remember.getData().putString("password", password);
- remember.obj = resumeMsg;
-
- final Message neverRemember = mPrivateHandler.obtainMessage(
- NEVER_REMEMBER_PASSWORD);
- neverRemember.getData().putString("host", schemePlusHost);
- neverRemember.getData().putString("username", username);
- neverRemember.getData().putString("password", password);
- neverRemember.obj = resumeMsg;
-
- new AlertDialog.Builder(getContext())
- .setTitle(com.android.internal.R.string.save_password_label)
- .setMessage(com.android.internal.R.string.save_password_message)
- .setPositiveButton(com.android.internal.R.string.save_password_notnow,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- resumeMsg.sendToTarget();
- }
- })
- .setNeutralButton(com.android.internal.R.string.save_password_remember,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- remember.sendToTarget();
- }
- })
- .setNegativeButton(com.android.internal.R.string.save_password_never,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- neverRemember.sendToTarget();
- }
- })
- .setOnCancelListener(new OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- resumeMsg.sendToTarget();
- }
- }).show();
- // Return true so that WebViewCore will pause while the dialog is
- // up.
- rVal = true;
- }
- return rVal;
- }
-
- @Override
- public void setScrollBarStyle(int style) {
- if (style == View.SCROLLBARS_INSIDE_INSET
- || style == View.SCROLLBARS_OUTSIDE_INSET) {
- mOverlayHorizontalScrollbar = mOverlayVerticalScrollbar = false;
- } else {
- mOverlayHorizontalScrollbar = mOverlayVerticalScrollbar = true;
- }
- super.setScrollBarStyle(style);
+ ensureProviderCreated();
+ mProvider.init(javaScriptInterfaces, privateBrowsing);
}
/**
@@ -1949,7 +488,7 @@ public class WebView extends AbsoluteLayout
*/
public void setHorizontalScrollbarOverlay(boolean overlay) {
checkThread();
- mOverlayHorizontalScrollbar = overlay;
+ mProvider.setHorizontalScrollbarOverlay(overlay);
}
/**
@@ -1958,7 +497,7 @@ public class WebView extends AbsoluteLayout
*/
public void setVerticalScrollbarOverlay(boolean overlay) {
checkThread();
- mOverlayVerticalScrollbar = overlay;
+ mProvider.setVerticalScrollbarOverlay(overlay);
}
/**
@@ -1967,7 +506,7 @@ public class WebView extends AbsoluteLayout
*/
public boolean overlayHorizontalScrollbar() {
checkThread();
- return mOverlayHorizontalScrollbar;
+ return mProvider.overlayHorizontalScrollbar();
}
/**
@@ -1976,80 +515,17 @@ public class WebView extends AbsoluteLayout
*/
public boolean overlayVerticalScrollbar() {
checkThread();
- return mOverlayVerticalScrollbar;
- }
-
- /*
- * Return the width of the view where the content of WebView should render
- * to.
- * Note: this can be called from WebCoreThread.
- */
- /* package */ int getViewWidth() {
- if (!isVerticalScrollBarEnabled() || mOverlayVerticalScrollbar) {
- return getWidth();
- } else {
- return Math.max(0, getWidth() - getVerticalScrollbarWidth());
- }
- }
-
- /**
- * Returns the height (in pixels) of the embedded title bar (if any). Does not care about
- * scrolling
- * @hide
- */
- protected int getTitleHeight() {
- return mTitleBar != null ? mTitleBar.getHeight() : 0;
+ return mProvider.overlayVerticalScrollbar();
}
/**
* Return the visible height (in pixels) of the embedded title bar (if any).
*
- * @return This method is obsolete and always returns 0.
* @deprecated This method is now obsolete.
*/
- @Deprecated
public int getVisibleTitleHeight() {
- // Actually, this method returns the height of the embedded title bar if one is set via the
- // hidden setEmbeddedTitleBar method.
checkThread();
- return getVisibleTitleHeightImpl();
- }
-
- private int getVisibleTitleHeightImpl() {
- // need to restrict mScrollY due to over scroll
- return Math.max(getTitleHeight() - Math.max(0, mScrollY),
- getOverlappingActionModeHeight());
- }
-
- private int mCachedOverlappingActionModeHeight = -1;
-
- private int getOverlappingActionModeHeight() {
- if (mFindCallback == null) {
- return 0;
- }
- if (mCachedOverlappingActionModeHeight < 0) {
- getGlobalVisibleRect(mGlobalVisibleRect, mGlobalVisibleOffset);
- mCachedOverlappingActionModeHeight = Math.max(0,
- mFindCallback.getActionModeGlobalBottom() - mGlobalVisibleRect.top);
- }
- return mCachedOverlappingActionModeHeight;
- }
-
- /*
- * Return the height of the view where the content of WebView should render
- * to. Note that this excludes mTitleBar, if there is one.
- * Note: this can be called from WebCoreThread.
- */
- /* package */ int getViewHeight() {
- return getViewHeightWithTitle() - getVisibleTitleHeightImpl();
- }
-
- int getViewHeightWithTitle() {
- int height = getHeight();
- if (isHorizontalScrollBarEnabled() && !mOverlayHorizontalScrollbar) {
- height -= getHorizontalScrollbarHeight();
- }
- return height;
+ return mProvider.getVisibleTitleHeight();
}
/**
@@ -2058,7 +534,7 @@ public class WebView extends AbsoluteLayout
*/
public SslCertificate getCertificate() {
checkThread();
- return mCertificate;
+ return mProvider.getCertificate();
}
/**
@@ -2066,11 +542,7 @@ public class WebView extends AbsoluteLayout
*/
public void setCertificate(SslCertificate certificate) {
checkThread();
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "setCertificate=" + certificate);
- }
- // here, the certificate can be null (if the site is not secure)
- mCertificate = certificate;
+ mProvider.setCertificate(certificate);
}
//-------------------------------------------------------------------------
@@ -2086,7 +558,7 @@ public class WebView extends AbsoluteLayout
*/
public void savePassword(String host, String username, String password) {
checkThread();
- mDatabase.setUsernamePassword(host, username, password);
+ mProvider.savePassword(host, username, password);
}
/**
@@ -2101,7 +573,7 @@ public class WebView extends AbsoluteLayout
public void setHttpAuthUsernamePassword(String host, String realm,
String username, String password) {
checkThread();
- mDatabase.setHttpAuthUsernamePassword(host, realm, username, password);
+ mProvider.setHttpAuthUsernamePassword(host, realm, username, password);
}
/**
@@ -2115,38 +587,7 @@ public class WebView extends AbsoluteLayout
*/
public String[] getHttpAuthUsernamePassword(String host, String realm) {
checkThread();
- return mDatabase.getHttpAuthUsernamePassword(host, realm);
- }
-
- /**
- * Remove Find or Select ActionModes, if active.
- */
- private void clearActionModes() {
- if (mSelectCallback != null) {
- mSelectCallback.finish();
- }
- if (mFindCallback != null) {
- mFindCallback.finish();
- }
- }
-
- /**
- * Called to clear state when moving from one page to another, or changing
- * in some other way that makes elements associated with the current page
- * (such as WebTextView or ActionModes) no longer relevant.
- */
- private void clearHelpers() {
- clearTextEntry();
- clearActionModes();
- dismissFullScreenMode();
- cancelSelectDialog();
- }
-
- private void cancelSelectDialog() {
- if (mListBoxDialog != null) {
- mListBoxDialog.cancel();
- mListBoxDialog = null;
- }
+ return mProvider.getHttpAuthUsernamePassword(host, realm);
}
/**
@@ -2156,45 +597,7 @@ public class WebView extends AbsoluteLayout
*/
public void destroy() {
checkThread();
- destroyImpl();
- }
-
- private void destroyImpl() {
- clearHelpers();
- if (mListBoxDialog != null) {
- mListBoxDialog.dismiss();
- mListBoxDialog = null;
- }
- // remove so that it doesn't cause events
- if (mWebTextView != null) {
- mWebTextView.remove();
- mWebTextView = null;
- }
- if (mNativeClass != 0) nativeStopGL();
- if (mWebViewCore != null) {
- // Set the handlers to null before destroying WebViewCore so no
- // more messages will be posted.
- mCallbackProxy.setWebViewClient(null);
- mCallbackProxy.setWebChromeClient(null);
- // Tell WebViewCore to destroy itself
- synchronized (this) {
- WebViewCore webViewCore = mWebViewCore;
- mWebViewCore = null; // prevent using partial webViewCore
- webViewCore.destroy();
- }
- // Remove any pending messages that might not be serviced yet.
- mPrivateHandler.removeCallbacksAndMessages(null);
- mCallbackProxy.removeCallbacksAndMessages(null);
- // Wake up the WebCore thread just in case it is waiting for a
- // JavaScript dialog.
- synchronized (mCallbackProxy) {
- mCallbackProxy.notify();
- }
- }
- if (mNativeClass != 0) {
- nativeDestroy();
- mNativeClass = 0;
- }
+ mProvider.destroy();
}
/**
@@ -2206,12 +609,7 @@ public class WebView extends AbsoluteLayout
@Deprecated
public static void enablePlatformNotifications() {
checkThread();
- synchronized (WebView.class) {
- sNotificationsEnabled = true;
- Context context = JniUtil.getContext();
- if (context != null)
- setupProxyListener(context);
- }
+ getFactory().getStatics().setPlatformNotificationsEnabled(true);
}
/**
@@ -2223,24 +621,7 @@ public class WebView extends AbsoluteLayout
@Deprecated
public static void disablePlatformNotifications() {
checkThread();
- synchronized (WebView.class) {
- sNotificationsEnabled = false;
- Context context = JniUtil.getContext();
- if (context != null)
- disableProxyListener(context);
- }
- }
-
- /**
- * Sets JavaScript engine flags.
- *
- * @param flags JS engine flags in a String
- *
- * @hide This is an implementation detail.
- */
- public void setJsFlags(String flags) {
- checkThread();
- mWebViewCore.sendMessage(EventHub.SET_JS_FLAGS, flags);
+ getFactory().getStatics().setPlatformNotificationsEnabled(false);
}
/**
@@ -2251,22 +632,10 @@ public class WebView extends AbsoluteLayout
*/
public void setNetworkAvailable(boolean networkUp) {
checkThread();
- mWebViewCore.sendMessage(EventHub.SET_NETWORK_STATE,
- networkUp ? 1 : 0, 0);
+ mProvider.setNetworkAvailable(networkUp);
}
/**
- * Inform WebView about the current network type.
- * {@hide}
- */
- public void setNetworkType(String type, String subtype) {
- checkThread();
- Map<String, String> map = new HashMap<String, String>();
- map.put("type", type);
- map.put("subtype", subtype);
- mWebViewCore.sendMessage(EventHub.SET_NETWORK_TYPE, map);
- }
- /**
* Save the state of this WebView used in
* {@link android.app.Activity#onSaveInstanceState}. Please note that this
* method no longer stores the display data for this WebView. The previous
@@ -2281,49 +650,7 @@ public class WebView extends AbsoluteLayout
*/
public WebBackForwardList saveState(Bundle outState) {
checkThread();
- if (outState == null) {
- return null;
- }
- // We grab a copy of the back/forward list because a client of WebView
- // may have invalidated the history list by calling clearHistory.
- WebBackForwardList list = copyBackForwardList();
- final int currentIndex = list.getCurrentIndex();
- final int size = list.getSize();
- // We should fail saving the state if the list is empty or the index is
- // not in a valid range.
- if (currentIndex < 0 || currentIndex >= size || size == 0) {
- return null;
- }
- outState.putInt("index", currentIndex);
- // FIXME: This should just be a byte[][] instead of ArrayList but
- // Parcel.java does not have the code to handle multi-dimensional
- // arrays.
- ArrayList<byte[]> history = new ArrayList<byte[]>(size);
- for (int i = 0; i < size; i++) {
- WebHistoryItem item = list.getItemAtIndex(i);
- if (null == item) {
- // FIXME: this shouldn't happen
- // need to determine how item got set to null
- Log.w(LOGTAG, "saveState: Unexpected null history item.");
- return null;
- }
- byte[] data = item.getFlattenedData();
- if (data == null) {
- // It would be very odd to not have any data for a given history
- // item. And we will fail to rebuild the history list without
- // flattened data.
- return null;
- }
- history.add(data);
- }
- outState.putSerializable("history", history);
- if (mCertificate != null) {
- outState.putBundle("certificate",
- SslCertificate.saveState(mCertificate));
- }
- outState.putBoolean("privateBrowsingEnabled", isPrivateBrowsingEnabled());
- mZoomManager.saveZoomState(outState);
- return list;
+ return mProvider.saveState(outState);
}
/**
@@ -2338,59 +665,7 @@ public class WebView extends AbsoluteLayout
@Deprecated
public boolean savePicture(Bundle b, final File dest) {
checkThread();
- if (dest == null || b == null) {
- return false;
- }
- final Picture p = capturePicture();
- // Use a temporary file while writing to ensure the destination file
- // contains valid data.
- final File temp = new File(dest.getPath() + ".writing");
- new Thread(new Runnable() {
- @Override
- public void run() {
- FileOutputStream out = null;
- try {
- out = new FileOutputStream(temp);
- p.writeToStream(out);
- // Writing the picture succeeded, rename the temporary file
- // to the destination.
- temp.renameTo(dest);
- } catch (Exception e) {
- // too late to do anything about it.
- } finally {
- if (out != null) {
- try {
- out.close();
- } catch (Exception e) {
- // Can't do anything about that
- }
- }
- temp.delete();
- }
- }
- }).start();
- // now update the bundle
- b.putInt("scrollX", mScrollX);
- b.putInt("scrollY", mScrollY);
- mZoomManager.saveZoomState(b);
- return true;
- }
-
- private void restoreHistoryPictureFields(Picture p, Bundle b) {
- int sx = b.getInt("scrollX", 0);
- int sy = b.getInt("scrollY", 0);
-
- mDrawHistory = true;
- mHistoryPicture = p;
-
- mScrollX = sx;
- mScrollY = sy;
- mZoomManager.restoreZoomState(b);
- final float scale = mZoomManager.getScale();
- mHistoryWidth = Math.round(p.getWidth() * scale);
- mHistoryHeight = Math.round(p.getHeight() * scale);
-
- invalidate();
+ return mProvider.savePicture(b, dest);
}
/**
@@ -2406,91 +681,7 @@ public class WebView extends AbsoluteLayout
@Deprecated
public boolean restorePicture(Bundle b, File src) {
checkThread();
- if (src == null || b == null) {
- return false;
- }
- if (!src.exists()) {
- return false;
- }
- try {
- final FileInputStream in = new FileInputStream(src);
- final Bundle copy = new Bundle(b);
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- final Picture p = Picture.createFromStream(in);
- if (p != null) {
- // Post a runnable on the main thread to update the
- // history picture fields.
- mPrivateHandler.post(new Runnable() {
- @Override
- public void run() {
- restoreHistoryPictureFields(p, copy);
- }
- });
- }
- } finally {
- try {
- in.close();
- } catch (Exception e) {
- // Nothing we can do now.
- }
- }
- }
- }).start();
- } catch (FileNotFoundException e){
- e.printStackTrace();
- }
- return true;
- }
-
- /**
- * Saves the view data to the output stream. The output is highly
- * version specific, and may not be able to be loaded by newer versions
- * of WebView.
- * @param stream The {@link OutputStream} to save to
- * @return True if saved successfully
- * @hide
- */
- public boolean saveViewState(OutputStream stream) {
- try {
- return ViewStateSerializer.serializeViewState(stream, this);
- } catch (IOException e) {
- Log.w(LOGTAG, "Failed to saveViewState", e);
- }
- return false;
- }
-
- /**
- * Loads the view data from the input stream. See
- * {@link #saveViewState(OutputStream)} for more information.
- * @param stream The {@link InputStream} to load from
- * @return True if loaded successfully
- * @hide
- */
- public boolean loadViewState(InputStream stream) {
- try {
- mLoadedPicture = ViewStateSerializer.deserializeViewState(stream, this);
- mBlockWebkitViewMessages = true;
- setNewPicture(mLoadedPicture, true);
- mLoadedPicture.mViewState = null;
- return true;
- } catch (IOException e) {
- Log.w(LOGTAG, "Failed to loadViewState", e);
- }
- return false;
- }
-
- /**
- * Clears the view state set with {@link #loadViewState(InputStream)}.
- * This WebView will then switch to showing the content from webkit
- * @hide
- */
- public void clearViewState() {
- mBlockWebkitViewMessages = false;
- mLoadedPicture = null;
- invalidate();
+ return mProvider.restorePicture(b, src);
}
/**
@@ -2509,55 +700,7 @@ public class WebView extends AbsoluteLayout
*/
public WebBackForwardList restoreState(Bundle inState) {
checkThread();
- WebBackForwardList returnList = null;
- if (inState == null) {
- return returnList;
- }
- if (inState.containsKey("index") && inState.containsKey("history")) {
- mCertificate = SslCertificate.restoreState(
- inState.getBundle("certificate"));
-
- final WebBackForwardList list = mCallbackProxy.getBackForwardList();
- final int index = inState.getInt("index");
- // We can't use a clone of the list because we need to modify the
- // shared copy, so synchronize instead to prevent concurrent
- // modifications.
- synchronized (list) {
- final List<byte[]> history =
- (List<byte[]>) inState.getSerializable("history");
- final int size = history.size();
- // Check the index bounds so we don't crash in native code while
- // restoring the history index.
- if (index < 0 || index >= size) {
- return null;
- }
- for (int i = 0; i < size; i++) {
- byte[] data = history.remove(0);
- if (data == null) {
- // If we somehow have null data, we cannot reconstruct
- // the item and thus our history list cannot be rebuilt.
- return null;
- }
- WebHistoryItem item = new WebHistoryItem(data);
- list.addHistoryItem(item);
- }
- // Grab the most recent copy to return to the caller.
- returnList = copyBackForwardList();
- // Update the copy to have the correct index.
- returnList.setCurrentIndex(index);
- }
- // Restore private browsing setting.
- if (inState.getBoolean("privateBrowsingEnabled")) {
- getSettings().setPrivateBrowsingEnabled(true);
- }
- mZoomManager.restoreZoomState(inState);
- // Remove all pending messages because we are restoring previous
- // state.
- mWebViewCore.removeMessages();
- // Send a restore state message.
- mWebViewCore.sendMessage(EventHub.RESTORE_STATE, index);
- }
- return returnList;
+ return mProvider.restoreState(inState);
}
/**
@@ -2572,16 +715,7 @@ public class WebView extends AbsoluteLayout
*/
public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
checkThread();
- loadUrlImpl(url, additionalHttpHeaders);
- }
-
- private void loadUrlImpl(String url, Map<String, String> extraHeaders) {
- switchOutDrawHistory();
- WebViewCore.GetUrlData arg = new WebViewCore.GetUrlData();
- arg.mUrl = url;
- arg.mExtraHeaders = extraHeaders;
- mWebViewCore.sendMessage(EventHub.LOAD_URL, arg);
- clearHelpers();
+ mProvider.loadUrl(url, additionalHttpHeaders);
}
/**
@@ -2590,14 +724,7 @@ public class WebView extends AbsoluteLayout
*/
public void loadUrl(String url) {
checkThread();
- loadUrlImpl(url);
- }
-
- private void loadUrlImpl(String url) {
- if (url == null) {
- return;
- }
- loadUrlImpl(url, null);
+ mProvider.loadUrl(url);
}
/**
@@ -2610,16 +737,7 @@ public class WebView extends AbsoluteLayout
*/
public void postUrl(String url, byte[] postData) {
checkThread();
- if (URLUtil.isNetworkUrl(url)) {
- switchOutDrawHistory();
- WebViewCore.PostUrlData arg = new WebViewCore.PostUrlData();
- arg.mUrl = url;
- arg.mPostData = postData;
- mWebViewCore.sendMessage(EventHub.POST_URL, arg);
- clearHelpers();
- } else {
- loadUrlImpl(url);
- }
+ mProvider.postUrl(url, postData);
}
/**
@@ -2650,18 +768,7 @@ public class WebView extends AbsoluteLayout
*/
public void loadData(String data, String mimeType, String encoding) {
checkThread();
- loadDataImpl(data, mimeType, encoding);
- }
-
- private void loadDataImpl(String data, String mimeType, String encoding) {
- StringBuilder dataUrl = new StringBuilder("data:");
- dataUrl.append(mimeType);
- if ("base64".equals(encoding)) {
- dataUrl.append(";base64");
- }
- dataUrl.append(",");
- dataUrl.append(data);
- loadUrlImpl(dataUrl.toString());
+ mProvider.loadData(data, mimeType, encoding);
}
/**
@@ -2689,20 +796,7 @@ public class WebView extends AbsoluteLayout
public void loadDataWithBaseURL(String baseUrl, String data,
String mimeType, String encoding, String historyUrl) {
checkThread();
-
- if (baseUrl != null && baseUrl.toLowerCase().startsWith("data:")) {
- loadDataImpl(data, mimeType, encoding);
- return;
- }
- switchOutDrawHistory();
- WebViewCore.BaseUrlData arg = new WebViewCore.BaseUrlData();
- arg.mBaseUrl = baseUrl;
- arg.mData = data;
- arg.mMimeType = mimeType;
- arg.mEncoding = encoding;
- arg.mHistoryUrl = historyUrl;
- mWebViewCore.sendMessage(EventHub.LOAD_DATA, arg);
- clearHelpers();
+ mProvider.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
}
/**
@@ -2712,20 +806,7 @@ public class WebView extends AbsoluteLayout
*/
public void saveWebArchive(String filename) {
checkThread();
- saveWebArchiveImpl(filename, false, null);
- }
-
- /* package */ static class SaveWebArchiveMessage {
- SaveWebArchiveMessage (String basename, boolean autoname, ValueCallback<String> callback) {
- mBasename = basename;
- mAutoname = autoname;
- mCallback = callback;
- }
-
- /* package */ final String mBasename;
- /* package */ final boolean mAutoname;
- /* package */ final ValueCallback<String> mCallback;
- /* package */ String mResultFile;
+ mProvider.saveWebArchive(filename);
}
/**
@@ -2742,13 +823,7 @@ public class WebView extends AbsoluteLayout
*/
public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback) {
checkThread();
- saveWebArchiveImpl(basename, autoname, callback);
- }
-
- private void saveWebArchiveImpl(String basename, boolean autoname,
- ValueCallback<String> callback) {
- mWebViewCore.sendMessage(EventHub.SAVE_WEBARCHIVE,
- new SaveWebArchiveMessage(basename, autoname, callback));
+ mProvider.saveWebArchive(basename, autoname, callback);
}
/**
@@ -2756,10 +831,7 @@ public class WebView extends AbsoluteLayout
*/
public void stopLoading() {
checkThread();
- // TODO: should we clear all the messages in the queue before sending
- // STOP_LOADING?
- switchOutDrawHistory();
- mWebViewCore.sendMessage(EventHub.STOP_LOADING);
+ mProvider.stopLoading();
}
/**
@@ -2767,9 +839,7 @@ public class WebView extends AbsoluteLayout
*/
public void reload() {
checkThread();
- clearHelpers();
- switchOutDrawHistory();
- mWebViewCore.sendMessage(EventHub.RELOAD);
+ mProvider.reload();
}
/**
@@ -2778,14 +848,7 @@ public class WebView extends AbsoluteLayout
*/
public boolean canGoBack() {
checkThread();
- WebBackForwardList l = mCallbackProxy.getBackForwardList();
- synchronized (l) {
- if (l.getClearPending()) {
- return false;
- } else {
- return l.getCurrentIndex() > 0;
- }
- }
+ return mProvider.canGoBack();
}
/**
@@ -2793,7 +856,7 @@ public class WebView extends AbsoluteLayout
*/
public void goBack() {
checkThread();
- goBackOrForwardImpl(-1);
+ mProvider.goBack();
}
/**
@@ -2802,14 +865,7 @@ public class WebView extends AbsoluteLayout
*/
public boolean canGoForward() {
checkThread();
- WebBackForwardList l = mCallbackProxy.getBackForwardList();
- synchronized (l) {
- if (l.getClearPending()) {
- return false;
- } else {
- return l.getCurrentIndex() < l.getSize() - 1;
- }
- }
+ return mProvider.canGoForward();
}
/**
@@ -2817,7 +873,7 @@ public class WebView extends AbsoluteLayout
*/
public void goForward() {
checkThread();
- goBackOrForwardImpl(1);
+ mProvider.goForward();
}
/**
@@ -2828,15 +884,7 @@ public class WebView extends AbsoluteLayout
*/
public boolean canGoBackOrForward(int steps) {
checkThread();
- WebBackForwardList l = mCallbackProxy.getBackForwardList();
- synchronized (l) {
- if (l.getClearPending()) {
- return false;
- } else {
- int newIndex = l.getCurrentIndex() + steps;
- return newIndex >= 0 && newIndex < l.getSize();
- }
- }
+ return mProvider.canGoBackOrForward(steps);
}
/**
@@ -2848,19 +896,7 @@ public class WebView extends AbsoluteLayout
*/
public void goBackOrForward(int steps) {
checkThread();
- goBackOrForwardImpl(steps);
- }
-
- private void goBackOrForwardImpl(int steps) {
- goBackOrForward(steps, false);
- }
-
- private void goBackOrForward(int steps, boolean ignoreSnapshot) {
- if (steps != 0) {
- clearHelpers();
- mWebViewCore.sendMessage(EventHub.GO_BACK_FORWARD, steps,
- ignoreSnapshot ? 1 : 0);
- }
+ mProvider.goBackOrForward(steps);
}
/**
@@ -2868,20 +904,7 @@ public class WebView extends AbsoluteLayout
*/
public boolean isPrivateBrowsingEnabled() {
checkThread();
- return getSettings().isPrivateBrowsingEnabled();
- }
-
- private void startPrivateBrowsing() {
- getSettings().setPrivateBrowsingEnabled(true);
- }
-
- private boolean extendScroll(int y) {
- int finalY = mScroller.getFinalY();
- int newY = pinLocY(finalY + y);
- if (newY == finalY) return false;
- mScroller.setFinalY(newY);
- mScroller.extendDuration(computeDuration(0, y));
- return true;
+ return mProvider.isPrivateBrowsingEnabled();
}
/**
@@ -2891,24 +914,7 @@ public class WebView extends AbsoluteLayout
*/
public boolean pageUp(boolean top) {
checkThread();
- if (mNativeClass == 0) {
- return false;
- }
- nativeClearCursor(); // start next trackball movement from page edge
- if (top) {
- // go to the top of the document
- return pinScrollTo(mScrollX, 0, true, 0);
- }
- // Page up
- int h = getHeight();
- int y;
- if (h > 2 * PAGE_SCROLL_OVERLAP) {
- y = -h + PAGE_SCROLL_OVERLAP;
- } else {
- y = -h / 2;
- }
- return mScroller.isFinished() ? pinScrollBy(0, y, true, 0)
- : extendScroll(y);
+ return mProvider.pageUp(top);
}
/**
@@ -2918,23 +924,7 @@ public class WebView extends AbsoluteLayout
*/
public boolean pageDown(boolean bottom) {
checkThread();
- if (mNativeClass == 0) {
- return false;
- }
- nativeClearCursor(); // start next trackball movement from page edge
- if (bottom) {
- return pinScrollTo(mScrollX, computeRealVerticalScrollRange(), true, 0);
- }
- // Page down.
- int h = getHeight();
- int y;
- if (h > 2 * PAGE_SCROLL_OVERLAP) {
- y = h - PAGE_SCROLL_OVERLAP;
- } else {
- y = h / 2;
- }
- return mScroller.isFinished() ? pinScrollBy(0, y, true, 0)
- : extendScroll(y);
+ return mProvider.pageDown(bottom);
}
/**
@@ -2943,10 +933,7 @@ public class WebView extends AbsoluteLayout
*/
public void clearView() {
checkThread();
- mContentWidth = 0;
- mContentHeight = 0;
- setBaseLayer(0, null, false, false);
- mWebViewCore.sendMessage(EventHub.CLEAR_CONTENT);
+ mProvider.clearView();
}
/**
@@ -2960,29 +947,7 @@ public class WebView extends AbsoluteLayout
*/
public Picture capturePicture() {
checkThread();
- if (mNativeClass == 0) return null;
- Picture result = new Picture();
- nativeCopyBaseContentToPicture(result);
- return result;
- }
-
- /**
- * Return true if the browser is displaying a TextView for text input.
- */
- private boolean inEditingMode() {
- return mWebTextView != null && mWebTextView.getParent() != null;
- }
-
- /**
- * Remove the WebTextView.
- */
- private void clearTextEntry() {
- if (inEditingMode()) {
- mWebTextView.remove();
- } else {
- // The keyboard may be open with the WebView as the served view
- hideSoftKeyboard();
- }
+ return mProvider.capturePicture();
}
/**
@@ -2991,16 +956,7 @@ public class WebView extends AbsoluteLayout
*/
public float getScale() {
checkThread();
- return mZoomManager.getScale();
- }
-
- /**
- * Compute the reading level scale of the WebView
- * @param scale The current scale.
- * @return The reading level scale.
- */
- /*package*/ float computeReadingLevelScale(float scale) {
- return mZoomManager.computeReadingLevelScale(scale);
+ return mProvider.getScale();
}
/**
@@ -3015,7 +971,7 @@ public class WebView extends AbsoluteLayout
*/
public void setInitialScale(int scaleInPercent) {
checkThread();
- mZoomManager.setInitialScaleInPercent(scaleInPercent);
+ mProvider.setInitialScale(scaleInPercent);
}
/**
@@ -3025,12 +981,7 @@ public class WebView extends AbsoluteLayout
*/
public void invokeZoomPicker() {
checkThread();
- if (!getSettings().supportZoom()) {
- Log.w(LOGTAG, "This WebView doesn't support zoom.");
- return;
- }
- clearHelpers();
- mZoomManager.invokeZoomPicker();
+ mProvider.invokeZoomPicker();
}
/**
@@ -3053,101 +1004,9 @@ public class WebView extends AbsoluteLayout
*/
public HitTestResult getHitTestResult() {
checkThread();
- return hitTestResult(mInitialHitTestResult);
- }
-
- private HitTestResult hitTestResult(HitTestResult fallback) {
- if (mNativeClass == 0 || sDisableNavcache) {
- return fallback;
- }
-
- HitTestResult result = new HitTestResult();
- if (nativeHasCursorNode()) {
- if (nativeCursorIsTextInput()) {
- result.setType(HitTestResult.EDIT_TEXT_TYPE);
- } else {
- String text = nativeCursorText();
- if (text != null) {
- if (text.startsWith(SCHEME_TEL)) {
- result.setType(HitTestResult.PHONE_TYPE);
- result.setExtra(URLDecoder.decode(text
- .substring(SCHEME_TEL.length())));
- } else if (text.startsWith(SCHEME_MAILTO)) {
- result.setType(HitTestResult.EMAIL_TYPE);
- result.setExtra(text.substring(SCHEME_MAILTO.length()));
- } else if (text.startsWith(SCHEME_GEO)) {
- result.setType(HitTestResult.GEO_TYPE);
- result.setExtra(URLDecoder.decode(text
- .substring(SCHEME_GEO.length())));
- } else if (nativeCursorIsAnchor()) {
- result.setType(HitTestResult.SRC_ANCHOR_TYPE);
- result.setExtra(text);
- }
- }
- }
- } else if (fallback != null) {
- /* If webkit causes a rebuild while the long press is in progress,
- * the cursor node may be reset, even if it is still around. This
- * uses the cursor node saved when the touch began. Since the
- * nativeImageURI below only changes the result if it is successful,
- * this uses the data beneath the touch if available or the original
- * tap data otherwise.
- */
- Log.v(LOGTAG, "hitTestResult use fallback");
- result = fallback;
- }
- int type = result.getType();
- if (type == HitTestResult.UNKNOWN_TYPE
- || type == HitTestResult.SRC_ANCHOR_TYPE) {
- // Now check to see if it is an image.
- int contentX = viewToContentX(mLastTouchX + mScrollX);
- int contentY = viewToContentY(mLastTouchY + mScrollY);
- String text = nativeImageURI(contentX, contentY);
- if (text != null) {
- result.setType(type == HitTestResult.UNKNOWN_TYPE ?
- HitTestResult.IMAGE_TYPE :
- HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
- result.setExtra(text);
- }
- }
- return result;
- }
-
- int getBlockLeftEdge(int x, int y, float readingScale) {
- if (!sDisableNavcache) {
- return nativeGetBlockLeftEdge(x, y, readingScale);
- }
-
- float invReadingScale = 1.0f / readingScale;
- int readingWidth = (int) (getViewWidth() * invReadingScale);
- int left = NO_LEFTEDGE;
- if (mFocusedNode != null) {
- final int length = mFocusedNode.mEnclosingParentRects.length;
- for (int i = 0; i < length; i++) {
- Rect rect = mFocusedNode.mEnclosingParentRects[i];
- if (rect.width() < mFocusedNode.mHitTestSlop) {
- // ignore bounding boxes that are too small
- continue;
- } else if (left != NO_LEFTEDGE && rect.width() > readingWidth) {
- // stop when bounding box doesn't fit the screen width
- // at reading scale
- break;
- }
-
- left = rect.left;
- }
- }
-
- return left;
+ return mProvider.getHitTestResult();
}
- // Called by JNI when the DOM has changed the focus. Clear the focus so
- // that new keys will go to the newly focused field
- private void domChangedFocus() {
- if (inEditingMode()) {
- mPrivateHandler.obtainMessage(DOM_FOCUS_CHANGED).sendToTarget();
- }
- }
/**
* Request the anchor or image element URL at the last tapped point.
* If hrefMsg is null, this method returns immediately and does not
@@ -3164,32 +1023,7 @@ public class WebView extends AbsoluteLayout
*/
public void requestFocusNodeHref(Message hrefMsg) {
checkThread();
- if (hrefMsg == null) {
- return;
- }
- int contentX = viewToContentX(mLastTouchX + mScrollX);
- int contentY = viewToContentY(mLastTouchY + mScrollY);
- if (mFocusedNode != null && mFocusedNode.mHitTestX == contentX
- && mFocusedNode.mHitTestY == contentY) {
- hrefMsg.getData().putString(FocusNodeHref.URL, mFocusedNode.mLinkUrl);
- hrefMsg.getData().putString(FocusNodeHref.TITLE, mFocusedNode.mAnchorText);
- hrefMsg.getData().putString(FocusNodeHref.SRC, mFocusedNode.mImageUrl);
- hrefMsg.sendToTarget();
- return;
- }
- if (nativeHasCursorNode()) {
- Rect cursorBounds = cursorRingBounds();
- if (!cursorBounds.contains(contentX, contentY)) {
- int slop = viewToContentDimension(mNavSlop);
- cursorBounds.inset(-slop, -slop);
- if (cursorBounds.contains(contentX, contentY)) {
- contentX = cursorBounds.centerX();
- contentY = cursorBounds.centerY();
- }
- }
- }
- mWebViewCore.sendMessage(EventHub.REQUEST_CURSOR_HREF,
- contentX, contentY, hrefMsg);
+ mProvider.requestFocusNodeHref(hrefMsg);
}
/**
@@ -3201,503 +1035,7 @@ public class WebView extends AbsoluteLayout
*/
public void requestImageRef(Message msg) {
checkThread();
- if (0 == mNativeClass) return; // client isn't initialized
- int contentX = viewToContentX(mLastTouchX + mScrollX);
- int contentY = viewToContentY(mLastTouchY + mScrollY);
- String ref = nativeImageURI(contentX, contentY);
- Bundle data = msg.getData();
- data.putString("url", ref);
- msg.setData(data);
- msg.sendToTarget();
- }
-
- static int pinLoc(int x, int viewMax, int docMax) {
-// Log.d(LOGTAG, "-- pinLoc " + x + " " + viewMax + " " + docMax);
- if (docMax < viewMax) { // the doc has room on the sides for "blank"
- // pin the short document to the top/left of the screen
- x = 0;
-// Log.d(LOGTAG, "--- center " + x);
- } else if (x < 0) {
- x = 0;
-// Log.d(LOGTAG, "--- zero");
- } else if (x + viewMax > docMax) {
- x = docMax - viewMax;
-// Log.d(LOGTAG, "--- pin " + x);
- }
- return x;
- }
-
- // Expects x in view coordinates
- int pinLocX(int x) {
- if (mInOverScrollMode) return x;
- return pinLoc(x, getViewWidth(), computeRealHorizontalScrollRange());
- }
-
- // Expects y in view coordinates
- int pinLocY(int y) {
- if (mInOverScrollMode) return y;
- return pinLoc(y, getViewHeightWithTitle(),
- computeRealVerticalScrollRange() + getTitleHeight());
- }
-
- /**
- * A title bar which is embedded in this WebView, and scrolls along with it
- * vertically, but not horizontally.
- */
- private View mTitleBar;
-
- /**
- * the title bar rendering gravity
- */
- private int mTitleGravity;
-
- /**
- * Add or remove a title bar to be embedded into the WebView, and scroll
- * along with it vertically, while remaining in view horizontally. Pass
- * null to remove the title bar from the WebView, and return to drawing
- * the WebView normally without translating to account for the title bar.
- * @hide
- */
- public void setEmbeddedTitleBar(View v) {
- if (mTitleBar == v) return;
- if (mTitleBar != null) {
- removeView(mTitleBar);
- }
- if (null != v) {
- addView(v, new AbsoluteLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0));
- }
- mTitleBar = v;
- }
-
- /**
- * Set where to render the embedded title bar
- * NO_GRAVITY at the top of the page
- * TOP at the top of the screen
- * @hide
- */
- public void setTitleBarGravity(int gravity) {
- mTitleGravity = gravity;
- // force refresh
- invalidate();
- }
-
- /**
- * Given a distance in view space, convert it to content space. Note: this
- * does not reflect translation, just scaling, so this should not be called
- * with coordinates, but should be called for dimensions like width or
- * height.
- */
- private int viewToContentDimension(int d) {
- return Math.round(d * mZoomManager.getInvScale());
- }
-
- /**
- * Given an x coordinate in view space, convert it to content space. Also
- * may be used for absolute heights (such as for the WebTextView's
- * textSize, which is unaffected by the height of the title bar).
- */
- /*package*/ int viewToContentX(int x) {
- return viewToContentDimension(x);
- }
-
- /**
- * Given a y coordinate in view space, convert it to content space.
- * Takes into account the height of the title bar if there is one
- * embedded into the WebView.
- */
- /*package*/ int viewToContentY(int y) {
- return viewToContentDimension(y - getTitleHeight());
- }
-
- /**
- * Given a x coordinate in view space, convert it to content space.
- * Returns the result as a float.
- */
- private float viewToContentXf(int x) {
- return x * mZoomManager.getInvScale();
- }
-
- /**
- * Given a y coordinate in view space, convert it to content space.
- * Takes into account the height of the title bar if there is one
- * embedded into the WebView. Returns the result as a float.
- */
- private float viewToContentYf(int y) {
- return (y - getTitleHeight()) * mZoomManager.getInvScale();
- }
-
- /**
- * Given a distance in content space, convert it to view space. Note: this
- * does not reflect translation, just scaling, so this should not be called
- * with coordinates, but should be called for dimensions like width or
- * height.
- */
- /*package*/ int contentToViewDimension(int d) {
- return Math.round(d * mZoomManager.getScale());
- }
-
- /**
- * Given an x coordinate in content space, convert it to view
- * space.
- */
- /*package*/ int contentToViewX(int x) {
- return contentToViewDimension(x);
- }
-
- /**
- * Given a y coordinate in content space, convert it to view
- * space. Takes into account the height of the title bar.
- */
- /*package*/ int contentToViewY(int y) {
- return contentToViewDimension(y) + getTitleHeight();
- }
-
- private Rect contentToViewRect(Rect x) {
- return new Rect(contentToViewX(x.left), contentToViewY(x.top),
- contentToViewX(x.right), contentToViewY(x.bottom));
- }
-
- /* To invalidate a rectangle in content coordinates, we need to transform
- the rect into view coordinates, so we can then call invalidate(...).
-
- Normally, we would just call contentToView[XY](...), which eventually
- calls Math.round(coordinate * mActualScale). However, for invalidates,
- we need to account for the slop that occurs with antialiasing. To
- address that, we are a little more liberal in the size of the rect that
- we invalidate.
-
- This liberal calculation calls floor() for the top/left, and ceil() for
- the bottom/right coordinates. This catches the possible extra pixels of
- antialiasing that we might have missed with just round().
- */
-
- // Called by JNI to invalidate the View, given rectangle coordinates in
- // content space
- private void viewInvalidate(int l, int t, int r, int b) {
- final float scale = mZoomManager.getScale();
- final int dy = getTitleHeight();
- invalidate((int)Math.floor(l * scale),
- (int)Math.floor(t * scale) + dy,
- (int)Math.ceil(r * scale),
- (int)Math.ceil(b * scale) + dy);
- }
-
- // Called by JNI to invalidate the View after a delay, given rectangle
- // coordinates in content space
- private void viewInvalidateDelayed(long delay, int l, int t, int r, int b) {
- final float scale = mZoomManager.getScale();
- final int dy = getTitleHeight();
- postInvalidateDelayed(delay,
- (int)Math.floor(l * scale),
- (int)Math.floor(t * scale) + dy,
- (int)Math.ceil(r * scale),
- (int)Math.ceil(b * scale) + dy);
- }
-
- private void invalidateContentRect(Rect r) {
- viewInvalidate(r.left, r.top, r.right, r.bottom);
- }
-
- // stop the scroll animation, and don't let a subsequent fling add
- // to the existing velocity
- private void abortAnimation() {
- mScroller.abortAnimation();
- mLastVelocity = 0;
- }
-
- /* call from webcoreview.draw(), so we're still executing in the UI thread
- */
- private void recordNewContentSize(int w, int h, boolean updateLayout) {
-
- // premature data from webkit, ignore
- if ((w | h) == 0) {
- return;
- }
-
- // don't abort a scroll animation if we didn't change anything
- if (mContentWidth != w || mContentHeight != h) {
- // record new dimensions
- mContentWidth = w;
- mContentHeight = h;
- // If history Picture is drawn, don't update scroll. They will be
- // updated when we get out of that mode.
- if (!mDrawHistory) {
- // repin our scroll, taking into account the new content size
- updateScrollCoordinates(pinLocX(mScrollX), pinLocY(mScrollY));
- if (!mScroller.isFinished()) {
- // We are in the middle of a scroll. Repin the final scroll
- // position.
- mScroller.setFinalX(pinLocX(mScroller.getFinalX()));
- mScroller.setFinalY(pinLocY(mScroller.getFinalY()));
- }
- }
- }
- contentSizeChanged(updateLayout);
- }
-
- // Used to avoid sending many visible rect messages.
- private Rect mLastVisibleRectSent = new Rect();
- private Rect mLastGlobalRect = new Rect();
- private Rect mVisibleRect = new Rect();
- private Rect mGlobalVisibleRect = new Rect();
- private Point mScrollOffset = new Point();
-
- Rect sendOurVisibleRect() {
- if (mZoomManager.isPreventingWebkitUpdates()) return mLastVisibleRectSent;
- calcOurContentVisibleRect(mVisibleRect);
- // Rect.equals() checks for null input.
- if (!mVisibleRect.equals(mLastVisibleRectSent)) {
- if (!mBlockWebkitViewMessages) {
- mScrollOffset.set(mVisibleRect.left, mVisibleRect.top);
- mWebViewCore.removeMessages(EventHub.SET_SCROLL_OFFSET);
- mWebViewCore.sendMessage(EventHub.SET_SCROLL_OFFSET,
- nativeMoveGeneration(), mSendScrollEvent ? 1 : 0, mScrollOffset);
- }
- mLastVisibleRectSent.set(mVisibleRect);
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- }
- if (getGlobalVisibleRect(mGlobalVisibleRect)
- && !mGlobalVisibleRect.equals(mLastGlobalRect)) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "sendOurVisibleRect=(" + mGlobalVisibleRect.left + ","
- + mGlobalVisibleRect.top + ",r=" + mGlobalVisibleRect.right + ",b="
- + mGlobalVisibleRect.bottom);
- }
- // TODO: the global offset is only used by windowRect()
- // in ChromeClientAndroid ; other clients such as touch
- // and mouse events could return view + screen relative points.
- if (!mBlockWebkitViewMessages) {
- mWebViewCore.sendMessage(EventHub.SET_GLOBAL_BOUNDS, mGlobalVisibleRect);
- }
- mLastGlobalRect.set(mGlobalVisibleRect);
- }
- return mVisibleRect;
- }
-
- private Point mGlobalVisibleOffset = new Point();
- // Sets r to be the visible rectangle of our webview in view coordinates
- private void calcOurVisibleRect(Rect r) {
- getGlobalVisibleRect(r, mGlobalVisibleOffset);
- r.offset(-mGlobalVisibleOffset.x, -mGlobalVisibleOffset.y);
- }
-
- // Sets r to be our visible rectangle in content coordinates
- private void calcOurContentVisibleRect(Rect r) {
- calcOurVisibleRect(r);
- r.left = viewToContentX(r.left);
- // viewToContentY will remove the total height of the title bar. Add
- // the visible height back in to account for the fact that if the title
- // bar is partially visible, the part of the visible rect which is
- // displaying our content is displaced by that amount.
- r.top = viewToContentY(r.top + getVisibleTitleHeightImpl());
- r.right = viewToContentX(r.right);
- r.bottom = viewToContentY(r.bottom);
- }
-
- private Rect mContentVisibleRect = new Rect();
- // Sets r to be our visible rectangle in content coordinates. We use this
- // method on the native side to compute the position of the fixed layers.
- // Uses floating coordinates (necessary to correctly place elements when
- // the scale factor is not 1)
- private void calcOurContentVisibleRectF(RectF r) {
- calcOurVisibleRect(mContentVisibleRect);
- r.left = viewToContentXf(mContentVisibleRect.left);
- // viewToContentY will remove the total height of the title bar. Add
- // the visible height back in to account for the fact that if the title
- // bar is partially visible, the part of the visible rect which is
- // displaying our content is displaced by that amount.
- r.top = viewToContentYf(mContentVisibleRect.top + getVisibleTitleHeightImpl());
- r.right = viewToContentXf(mContentVisibleRect.right);
- r.bottom = viewToContentYf(mContentVisibleRect.bottom);
- }
-
- static class ViewSizeData {
- int mWidth;
- int mHeight;
- float mHeightWidthRatio;
- int mActualViewHeight;
- int mTextWrapWidth;
- int mAnchorX;
- int mAnchorY;
- float mScale;
- boolean mIgnoreHeight;
- }
-
- /**
- * Compute unzoomed width and height, and if they differ from the last
- * values we sent, send them to webkit (to be used as new viewport)
- *
- * @param force ensures that the message is sent to webkit even if the width
- * or height has not changed since the last message
- *
- * @return true if new values were sent
- */
- boolean sendViewSizeZoom(boolean force) {
- if (mBlockWebkitViewMessages) return false;
- if (mZoomManager.isPreventingWebkitUpdates()) return false;
-
- int viewWidth = getViewWidth();
- int newWidth = Math.round(viewWidth * mZoomManager.getInvScale());
- // This height could be fixed and be different from actual visible height.
- int viewHeight = getViewHeightWithTitle() - getTitleHeight();
- int newHeight = Math.round(viewHeight * mZoomManager.getInvScale());
- // Make the ratio more accurate than (newHeight / newWidth), since the
- // latter both are calculated and rounded.
- float heightWidthRatio = (float) viewHeight / viewWidth;
- /*
- * Because the native side may have already done a layout before the
- * View system was able to measure us, we have to send a height of 0 to
- * remove excess whitespace when we grow our width. This will trigger a
- * layout and a change in content size. This content size change will
- * mean that contentSizeChanged will either call this method directly or
- * indirectly from onSizeChanged.
- */
- if (newWidth > mLastWidthSent && mWrapContent) {
- newHeight = 0;
- heightWidthRatio = 0;
- }
- // Actual visible content height.
- int actualViewHeight = Math.round(getViewHeight() * mZoomManager.getInvScale());
- // Avoid sending another message if the dimensions have not changed.
- if (newWidth != mLastWidthSent || newHeight != mLastHeightSent || force ||
- actualViewHeight != mLastActualHeightSent) {
- ViewSizeData data = new ViewSizeData();
- data.mWidth = newWidth;
- data.mHeight = newHeight;
- data.mHeightWidthRatio = heightWidthRatio;
- data.mActualViewHeight = actualViewHeight;
- data.mTextWrapWidth = Math.round(viewWidth / mZoomManager.getTextWrapScale());
- data.mScale = mZoomManager.getScale();
- data.mIgnoreHeight = mZoomManager.isFixedLengthAnimationInProgress()
- && !mHeightCanMeasure;
- data.mAnchorX = mZoomManager.getDocumentAnchorX();
- data.mAnchorY = mZoomManager.getDocumentAnchorY();
- mWebViewCore.sendMessage(EventHub.VIEW_SIZE_CHANGED, data);
- mLastWidthSent = newWidth;
- mLastHeightSent = newHeight;
- mLastActualHeightSent = actualViewHeight;
- mZoomManager.clearDocumentAnchor();
- return true;
- }
- return false;
- }
-
- /**
- * Update the double-tap zoom.
- */
- /* package */ void updateDoubleTapZoom(int doubleTapZoom) {
- mZoomManager.updateDoubleTapZoom(doubleTapZoom);
- }
-
- private int computeRealHorizontalScrollRange() {
- if (mDrawHistory) {
- return mHistoryWidth;
- } else {
- // to avoid rounding error caused unnecessary scrollbar, use floor
- return (int) Math.floor(mContentWidth * mZoomManager.getScale());
- }
- }
-
- @Override
- protected int computeHorizontalScrollRange() {
- int range = computeRealHorizontalScrollRange();
-
- // Adjust reported range if overscrolled to compress the scroll bars
- final int scrollX = mScrollX;
- final int overscrollRight = computeMaxScrollX();
- if (scrollX < 0) {
- range -= scrollX;
- } else if (scrollX > overscrollRight) {
- range += scrollX - overscrollRight;
- }
-
- return range;
- }
-
- @Override
- protected int computeHorizontalScrollOffset() {
- return Math.max(mScrollX, 0);
- }
-
- private int computeRealVerticalScrollRange() {
- if (mDrawHistory) {
- return mHistoryHeight;
- } else {
- // to avoid rounding error caused unnecessary scrollbar, use floor
- return (int) Math.floor(mContentHeight * mZoomManager.getScale());
- }
- }
-
- @Override
- protected int computeVerticalScrollRange() {
- int range = computeRealVerticalScrollRange();
-
- // Adjust reported range if overscrolled to compress the scroll bars
- final int scrollY = mScrollY;
- final int overscrollBottom = computeMaxScrollY();
- if (scrollY < 0) {
- range -= scrollY;
- } else if (scrollY > overscrollBottom) {
- range += scrollY - overscrollBottom;
- }
-
- return range;
- }
-
- @Override
- protected int computeVerticalScrollOffset() {
- return Math.max(mScrollY - getTitleHeight(), 0);
- }
-
- @Override
- protected int computeVerticalScrollExtent() {
- return getViewHeight();
- }
-
- /** @hide */
- @Override
- protected void onDrawVerticalScrollBar(Canvas canvas,
- Drawable scrollBar,
- int l, int t, int r, int b) {
- if (mScrollY < 0) {
- t -= mScrollY;
- }
- scrollBar.setBounds(l, t + getVisibleTitleHeightImpl(), r, b);
- scrollBar.draw(canvas);
- }
-
- @Override
- protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX,
- boolean clampedY) {
- // Special-case layer scrolling so that we do not trigger normal scroll
- // updating.
- if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
- scrollLayerTo(scrollX, scrollY);
- return;
- }
- mInOverScrollMode = false;
- int maxX = computeMaxScrollX();
- int maxY = computeMaxScrollY();
- if (maxX == 0) {
- // do not over scroll x if the page just fits the screen
- scrollX = pinLocX(scrollX);
- } else if (scrollX < 0 || scrollX > maxX) {
- mInOverScrollMode = true;
- }
- if (scrollY < 0 || scrollY > maxY) {
- mInOverScrollMode = true;
- }
-
- int oldX = mScrollX;
- int oldY = mScrollY;
-
- super.scrollTo(scrollX, scrollY);
-
- if (mOverScrollGlow != null) {
- mOverScrollGlow.pullGlow(mScrollX, mScrollY, oldX, oldY, maxX, maxY);
- }
+ mProvider.requestImageRef(msg);
}
/**
@@ -3708,8 +1046,7 @@ public class WebView extends AbsoluteLayout
*/
public String getUrl() {
checkThread();
- WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
- return h != null ? h.getUrl() : null;
+ return mProvider.getUrl();
}
/**
@@ -3722,8 +1059,7 @@ public class WebView extends AbsoluteLayout
*/
public String getOriginalUrl() {
checkThread();
- WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
- return h != null ? h.getOriginalUrl() : null;
+ return mProvider.getOriginalUrl();
}
/**
@@ -3733,8 +1069,7 @@ public class WebView extends AbsoluteLayout
*/
public String getTitle() {
checkThread();
- WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
- return h != null ? h.getTitle() : null;
+ return mProvider.getTitle();
}
/**
@@ -3744,8 +1079,7 @@ public class WebView extends AbsoluteLayout
*/
public Bitmap getFavicon() {
checkThread();
- WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
- return h != null ? h.getFavicon() : null;
+ return mProvider.getFavicon();
}
/**
@@ -3755,8 +1089,7 @@ public class WebView extends AbsoluteLayout
* @hide
*/
public String getTouchIconUrl() {
- WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
- return h != null ? h.getTouchIconUrl() : null;
+ return mProvider.getTouchIconUrl();
}
/**
@@ -3765,7 +1098,7 @@ public class WebView extends AbsoluteLayout
*/
public int getProgress() {
checkThread();
- return mCallbackProxy.getProgress();
+ return mProvider.getProgress();
}
/**
@@ -3773,7 +1106,7 @@ public class WebView extends AbsoluteLayout
*/
public int getContentHeight() {
checkThread();
- return mContentHeight;
+ return mProvider.getContentHeight();
}
/**
@@ -3781,14 +1114,7 @@ public class WebView extends AbsoluteLayout
* @hide
*/
public int getContentWidth() {
- return mContentWidth;
- }
-
- /**
- * @hide
- */
- public int getPageBackgroundColor() {
- return nativeGetBackgroundColor();
+ return mProvider.getContentWidth();
}
/**
@@ -3798,7 +1124,7 @@ public class WebView extends AbsoluteLayout
*/
public void pauseTimers() {
checkThread();
- mWebViewCore.sendMessage(EventHub.PAUSE_TIMERS);
+ mProvider.pauseTimers();
}
/**
@@ -3807,7 +1133,7 @@ public class WebView extends AbsoluteLayout
*/
public void resumeTimers() {
checkThread();
- mWebViewCore.sendMessage(EventHub.RESUME_TIMERS);
+ mProvider.resumeTimers();
}
/**
@@ -3820,38 +1146,7 @@ public class WebView extends AbsoluteLayout
*/
public void onPause() {
checkThread();
- if (!mIsPaused) {
- mIsPaused = true;
- mWebViewCore.sendMessage(EventHub.ON_PAUSE);
- // We want to pause the current playing video when switching out
- // from the current WebView/tab.
- if (mHTML5VideoViewProxy != null) {
- mHTML5VideoViewProxy.pauseAndDispatch();
- }
- if (mNativeClass != 0) {
- nativeSetPauseDrawing(mNativeClass, true);
- }
-
- cancelSelectDialog();
- WebCoreThreadWatchdog.pause();
- }
- }
-
- @Override
- protected void onWindowVisibilityChanged(int visibility) {
- super.onWindowVisibilityChanged(visibility);
- updateDrawingState();
- }
-
- void updateDrawingState() {
- if (mNativeClass == 0 || mIsPaused) return;
- if (getWindowVisibility() != VISIBLE) {
- nativeSetPauseDrawing(mNativeClass, true);
- } else if (getVisibility() != VISIBLE) {
- nativeSetPauseDrawing(mNativeClass, true);
- } else {
- nativeSetPauseDrawing(mNativeClass, false);
- }
+ mProvider.onPause();
}
/**
@@ -3859,22 +1154,7 @@ public class WebView extends AbsoluteLayout
*/
public void onResume() {
checkThread();
- if (mIsPaused) {
- mIsPaused = false;
- mWebViewCore.sendMessage(EventHub.ON_RESUME);
- if (mNativeClass != 0) {
- nativeSetPauseDrawing(mNativeClass, false);
- }
- }
- // Ensure that the watchdog has a currently valid Context to be able to display
- // a prompt dialog. For example, if the Activity was finished whilst the WebCore
- // thread was blocked and the Activity is started again, we may reuse the blocked
- // thread, but we'll have a new Activity.
- WebCoreThreadWatchdog.updateContext(mContext);
- // We get a call to onResume for new WebViews (i.e. mIsPaused will be false). We need
- // to ensure that the Watchdog thread is running for the new WebView, so call
- // it outside the if block above.
- WebCoreThreadWatchdog.resume();
+ mProvider.onResume();
}
/**
@@ -3883,7 +1163,7 @@ public class WebView extends AbsoluteLayout
* @hide
*/
public boolean isPaused() {
- return mIsPaused;
+ return mProvider.isPaused();
}
/**
@@ -3892,7 +1172,7 @@ public class WebView extends AbsoluteLayout
*/
public void freeMemory() {
checkThread();
- mWebViewCore.sendMessage(EventHub.FREE_MEMORY);
+ mProvider.freeMemory();
}
/**
@@ -3903,11 +1183,7 @@ public class WebView extends AbsoluteLayout
*/
public void clearCache(boolean includeDiskFiles) {
checkThread();
- // Note: this really needs to be a static method as it clears cache for all
- // WebView. But we need mWebViewCore to send message to WebCore thread, so
- // we can't make this static.
- mWebViewCore.sendMessage(EventHub.CLEAR_CACHE,
- includeDiskFiles ? 1 : 0, 0);
+ mProvider.clearCache(includeDiskFiles);
}
/**
@@ -3916,9 +1192,7 @@ public class WebView extends AbsoluteLayout
*/
public void clearFormData() {
checkThread();
- if (inEditingMode()) {
- mWebTextView.setAdapterCustom(null);
- }
+ mProvider.clearFormData();
}
/**
@@ -3926,8 +1200,7 @@ public class WebView extends AbsoluteLayout
*/
public void clearHistory() {
checkThread();
- mCallbackProxy.getBackForwardList().setClearPending();
- mWebViewCore.sendMessage(EventHub.CLEAR_HISTORY);
+ mProvider.clearHistory();
}
/**
@@ -3936,7 +1209,7 @@ public class WebView extends AbsoluteLayout
*/
public void clearSslPreferences() {
checkThread();
- mWebViewCore.sendMessage(EventHub.CLEAR_SSL_PREF_TABLE);
+ mProvider.clearSslPreferences();
}
/**
@@ -3949,7 +1222,8 @@ public class WebView extends AbsoluteLayout
*/
public WebBackForwardList copyBackForwardList() {
checkThread();
- return mCallbackProxy.getBackForwardList().clone();
+ return mProvider.copyBackForwardList();
+
}
/*
@@ -3961,8 +1235,7 @@ public class WebView extends AbsoluteLayout
*/
public void findNext(boolean forward) {
checkThread();
- if (0 == mNativeClass) return; // client isn't initialized
- mWebViewCore.sendMessage(EventHub.FIND_NEXT, forward ? 1 : 0);
+ mProvider.findNext(forward);
}
/*
@@ -3972,40 +1245,8 @@ public class WebView extends AbsoluteLayout
* that were found.
*/
public int findAll(String find) {
- return findAllBody(find, false);
- }
-
- /**
- * @hide
- */
- public void findAllAsync(String find) {
- findAllBody(find, true);
- }
-
- private int findAllBody(String find, boolean isAsync) {
checkThread();
- if (0 == mNativeClass) return 0; // client isn't initialized
- mLastFind = find;
- mWebViewCore.removeMessages(EventHub.FIND_ALL);
- WebViewCore.FindAllRequest request = new
- WebViewCore.FindAllRequest(find);
- if (isAsync) {
- mWebViewCore.sendMessage(EventHub.FIND_ALL, request);
- return 0; // no need to wait for response
- }
- synchronized(request) {
- try {
- mWebViewCore.sendMessageAtFrontOfQueue(EventHub.FIND_ALL,
- request);
- while (request.mMatchCount == -1) {
- request.wait();
- }
- }
- catch (InterruptedException e) {
- return 0;
- }
- }
- return request.mMatchCount;
+ return mProvider.findAll(find);
}
/**
@@ -4020,56 +1261,10 @@ public class WebView extends AbsoluteLayout
*/
public boolean showFindDialog(String text, boolean showIme) {
checkThread();
- FindActionModeCallback callback = new FindActionModeCallback(mContext);
- if (getParent() == null || startActionMode(callback) == null) {
- // Could not start the action mode, so end Find on page
- return false;
- }
- mCachedOverlappingActionModeHeight = -1;
- mFindCallback = callback;
- setFindIsUp(true);
- mFindCallback.setWebView(this);
- if (showIme) {
- mFindCallback.showSoftInput();
- } else if (text != null) {
- mFindCallback.setText(text);
- mFindCallback.findAll();
- return true;
- }
- if (text == null) {
- text = mLastFind;
- }
- if (text != null) {
- mFindCallback.setText(text);
- mFindCallback.findAll();
- }
- return true;
+ return mProvider.showFindDialog(text, showIme);
}
/**
- * Keep track of the find callback so that we can remove its titlebar if
- * necessary.
- */
- private FindActionModeCallback mFindCallback;
-
- /**
- * Toggle whether the find dialog is showing, for both native and Java.
- */
- private void setFindIsUp(boolean isUp) {
- mFindIsUp = isUp;
- if (0 == mNativeClass) return; // client isn't initialized
- nativeSetFindIsUp(isUp);
- }
-
- // Used to know whether the find dialog is open. Affects whether
- // or not we draw the highlights for matches.
- private boolean mFindIsUp;
-
- // Keep track of the last string sent, so we can search again when find is
- // reopened.
- private String mLastFind;
-
- /**
* Return the first substring consisting of the address of a physical
* location. Currently, only addresses in the United States are detected,
* and consist of:
@@ -4091,33 +1286,7 @@ public class WebView extends AbsoluteLayout
*/
public static String findAddress(String addr) {
checkThread();
- return findAddress(addr, false);
- }
-
- /**
- * @hide
- * Return the first substring consisting of the address of a physical
- * location. Currently, only addresses in the United States are detected,
- * and consist of:
- * - a house number
- * - a street name
- * - a street type (Road, Circle, etc), either spelled out or abbreviated
- * - a city name
- * - a state or territory, either spelled out or two-letter abbr.
- * - an optional 5 digit or 9 digit zip code.
- *
- * Names are optionally capitalized, and the zip code, if present,
- * must be valid for the state. The street type must be a standard USPS
- * spelling or abbreviation. The state or territory must also be spelled
- * or abbreviated using USPS standards. The house number may not exceed
- * five digits.
- * @param addr The string to search for addresses.
- * @param caseInsensitive addr Set to true to make search ignore case.
- *
- * @return the address, or if no address is found, return null.
- */
- public static String findAddress(String addr, boolean caseInsensitive) {
- return WebViewCore.nativeFindAddress(addr, caseInsensitive);
+ return getFactory().getStatics().findAddress(addr);
}
/*
@@ -4125,28 +1294,7 @@ public class WebView extends AbsoluteLayout
*/
public void clearMatches() {
checkThread();
- if (mNativeClass == 0)
- return;
- mWebViewCore.removeMessages(EventHub.FIND_ALL);
- mWebViewCore.sendMessage(EventHub.FIND_ALL, null);
- }
-
-
- /**
- * Called when the find ActionMode ends.
- */
- void notifyFindDialogDismissed() {
- mFindCallback = null;
- mCachedOverlappingActionModeHeight = -1;
- if (mWebViewCore == null) {
- return;
- }
- clearMatches();
- setFindIsUp(false);
- // Now that the dialog has been removed, ensure that we scroll to a
- // location that is not beyond the end of the page.
- pinScrollTo(mScrollX, mScrollY, false, 0);
- invalidate();
+ mProvider.clearMatches();
}
/**
@@ -4157,427 +1305,7 @@ public class WebView extends AbsoluteLayout
*/
public void documentHasImages(Message response) {
checkThread();
- if (response == null) {
- return;
- }
- mWebViewCore.sendMessage(EventHub.DOC_HAS_IMAGES, response);
- }
-
- /**
- * Request the scroller to abort any ongoing animation
- *
- * @hide
- */
- public void stopScroll() {
- mScroller.forceFinished(true);
- mLastVelocity = 0;
- }
-
- @Override
- public void computeScroll() {
- if (mScroller.computeScrollOffset()) {
- int oldX = mScrollX;
- int oldY = mScrollY;
- int x = mScroller.getCurrX();
- int y = mScroller.getCurrY();
- invalidate(); // So we draw again
-
- if (!mScroller.isFinished()) {
- int rangeX = computeMaxScrollX();
- int rangeY = computeMaxScrollY();
- int overflingDistance = mOverflingDistance;
-
- // Use the layer's scroll data if needed.
- if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
- oldX = mScrollingLayerRect.left;
- oldY = mScrollingLayerRect.top;
- rangeX = mScrollingLayerRect.right;
- rangeY = mScrollingLayerRect.bottom;
- // No overscrolling for layers.
- overflingDistance = 0;
- }
-
- overScrollBy(x - oldX, y - oldY, oldX, oldY,
- rangeX, rangeY,
- overflingDistance, overflingDistance, false);
-
- if (mOverScrollGlow != null) {
- mOverScrollGlow.absorbGlow(x, y, oldX, oldY, rangeX, rangeY);
- }
- } else {
- if (mTouchMode != TOUCH_DRAG_LAYER_MODE) {
- mScrollX = x;
- mScrollY = y;
- } else {
- // Update the layer position instead of WebView.
- scrollLayerTo(x, y);
- }
- abortAnimation();
- nativeSetIsScrolling(false);
- if (!mBlockWebkitViewMessages) {
- WebViewCore.resumePriority();
- if (!mSelectingText) {
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- }
- }
- if (oldX != mScrollX || oldY != mScrollY) {
- sendOurVisibleRect();
- }
- }
- } else {
- super.computeScroll();
- }
- }
-
- private void scrollLayerTo(int x, int y) {
- if (x == mScrollingLayerRect.left && y == mScrollingLayerRect.top) {
- return;
- }
- if (mSelectingText) {
- int dx = mScrollingLayerRect.left - x;
- int dy = mScrollingLayerRect.top - y;
- if (mSelectCursorBaseLayerId == mCurrentScrollingLayerId) {
- mSelectCursorBase.offset(dx, dy);
- }
- if (mSelectCursorExtentLayerId == mCurrentScrollingLayerId) {
- mSelectCursorExtent.offset(dx, dy);
- }
- }
- nativeScrollLayer(mCurrentScrollingLayerId, x, y);
- mScrollingLayerRect.left = x;
- mScrollingLayerRect.top = y;
- mWebViewCore.sendMessage(WebViewCore.EventHub.SCROLL_LAYER, mCurrentScrollingLayerId,
- mScrollingLayerRect);
- onScrollChanged(mScrollX, mScrollY, mScrollX, mScrollY);
- invalidate();
- }
-
- private static int computeDuration(int dx, int dy) {
- int distance = Math.max(Math.abs(dx), Math.abs(dy));
- int duration = distance * 1000 / STD_SPEED;
- return Math.min(duration, MAX_DURATION);
- }
-
- // helper to pin the scrollBy parameters (already in view coordinates)
- // returns true if the scroll was changed
- private boolean pinScrollBy(int dx, int dy, boolean animate, int animationDuration) {
- return pinScrollTo(mScrollX + dx, mScrollY + dy, animate, animationDuration);
- }
- // helper to pin the scrollTo parameters (already in view coordinates)
- // returns true if the scroll was changed
- private boolean pinScrollTo(int x, int y, boolean animate, int animationDuration) {
- x = pinLocX(x);
- y = pinLocY(y);
- int dx = x - mScrollX;
- int dy = y - mScrollY;
-
- if ((dx | dy) == 0) {
- return false;
- }
- abortAnimation();
- if (animate) {
- // Log.d(LOGTAG, "startScroll: " + dx + " " + dy);
- mScroller.startScroll(mScrollX, mScrollY, dx, dy,
- animationDuration > 0 ? animationDuration : computeDuration(dx, dy));
- awakenScrollBars(mScroller.getDuration());
- invalidate();
- } else {
- scrollTo(x, y);
- }
- return true;
- }
-
- // Scale from content to view coordinates, and pin.
- // Also called by jni webview.cpp
- private boolean setContentScrollBy(int cx, int cy, boolean animate) {
- if (mDrawHistory) {
- // disallow WebView to change the scroll position as History Picture
- // is used in the view system.
- // TODO: as we switchOutDrawHistory when trackball or navigation
- // keys are hit, this should be safe. Right?
- return false;
- }
- cx = contentToViewDimension(cx);
- cy = contentToViewDimension(cy);
- if (mHeightCanMeasure) {
- // move our visible rect according to scroll request
- if (cy != 0) {
- Rect tempRect = new Rect();
- calcOurVisibleRect(tempRect);
- tempRect.offset(cx, cy);
- requestRectangleOnScreen(tempRect);
- }
- // FIXME: We scroll horizontally no matter what because currently
- // ScrollView and ListView will not scroll horizontally.
- // FIXME: Why do we only scroll horizontally if there is no
- // vertical scroll?
-// Log.d(LOGTAG, "setContentScrollBy cy=" + cy);
- return cy == 0 && cx != 0 && pinScrollBy(cx, 0, animate, 0);
- } else {
- return pinScrollBy(cx, cy, animate, 0);
- }
- }
-
- /**
- * Called by CallbackProxy when the page starts loading.
- * @param url The URL of the page which has started loading.
- */
- /* package */ void onPageStarted(String url) {
- // every time we start a new page, we want to reset the
- // WebView certificate: if the new site is secure, we
- // will reload it and get a new certificate set;
- // if the new site is not secure, the certificate must be
- // null, and that will be the case
- setCertificate(null);
-
- // reset the flag since we set to true in if need after
- // loading is see onPageFinished(Url)
- mAccessibilityScriptInjected = false;
- }
-
- /**
- * Called by CallbackProxy when the page finishes loading.
- * @param url The URL of the page which has finished loading.
- */
- /* package */ void onPageFinished(String url) {
- if (mPageThatNeedsToSlideTitleBarOffScreen != null) {
- // If the user is now on a different page, or has scrolled the page
- // past the point where the title bar is offscreen, ignore the
- // scroll request.
- if (mPageThatNeedsToSlideTitleBarOffScreen.equals(url)
- && mScrollX == 0 && mScrollY == 0) {
- pinScrollTo(0, mYDistanceToSlideTitleOffScreen, true,
- SLIDE_TITLE_DURATION);
- }
- mPageThatNeedsToSlideTitleBarOffScreen = null;
- }
- mZoomManager.onPageFinished(url);
- injectAccessibilityForUrl(url);
- }
-
- /**
- * This method injects accessibility in the loaded document if accessibility
- * is enabled. If JavaScript is enabled we try to inject a URL specific script.
- * If no URL specific script is found or JavaScript is disabled we fallback to
- * the default {@link AccessibilityInjector} implementation.
- * </p>
- * If the URL has the "axs" paramter set to 1 it has already done the
- * script injection so we do nothing. If the parameter is set to 0
- * the URL opts out accessibility script injection so we fall back to
- * the default {@link AccessibilityInjector}.
- * </p>
- * Note: If the user has not opted-in the accessibility script injection no scripts
- * are injected rather the default {@link AccessibilityInjector} implementation
- * is used.
- *
- * @param url The URL loaded by this {@link WebView}.
- */
- private void injectAccessibilityForUrl(String url) {
- if (mWebViewCore == null) {
- return;
- }
- AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(mContext);
-
- if (!accessibilityManager.isEnabled()) {
- // it is possible that accessibility was turned off between reloads
- ensureAccessibilityScriptInjectorInstance(false);
- return;
- }
-
- if (!getSettings().getJavaScriptEnabled()) {
- // no JS so we fallback to the basic buil-in support
- ensureAccessibilityScriptInjectorInstance(true);
- return;
- }
-
- // check the URL "axs" parameter to choose appropriate action
- int axsParameterValue = getAxsUrlParameterValue(url);
- if (axsParameterValue == ACCESSIBILITY_SCRIPT_INJECTION_UNDEFINED) {
- boolean onDeviceScriptInjectionEnabled = (Settings.Secure.getInt(mContext
- .getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0) == 1);
- if (onDeviceScriptInjectionEnabled) {
- ensureAccessibilityScriptInjectorInstance(false);
- // neither script injected nor script injection opted out => we inject
- loadUrl(getScreenReaderInjectingJs());
- // TODO: Set this flag after successfull script injection. Maybe upon injection
- // the chooser should update the meta tag and we check it to declare success
- mAccessibilityScriptInjected = true;
- } else {
- // injection disabled so we fallback to the basic built-in support
- ensureAccessibilityScriptInjectorInstance(true);
- }
- } else if (axsParameterValue == ACCESSIBILITY_SCRIPT_INJECTION_OPTED_OUT) {
- // injection opted out so we fallback to the basic buil-in support
- ensureAccessibilityScriptInjectorInstance(true);
- } else if (axsParameterValue == ACCESSIBILITY_SCRIPT_INJECTION_PROVIDED) {
- ensureAccessibilityScriptInjectorInstance(false);
- // the URL provides accessibility but we still need to add our generic script
- loadUrl(getScreenReaderInjectingJs());
- } else {
- Log.e(LOGTAG, "Unknown URL value for the \"axs\" URL parameter: " + axsParameterValue);
- }
- }
-
- /**
- * Ensures the instance of the {@link AccessibilityInjector} to be present ot not.
- *
- * @param present True to ensure an insance, false to ensure no instance.
- */
- private void ensureAccessibilityScriptInjectorInstance(boolean present) {
- if (present) {
- if (mAccessibilityInjector == null) {
- mAccessibilityInjector = new AccessibilityInjector(this);
- }
- } else {
- mAccessibilityInjector = null;
- }
- }
-
- /**
- * Gets JavaScript that injects a screen-reader.
- *
- * @return The JavaScript snippet.
- */
- private String getScreenReaderInjectingJs() {
- String screenReaderUrl = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL);
- return String.format(ACCESSIBILITY_SCREEN_READER_JAVASCRIPT_TEMPLATE, screenReaderUrl);
- }
-
- /**
- * Gets the "axs" URL parameter value.
- *
- * @param url A url to fetch the paramter from.
- * @return The parameter value if such, -1 otherwise.
- */
- private int getAxsUrlParameterValue(String url) {
- if (mMatchAxsUrlParameterPattern == null) {
- mMatchAxsUrlParameterPattern = Pattern.compile(PATTERN_MATCH_AXS_URL_PARAMETER);
- }
- Matcher matcher = mMatchAxsUrlParameterPattern.matcher(url);
- if (matcher.find()) {
- String keyValuePair = url.substring(matcher.start(), matcher.end());
- return Integer.parseInt(keyValuePair.split("=")[1]);
- }
- return -1;
- }
-
- /**
- * The URL of a page that sent a message to scroll the title bar off screen.
- *
- * Many mobile sites tell the page to scroll to (0,1) in order to scroll the
- * title bar off the screen. Sometimes, the scroll position is set before
- * the page finishes loading. Rather than scrolling while the page is still
- * loading, keep track of the URL and new scroll position so we can perform
- * the scroll once the page finishes loading.
- */
- private String mPageThatNeedsToSlideTitleBarOffScreen;
-
- /**
- * The destination Y scroll position to be used when the page finishes
- * loading. See mPageThatNeedsToSlideTitleBarOffScreen.
- */
- private int mYDistanceToSlideTitleOffScreen;
-
- // scale from content to view coordinates, and pin
- // return true if pin caused the final x/y different than the request cx/cy,
- // and a future scroll may reach the request cx/cy after our size has
- // changed
- // return false if the view scroll to the exact position as it is requested,
- // where negative numbers are taken to mean 0
- private boolean setContentScrollTo(int cx, int cy) {
- if (mDrawHistory) {
- // disallow WebView to change the scroll position as History Picture
- // is used in the view system.
- // One known case where this is called is that WebCore tries to
- // restore the scroll position. As history Picture already uses the
- // saved scroll position, it is ok to skip this.
- return false;
- }
- int vx;
- int vy;
- if ((cx | cy) == 0) {
- // If the page is being scrolled to (0,0), do not add in the title
- // bar's height, and simply scroll to (0,0). (The only other work
- // in contentToView_ is to multiply, so this would not change 0.)
- vx = 0;
- vy = 0;
- } else {
- vx = contentToViewX(cx);
- vy = contentToViewY(cy);
- }
-// Log.d(LOGTAG, "content scrollTo [" + cx + " " + cy + "] view=[" +
-// vx + " " + vy + "]");
- // Some mobile sites attempt to scroll the title bar off the page by
- // scrolling to (0,1). If we are at the top left corner of the
- // page, assume this is an attempt to scroll off the title bar, and
- // animate the title bar off screen slowly enough that the user can see
- // it.
- if (cx == 0 && cy == 1 && mScrollX == 0 && mScrollY == 0
- && mTitleBar != null) {
- // FIXME: 100 should be defined somewhere as our max progress.
- if (getProgress() < 100) {
- // Wait to scroll the title bar off screen until the page has
- // finished loading. Keep track of the URL and the destination
- // Y position
- mPageThatNeedsToSlideTitleBarOffScreen = getUrl();
- mYDistanceToSlideTitleOffScreen = vy;
- } else {
- pinScrollTo(vx, vy, true, SLIDE_TITLE_DURATION);
- }
- // Since we are animating, we have not yet reached the desired
- // scroll position. Do not return true to request another attempt
- return false;
- }
- pinScrollTo(vx, vy, false, 0);
- // If the request was to scroll to a negative coordinate, treat it as if
- // it was a request to scroll to 0
- if ((mScrollX != vx && cx >= 0) || (mScrollY != vy && cy >= 0)) {
- return true;
- } else {
- return false;
- }
- }
-
- // scale from content to view coordinates, and pin
- private void spawnContentScrollTo(int cx, int cy) {
- if (mDrawHistory) {
- // disallow WebView to change the scroll position as History Picture
- // is used in the view system.
- return;
- }
- int vx = contentToViewX(cx);
- int vy = contentToViewY(cy);
- pinScrollTo(vx, vy, true, 0);
- }
-
- /**
- * These are from webkit, and are in content coordinate system (unzoomed)
- */
- private void contentSizeChanged(boolean updateLayout) {
- // suppress 0,0 since we usually see real dimensions soon after
- // this avoids drawing the prev content in a funny place. If we find a
- // way to consolidate these notifications, this check may become
- // obsolete
- if ((mContentWidth | mContentHeight) == 0) {
- return;
- }
-
- if (mHeightCanMeasure) {
- if (getMeasuredHeight() != contentToViewDimension(mContentHeight)
- || updateLayout) {
- requestLayout();
- }
- } else if (mWidthCanMeasure) {
- if (getMeasuredWidth() != contentToViewDimension(mContentWidth)
- || updateLayout) {
- requestLayout();
- }
- } else {
- // If we don't request a layout, try to send our view size to the
- // native side to ensure that WebCore has the correct dimensions.
- sendViewSizeZoom(false);
- }
+ mProvider.documentHasImages(response);
}
/**
@@ -4587,17 +1315,7 @@ public class WebView extends AbsoluteLayout
*/
public void setWebViewClient(WebViewClient client) {
checkThread();
- mCallbackProxy.setWebViewClient(client);
- }
-
- /**
- * Gets the WebViewClient
- * @return the current WebViewClient instance.
- *
- * @hide This is an implementation detail.
- */
- public WebViewClient getWebViewClient() {
- return mCallbackProxy.getWebViewClient();
+ mProvider.setWebViewClient(client);
}
/**
@@ -4608,7 +1326,7 @@ public class WebView extends AbsoluteLayout
*/
public void setDownloadListener(DownloadListener listener) {
checkThread();
- mCallbackProxy.setDownloadListener(listener);
+ mProvider.setDownloadListener(listener);
}
/**
@@ -4619,36 +1337,7 @@ public class WebView extends AbsoluteLayout
*/
public void setWebChromeClient(WebChromeClient client) {
checkThread();
- mCallbackProxy.setWebChromeClient(client);
- }
-
- /**
- * Gets the chrome handler.
- * @return the current WebChromeClient instance.
- *
- * @hide This is an implementation detail.
- */
- public WebChromeClient getWebChromeClient() {
- return mCallbackProxy.getWebChromeClient();
- }
-
- /**
- * Set the back/forward list client. This is an implementation of
- * WebBackForwardListClient for handling new items and changes in the
- * history index.
- * @param client An implementation of WebBackForwardListClient.
- * {@hide}
- */
- public void setWebBackForwardListClient(WebBackForwardListClient client) {
- mCallbackProxy.setWebBackForwardListClient(client);
- }
-
- /**
- * Gets the WebBackForwardListClient.
- * {@hide}
- */
- public WebBackForwardListClient getWebBackForwardListClient() {
- return mCallbackProxy.getWebBackForwardListClient();
+ mProvider.setWebChromeClient(client);
}
/**
@@ -4660,23 +1349,7 @@ public class WebView extends AbsoluteLayout
@Deprecated
public void setPictureListener(PictureListener listener) {
checkThread();
- mPictureListener = listener;
- }
-
- /**
- * {@hide}
- */
- /* FIXME: Debug only! Remove for SDK! */
- public void externalRepresentation(Message callback) {
- mWebViewCore.sendMessage(EventHub.REQUEST_EXT_REPRESENTATION, callback);
- }
-
- /**
- * {@hide}
- */
- /* FIXME: Debug only! Remove for SDK! */
- public void documentAsText(Message callback) {
- mWebViewCore.sendMessage(EventHub.REQUEST_DOC_AS_TEXT, callback);
+ mProvider.setPictureListener(listener);
}
/**
@@ -4707,13 +1380,7 @@ public class WebView extends AbsoluteLayout
*/
public void addJavascriptInterface(Object object, String name) {
checkThread();
- if (object == null) {
- return;
- }
- WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
- arg.mObject = object;
- arg.mInterfaceName = name;
- mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);
+ mProvider.addJavascriptInterface(object, name);
}
/**
@@ -4722,11 +1389,7 @@ public class WebView extends AbsoluteLayout
*/
public void removeJavascriptInterface(String interfaceName) {
checkThread();
- if (mWebViewCore != null) {
- WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
- arg.mInterfaceName = interfaceName;
- mWebViewCore.sendMessage(EventHub.REMOVE_JS_INTERFACE, arg);
- }
+ mProvider.removeJavascriptInterface(interfaceName);
}
/**
@@ -4737,1410 +1400,31 @@ public class WebView extends AbsoluteLayout
*/
public WebSettings getSettings() {
checkThread();
- return (mWebViewCore != null) ? mWebViewCore.getSettings() : null;
+ return mProvider.getSettings();
}
- /**
- * Return the list of currently loaded plugins.
- * @return The list of currently loaded plugins.
- *
- * @hide
- * @deprecated This was used for Gears, which has been deprecated.
- */
+ /**
+ * Return the list of currently loaded plugins.
+ * @return The list of currently loaded plugins.
+ *
+ * @hide
+ * @deprecated This was used for Gears, which has been deprecated.
+ */
@Deprecated
public static synchronized PluginList getPluginList() {
checkThread();
return new PluginList();
}
- /**
- * @hide
- * @deprecated This was used for Gears, which has been deprecated.
- */
+ /**
+ * @hide
+ * @deprecated This was used for Gears, which has been deprecated.
+ */
@Deprecated
public void refreshPlugins(boolean reloadOpenPages) {
checkThread();
}
- //-------------------------------------------------------------------------
- // Override View methods
- //-------------------------------------------------------------------------
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mNativeClass != 0) {
- mPrivateHandler.post(new Runnable() {
- @Override
- public void run() {
- destroy();
- }
- });
- }
- } finally {
- super.finalize();
- }
- }
-
- @Override
- protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
- if (child == mTitleBar) {
- // When drawing the title bar, move it horizontally to always show
- // at the top of the WebView.
- mTitleBar.offsetLeftAndRight(mScrollX - mTitleBar.getLeft());
- int newTop = 0;
- if (mTitleGravity == Gravity.NO_GRAVITY) {
- newTop = Math.min(0, mScrollY);
- } else if (mTitleGravity == Gravity.TOP) {
- newTop = mScrollY;
- }
- mTitleBar.setBottom(newTop + mTitleBar.getHeight());
- mTitleBar.setTop(newTop);
- }
- return super.drawChild(canvas, child, drawingTime);
- }
-
- private void drawContent(Canvas canvas, boolean drawRings) {
- drawCoreAndCursorRing(canvas, mBackgroundColor,
- mDrawCursorRing && drawRings);
- }
-
- /**
- * Draw the background when beyond bounds
- * @param canvas Canvas to draw into
- */
- private void drawOverScrollBackground(Canvas canvas) {
- if (mOverScrollBackground == null) {
- mOverScrollBackground = new Paint();
- Bitmap bm = BitmapFactory.decodeResource(
- mContext.getResources(),
- com.android.internal.R.drawable.status_bar_background);
- mOverScrollBackground.setShader(new BitmapShader(bm,
- Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
- mOverScrollBorder = new Paint();
- mOverScrollBorder.setStyle(Paint.Style.STROKE);
- mOverScrollBorder.setStrokeWidth(0);
- mOverScrollBorder.setColor(0xffbbbbbb);
- }
-
- int top = 0;
- int right = computeRealHorizontalScrollRange();
- int bottom = top + computeRealVerticalScrollRange();
- // first draw the background and anchor to the top of the view
- canvas.save();
- canvas.translate(mScrollX, mScrollY);
- canvas.clipRect(-mScrollX, top - mScrollY, right - mScrollX, bottom
- - mScrollY, Region.Op.DIFFERENCE);
- canvas.drawPaint(mOverScrollBackground);
- canvas.restore();
- // then draw the border
- canvas.drawRect(-1, top - 1, right, bottom, mOverScrollBorder);
- // next clip the region for the content
- canvas.clipRect(0, top, right, bottom);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (inFullScreenMode()) {
- return; // no need to draw anything if we aren't visible.
- }
- // if mNativeClass is 0, the WebView is either destroyed or not
- // initialized. In either case, just draw the background color and return
- if (mNativeClass == 0) {
- canvas.drawColor(mBackgroundColor);
- return;
- }
-
- // if both mContentWidth and mContentHeight are 0, it means there is no
- // valid Picture passed to WebView yet. This can happen when WebView
- // just starts. Draw the background and return.
- if ((mContentWidth | mContentHeight) == 0 && mHistoryPicture == null) {
- canvas.drawColor(mBackgroundColor);
- return;
- }
-
- if (canvas.isHardwareAccelerated()) {
- mZoomManager.setHardwareAccelerated();
- } else {
- mWebViewCore.resumeWebKitDraw();
- }
-
- int saveCount = canvas.save();
- if (mInOverScrollMode && !getSettings()
- .getUseWebViewBackgroundForOverscrollBackground()) {
- drawOverScrollBackground(canvas);
- }
- if (mTitleBar != null) {
- canvas.translate(0, getTitleHeight());
- }
- boolean drawNativeRings = !sDisableNavcache;
- drawContent(canvas, drawNativeRings);
- canvas.restoreToCount(saveCount);
-
- if (AUTO_REDRAW_HACK && mAutoRedraw) {
- invalidate();
- }
- mWebViewCore.signalRepaintDone();
-
- if (mOverScrollGlow != null && mOverScrollGlow.drawEdgeGlows(canvas)) {
- invalidate();
- }
-
- if (mFocusTransition != null) {
- mFocusTransition.draw(canvas);
- } else if (shouldDrawHighlightRect()) {
- RegionIterator iter = new RegionIterator(mTouchHighlightRegion);
- Rect r = new Rect();
- while (iter.next(r)) {
- canvas.drawRect(r, mTouchHightlightPaint);
- }
- }
- if (DEBUG_TOUCH_HIGHLIGHT) {
- if (getSettings().getNavDump()) {
- if ((mTouchHighlightX | mTouchHighlightY) != 0) {
- if (mTouchCrossHairColor == null) {
- mTouchCrossHairColor = new Paint();
- mTouchCrossHairColor.setColor(Color.RED);
- }
- canvas.drawLine(mTouchHighlightX - mNavSlop,
- mTouchHighlightY - mNavSlop, mTouchHighlightX
- + mNavSlop + 1, mTouchHighlightY + mNavSlop
- + 1, mTouchCrossHairColor);
- canvas.drawLine(mTouchHighlightX + mNavSlop + 1,
- mTouchHighlightY - mNavSlop, mTouchHighlightX
- - mNavSlop,
- mTouchHighlightY + mNavSlop + 1,
- mTouchCrossHairColor);
- }
- }
- }
- }
-
- private void removeTouchHighlight() {
- mWebViewCore.removeMessages(EventHub.HIT_TEST);
- mPrivateHandler.removeMessages(HIT_TEST_RESULT);
- setTouchHighlightRects(null);
- }
-
- @Override
- public void setLayoutParams(ViewGroup.LayoutParams params) {
- if (params.height == LayoutParams.WRAP_CONTENT) {
- mWrapContent = true;
- }
- super.setLayoutParams(params);
- }
-
- @Override
- public boolean performLongClick() {
- // performLongClick() is the result of a delayed message. If we switch
- // to windows overview, the WebView will be temporarily removed from the
- // view system. In that case, do nothing.
- if (getParent() == null) return false;
-
- // A multi-finger gesture can look like a long press; make sure we don't take
- // long press actions if we're scaling.
- final ScaleGestureDetector detector = mZoomManager.getMultiTouchGestureDetector();
- if (detector != null && detector.isInProgress()) {
- return false;
- }
-
- if (mNativeClass != 0 && nativeCursorIsTextInput()) {
- // Send the click so that the textfield is in focus
- centerKeyPressOnTextField();
- rebuildWebTextView();
- } else {
- clearTextEntry();
- }
- if (inEditingMode()) {
- // Since we just called rebuildWebTextView, the layout is not set
- // properly. Update it so it can correctly find the word to select.
- mWebTextView.ensureLayout();
- // Provide a touch down event to WebTextView, which will allow it
- // to store the location to use in performLongClick.
- AbsoluteLayout.LayoutParams params
- = (AbsoluteLayout.LayoutParams) mWebTextView.getLayoutParams();
- MotionEvent fake = MotionEvent.obtain(mLastTouchTime,
- mLastTouchTime, MotionEvent.ACTION_DOWN,
- mLastTouchX - params.x + mScrollX,
- mLastTouchY - params.y + mScrollY, 0);
- mWebTextView.dispatchTouchEvent(fake);
- return mWebTextView.performLongClick();
- }
- if (mSelectingText) return false; // long click does nothing on selection
- /* if long click brings up a context menu, the super function
- * returns true and we're done. Otherwise, nothing happened when
- * the user clicked. */
- if (super.performLongClick()) {
- return true;
- }
- /* In the case where the application hasn't already handled the long
- * click action, look for a word under the click. If one is found,
- * animate the text selection into view.
- * FIXME: no animation code yet */
- final boolean isSelecting = selectText();
- if (isSelecting) {
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- } else if (focusCandidateIsEditableText()) {
- mSelectCallback = new SelectActionModeCallback();
- mSelectCallback.setWebView(this);
- mSelectCallback.setTextSelected(false);
- startActionMode(mSelectCallback);
- }
- return isSelecting;
- }
-
- /**
- * Select the word at the last click point.
- *
- * @hide This is an implementation detail.
- */
- public boolean selectText() {
- int x = viewToContentX(mLastTouchX + mScrollX);
- int y = viewToContentY(mLastTouchY + mScrollY);
- return selectText(x, y);
- }
-
- /**
- * Select the word at the indicated content coordinates.
- */
- boolean selectText(int x, int y) {
- mWebViewCore.sendMessage(EventHub.SELECT_WORD_AT, x, y);
- return true;
- }
-
- private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- mCachedOverlappingActionModeHeight = -1;
- if (mSelectingText && mOrientation != newConfig.orientation) {
- selectionDone();
- }
- mOrientation = newConfig.orientation;
- if (mWebViewCore != null && !mBlockWebkitViewMessages) {
- mWebViewCore.sendMessage(EventHub.CLEAR_CONTENT);
- }
- }
-
- /**
- * Keep track of the Callback so we can end its ActionMode or remove its
- * titlebar.
- */
- private SelectActionModeCallback mSelectCallback;
-
- // These values are possible options for didUpdateWebTextViewDimensions.
- private static final int FULLY_ON_SCREEN = 0;
- private static final int INTERSECTS_SCREEN = 1;
- private static final int ANYWHERE = 2;
-
- /**
- * Check to see if the focused textfield/textarea is still on screen. If it
- * is, update the the dimensions and location of WebTextView. Otherwise,
- * remove the WebTextView. Should be called when the zoom level changes.
- * @param intersection How to determine whether the textfield/textarea is
- * still on screen.
- * @return boolean True if the textfield/textarea is still on screen and the
- * dimensions/location of WebTextView have been updated.
- */
- private boolean didUpdateWebTextViewDimensions(int intersection) {
- Rect contentBounds = nativeFocusCandidateNodeBounds();
- Rect vBox = contentToViewRect(contentBounds);
- Rect visibleRect = new Rect();
- calcOurVisibleRect(visibleRect);
- offsetByLayerScrollPosition(vBox);
- // If the textfield is on screen, place the WebTextView in
- // its new place, accounting for our new scroll/zoom values,
- // and adjust its textsize.
- boolean onScreen;
- switch (intersection) {
- case FULLY_ON_SCREEN:
- onScreen = visibleRect.contains(vBox);
- break;
- case INTERSECTS_SCREEN:
- onScreen = Rect.intersects(visibleRect, vBox);
- break;
- case ANYWHERE:
- onScreen = true;
- break;
- default:
- throw new AssertionError(
- "invalid parameter passed to didUpdateWebTextViewDimensions");
- }
- if (onScreen) {
- mWebTextView.setRect(vBox.left, vBox.top, vBox.width(),
- vBox.height());
- mWebTextView.updateTextSize();
- updateWebTextViewPadding();
- return true;
- } else {
- // The textfield is now off screen. The user probably
- // was not zooming to see the textfield better. Remove
- // the WebTextView. If the user types a key, and the
- // textfield is still in focus, we will reconstruct
- // the WebTextView and scroll it back on screen.
- mWebTextView.remove();
- return false;
- }
- }
-
- private void offsetByLayerScrollPosition(Rect box) {
- if ((mCurrentScrollingLayerId != 0)
- && (mCurrentScrollingLayerId == nativeFocusCandidateLayerId())) {
- box.offsetTo(box.left - mScrollingLayerRect.left,
- box.top - mScrollingLayerRect.top);
- }
- }
-
- void setBaseLayer(int layer, Region invalRegion, boolean showVisualIndicator,
- boolean isPictureAfterFirstLayout) {
- if (mNativeClass == 0)
- return;
- boolean queueFull;
- queueFull = nativeSetBaseLayer(mNativeClass, layer, invalRegion,
- showVisualIndicator, isPictureAfterFirstLayout);
-
- if (layer == 0 || isPictureAfterFirstLayout) {
- mWebViewCore.resumeWebKitDraw();
- } else if (queueFull) {
- // temporarily disable webkit draw throttling
- // TODO: re-enable
- // mWebViewCore.pauseWebKitDraw();
- }
-
- if (mHTML5VideoViewProxy != null) {
- mHTML5VideoViewProxy.setBaseLayer(layer);
- }
- }
-
- int getBaseLayer() {
- if (mNativeClass == 0) {
- return 0;
- }
- return nativeGetBaseLayer();
- }
-
- private void onZoomAnimationStart() {
- // If it is in password mode, turn it off so it does not draw misplaced.
- if (inEditingMode()) {
- mWebTextView.setVisibility(INVISIBLE);
- }
- }
-
- private void onZoomAnimationEnd() {
- // adjust the edit text view if needed
- if (inEditingMode()
- && didUpdateWebTextViewDimensions(FULLY_ON_SCREEN)) {
- // If it is a password field, start drawing the WebTextView once
- // again.
- mWebTextView.setVisibility(VISIBLE);
- }
- }
-
- void onFixedLengthZoomAnimationStart() {
- WebViewCore.pauseUpdatePicture(getWebViewCore());
- onZoomAnimationStart();
- }
-
- void onFixedLengthZoomAnimationEnd() {
- if (!mBlockWebkitViewMessages && !mSelectingText) {
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- }
- onZoomAnimationEnd();
- }
-
- private static final int ZOOM_BITS = Paint.FILTER_BITMAP_FLAG |
- Paint.DITHER_FLAG |
- Paint.SUBPIXEL_TEXT_FLAG;
- private static final int SCROLL_BITS = Paint.FILTER_BITMAP_FLAG |
- Paint.DITHER_FLAG;
-
- private final DrawFilter mZoomFilter =
- new PaintFlagsDrawFilter(ZOOM_BITS, Paint.LINEAR_TEXT_FLAG);
- // If we need to trade better quality for speed, set mScrollFilter to null
- private final DrawFilter mScrollFilter =
- new PaintFlagsDrawFilter(SCROLL_BITS, 0);
-
- private void drawCoreAndCursorRing(Canvas canvas, int color,
- boolean drawCursorRing) {
- if (mDrawHistory) {
- canvas.scale(mZoomManager.getScale(), mZoomManager.getScale());
- canvas.drawPicture(mHistoryPicture);
- return;
- }
- if (mNativeClass == 0) return;
-
- boolean animateZoom = mZoomManager.isFixedLengthAnimationInProgress();
- boolean animateScroll = ((!mScroller.isFinished()
- || mVelocityTracker != null)
- && (mTouchMode != TOUCH_DRAG_MODE ||
- mHeldMotionless != MOTIONLESS_TRUE))
- || mDeferTouchMode == TOUCH_DRAG_MODE;
- if (mTouchMode == TOUCH_DRAG_MODE) {
- if (mHeldMotionless == MOTIONLESS_PENDING) {
- mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS);
- mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS);
- mHeldMotionless = MOTIONLESS_FALSE;
- }
- if (mHeldMotionless == MOTIONLESS_FALSE) {
- mPrivateHandler.sendMessageDelayed(mPrivateHandler
- .obtainMessage(DRAG_HELD_MOTIONLESS), MOTIONLESS_TIME);
- mPrivateHandler.sendMessageDelayed(mPrivateHandler
- .obtainMessage(AWAKEN_SCROLL_BARS),
- ViewConfiguration.getScrollDefaultDelay());
- mHeldMotionless = MOTIONLESS_PENDING;
- }
- }
- int saveCount = canvas.save();
- if (animateZoom) {
- mZoomManager.animateZoom(canvas);
- } else if (!canvas.isHardwareAccelerated()) {
- canvas.scale(mZoomManager.getScale(), mZoomManager.getScale());
- }
-
- boolean UIAnimationsRunning = false;
- // Currently for each draw we compute the animation values;
- // We may in the future decide to do that independently.
- if (mNativeClass != 0 && !canvas.isHardwareAccelerated()
- && nativeEvaluateLayersAnimations(mNativeClass)) {
- UIAnimationsRunning = true;
- // If we have unfinished (or unstarted) animations,
- // we ask for a repaint. We only need to do this in software
- // rendering (with hardware rendering we already have a different
- // method of requesting a repaint)
- mWebViewCore.sendMessage(EventHub.NOTIFY_ANIMATION_STARTED);
- invalidate();
- }
-
- // decide which adornments to draw
- int extras = DRAW_EXTRAS_NONE;
- if (!mFindIsUp) {
- if (mSelectingText) {
- extras = DRAW_EXTRAS_SELECTION;
- } else if (drawCursorRing) {
- extras = DRAW_EXTRAS_CURSOR_RING;
- }
- }
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "mFindIsUp=" + mFindIsUp
- + " mSelectingText=" + mSelectingText
- + " nativePageShouldHandleShiftAndArrows()="
- + nativePageShouldHandleShiftAndArrows()
- + " animateZoom=" + animateZoom
- + " extras=" + extras);
- }
-
- calcOurContentVisibleRectF(mVisibleContentRect);
- if (canvas.isHardwareAccelerated()) {
- Rect glRectViewport = mGLViewportEmpty ? null : mGLRectViewport;
- Rect viewRectViewport = mGLViewportEmpty ? null : mViewRectViewport;
-
- int functor = nativeGetDrawGLFunction(mNativeClass, glRectViewport,
- viewRectViewport, mVisibleContentRect, getScale(), extras);
- ((HardwareCanvas) canvas).callDrawGLFunction(functor);
- if (mHardwareAccelSkia != getSettings().getHardwareAccelSkiaEnabled()) {
- mHardwareAccelSkia = getSettings().getHardwareAccelSkiaEnabled();
- nativeUseHardwareAccelSkia(mHardwareAccelSkia);
- }
-
- } else {
- DrawFilter df = null;
- if (mZoomManager.isZoomAnimating() || UIAnimationsRunning) {
- df = mZoomFilter;
- } else if (animateScroll) {
- df = mScrollFilter;
- }
- canvas.setDrawFilter(df);
- // XXX: Revisit splitting content. Right now it causes a
- // synchronization problem with layers.
- int content = nativeDraw(canvas, mVisibleContentRect, color,
- extras, false);
- canvas.setDrawFilter(null);
- if (!mBlockWebkitViewMessages && content != 0) {
- mWebViewCore.sendMessage(EventHub.SPLIT_PICTURE_SET, content, 0);
- }
- }
-
- canvas.restoreToCount(saveCount);
- if (mSelectingText) {
- drawTextSelectionHandles(canvas);
- }
-
- if (extras == DRAW_EXTRAS_CURSOR_RING) {
- if (mTouchMode == TOUCH_SHORTPRESS_START_MODE) {
- mTouchMode = TOUCH_SHORTPRESS_MODE;
- }
- }
- if (mFocusSizeChanged) {
- mFocusSizeChanged = false;
- // If we are zooming, this will get handled above, when the zoom
- // finishes. We also do not need to do this unless the WebTextView
- // is showing. With hardware acceleration, the pageSwapCallback()
- // updates the WebTextView position in sync with page swapping
- if (!canvas.isHardwareAccelerated() && !animateZoom && inEditingMode()) {
- didUpdateWebTextViewDimensions(ANYWHERE);
- }
- }
- }
-
- private void drawTextSelectionHandles(Canvas canvas) {
- int[] handles = new int[4];
- getSelectionHandles(handles);
- int start_x = contentToViewDimension(handles[0]);
- int start_y = contentToViewDimension(handles[1]);
- int end_x = contentToViewDimension(handles[2]);
- int end_y = contentToViewDimension(handles[3]);
-
- if (mIsCaretSelection) {
- if (mSelectHandleCenter == null) {
- mSelectHandleCenter = mContext.getResources().getDrawable(
- com.android.internal.R.drawable.text_select_handle_middle);
- }
- // Caret handle is centered
- start_x -= (mSelectHandleCenter.getIntrinsicWidth() / 2);
- mSelectHandleCenter.setBounds(start_x, start_y,
- start_x + mSelectHandleCenter.getIntrinsicWidth(),
- start_y + mSelectHandleCenter.getIntrinsicHeight());
- mSelectHandleCenter.draw(canvas);
- } else {
- if (mSelectHandleLeft == null) {
- mSelectHandleLeft = mContext.getResources().getDrawable(
- com.android.internal.R.drawable.text_select_handle_left);
- }
- // Magic formula copied from TextView
- start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4;
- mSelectHandleLeft.setBounds(start_x, start_y,
- start_x + mSelectHandleLeft.getIntrinsicWidth(),
- start_y + mSelectHandleLeft.getIntrinsicHeight());
- if (mSelectHandleRight == null) {
- mSelectHandleRight = mContext.getResources().getDrawable(
- com.android.internal.R.drawable.text_select_handle_right);
- }
- end_x -= mSelectHandleRight.getIntrinsicWidth() / 4;
- mSelectHandleRight.setBounds(end_x, end_y,
- end_x + mSelectHandleRight.getIntrinsicWidth(),
- end_y + mSelectHandleRight.getIntrinsicHeight());
- mSelectHandleLeft.draw(canvas);
- mSelectHandleRight.draw(canvas);
- }
- }
-
- /**
- * Takes an int[4] array as an output param with the values being
- * startX, startY, endX, endY
- */
- private void getSelectionHandles(int[] handles) {
- handles[0] = mSelectCursorBase.right;
- handles[1] = mSelectCursorBase.bottom -
- (mSelectCursorBase.height() / 4);
- handles[2] = mSelectCursorExtent.left;
- handles[3] = mSelectCursorExtent.bottom
- - (mSelectCursorExtent.height() / 4);
- if (!nativeIsBaseFirst(mNativeClass)) {
- int swap = handles[0];
- handles[0] = handles[2];
- handles[2] = swap;
- swap = handles[1];
- handles[1] = handles[3];
- handles[3] = swap;
- }
- }
-
- // draw history
- private boolean mDrawHistory = false;
- private Picture mHistoryPicture = null;
- private int mHistoryWidth = 0;
- private int mHistoryHeight = 0;
-
- // Only check the flag, can be called from WebCore thread
- boolean drawHistory() {
- return mDrawHistory;
- }
-
- int getHistoryPictureWidth() {
- return (mHistoryPicture != null) ? mHistoryPicture.getWidth() : 0;
- }
-
- // Should only be called in UI thread
- void switchOutDrawHistory() {
- if (null == mWebViewCore) return; // CallbackProxy may trigger this
- if (mDrawHistory && (getProgress() == 100 || nativeHasContent())) {
- mDrawHistory = false;
- mHistoryPicture = null;
- invalidate();
- int oldScrollX = mScrollX;
- int oldScrollY = mScrollY;
- mScrollX = pinLocX(mScrollX);
- mScrollY = pinLocY(mScrollY);
- if (oldScrollX != mScrollX || oldScrollY != mScrollY) {
- onScrollChanged(mScrollX, mScrollY, oldScrollX, oldScrollY);
- } else {
- sendOurVisibleRect();
- }
- }
- }
-
- // TODO: Remove this
- WebViewCore.CursorData cursorData() {
- if (sDisableNavcache) {
- return new WebViewCore.CursorData(0, 0, 0, 0);
- }
- WebViewCore.CursorData result = cursorDataNoPosition();
- Point position = nativeCursorPosition();
- result.mX = position.x;
- result.mY = position.y;
- return result;
- }
-
- WebViewCore.CursorData cursorDataNoPosition() {
- WebViewCore.CursorData result = new WebViewCore.CursorData();
- result.mMoveGeneration = nativeMoveGeneration();
- result.mFrame = nativeCursorFramePointer();
- return result;
- }
-
- /**
- * Delete text from start to end in the focused textfield. If there is no
- * focus, or if start == end, silently fail. If start and end are out of
- * order, swap them.
- * @param start Beginning of selection to delete.
- * @param end End of selection to delete.
- */
- /* package */ void deleteSelection(int start, int end) {
- mTextGeneration++;
- WebViewCore.TextSelectionData data
- = new WebViewCore.TextSelectionData(start, end, 0);
- mWebViewCore.sendMessage(EventHub.DELETE_SELECTION, mTextGeneration, 0,
- data);
- }
-
- /**
- * Set the selection to (start, end) in the focused textfield. If start and
- * end are out of order, swap them.
- * @param start Beginning of selection.
- * @param end End of selection.
- */
- /* package */ void setSelection(int start, int end) {
- if (mWebViewCore != null) {
- mWebViewCore.sendMessage(EventHub.SET_SELECTION, start, end);
- }
- }
-
- @Override
- public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
- if (mInputConnection == null) {
- mInputConnection = new WebViewInputConnection();
- }
- mInputConnection.setupEditorInfo(outAttrs);
- return mInputConnection;
- }
-
- /**
- * Called in response to a message from webkit telling us that the soft
- * keyboard should be launched.
- */
- private void displaySoftKeyboard(boolean isTextView) {
- InputMethodManager imm = (InputMethodManager)
- getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-
- // bring it back to the default level scale so that user can enter text
- boolean zoom = mZoomManager.getScale() < mZoomManager.getDefaultScale();
- if (zoom) {
- mZoomManager.setZoomCenter(mLastTouchX, mLastTouchY);
- mZoomManager.setZoomScale(mZoomManager.getDefaultScale(), false);
- }
- if (isTextView) {
- rebuildWebTextView();
- if (inEditingMode()) {
- imm.showSoftInput(mWebTextView, 0, mWebTextView.getResultReceiver());
- if (zoom) {
- didUpdateWebTextViewDimensions(INTERSECTS_SCREEN);
- }
- return;
- }
- }
- // Used by plugins and contentEditable.
- // Also used if the navigation cache is out of date, and
- // does not recognize that a textfield is in focus. In that
- // case, use WebView as the targeted view.
- // see http://b/issue?id=2457459
- imm.showSoftInput(this, 0);
- }
-
- // Called by WebKit to instruct the UI to hide the keyboard
- private void hideSoftKeyboard() {
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null && (imm.isActive(this)
- || (inEditingMode() && imm.isActive(mWebTextView)))) {
- imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
- }
- }
-
- /*
- * This method checks the current focus and cursor and potentially rebuilds
- * mWebTextView to have the appropriate properties, such as password,
- * multiline, and what text it contains. It also removes it if necessary.
- */
- /* package */ void rebuildWebTextView() {
- if (!sEnableWebTextView) {
- return; // always use WebKit's text entry
- }
- // If the WebView does not have focus, do nothing until it gains focus.
- if (!hasFocus() && (null == mWebTextView || !mWebTextView.hasFocus())) {
- return;
- }
- boolean alreadyThere = inEditingMode();
- // inEditingMode can only return true if mWebTextView is non-null,
- // so we can safely call remove() if (alreadyThere)
- if (0 == mNativeClass || !nativeFocusCandidateIsTextInput()) {
- if (alreadyThere) {
- mWebTextView.remove();
- }
- return;
- }
- // At this point, we know we have found an input field, so go ahead
- // and create the WebTextView if necessary.
- if (mWebTextView == null) {
- mWebTextView = new WebTextView(mContext, WebView.this, mAutoFillData.getQueryId());
- // Initialize our generation number.
- mTextGeneration = 0;
- }
- mWebTextView.updateTextSize();
- updateWebTextViewPosition();
- String text = nativeFocusCandidateText();
- int nodePointer = nativeFocusCandidatePointer();
- // This needs to be called before setType, which may call
- // requestFormData, and it needs to have the correct nodePointer.
- mWebTextView.setNodePointer(nodePointer);
- mWebTextView.setType(nativeFocusCandidateType());
- // Gravity needs to be set after setType
- mWebTextView.setGravityForRtl(nativeFocusCandidateIsRtlText());
- if (null == text) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "rebuildWebTextView null == text");
- }
- text = "";
- }
- mWebTextView.setTextAndKeepSelection(text);
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null && imm.isActive(mWebTextView)) {
- imm.restartInput(mWebTextView);
- mWebTextView.clearComposingText();
- }
- if (isFocused()) {
- mWebTextView.requestFocus();
- }
- }
-
- private void updateWebTextViewPosition() {
- Rect visibleRect = new Rect();
- calcOurContentVisibleRect(visibleRect);
- // Note that sendOurVisibleRect calls viewToContent, so the coordinates
- // should be in content coordinates.
- Rect bounds = nativeFocusCandidateNodeBounds();
- Rect vBox = contentToViewRect(bounds);
- offsetByLayerScrollPosition(vBox);
- mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), vBox.height());
- if (!Rect.intersects(bounds, visibleRect)) {
- revealSelection();
- }
- updateWebTextViewPadding();
- }
-
- /**
- * Update the padding of mWebTextView based on the native textfield/textarea
- */
- void updateWebTextViewPadding() {
- Rect paddingRect = nativeFocusCandidatePaddingRect();
- if (paddingRect != null) {
- // Use contentToViewDimension since these are the dimensions of
- // the padding.
- mWebTextView.setPadding(
- contentToViewDimension(paddingRect.left),
- contentToViewDimension(paddingRect.top),
- contentToViewDimension(paddingRect.right),
- contentToViewDimension(paddingRect.bottom));
- }
- }
-
- /**
- * Tell webkit to put the cursor on screen.
- */
- /* package */ void revealSelection() {
- if (mWebViewCore != null) {
- mWebViewCore.sendMessage(EventHub.REVEAL_SELECTION);
- }
- }
-
- /**
- * Called by WebTextView to find saved form data associated with the
- * textfield
- * @param name Name of the textfield.
- * @param nodePointer Pointer to the node of the textfield, so it can be
- * compared to the currently focused textfield when the data is
- * retrieved.
- * @param autoFillable true if WebKit has determined this field is part of
- * a form that can be auto filled.
- * @param autoComplete true if the attribute "autocomplete" is set to true
- * on the textfield.
- */
- /* package */ void requestFormData(String name, int nodePointer,
- boolean autoFillable, boolean autoComplete) {
- if (mWebViewCore.getSettings().getSaveFormData()) {
- Message update = mPrivateHandler.obtainMessage(REQUEST_FORM_DATA);
- update.arg1 = nodePointer;
- RequestFormData updater = new RequestFormData(name, getUrl(),
- update, autoFillable, autoComplete);
- Thread t = new Thread(updater);
- t.start();
- }
- }
-
- /**
- * Pass a message to find out the <label> associated with the <input>
- * identified by nodePointer
- * @param framePointer Pointer to the frame containing the <input> node
- * @param nodePointer Pointer to the node for which a <label> is desired.
- */
- /* package */ void requestLabel(int framePointer, int nodePointer) {
- mWebViewCore.sendMessage(EventHub.REQUEST_LABEL, framePointer,
- nodePointer);
- }
-
- /*
- * This class requests an Adapter for the WebTextView which shows past
- * entries stored in the database. It is a Runnable so that it can be done
- * in its own thread, without slowing down the UI.
- */
- private class RequestFormData implements Runnable {
- private String mName;
- private String mUrl;
- private Message mUpdateMessage;
- private boolean mAutoFillable;
- private boolean mAutoComplete;
- private WebSettings mWebSettings;
-
- public RequestFormData(String name, String url, Message msg,
- boolean autoFillable, boolean autoComplete) {
- mName = name;
- mUrl = WebTextView.urlForAutoCompleteData(url);
- mUpdateMessage = msg;
- mAutoFillable = autoFillable;
- mAutoComplete = autoComplete;
- mWebSettings = getSettings();
- }
-
- @Override
- public void run() {
- ArrayList<String> pastEntries = new ArrayList<String>();
-
- if (mAutoFillable) {
- // Note that code inside the adapter click handler in WebTextView depends
- // on the AutoFill item being at the top of the drop down list. If you change
- // the order, make sure to do it there too!
- if (mWebSettings != null && mWebSettings.getAutoFillProfile() != null) {
- pastEntries.add(getResources().getText(
- com.android.internal.R.string.autofill_this_form).toString() +
- " " +
- mAutoFillData.getPreviewString());
- mWebTextView.setAutoFillProfileIsSet(true);
- } else {
- // There is no autofill profile set up yet, so add an option that
- // will invite the user to set their profile up.
- pastEntries.add(getResources().getText(
- com.android.internal.R.string.setup_autofill).toString());
- mWebTextView.setAutoFillProfileIsSet(false);
- }
- }
-
- if (mAutoComplete) {
- pastEntries.addAll(mDatabase.getFormData(mUrl, mName));
- }
-
- if (pastEntries.size() > 0) {
- AutoCompleteAdapter adapter = new
- AutoCompleteAdapter(mContext, pastEntries);
- mUpdateMessage.obj = adapter;
- mUpdateMessage.sendToTarget();
- }
- }
- }
-
- /**
- * Dump the display tree to "/sdcard/displayTree.txt"
- *
- * @hide debug only
- */
- public void dumpDisplayTree() {
- nativeDumpDisplayTree(getUrl());
- }
-
- /**
- * Dump the dom tree to adb shell if "toFile" is False, otherwise dump it to
- * "/sdcard/domTree.txt"
- *
- * @hide debug only
- */
- public void dumpDomTree(boolean toFile) {
- mWebViewCore.sendMessage(EventHub.DUMP_DOMTREE, toFile ? 1 : 0, 0);
- }
-
- /**
- * Dump the render tree to adb shell if "toFile" is False, otherwise dump it
- * to "/sdcard/renderTree.txt"
- *
- * @hide debug only
- */
- public void dumpRenderTree(boolean toFile) {
- mWebViewCore.sendMessage(EventHub.DUMP_RENDERTREE, toFile ? 1 : 0, 0);
- }
-
- /**
- * Called by DRT on UI thread, need to proxy to WebCore thread.
- *
- * @hide debug only
- */
- public void useMockDeviceOrientation() {
- mWebViewCore.sendMessage(EventHub.USE_MOCK_DEVICE_ORIENTATION);
- }
-
- /**
- * Called by DRT on WebCore thread.
- *
- * @hide debug only
- */
- public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
- boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
- mWebViewCore.setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta,
- canProvideGamma, gamma);
- }
-
- // This is used to determine long press with the center key. Does not
- // affect long press with the trackball/touch.
- private boolean mGotCenterDown = false;
-
- @Override
- public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
- if (mBlockWebkitViewMessages) {
- return false;
- }
- // send complex characters to webkit for use by JS and plugins
- if (keyCode == KeyEvent.KEYCODE_UNKNOWN && event.getCharacters() != null) {
- // pass the key to DOM
- mWebViewCore.sendMessage(EventHub.KEY_DOWN, event);
- mWebViewCore.sendMessage(EventHub.KEY_UP, event);
- // return true as DOM handles the key
- return true;
- }
- return false;
- }
-
- private boolean isEnterActionKey(int keyCode) {
- return keyCode == KeyEvent.KEYCODE_DPAD_CENTER
- || keyCode == KeyEvent.KEYCODE_ENTER
- || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER;
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "keyDown at " + System.currentTimeMillis()
- + "keyCode=" + keyCode
- + ", " + event + ", unicode=" + event.getUnicodeChar());
- }
- if (mIsCaretSelection) {
- selectionDone();
- }
- if (mBlockWebkitViewMessages) {
- return false;
- }
-
- // don't implement accelerator keys here; defer to host application
- if (event.isCtrlPressed()) {
- return false;
- }
-
- if (mNativeClass == 0) {
- return false;
- }
-
- // do this hack up front, so it always works, regardless of touch-mode
- if (AUTO_REDRAW_HACK && (keyCode == KeyEvent.KEYCODE_CALL)) {
- mAutoRedraw = !mAutoRedraw;
- if (mAutoRedraw) {
- invalidate();
- }
- return true;
- }
-
- // Bubble up the key event if
- // 1. it is a system key; or
- // 2. the host application wants to handle it;
- if (event.isSystem()
- || mCallbackProxy.uiOverrideKeyEvent(event)) {
- return false;
- }
-
- // accessibility support
- if (accessibilityScriptInjected()) {
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
- // if an accessibility script is injected we delegate to it the key handling.
- // this script is a screen reader which is a fully fledged solution for blind
- // users to navigate in and interact with web pages.
- mWebViewCore.sendMessage(EventHub.KEY_DOWN, event);
- return true;
- } else {
- // Clean up if accessibility was disabled after loading the current URL.
- mAccessibilityScriptInjected = false;
- }
- } else if (mAccessibilityInjector != null) {
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
- if (mAccessibilityInjector.onKeyEvent(event)) {
- // if an accessibility injector is present (no JavaScript enabled or the site
- // opts out injecting our JavaScript screen reader) we let it decide whether
- // to act on and consume the event.
- return true;
- }
- } else {
- // Clean up if accessibility was disabled after loading the current URL.
- mAccessibilityInjector = null;
- }
- }
-
- if (keyCode == KeyEvent.KEYCODE_PAGE_UP) {
- if (event.hasNoModifiers()) {
- pageUp(false);
- return true;
- } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
- pageUp(true);
- return true;
- }
- }
-
- if (keyCode == KeyEvent.KEYCODE_PAGE_DOWN) {
- if (event.hasNoModifiers()) {
- pageDown(false);
- return true;
- } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
- pageDown(true);
- return true;
- }
- }
-
- if (keyCode == KeyEvent.KEYCODE_MOVE_HOME && event.hasNoModifiers()) {
- pageUp(true);
- return true;
- }
-
- if (keyCode == KeyEvent.KEYCODE_MOVE_END && event.hasNoModifiers()) {
- pageDown(true);
- return true;
- }
-
- if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
- && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
- switchOutDrawHistory();
- if (nativePageShouldHandleShiftAndArrows()) {
- letPageHandleNavKey(keyCode, event.getEventTime(), true, event.getMetaState());
- return true;
- }
- if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_UP:
- pageUp(true);
- return true;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- pageDown(true);
- return true;
- case KeyEvent.KEYCODE_DPAD_LEFT:
- nativeClearCursor(); // start next trackball movement from page edge
- return pinScrollTo(0, mScrollY, true, 0);
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- nativeClearCursor(); // start next trackball movement from page edge
- return pinScrollTo(mContentWidth, mScrollY, true, 0);
- }
- }
- if (navHandledKey(keyCode, 1, false, event.getEventTime())) {
- playSoundEffect(keyCodeToSoundsEffect(keyCode));
- return true;
- }
- // Bubble up the key event as WebView doesn't handle it
- return false;
- }
-
- if (isEnterActionKey(keyCode)) {
- switchOutDrawHistory();
- boolean wantsKeyEvents = nativeCursorNodePointer() == 0
- || nativeCursorWantsKeyEvents();
- if (event.getRepeatCount() == 0) {
- if (mSelectingText) {
- return true; // discard press if copy in progress
- }
- mGotCenterDown = true;
- mPrivateHandler.sendMessageDelayed(mPrivateHandler
- .obtainMessage(LONG_PRESS_CENTER), LONG_PRESS_TIMEOUT);
- if (!wantsKeyEvents) return true;
- }
- // Bubble up the key event as WebView doesn't handle it
- if (!wantsKeyEvents) return false;
- }
-
- if (getSettings().getNavDump()) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_4:
- dumpDisplayTree();
- break;
- case KeyEvent.KEYCODE_5:
- case KeyEvent.KEYCODE_6:
- dumpDomTree(keyCode == KeyEvent.KEYCODE_5);
- break;
- case KeyEvent.KEYCODE_7:
- case KeyEvent.KEYCODE_8:
- dumpRenderTree(keyCode == KeyEvent.KEYCODE_7);
- break;
- }
- }
-
- if (nativeCursorIsTextInput()) {
- // This message will put the node in focus, for the DOM's notion
- // of focus.
- mWebViewCore.sendMessage(EventHub.FAKE_CLICK, nativeCursorFramePointer(),
- nativeCursorNodePointer());
- // This will bring up the WebTextView and put it in focus, for
- // our view system's notion of focus
- rebuildWebTextView();
- // Now we need to pass the event to it
- if (inEditingMode()) {
- mWebTextView.setDefaultSelection();
- return mWebTextView.dispatchKeyEvent(event);
- }
- } else if (nativeHasFocusNode()) {
- // In this case, the cursor is not on a text input, but the focus
- // might be. Check it, and if so, hand over to the WebTextView.
- rebuildWebTextView();
- if (inEditingMode()) {
- mWebTextView.setDefaultSelection();
- return mWebTextView.dispatchKeyEvent(event);
- }
- }
-
- // TODO: should we pass all the keys to DOM or check the meta tag
- if (nativeCursorWantsKeyEvents() || true) {
- // pass the key to DOM
- mWebViewCore.sendMessage(EventHub.KEY_DOWN, event);
- // return true as DOM handles the key
- return true;
- }
-
- // Bubble up the key event as WebView doesn't handle it
- return false;
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "keyUp at " + System.currentTimeMillis()
- + ", " + event + ", unicode=" + event.getUnicodeChar());
- }
- if (mBlockWebkitViewMessages) {
- return false;
- }
-
- if (mNativeClass == 0) {
- return false;
- }
-
- // special CALL handling when cursor node's href is "tel:XXX"
- if (keyCode == KeyEvent.KEYCODE_CALL && nativeHasCursorNode()) {
- String text = nativeCursorText();
- if (!nativeCursorIsTextInput() && text != null
- && text.startsWith(SCHEME_TEL)) {
- Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(text));
- getContext().startActivity(intent);
- return true;
- }
- }
-
- // Bubble up the key event if
- // 1. it is a system key; or
- // 2. the host application wants to handle it;
- if (event.isSystem()
- || mCallbackProxy.uiOverrideKeyEvent(event)) {
- return false;
- }
-
- // accessibility support
- if (accessibilityScriptInjected()) {
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
- // if an accessibility script is injected we delegate to it the key handling.
- // this script is a screen reader which is a fully fledged solution for blind
- // users to navigate in and interact with web pages.
- mWebViewCore.sendMessage(EventHub.KEY_UP, event);
- return true;
- } else {
- // Clean up if accessibility was disabled after loading the current URL.
- mAccessibilityScriptInjected = false;
- }
- } else if (mAccessibilityInjector != null) {
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
- if (mAccessibilityInjector.onKeyEvent(event)) {
- // if an accessibility injector is present (no JavaScript enabled or the site
- // opts out injecting our JavaScript screen reader) we let it decide whether to
- // act on and consume the event.
- return true;
- }
- } else {
- // Clean up if accessibility was disabled after loading the current URL.
- mAccessibilityInjector = null;
- }
- }
-
- if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
- && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
- if (nativePageShouldHandleShiftAndArrows()) {
- letPageHandleNavKey(keyCode, event.getEventTime(), false, event.getMetaState());
- return true;
- }
- // always handle the navigation keys in the UI thread
- // Bubble up the key event as WebView doesn't handle it
- return false;
- }
-
- if (isEnterActionKey(keyCode)) {
- // remove the long press message first
- mPrivateHandler.removeMessages(LONG_PRESS_CENTER);
- mGotCenterDown = false;
-
- if (mSelectingText) {
- copySelection();
- selectionDone();
- return true; // discard press if copy in progress
- }
-
- if (!sDisableNavcache) {
- // perform the single click
- Rect visibleRect = sendOurVisibleRect();
- // Note that sendOurVisibleRect calls viewToContent, so the
- // coordinates should be in content coordinates.
- if (!nativeCursorIntersects(visibleRect)) {
- return false;
- }
- WebViewCore.CursorData data = cursorData();
- mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE, data);
- playSoundEffect(SoundEffectConstants.CLICK);
- if (nativeCursorIsTextInput()) {
- rebuildWebTextView();
- centerKeyPressOnTextField();
- if (inEditingMode()) {
- mWebTextView.setDefaultSelection();
- }
- return true;
- }
- clearTextEntry();
- nativeShowCursorTimed();
- if (mCallbackProxy.uiOverrideUrlLoading(nativeCursorText())) {
- return true;
- }
- if (nativeCursorNodePointer() != 0 && !nativeCursorWantsKeyEvents()) {
- mWebViewCore.sendMessage(EventHub.CLICK, data.mFrame,
- nativeCursorNodePointer());
- return true;
- }
- }
- }
-
- // TODO: should we pass all the keys to DOM or check the meta tag
- if (nativeCursorWantsKeyEvents() || true) {
- // pass the key to DOM
- mWebViewCore.sendMessage(EventHub.KEY_UP, event);
- // return true as DOM handles the key
- return true;
- }
-
- // Bubble up the key event as WebView doesn't handle it
- return false;
- }
-
- private boolean startSelectActionMode() {
- mSelectCallback = new SelectActionModeCallback();
- mSelectCallback.setTextSelected(!mIsCaretSelection);
- mSelectCallback.setWebView(this);
- if (startActionMode(mSelectCallback) == null) {
- // There is no ActionMode, so do not allow the user to modify a
- // selection.
- selectionDone();
- return false;
- }
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- return true;
- }
-
- private void showPasteWindow() {
- ClipboardManager cm = (ClipboardManager)(mContext
- .getSystemService(Context.CLIPBOARD_SERVICE));
- if (cm.hasPrimaryClip()) {
- Rect cursorRect = contentToViewRect(mSelectCursorBase);
- int[] location = new int[2];
- getLocationInWindow(location);
- cursorRect.offset(location[0] - mScrollX, location[1] - mScrollY);
- if (mPasteWindow == null) {
- mPasteWindow = new PastePopupWindow();
- }
- mPasteWindow.show(cursorRect, location[0], location[1]);
- }
- }
-
- private void hidePasteButton() {
- if (mPasteWindow != null) {
- mPasteWindow.hide();
- }
- }
-
- private void syncSelectionCursors() {
- mSelectCursorBaseLayerId =
- nativeGetHandleLayerId(mNativeClass, HANDLE_ID_BASE, mSelectCursorBase);
- mSelectCursorExtentLayerId =
- nativeGetHandleLayerId(mNativeClass, HANDLE_ID_EXTENT, mSelectCursorExtent);
- }
-
- private boolean setupWebkitSelect() {
- syncSelectionCursors();
- if (mIsCaretSelection) {
- showPasteWindow();
- } else if (!startSelectActionMode()) {
- selectionDone();
- return false;
- }
- mSelectingText = true;
- mTouchMode = TOUCH_DRAG_MODE;
- return true;
- }
-
- private void updateWebkitSelection() {
- int[] handles = null;
- if (mIsCaretSelection) {
- mSelectCursorExtent.set(mSelectCursorBase);
- }
- if (mSelectingText) {
- handles = new int[4];
- handles[0] = mSelectCursorBase.centerX();
- handles[1] = mSelectCursorBase.centerY();
- handles[2] = mSelectCursorExtent.centerX();
- handles[3] = mSelectCursorExtent.centerY();
- } else {
- nativeSetTextSelection(mNativeClass, 0);
- }
- mWebViewCore.removeMessages(EventHub.SELECT_TEXT);
- mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SELECT_TEXT, handles);
- }
-
- private void resetCaretTimer() {
- mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
- if (!mSelectionStarted) {
- mPrivateHandler.sendEmptyMessageDelayed(CLEAR_CARET_HANDLE,
- CARET_HANDLE_STAMINA_MS);
- }
- }
-
/**
* Use this method to put the WebView into text selection mode.
* Do not rely on this functionality; it will be deprecated in the future.
@@ -6149,165 +1433,7 @@ public class WebView extends AbsoluteLayout
@Deprecated
public void emulateShiftHeld() {
checkThread();
- }
-
- /**
- * Select all of the text in this WebView.
- *
- * @hide This is an implementation detail.
- */
- public void selectAll() {
- mWebViewCore.sendMessage(EventHub.SELECT_ALL);
- }
-
- /**
- * Called when the selection has been removed.
- */
- void selectionDone() {
- if (mSelectingText) {
- hidePasteButton();
- mSelectingText = false;
- // finish is idempotent, so this is fine even if selectionDone was
- // called by mSelectCallback.onDestroyActionMode
- if (mSelectCallback != null) {
- mSelectCallback.finish();
- mSelectCallback = null;
- }
- if (!mIsCaretSelection) {
- updateWebkitSelection();
- }
- mIsCaretSelection = false;
- invalidate(); // redraw without selection
- mAutoScrollX = 0;
- mAutoScrollY = 0;
- mSentAutoScrollMessage = false;
- }
- }
-
- /**
- * Copy the selection to the clipboard
- *
- * @hide This is an implementation detail.
- */
- public boolean copySelection() {
- boolean copiedSomething = false;
- String selection = getSelection();
- if (selection != null && selection != "") {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "copySelection \"" + selection + "\"");
- }
- Toast.makeText(mContext
- , com.android.internal.R.string.text_copied
- , Toast.LENGTH_SHORT).show();
- copiedSomething = true;
- ClipboardManager cm = (ClipboardManager)getContext()
- .getSystemService(Context.CLIPBOARD_SERVICE);
- cm.setText(selection);
- int[] handles = new int[4];
- getSelectionHandles(handles);
- mWebViewCore.sendMessage(EventHub.COPY_TEXT, handles);
- }
- invalidate(); // remove selection region and pointer
- return copiedSomething;
- }
-
- /**
- * Cut the selected text into the clipboard
- *
- * @hide This is an implementation detail
- */
- public void cutSelection() {
- copySelection();
- int[] handles = new int[4];
- getSelectionHandles(handles);
- mWebViewCore.sendMessage(EventHub.DELETE_TEXT, handles);
- }
-
- /**
- * Paste text from the clipboard to the cursor position.
- *
- * @hide This is an implementation detail
- */
- public void pasteFromClipboard() {
- ClipboardManager cm = (ClipboardManager)getContext()
- .getSystemService(Context.CLIPBOARD_SERVICE);
- ClipData clipData = cm.getPrimaryClip();
- if (clipData != null) {
- ClipData.Item clipItem = clipData.getItemAt(0);
- CharSequence pasteText = clipItem.getText();
- if (mInputConnection != null) {
- mInputConnection.replaceSelection(pasteText);
- }
- }
- }
-
- /**
- * @hide This is an implementation detail.
- */
- public SearchBox getSearchBox() {
- if ((mWebViewCore == null) || (mWebViewCore.getBrowserFrame() == null)) {
- return null;
- }
- return mWebViewCore.getBrowserFrame().getSearchBox();
- }
-
- /**
- * Returns the currently highlighted text as a string.
- */
- String getSelection() {
- if (mNativeClass == 0) return "";
- return nativeGetSelection();
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- if (hasWindowFocus()) setActive(true);
- final ViewTreeObserver treeObserver = getViewTreeObserver();
- if (mGlobalLayoutListener == null) {
- mGlobalLayoutListener = new InnerGlobalLayoutListener();
- treeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener);
- }
- if (mScrollChangedListener == null) {
- mScrollChangedListener = new InnerScrollChangedListener();
- treeObserver.addOnScrollChangedListener(mScrollChangedListener);
- }
-
- addAccessibilityApisToJavaScript();
-
- mTouchEventQueue.reset();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- clearHelpers();
- mZoomManager.dismissZoomPicker();
- if (hasWindowFocus()) setActive(false);
-
- final ViewTreeObserver treeObserver = getViewTreeObserver();
- if (mGlobalLayoutListener != null) {
- treeObserver.removeGlobalOnLayoutListener(mGlobalLayoutListener);
- mGlobalLayoutListener = null;
- }
- if (mScrollChangedListener != null) {
- treeObserver.removeOnScrollChangedListener(mScrollChangedListener);
- mScrollChangedListener = null;
- }
-
- removeAccessibilityApisFromJavaScript();
-
- super.onDetachedFromWindow();
- }
-
- @Override
- protected void onVisibilityChanged(View changedView, int visibility) {
- super.onVisibilityChanged(changedView, visibility);
- // The zoomManager may be null if the webview is created from XML that
- // specifies the view's visibility param as not visible (see http://b/2794841)
- if (visibility != View.VISIBLE && mZoomManager != null) {
- mZoomManager.dismissZoomPicker();
- }
- updateDrawingState();
+ mProvider.emulateShiftHeld();
}
/**
@@ -6338,1571 +1464,15 @@ public class WebView extends AbsoluteLayout
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
}
- void setActive(boolean active) {
- if (active) {
- if (hasFocus()) {
- // If our window regained focus, and we have focus, then begin
- // drawing the cursor ring
- mDrawCursorRing = !inEditingMode();
- setFocusControllerActive(true);
- } else {
- mDrawCursorRing = false;
- if (!inEditingMode()) {
- // If our window gained focus, but we do not have it, do not
- // draw the cursor ring.
- setFocusControllerActive(false);
- }
- // We do not call recordButtons here because we assume
- // that when we lost focus, or window focus, it got called with
- // false for the first parameter
- }
- } else {
- if (!mZoomManager.isZoomPickerVisible()) {
- /*
- * The external zoom controls come in their own window, so our
- * window loses focus. Our policy is to not draw the cursor ring
- * if our window is not focused, but this is an exception since
- * the user can still navigate the web page with the zoom
- * controls showing.
- */
- mDrawCursorRing = false;
- }
- mKeysPressed.clear();
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- mTouchMode = TOUCH_DONE_MODE;
- setFocusControllerActive(false);
- }
- invalidate();
- }
-
- // To avoid drawing the cursor ring, and remove the TextView when our window
- // loses focus.
- @Override
- public void onWindowFocusChanged(boolean hasWindowFocus) {
- setActive(hasWindowFocus);
- if (hasWindowFocus) {
- JWebCoreJavaBridge.setActiveWebView(this);
- if (mPictureUpdatePausedForFocusChange) {
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- mPictureUpdatePausedForFocusChange = false;
- }
- } else {
- JWebCoreJavaBridge.removeActiveWebView(this);
- final WebSettings settings = getSettings();
- if (settings != null && settings.enableSmoothTransition() &&
- mWebViewCore != null && !WebViewCore.isUpdatePicturePaused(mWebViewCore)) {
- WebViewCore.pauseUpdatePicture(mWebViewCore);
- mPictureUpdatePausedForFocusChange = true;
- }
- }
- super.onWindowFocusChanged(hasWindowFocus);
- }
-
- /*
- * Pass a message to WebCore Thread, telling the WebCore::Page's
- * FocusController to be "inactive" so that it will
- * not draw the blinking cursor. It gets set to "active" to draw the cursor
- * in WebViewCore.cpp, when the WebCore thread receives key events/clicks.
- */
- /* package */ void setFocusControllerActive(boolean active) {
- if (mWebViewCore == null) return;
- mWebViewCore.sendMessage(EventHub.SET_ACTIVE, active ? 1 : 0, 0);
- // Need to send this message after the document regains focus.
- if (active && mListBoxMessage != null) {
- mWebViewCore.sendMessage(mListBoxMessage);
- mListBoxMessage = null;
- }
- }
-
- @Override
- protected void onFocusChanged(boolean focused, int direction,
- Rect previouslyFocusedRect) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "MT focusChanged " + focused + ", " + direction);
- }
- if (focused) {
- // When we regain focus, if we have window focus, resume drawing
- // the cursor ring
- if (hasWindowFocus()) {
- mDrawCursorRing = !inEditingMode();
- setFocusControllerActive(true);
- //} else {
- // The WebView has gained focus while we do not have
- // windowfocus. When our window lost focus, we should have
- // called recordButtons(false...)
- }
- } else {
- // When we lost focus, unless focus went to the TextView (which is
- // true if we are in editing mode), stop drawing the cursor ring.
- mDrawCursorRing = false;
- if (!inEditingMode()) {
- setFocusControllerActive(false);
- }
- mKeysPressed.clear();
- }
-
- super.onFocusChanged(focused, direction, previouslyFocusedRect);
- }
-
- void setGLRectViewport() {
- // Use the getGlobalVisibleRect() to get the intersection among the parents
- // visible == false means we're clipped - send a null rect down to indicate that
- // we should not draw
- boolean visible = getGlobalVisibleRect(mGLRectViewport);
- if (visible) {
- // Then need to invert the Y axis, just for GL
- View rootView = getRootView();
- int rootViewHeight = rootView.getHeight();
- mViewRectViewport.set(mGLRectViewport);
- int savedWebViewBottom = mGLRectViewport.bottom;
- mGLRectViewport.bottom = rootViewHeight - mGLRectViewport.top - getVisibleTitleHeightImpl();
- mGLRectViewport.top = rootViewHeight - savedWebViewBottom;
- mGLViewportEmpty = false;
- } else {
- mGLViewportEmpty = true;
- }
- calcOurContentVisibleRectF(mVisibleContentRect);
- nativeUpdateDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport,
- mGLViewportEmpty ? null : mViewRectViewport,
- mVisibleContentRect, getScale());
- }
-
- /**
- * @hide
- */
- @Override
- protected boolean setFrame(int left, int top, int right, int bottom) {
- boolean changed = super.setFrame(left, top, right, bottom);
- if (!changed && mHeightCanMeasure) {
- // When mHeightCanMeasure is true, we will set mLastHeightSent to 0
- // in WebViewCore after we get the first layout. We do call
- // requestLayout() when we get contentSizeChanged(). But the View
- // system won't call onSizeChanged if the dimension is not changed.
- // In this case, we need to call sendViewSizeZoom() explicitly to
- // notify the WebKit about the new dimensions.
- sendViewSizeZoom(false);
- }
- setGLRectViewport();
- return changed;
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int ow, int oh) {
- super.onSizeChanged(w, h, ow, oh);
-
- // adjust the max viewport width depending on the view dimensions. This
- // is to ensure the scaling is not going insane. So do not shrink it if
- // the view size is temporarily smaller, e.g. when soft keyboard is up.
- int newMaxViewportWidth = (int) (Math.max(w, h) / mZoomManager.getDefaultMinZoomScale());
- if (newMaxViewportWidth > sMaxViewportWidth) {
- sMaxViewportWidth = newMaxViewportWidth;
- }
-
- mZoomManager.onSizeChanged(w, h, ow, oh);
-
- if (mLoadedPicture != null && mDelaySetPicture == null) {
- // Size changes normally result in a new picture
- // Re-set the loaded picture to simulate that
- // However, do not update the base layer as that hasn't changed
- setNewPicture(mLoadedPicture, false);
- }
- }
-
- @Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- super.onScrollChanged(l, t, oldl, oldt);
- if (!mInOverScrollMode) {
- sendOurVisibleRect();
- // update WebKit if visible title bar height changed. The logic is same
- // as getVisibleTitleHeightImpl.
- int titleHeight = getTitleHeight();
- if (Math.max(titleHeight - t, 0) != Math.max(titleHeight - oldt, 0)) {
- sendViewSizeZoom(false);
- }
- }
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- switch (event.getAction()) {
- case KeyEvent.ACTION_DOWN:
- mKeysPressed.add(Integer.valueOf(event.getKeyCode()));
- break;
- case KeyEvent.ACTION_MULTIPLE:
- // Always accept the action.
- break;
- case KeyEvent.ACTION_UP:
- int location = mKeysPressed.indexOf(Integer.valueOf(event.getKeyCode()));
- if (location == -1) {
- // We did not receive the key down for this key, so do not
- // handle the key up.
- return false;
- } else {
- // We did receive the key down. Handle the key up, and
- // remove it from our pressed keys.
- mKeysPressed.remove(location);
- }
- break;
- default:
- // Accept the action. This should not happen, unless a new
- // action is added to KeyEvent.
- break;
- }
- if (inEditingMode() && mWebTextView.isFocused()) {
- // Ensure that the WebTextView gets the event, even if it does
- // not currently have a bounds.
- return mWebTextView.dispatchKeyEvent(event);
- } else {
- return super.dispatchKeyEvent(event);
- }
- }
-
- /*
- * Here is the snap align logic:
- * 1. If it starts nearly horizontally or vertically, snap align;
- * 2. If there is a dramitic direction change, let it go;
- *
- * Adjustable parameters. Angle is the radians on a unit circle, limited
- * to quadrant 1. Values range from 0f (horizontal) to PI/2 (vertical)
- */
- private static final float HSLOPE_TO_START_SNAP = .25f;
- private static final float HSLOPE_TO_BREAK_SNAP = .4f;
- private static final float VSLOPE_TO_START_SNAP = 1.25f;
- private static final float VSLOPE_TO_BREAK_SNAP = .95f;
- /*
- * These values are used to influence the average angle when entering
- * snap mode. If is is the first movement entering snap, we set the average
- * to the appropriate ideal. If the user is entering into snap after the
- * first movement, then we average the average angle with these values.
- */
- private static final float ANGLE_VERT = 2f;
- private static final float ANGLE_HORIZ = 0f;
- /*
- * The modified moving average weight.
- * Formula: MAV[t]=MAV[t-1] + (P[t]-MAV[t-1])/n
- */
- private static final float MMA_WEIGHT_N = 5;
-
- private boolean hitFocusedPlugin(int contentX, int contentY) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "nativeFocusIsPlugin()=" + nativeFocusIsPlugin());
- Rect r = nativeFocusNodeBounds();
- Log.v(LOGTAG, "nativeFocusNodeBounds()=(" + r.left + ", " + r.top
- + ", " + r.right + ", " + r.bottom + ")");
- }
- return nativeFocusIsPlugin()
- && nativeFocusNodeBounds().contains(contentX, contentY);
- }
-
- private boolean shouldForwardTouchEvent() {
- if (mFullScreenHolder != null) return true;
- if (mBlockWebkitViewMessages) return false;
- return mForwardTouchEvents
- && !mSelectingText
- && mPreventDefault != PREVENT_DEFAULT_IGNORE
- && mPreventDefault != PREVENT_DEFAULT_NO;
- }
-
- private boolean inFullScreenMode() {
- return mFullScreenHolder != null;
- }
-
- private void dismissFullScreenMode() {
- if (inFullScreenMode()) {
- mFullScreenHolder.hide();
- mFullScreenHolder = null;
- invalidate();
- }
- }
-
- void onPinchToZoomAnimationStart() {
- // cancel the single touch handling
- cancelTouch();
- onZoomAnimationStart();
- }
-
- void onPinchToZoomAnimationEnd(ScaleGestureDetector detector) {
- onZoomAnimationEnd();
- // start a drag, TOUCH_PINCH_DRAG, can't use TOUCH_INIT_MODE as
- // it may trigger the unwanted click, can't use TOUCH_DRAG_MODE
- // as it may trigger the unwanted fling.
- mTouchMode = TOUCH_PINCH_DRAG;
- mConfirmMove = true;
- startTouch(detector.getFocusX(), detector.getFocusY(), mLastTouchTime);
- }
-
- // See if there is a layer at x, y and switch to TOUCH_DRAG_LAYER_MODE if a
- // layer is found.
- private void startScrollingLayer(float x, float y) {
- int contentX = viewToContentX((int) x + mScrollX);
- int contentY = viewToContentY((int) y + mScrollY);
- mCurrentScrollingLayerId = nativeScrollableLayer(contentX, contentY,
- mScrollingLayerRect, mScrollingLayerBounds);
- if (mCurrentScrollingLayerId != 0) {
- mTouchMode = TOUCH_DRAG_LAYER_MODE;
- }
- }
-
- // 1/(density * density) used to compute the distance between points.
- // Computed in init().
- private float DRAG_LAYER_INVERSE_DENSITY_SQUARED;
-
- // The distance between two points reported in onTouchEvent scaled by the
- // density of the screen.
- private static final int DRAG_LAYER_FINGER_DISTANCE = 20000;
-
- @Override
- public boolean onHoverEvent(MotionEvent event) {
- if (mNativeClass == 0) {
- return false;
- }
- WebViewCore.CursorData data = cursorDataNoPosition();
- data.mX = viewToContentX((int) event.getX() + mScrollX);
- data.mY = viewToContentY((int) event.getY() + mScrollY);
- mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE, data);
- return true;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (mNativeClass == 0 || (!isClickable() && !isLongClickable())) {
- return false;
- }
-
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, ev + " at " + ev.getEventTime()
- + " mTouchMode=" + mTouchMode
- + " numPointers=" + ev.getPointerCount());
- }
-
- // If WebKit wasn't interested in this multitouch gesture, enqueue
- // the event for handling directly rather than making the round trip
- // to WebKit and back.
- if (ev.getPointerCount() > 1 && mPreventDefault != PREVENT_DEFAULT_NO) {
- passMultiTouchToWebKit(ev, mTouchEventQueue.nextTouchSequence());
- } else {
- mTouchEventQueue.enqueueTouchEvent(ev);
- }
-
- // Since all events are handled asynchronously, we always want the gesture stream.
- return true;
- }
-
- private float calculateDragAngle(int dx, int dy) {
- dx = Math.abs(dx);
- dy = Math.abs(dy);
- return (float) Math.atan2(dy, dx);
- }
-
- /*
- * Common code for single touch and multi-touch.
- * (x, y) denotes current focus point, which is the touch point for single touch
- * and the middle point for multi-touch.
- */
- private boolean handleTouchEventCommon(MotionEvent ev, int action, int x, int y) {
- long eventTime = ev.getEventTime();
-
- // Due to the touch screen edge effect, a touch closer to the edge
- // always snapped to the edge. As getViewWidth() can be different from
- // getWidth() due to the scrollbar, adjusting the point to match
- // getViewWidth(). Same applied to the height.
- x = Math.min(x, getViewWidth() - 1);
- y = Math.min(y, getViewHeightWithTitle() - 1);
-
- int deltaX = mLastTouchX - x;
- int deltaY = mLastTouchY - y;
- int contentX = viewToContentX(x + mScrollX);
- int contentY = viewToContentY(y + mScrollY);
-
- switch (action) {
- case MotionEvent.ACTION_DOWN: {
- mPreventDefault = PREVENT_DEFAULT_NO;
- mConfirmMove = false;
- mInitialHitTestResult = null;
- if (!mScroller.isFinished()) {
- // stop the current scroll animation, but if this is
- // the start of a fling, allow it to add to the current
- // fling's velocity
- mScroller.abortAnimation();
- mTouchMode = TOUCH_DRAG_START_MODE;
- mConfirmMove = true;
- nativeSetIsScrolling(false);
- } else if (mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) {
- mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
- if (sDisableNavcache) {
- removeTouchHighlight();
- }
- if (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare) {
- mTouchMode = TOUCH_DOUBLE_TAP_MODE;
- } else {
- // commit the short press action for the previous tap
- doShortPress();
- mTouchMode = TOUCH_INIT_MODE;
- mDeferTouchProcess = !mBlockWebkitViewMessages
- && (!inFullScreenMode() && mForwardTouchEvents)
- ? hitFocusedPlugin(contentX, contentY)
- : false;
- }
- } else { // the normal case
- mTouchMode = TOUCH_INIT_MODE;
- mDeferTouchProcess = !mBlockWebkitViewMessages
- && (!inFullScreenMode() && mForwardTouchEvents)
- ? hitFocusedPlugin(contentX, contentY)
- : false;
- if (!mBlockWebkitViewMessages) {
- mWebViewCore.sendMessage(
- EventHub.UPDATE_FRAME_CACHE_IF_LOADING);
- }
- if (sDisableNavcache) {
- TouchHighlightData data = new TouchHighlightData();
- data.mX = contentX;
- data.mY = contentY;
- data.mNativeLayerRect = new Rect();
- data.mNativeLayer = nativeScrollableLayer(
- contentX, contentY, data.mNativeLayerRect, null);
- data.mSlop = viewToContentDimension(mNavSlop);
- mTouchHighlightRegion.setEmpty();
- if (!mBlockWebkitViewMessages) {
- mTouchHighlightRequested = System.currentTimeMillis();
- mWebViewCore.sendMessageAtFrontOfQueue(
- EventHub.HIT_TEST, data);
- }
- if (DEBUG_TOUCH_HIGHLIGHT) {
- if (getSettings().getNavDump()) {
- mTouchHighlightX = x + mScrollX;
- mTouchHighlightY = y + mScrollY;
- mPrivateHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mTouchHighlightX = mTouchHighlightY = 0;
- invalidate();
- }
- }, TOUCH_HIGHLIGHT_ELAPSE_TIME);
- }
- }
- }
- if (mLogEvent && eventTime - mLastTouchUpTime < 1000) {
- EventLog.writeEvent(EventLogTags.BROWSER_DOUBLE_TAP_DURATION,
- (eventTime - mLastTouchUpTime), eventTime);
- }
- mSelectionStarted = false;
- if (mSelectingText) {
- int shiftedY = y - getTitleHeight() + mScrollY;
- int shiftedX = x + mScrollX;
- if (mSelectHandleCenter != null && mSelectHandleCenter.getBounds()
- .contains(shiftedX, shiftedY)) {
- mSelectionStarted = true;
- mSelectDraggingCursor = mSelectCursorBase;
- mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
- hidePasteButton();
- } else if (mSelectHandleLeft != null
- && mSelectHandleLeft.getBounds()
- .contains(shiftedX, shiftedY)) {
- mSelectionStarted = true;
- mSelectDraggingCursor = mSelectCursorBase;
- } else if (mSelectHandleRight != null
- && mSelectHandleRight.getBounds()
- .contains(shiftedX, shiftedY)) {
- mSelectionStarted = true;
- mSelectDraggingCursor = mSelectCursorExtent;
- } else if (mIsCaretSelection) {
- selectionDone();
- }
- if (mSelectDraggingCursor != null) {
- mSelectDraggingOffset.set(
- mSelectDraggingCursor.left - contentX,
- mSelectDraggingCursor.top - contentY);
- }
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "select=" + contentX + "," + contentY);
- }
- }
- }
- // Trigger the link
- if (!mSelectingText && (mTouchMode == TOUCH_INIT_MODE
- || mTouchMode == TOUCH_DOUBLE_TAP_MODE)) {
- mPrivateHandler.sendEmptyMessageDelayed(
- SWITCH_TO_SHORTPRESS, TAP_TIMEOUT);
- mPrivateHandler.sendEmptyMessageDelayed(
- SWITCH_TO_LONGPRESS, LONG_PRESS_TIMEOUT);
- if (inFullScreenMode() || mDeferTouchProcess) {
- mPreventDefault = PREVENT_DEFAULT_YES;
- } else if (!mBlockWebkitViewMessages && mForwardTouchEvents) {
- mPreventDefault = PREVENT_DEFAULT_MAYBE_YES;
- } else {
- mPreventDefault = PREVENT_DEFAULT_NO;
- }
- // pass the touch events from UI thread to WebCore thread
- if (shouldForwardTouchEvent()) {
- TouchEventData ted = new TouchEventData();
- ted.mAction = action;
- ted.mIds = new int[1];
- ted.mIds[0] = ev.getPointerId(0);
- ted.mPoints = new Point[1];
- ted.mPoints[0] = new Point(contentX, contentY);
- ted.mPointsInView = new Point[1];
- ted.mPointsInView[0] = new Point(x, y);
- ted.mMetaState = ev.getMetaState();
- ted.mReprocess = mDeferTouchProcess;
- ted.mNativeLayer = nativeScrollableLayer(
- contentX, contentY, ted.mNativeLayerRect, null);
- ted.mSequence = mTouchEventQueue.nextTouchSequence();
- mTouchEventQueue.preQueueTouchEventData(ted);
- mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
- if (mDeferTouchProcess) {
- // still needs to set them for compute deltaX/Y
- mLastTouchX = x;
- mLastTouchY = y;
- break;
- }
- if (!inFullScreenMode()) {
- mPrivateHandler.removeMessages(PREVENT_DEFAULT_TIMEOUT);
- mPrivateHandler.sendMessageDelayed(mPrivateHandler
- .obtainMessage(PREVENT_DEFAULT_TIMEOUT,
- action, 0), TAP_TIMEOUT);
- }
- }
- }
- startTouch(x, y, eventTime);
- break;
- }
- case MotionEvent.ACTION_MOVE: {
- boolean firstMove = false;
- if (!mConfirmMove && (deltaX * deltaX + deltaY * deltaY)
- >= mTouchSlopSquare) {
- mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- mConfirmMove = true;
- firstMove = true;
- if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
- mTouchMode = TOUCH_INIT_MODE;
- }
- if (sDisableNavcache) {
- removeTouchHighlight();
- }
- }
- if (mSelectingText && mSelectionStarted) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "extend=" + contentX + "," + contentY);
- }
- ViewParent parent = getParent();
- if (parent != null) {
- parent.requestDisallowInterceptTouchEvent(true);
- }
- if (deltaX != 0 || deltaY != 0) {
- mSelectDraggingCursor.offsetTo(
- contentX + mSelectDraggingOffset.x,
- contentY + mSelectDraggingOffset.y);
- updateWebkitSelection();
- mLastTouchX = x;
- mLastTouchY = y;
- invalidate();
- }
- break;
- }
-
- // pass the touch events from UI thread to WebCore thread
- if (shouldForwardTouchEvent() && mConfirmMove && (firstMove
- || eventTime - mLastSentTouchTime > mCurrentTouchInterval)) {
- TouchEventData ted = new TouchEventData();
- ted.mAction = action;
- ted.mIds = new int[1];
- ted.mIds[0] = ev.getPointerId(0);
- ted.mPoints = new Point[1];
- ted.mPoints[0] = new Point(contentX, contentY);
- ted.mPointsInView = new Point[1];
- ted.mPointsInView[0] = new Point(x, y);
- ted.mMetaState = ev.getMetaState();
- ted.mReprocess = mDeferTouchProcess;
- ted.mNativeLayer = mCurrentScrollingLayerId;
- ted.mNativeLayerRect.set(mScrollingLayerRect);
- ted.mSequence = mTouchEventQueue.nextTouchSequence();
- mTouchEventQueue.preQueueTouchEventData(ted);
- mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
- mLastSentTouchTime = eventTime;
- if (mDeferTouchProcess) {
- break;
- }
- if (firstMove && !inFullScreenMode()) {
- mPrivateHandler.sendMessageDelayed(mPrivateHandler
- .obtainMessage(PREVENT_DEFAULT_TIMEOUT,
- action, 0), TAP_TIMEOUT);
- }
- }
- if (mTouchMode == TOUCH_DONE_MODE
- || mPreventDefault == PREVENT_DEFAULT_YES) {
- // no dragging during scroll zoom animation, or when prevent
- // default is yes
- break;
- }
- if (mVelocityTracker == null) {
- Log.e(LOGTAG, "Got null mVelocityTracker when "
- + "mPreventDefault = " + mPreventDefault
- + " mDeferTouchProcess = " + mDeferTouchProcess
- + " mTouchMode = " + mTouchMode);
- } else {
- mVelocityTracker.addMovement(ev);
- }
-
- if (mTouchMode != TOUCH_DRAG_MODE &&
- mTouchMode != TOUCH_DRAG_LAYER_MODE) {
-
- if (!mConfirmMove) {
- break;
- }
-
- if (mPreventDefault == PREVENT_DEFAULT_MAYBE_YES
- || mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN) {
- // track mLastTouchTime as we may need to do fling at
- // ACTION_UP
- mLastTouchTime = eventTime;
- break;
- }
-
- // Only lock dragging to one axis if we don't have a scale in progress.
- // Scaling implies free-roaming movement. Note this is only ever a question
- // if mZoomManager.supportsPanDuringZoom() is true.
- final ScaleGestureDetector detector =
- mZoomManager.getMultiTouchGestureDetector();
- mAverageAngle = calculateDragAngle(deltaX, deltaY);
- if (detector == null || !detector.isInProgress()) {
- // if it starts nearly horizontal or vertical, enforce it
- if (mAverageAngle < HSLOPE_TO_START_SNAP) {
- mSnapScrollMode = SNAP_X;
- mSnapPositive = deltaX > 0;
- mAverageAngle = ANGLE_HORIZ;
- } else if (mAverageAngle > VSLOPE_TO_START_SNAP) {
- mSnapScrollMode = SNAP_Y;
- mSnapPositive = deltaY > 0;
- mAverageAngle = ANGLE_VERT;
- }
- }
-
- mTouchMode = TOUCH_DRAG_MODE;
- mLastTouchX = x;
- mLastTouchY = y;
- deltaX = 0;
- deltaY = 0;
-
- startScrollingLayer(x, y);
- startDrag();
- }
-
- // do pan
- boolean done = false;
- boolean keepScrollBarsVisible = false;
- if (deltaX == 0 && deltaY == 0) {
- keepScrollBarsVisible = done = true;
- } else {
- mAverageAngle +=
- (calculateDragAngle(deltaX, deltaY) - mAverageAngle)
- / MMA_WEIGHT_N;
- if (mSnapScrollMode != SNAP_NONE) {
- if (mSnapScrollMode == SNAP_Y) {
- // radical change means getting out of snap mode
- if (mAverageAngle < VSLOPE_TO_BREAK_SNAP) {
- mSnapScrollMode = SNAP_NONE;
- }
- }
- if (mSnapScrollMode == SNAP_X) {
- // radical change means getting out of snap mode
- if (mAverageAngle > HSLOPE_TO_BREAK_SNAP) {
- mSnapScrollMode = SNAP_NONE;
- }
- }
- } else {
- if (mAverageAngle < HSLOPE_TO_START_SNAP) {
- mSnapScrollMode = SNAP_X;
- mSnapPositive = deltaX > 0;
- mAverageAngle = (mAverageAngle + ANGLE_HORIZ) / 2;
- } else if (mAverageAngle > VSLOPE_TO_START_SNAP) {
- mSnapScrollMode = SNAP_Y;
- mSnapPositive = deltaY > 0;
- mAverageAngle = (mAverageAngle + ANGLE_VERT) / 2;
- }
- }
- if (mSnapScrollMode != SNAP_NONE) {
- if ((mSnapScrollMode & SNAP_X) == SNAP_X) {
- deltaY = 0;
- } else {
- deltaX = 0;
- }
- }
- mLastTouchX = x;
- mLastTouchY = y;
-
- if (deltaX * deltaX + deltaY * deltaY > mTouchSlopSquare) {
- mHeldMotionless = MOTIONLESS_FALSE;
- nativeSetIsScrolling(true);
- } else {
- mHeldMotionless = MOTIONLESS_TRUE;
- nativeSetIsScrolling(false);
- keepScrollBarsVisible = true;
- }
-
- mLastTouchTime = eventTime;
- }
-
- doDrag(deltaX, deltaY);
-
- // Turn off scrollbars when dragging a layer.
- if (keepScrollBarsVisible &&
- mTouchMode != TOUCH_DRAG_LAYER_MODE) {
- if (mHeldMotionless != MOTIONLESS_TRUE) {
- mHeldMotionless = MOTIONLESS_TRUE;
- invalidate();
- }
- // keep the scrollbar on the screen even there is no scroll
- awakenScrollBars(ViewConfiguration.getScrollDefaultDelay(),
- false);
- // Post a message so that we'll keep them alive while we're not scrolling.
- mPrivateHandler.sendMessageDelayed(mPrivateHandler
- .obtainMessage(AWAKEN_SCROLL_BARS),
- ViewConfiguration.getScrollDefaultDelay());
- // return false to indicate that we can't pan out of the
- // view space
- return !done;
- } else {
- mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS);
- }
- break;
- }
- case MotionEvent.ACTION_UP: {
- if (!isFocused()) requestFocus();
- // pass the touch events from UI thread to WebCore thread
- if (shouldForwardTouchEvent()) {
- TouchEventData ted = new TouchEventData();
- ted.mIds = new int[1];
- ted.mIds[0] = ev.getPointerId(0);
- ted.mAction = action;
- ted.mPoints = new Point[1];
- ted.mPoints[0] = new Point(contentX, contentY);
- ted.mPointsInView = new Point[1];
- ted.mPointsInView[0] = new Point(x, y);
- ted.mMetaState = ev.getMetaState();
- ted.mReprocess = mDeferTouchProcess;
- ted.mNativeLayer = mCurrentScrollingLayerId;
- ted.mNativeLayerRect.set(mScrollingLayerRect);
- ted.mSequence = mTouchEventQueue.nextTouchSequence();
- mTouchEventQueue.preQueueTouchEventData(ted);
- mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
- }
- mLastTouchUpTime = eventTime;
- if (mSentAutoScrollMessage) {
- mAutoScrollX = mAutoScrollY = 0;
- }
- switch (mTouchMode) {
- case TOUCH_DOUBLE_TAP_MODE: // double tap
- mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- if (inFullScreenMode() || mDeferTouchProcess) {
- TouchEventData ted = new TouchEventData();
- ted.mIds = new int[1];
- ted.mIds[0] = ev.getPointerId(0);
- ted.mAction = WebViewCore.ACTION_DOUBLETAP;
- ted.mPoints = new Point[1];
- ted.mPoints[0] = new Point(contentX, contentY);
- ted.mPointsInView = new Point[1];
- ted.mPointsInView[0] = new Point(x, y);
- ted.mMetaState = ev.getMetaState();
- ted.mReprocess = mDeferTouchProcess;
- ted.mNativeLayer = nativeScrollableLayer(
- contentX, contentY,
- ted.mNativeLayerRect, null);
- ted.mSequence = mTouchEventQueue.nextTouchSequence();
- mTouchEventQueue.preQueueTouchEventData(ted);
- mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
- } else if (mPreventDefault != PREVENT_DEFAULT_YES){
- mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
- mTouchMode = TOUCH_DONE_MODE;
- }
- break;
- case TOUCH_INIT_MODE: // tap
- case TOUCH_SHORTPRESS_START_MODE:
- case TOUCH_SHORTPRESS_MODE:
- mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- if (mConfirmMove) {
- Log.w(LOGTAG, "Miss a drag as we are waiting for" +
- " WebCore's response for touch down.");
- if (mPreventDefault != PREVENT_DEFAULT_YES
- && (computeMaxScrollX() > 0
- || computeMaxScrollY() > 0)) {
- // If the user has performed a very quick touch
- // sequence it is possible that we may get here
- // before WebCore has had a chance to process the events.
- // In this case, any call to preventDefault in the
- // JS touch handler will not have been executed yet.
- // Hence we will see both the UI (now) and WebCore
- // (when context switches) handling the event,
- // regardless of whether the web developer actually
- // doeses preventDefault in their touch handler. This
- // is the nature of our asynchronous touch model.
-
- // we will not rewrite drag code here, but we
- // will try fling if it applies.
- WebViewCore.reducePriority();
- // to get better performance, pause updating the
- // picture
- WebViewCore.pauseUpdatePicture(mWebViewCore);
- // fall through to TOUCH_DRAG_MODE
- } else {
- // WebKit may consume the touch event and modify
- // DOM. drawContentPicture() will be called with
- // animateSroll as true for better performance.
- // Force redraw in high-quality.
- invalidate();
- break;
- }
- } else {
- if (mSelectingText) {
- // tapping on selection or controls does nothing
- if (!mSelectionStarted) {
- selectionDone();
- }
- break;
- }
- // only trigger double tap if the WebView is
- // scalable
- if (mTouchMode == TOUCH_INIT_MODE
- && (canZoomIn() || canZoomOut())) {
- mPrivateHandler.sendEmptyMessageDelayed(
- RELEASE_SINGLE_TAP, ViewConfiguration
- .getDoubleTapTimeout());
- } else {
- doShortPress();
- }
- break;
- }
- case TOUCH_DRAG_MODE:
- case TOUCH_DRAG_LAYER_MODE:
- mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS);
- mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS);
- // if the user waits a while w/o moving before the
- // up, we don't want to do a fling
- if (eventTime - mLastTouchTime <= MIN_FLING_TIME) {
- if (mVelocityTracker == null) {
- Log.e(LOGTAG, "Got null mVelocityTracker when "
- + "mPreventDefault = "
- + mPreventDefault
- + " mDeferTouchProcess = "
- + mDeferTouchProcess);
- } else {
- mVelocityTracker.addMovement(ev);
- }
- // set to MOTIONLESS_IGNORE so that it won't keep
- // removing and sending message in
- // drawCoreAndCursorRing()
- mHeldMotionless = MOTIONLESS_IGNORE;
- doFling();
- break;
- } else {
- if (mScroller.springBack(mScrollX, mScrollY, 0,
- computeMaxScrollX(), 0,
- computeMaxScrollY())) {
- invalidate();
- }
- }
- // redraw in high-quality, as we're done dragging
- mHeldMotionless = MOTIONLESS_TRUE;
- invalidate();
- // fall through
- case TOUCH_DRAG_START_MODE:
- // TOUCH_DRAG_START_MODE should not happen for the real
- // device as we almost certain will get a MOVE. But this
- // is possible on emulator.
- mLastVelocity = 0;
- WebViewCore.resumePriority();
- if (!mSelectingText) {
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- }
- break;
- }
- stopTouch();
- break;
- }
- case MotionEvent.ACTION_CANCEL: {
- if (mTouchMode == TOUCH_DRAG_MODE) {
- mScroller.springBack(mScrollX, mScrollY, 0,
- computeMaxScrollX(), 0, computeMaxScrollY());
- invalidate();
- }
- cancelWebCoreTouchEvent(contentX, contentY, false);
- cancelTouch();
- break;
- }
- }
- return true;
- }
-
- private void passMultiTouchToWebKit(MotionEvent ev, long sequence) {
- TouchEventData ted = new TouchEventData();
- ted.mAction = ev.getActionMasked();
- final int count = ev.getPointerCount();
- ted.mIds = new int[count];
- ted.mPoints = new Point[count];
- ted.mPointsInView = new Point[count];
- for (int c = 0; c < count; c++) {
- ted.mIds[c] = ev.getPointerId(c);
- int x = viewToContentX((int) ev.getX(c) + mScrollX);
- int y = viewToContentY((int) ev.getY(c) + mScrollY);
- ted.mPoints[c] = new Point(x, y);
- ted.mPointsInView[c] = new Point((int) ev.getX(c), (int) ev.getY(c));
- }
- if (ted.mAction == MotionEvent.ACTION_POINTER_DOWN
- || ted.mAction == MotionEvent.ACTION_POINTER_UP) {
- ted.mActionIndex = ev.getActionIndex();
- }
- ted.mMetaState = ev.getMetaState();
- ted.mReprocess = true;
- ted.mMotionEvent = MotionEvent.obtain(ev);
- ted.mSequence = sequence;
- mTouchEventQueue.preQueueTouchEventData(ted);
- mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
- cancelLongPress();
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- }
-
- void handleMultiTouchInWebView(MotionEvent ev) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "multi-touch: " + ev + " at " + ev.getEventTime()
- + " mTouchMode=" + mTouchMode
- + " numPointers=" + ev.getPointerCount()
- + " scrolloffset=(" + mScrollX + "," + mScrollY + ")");
- }
-
- final ScaleGestureDetector detector =
- mZoomManager.getMultiTouchGestureDetector();
-
- // A few apps use WebView but don't instantiate gesture detector.
- // We don't need to support multi touch for them.
- if (detector == null) return;
-
- float x = ev.getX();
- float y = ev.getY();
-
- if (mPreventDefault != PREVENT_DEFAULT_YES) {
- detector.onTouchEvent(ev);
-
- if (detector.isInProgress()) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "detector is in progress");
- }
- mLastTouchTime = ev.getEventTime();
- x = detector.getFocusX();
- y = detector.getFocusY();
-
- cancelLongPress();
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- if (!mZoomManager.supportsPanDuringZoom()) {
- return;
- }
- mTouchMode = TOUCH_DRAG_MODE;
- if (mVelocityTracker == null) {
- mVelocityTracker = VelocityTracker.obtain();
- }
- }
- }
-
- int action = ev.getActionMasked();
- if (action == MotionEvent.ACTION_POINTER_DOWN) {
- cancelTouch();
- action = MotionEvent.ACTION_DOWN;
- } else if (action == MotionEvent.ACTION_POINTER_UP && ev.getPointerCount() >= 2) {
- // set mLastTouchX/Y to the remaining points for multi-touch.
- mLastTouchX = Math.round(x);
- mLastTouchY = Math.round(y);
- } else if (action == MotionEvent.ACTION_MOVE) {
- // negative x or y indicate it is on the edge, skip it.
- if (x < 0 || y < 0) {
- return;
- }
- }
-
- handleTouchEventCommon(ev, action, Math.round(x), Math.round(y));
- }
-
- private void cancelWebCoreTouchEvent(int x, int y, boolean removeEvents) {
- if (shouldForwardTouchEvent()) {
- if (removeEvents) {
- mWebViewCore.removeMessages(EventHub.TOUCH_EVENT);
- }
- TouchEventData ted = new TouchEventData();
- ted.mIds = new int[1];
- ted.mIds[0] = 0;
- ted.mPoints = new Point[1];
- ted.mPoints[0] = new Point(x, y);
- ted.mPointsInView = new Point[1];
- int viewX = contentToViewX(x) - mScrollX;
- int viewY = contentToViewY(y) - mScrollY;
- ted.mPointsInView[0] = new Point(viewX, viewY);
- ted.mAction = MotionEvent.ACTION_CANCEL;
- ted.mNativeLayer = nativeScrollableLayer(
- x, y, ted.mNativeLayerRect, null);
- ted.mSequence = mTouchEventQueue.nextTouchSequence();
- mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
- mPreventDefault = PREVENT_DEFAULT_IGNORE;
-
- if (removeEvents) {
- // Mark this after sending the message above; we should
- // be willing to ignore the cancel event that we just sent.
- mTouchEventQueue.ignoreCurrentlyMissingEvents();
- }
- }
- }
-
- private void startTouch(float x, float y, long eventTime) {
- // Remember where the motion event started
- mStartTouchX = mLastTouchX = Math.round(x);
- mStartTouchY = mLastTouchY = Math.round(y);
- mLastTouchTime = eventTime;
- mVelocityTracker = VelocityTracker.obtain();
- mSnapScrollMode = SNAP_NONE;
- mPrivateHandler.sendEmptyMessageDelayed(UPDATE_SELECTION,
- ViewConfiguration.getTapTimeout());
- }
-
- private void startDrag() {
- WebViewCore.reducePriority();
- // to get better performance, pause updating the picture
- WebViewCore.pauseUpdatePicture(mWebViewCore);
- nativeSetIsScrolling(true);
-
- if (!mDragFromTextInput) {
- nativeHideCursor();
- }
-
- if (mHorizontalScrollBarMode != SCROLLBAR_ALWAYSOFF
- || mVerticalScrollBarMode != SCROLLBAR_ALWAYSOFF) {
- mZoomManager.invokeZoomPicker();
- }
- }
-
- private void doDrag(int deltaX, int deltaY) {
- if ((deltaX | deltaY) != 0) {
- int oldX = mScrollX;
- int oldY = mScrollY;
- int rangeX = computeMaxScrollX();
- int rangeY = computeMaxScrollY();
- // Check for the original scrolling layer in case we change
- // directions. mTouchMode might be TOUCH_DRAG_MODE if we have
- // reached the edge of a layer but mScrollingLayer will be non-zero
- // if we initiated the drag on a layer.
- if (mCurrentScrollingLayerId != 0) {
- final int contentX = viewToContentDimension(deltaX);
- final int contentY = viewToContentDimension(deltaY);
-
- // Check the scrolling bounds to see if we will actually do any
- // scrolling. The rectangle is in document coordinates.
- final int maxX = mScrollingLayerRect.right;
- final int maxY = mScrollingLayerRect.bottom;
- final int resultX = Math.max(0,
- Math.min(mScrollingLayerRect.left + contentX, maxX));
- final int resultY = Math.max(0,
- Math.min(mScrollingLayerRect.top + contentY, maxY));
-
- if (resultX != mScrollingLayerRect.left ||
- resultY != mScrollingLayerRect.top) {
- // In case we switched to dragging the page.
- mTouchMode = TOUCH_DRAG_LAYER_MODE;
- deltaX = contentX;
- deltaY = contentY;
- oldX = mScrollingLayerRect.left;
- oldY = mScrollingLayerRect.top;
- rangeX = maxX;
- rangeY = maxY;
- } else {
- // Scroll the main page if we are not going to scroll the
- // layer. This does not reset mScrollingLayer in case the
- // user changes directions and the layer can scroll the
- // other way.
- mTouchMode = TOUCH_DRAG_MODE;
- }
- }
-
- if (mOverScrollGlow != null) {
- mOverScrollGlow.setOverScrollDeltas(deltaX, deltaY);
- }
-
- overScrollBy(deltaX, deltaY, oldX, oldY,
- rangeX, rangeY,
- mOverscrollDistance, mOverscrollDistance, true);
- if (mOverScrollGlow != null && mOverScrollGlow.isAnimating()) {
- invalidate();
- }
- }
- mZoomManager.keepZoomPickerVisible();
- }
-
- private void stopTouch() {
- if (mScroller.isFinished() && !mSelectingText
- && (mTouchMode == TOUCH_DRAG_MODE || mTouchMode == TOUCH_DRAG_LAYER_MODE)) {
- WebViewCore.resumePriority();
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- nativeSetIsScrolling(false);
- }
-
- // we also use mVelocityTracker == null to tell us that we are
- // not "moving around", so we can take the slower/prettier
- // mode in the drawing code
- if (mVelocityTracker != null) {
- mVelocityTracker.recycle();
- mVelocityTracker = null;
- }
-
- // Release any pulled glows
- if (mOverScrollGlow != null) {
- mOverScrollGlow.releaseAll();
- }
-
- if (mSelectingText) {
- mSelectionStarted = false;
- syncSelectionCursors();
- if (mIsCaretSelection) {
- resetCaretTimer();
- showPasteWindow();
- }
- invalidate();
- }
- }
-
- private void cancelTouch() {
- // we also use mVelocityTracker == null to tell us that we are
- // not "moving around", so we can take the slower/prettier
- // mode in the drawing code
- if (mVelocityTracker != null) {
- mVelocityTracker.recycle();
- mVelocityTracker = null;
- }
-
- if ((mTouchMode == TOUCH_DRAG_MODE
- || mTouchMode == TOUCH_DRAG_LAYER_MODE) && !mSelectingText) {
- WebViewCore.resumePriority();
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- nativeSetIsScrolling(false);
- }
- mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS);
- mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS);
- if (sDisableNavcache) {
- removeTouchHighlight();
- }
- mHeldMotionless = MOTIONLESS_TRUE;
- mTouchMode = TOUCH_DONE_MODE;
- nativeHideCursor();
- }
-
- @Override
- public boolean onGenericMotionEvent(MotionEvent event) {
- if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_SCROLL: {
- final float vscroll;
- final float hscroll;
- if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
- vscroll = 0;
- hscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
- } else {
- vscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
- hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
- }
- if (hscroll != 0 || vscroll != 0) {
- final int vdelta = (int) (vscroll * getVerticalScrollFactor());
- final int hdelta = (int) (hscroll * getHorizontalScrollFactor());
- if (pinScrollBy(hdelta, vdelta, false, 0)) {
- return true;
- }
- }
- }
- }
- }
- return super.onGenericMotionEvent(event);
- }
-
- private long mTrackballFirstTime = 0;
- private long mTrackballLastTime = 0;
- private float mTrackballRemainsX = 0.0f;
- private float mTrackballRemainsY = 0.0f;
- private int mTrackballXMove = 0;
- private int mTrackballYMove = 0;
- private boolean mSelectingText = false;
- private boolean mSelectionStarted = false;
- private static final int TRACKBALL_KEY_TIMEOUT = 1000;
- private static final int TRACKBALL_TIMEOUT = 200;
- private static final int TRACKBALL_WAIT = 100;
- private static final int TRACKBALL_SCALE = 400;
- private static final int TRACKBALL_SCROLL_COUNT = 5;
- private static final int TRACKBALL_MOVE_COUNT = 10;
- private static final int TRACKBALL_MULTIPLIER = 3;
- private static final int SELECT_CURSOR_OFFSET = 16;
- private static final int SELECT_SCROLL = 5;
- private int mSelectX = 0;
- private int mSelectY = 0;
- private boolean mFocusSizeChanged = false;
- private boolean mTrackballDown = false;
- private long mTrackballUpTime = 0;
- private long mLastCursorTime = 0;
- private Rect mLastCursorBounds;
-
- // Set by default; BrowserActivity clears to interpret trackball data
- // directly for movement. Currently, the framework only passes
- // arrow key events, not trackball events, from one child to the next
- private boolean mMapTrackballToArrowKeys = true;
-
- private DrawData mDelaySetPicture;
- private DrawData mLoadedPicture;
-
public void setMapTrackballToArrowKeys(boolean setMap) {
checkThread();
- mMapTrackballToArrowKeys = setMap;
+ mProvider.setMapTrackballToArrowKeys(setMap);
}
- void resetTrackballTime() {
- mTrackballLastTime = 0;
- }
-
- @Override
- public boolean onTrackballEvent(MotionEvent ev) {
- long time = ev.getEventTime();
- if ((ev.getMetaState() & KeyEvent.META_ALT_ON) != 0) {
- if (ev.getY() > 0) pageDown(true);
- if (ev.getY() < 0) pageUp(true);
- return true;
- }
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- if (mSelectingText) {
- return true; // discard press if copy in progress
- }
- mTrackballDown = true;
- if (mNativeClass == 0) {
- return false;
- }
- if (time - mLastCursorTime <= TRACKBALL_TIMEOUT
- && !mLastCursorBounds.equals(cursorRingBounds())) {
- nativeSelectBestAt(mLastCursorBounds);
- }
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "onTrackballEvent down ev=" + ev
- + " time=" + time
- + " mLastCursorTime=" + mLastCursorTime);
- }
- if (isInTouchMode()) requestFocusFromTouch();
- return false; // let common code in onKeyDown at it
- }
- if (ev.getAction() == MotionEvent.ACTION_UP) {
- // LONG_PRESS_CENTER is set in common onKeyDown
- mPrivateHandler.removeMessages(LONG_PRESS_CENTER);
- mTrackballDown = false;
- mTrackballUpTime = time;
- if (mSelectingText) {
- copySelection();
- selectionDone();
- return true; // discard press if copy in progress
- }
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "onTrackballEvent up ev=" + ev
- + " time=" + time
- );
- }
- return false; // let common code in onKeyUp at it
- }
- if ((mMapTrackballToArrowKeys && (ev.getMetaState() & KeyEvent.META_SHIFT_ON) == 0) ||
- AccessibilityManager.getInstance(mContext).isEnabled()) {
- if (DebugFlags.WEB_VIEW) Log.v(LOGTAG, "onTrackballEvent gmail quit");
- return false;
- }
- if (mTrackballDown) {
- if (DebugFlags.WEB_VIEW) Log.v(LOGTAG, "onTrackballEvent down quit");
- return true; // discard move if trackball is down
- }
- if (time - mTrackballUpTime < TRACKBALL_TIMEOUT) {
- if (DebugFlags.WEB_VIEW) Log.v(LOGTAG, "onTrackballEvent up timeout quit");
- return true;
- }
- // TODO: alternatively we can do panning as touch does
- switchOutDrawHistory();
- if (time - mTrackballLastTime > TRACKBALL_TIMEOUT) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "onTrackballEvent time="
- + time + " last=" + mTrackballLastTime);
- }
- mTrackballFirstTime = time;
- mTrackballXMove = mTrackballYMove = 0;
- }
- mTrackballLastTime = time;
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "onTrackballEvent ev=" + ev + " time=" + time);
- }
- mTrackballRemainsX += ev.getX();
- mTrackballRemainsY += ev.getY();
- doTrackball(time, ev.getMetaState());
- return true;
- }
-
- private int scaleTrackballX(float xRate, int width) {
- int xMove = (int) (xRate / TRACKBALL_SCALE * width);
- int nextXMove = xMove;
- if (xMove > 0) {
- if (xMove > mTrackballXMove) {
- xMove -= mTrackballXMove;
- }
- } else if (xMove < mTrackballXMove) {
- xMove -= mTrackballXMove;
- }
- mTrackballXMove = nextXMove;
- return xMove;
- }
-
- private int scaleTrackballY(float yRate, int height) {
- int yMove = (int) (yRate / TRACKBALL_SCALE * height);
- int nextYMove = yMove;
- if (yMove > 0) {
- if (yMove > mTrackballYMove) {
- yMove -= mTrackballYMove;
- }
- } else if (yMove < mTrackballYMove) {
- yMove -= mTrackballYMove;
- }
- mTrackballYMove = nextYMove;
- return yMove;
- }
-
- private int keyCodeToSoundsEffect(int keyCode) {
- switch(keyCode) {
- case KeyEvent.KEYCODE_DPAD_UP:
- return SoundEffectConstants.NAVIGATION_UP;
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- return SoundEffectConstants.NAVIGATION_RIGHT;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- return SoundEffectConstants.NAVIGATION_DOWN;
- case KeyEvent.KEYCODE_DPAD_LEFT:
- return SoundEffectConstants.NAVIGATION_LEFT;
- }
- throw new IllegalArgumentException("keyCode must be one of " +
- "{KEYCODE_DPAD_UP, KEYCODE_DPAD_RIGHT, KEYCODE_DPAD_DOWN, " +
- "KEYCODE_DPAD_LEFT}.");
- }
-
- private void doTrackball(long time, int metaState) {
- int elapsed = (int) (mTrackballLastTime - mTrackballFirstTime);
- if (elapsed == 0) {
- elapsed = TRACKBALL_TIMEOUT;
- }
- float xRate = mTrackballRemainsX * 1000 / elapsed;
- float yRate = mTrackballRemainsY * 1000 / elapsed;
- int viewWidth = getViewWidth();
- int viewHeight = getViewHeight();
- float ax = Math.abs(xRate);
- float ay = Math.abs(yRate);
- float maxA = Math.max(ax, ay);
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "doTrackball elapsed=" + elapsed
- + " xRate=" + xRate
- + " yRate=" + yRate
- + " mTrackballRemainsX=" + mTrackballRemainsX
- + " mTrackballRemainsY=" + mTrackballRemainsY);
- }
- int width = mContentWidth - viewWidth;
- int height = mContentHeight - viewHeight;
- if (width < 0) width = 0;
- if (height < 0) height = 0;
- ax = Math.abs(mTrackballRemainsX * TRACKBALL_MULTIPLIER);
- ay = Math.abs(mTrackballRemainsY * TRACKBALL_MULTIPLIER);
- maxA = Math.max(ax, ay);
- int count = Math.max(0, (int) maxA);
- int oldScrollX = mScrollX;
- int oldScrollY = mScrollY;
- if (count > 0) {
- int selectKeyCode = ax < ay ? mTrackballRemainsY < 0 ?
- KeyEvent.KEYCODE_DPAD_UP : KeyEvent.KEYCODE_DPAD_DOWN :
- mTrackballRemainsX < 0 ? KeyEvent.KEYCODE_DPAD_LEFT :
- KeyEvent.KEYCODE_DPAD_RIGHT;
- count = Math.min(count, TRACKBALL_MOVE_COUNT);
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "doTrackball keyCode=" + selectKeyCode
- + " count=" + count
- + " mTrackballRemainsX=" + mTrackballRemainsX
- + " mTrackballRemainsY=" + mTrackballRemainsY);
- }
- if (mNativeClass != 0 && nativePageShouldHandleShiftAndArrows()) {
- for (int i = 0; i < count; i++) {
- letPageHandleNavKey(selectKeyCode, time, true, metaState);
- }
- letPageHandleNavKey(selectKeyCode, time, false, metaState);
- } else if (navHandledKey(selectKeyCode, count, false, time)) {
- playSoundEffect(keyCodeToSoundsEffect(selectKeyCode));
- }
- mTrackballRemainsX = mTrackballRemainsY = 0;
- }
- if (count >= TRACKBALL_SCROLL_COUNT) {
- int xMove = scaleTrackballX(xRate, width);
- int yMove = scaleTrackballY(yRate, height);
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "doTrackball pinScrollBy"
- + " count=" + count
- + " xMove=" + xMove + " yMove=" + yMove
- + " mScrollX-oldScrollX=" + (mScrollX-oldScrollX)
- + " mScrollY-oldScrollY=" + (mScrollY-oldScrollY)
- );
- }
- if (Math.abs(mScrollX - oldScrollX) > Math.abs(xMove)) {
- xMove = 0;
- }
- if (Math.abs(mScrollY - oldScrollY) > Math.abs(yMove)) {
- yMove = 0;
- }
- if (xMove != 0 || yMove != 0) {
- pinScrollBy(xMove, yMove, true, 0);
- }
- }
- }
-
- /**
- * Compute the maximum horizontal scroll position. Used by {@link OverScrollGlow}.
- * @return Maximum horizontal scroll position within real content
- */
- int computeMaxScrollX() {
- return Math.max(computeRealHorizontalScrollRange() - getViewWidth(), 0);
- }
-
- /**
- * Compute the maximum vertical scroll position. Used by {@link OverScrollGlow}.
- * @return Maximum vertical scroll position within real content
- */
- int computeMaxScrollY() {
- return Math.max(computeRealVerticalScrollRange() + getTitleHeight()
- - getViewHeightWithTitle(), 0);
- }
-
- boolean updateScrollCoordinates(int x, int y) {
- int oldX = mScrollX;
- int oldY = mScrollY;
- mScrollX = x;
- mScrollY = y;
- if (oldX != mScrollX || oldY != mScrollY) {
- onScrollChanged(mScrollX, mScrollY, oldX, oldY);
- return true;
- } else {
- return false;
- }
- }
public void flingScroll(int vx, int vy) {
checkThread();
- mScroller.fling(mScrollX, mScrollY, vx, vy, 0, computeMaxScrollX(), 0,
- computeMaxScrollY(), mOverflingDistance, mOverflingDistance);
- invalidate();
- }
-
- private void doFling() {
- if (mVelocityTracker == null) {
- return;
- }
- int maxX = computeMaxScrollX();
- int maxY = computeMaxScrollY();
-
- mVelocityTracker.computeCurrentVelocity(1000, mMaximumFling);
- int vx = (int) mVelocityTracker.getXVelocity();
- int vy = (int) mVelocityTracker.getYVelocity();
-
- int scrollX = mScrollX;
- int scrollY = mScrollY;
- int overscrollDistance = mOverscrollDistance;
- int overflingDistance = mOverflingDistance;
-
- // Use the layer's scroll data if applicable.
- if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
- scrollX = mScrollingLayerRect.left;
- scrollY = mScrollingLayerRect.top;
- maxX = mScrollingLayerRect.right;
- maxY = mScrollingLayerRect.bottom;
- // No overscrolling for layers.
- overscrollDistance = overflingDistance = 0;
- }
-
- if (mSnapScrollMode != SNAP_NONE) {
- if ((mSnapScrollMode & SNAP_X) == SNAP_X) {
- vy = 0;
- } else {
- vx = 0;
- }
- }
- if ((maxX == 0 && vy == 0) || (maxY == 0 && vx == 0)) {
- WebViewCore.resumePriority();
- if (!mSelectingText) {
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- }
- if (mScroller.springBack(scrollX, scrollY, 0, maxX, 0, maxY)) {
- invalidate();
- }
- return;
- }
- float currentVelocity = mScroller.getCurrVelocity();
- float velocity = (float) Math.hypot(vx, vy);
- if (mLastVelocity > 0 && currentVelocity > 0 && velocity
- > mLastVelocity * MINIMUM_VELOCITY_RATIO_FOR_ACCELERATION) {
- float deltaR = (float) (Math.abs(Math.atan2(mLastVelY, mLastVelX)
- - Math.atan2(vy, vx)));
- final float circle = (float) (Math.PI) * 2.0f;
- if (deltaR > circle * 0.9f || deltaR < circle * 0.1f) {
- vx += currentVelocity * mLastVelX / mLastVelocity;
- vy += currentVelocity * mLastVelY / mLastVelocity;
- velocity = (float) Math.hypot(vx, vy);
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "doFling vx= " + vx + " vy=" + vy);
- }
- } else if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "doFling missed " + deltaR / circle);
- }
- } else if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "doFling start last=" + mLastVelocity
- + " current=" + currentVelocity
- + " vx=" + vx + " vy=" + vy
- + " maxX=" + maxX + " maxY=" + maxY
- + " scrollX=" + scrollX + " scrollY=" + scrollY
- + " layer=" + mCurrentScrollingLayerId);
- }
-
- // Allow sloppy flings without overscrolling at the edges.
- if ((scrollX == 0 || scrollX == maxX) && Math.abs(vx) < Math.abs(vy)) {
- vx = 0;
- }
- if ((scrollY == 0 || scrollY == maxY) && Math.abs(vy) < Math.abs(vx)) {
- vy = 0;
- }
-
- if (overscrollDistance < overflingDistance) {
- if ((vx > 0 && scrollX == -overscrollDistance) ||
- (vx < 0 && scrollX == maxX + overscrollDistance)) {
- vx = 0;
- }
- if ((vy > 0 && scrollY == -overscrollDistance) ||
- (vy < 0 && scrollY == maxY + overscrollDistance)) {
- vy = 0;
- }
- }
-
- mLastVelX = vx;
- mLastVelY = vy;
- mLastVelocity = velocity;
-
- // no horizontal overscroll if the content just fits
- mScroller.fling(scrollX, scrollY, -vx, -vy, 0, maxX, 0, maxY,
- maxX == 0 ? 0 : overflingDistance, overflingDistance);
- // Duration is calculated based on velocity. With range boundaries and overscroll
- // we may not know how long the final animation will take. (Hence the deprecation
- // warning on the call below.) It's not a big deal for scroll bars but if webcore
- // resumes during this effect we will take a performance hit. See computeScroll;
- // we resume webcore there when the animation is finished.
- final int time = mScroller.getDuration();
-
- // Suppress scrollbars for layer scrolling.
- if (mTouchMode != TOUCH_DRAG_LAYER_MODE) {
- awakenScrollBars(time);
- }
-
- invalidate();
+ mProvider.flingScroll(vx, vy);
}
/**
@@ -7921,27 +1491,7 @@ public class WebView extends AbsoluteLayout
@Deprecated
public View getZoomControls() {
checkThread();
- if (!getSettings().supportZoom()) {
- Log.w(LOGTAG, "This WebView doesn't support zoom.");
- return null;
- }
- return mZoomManager.getExternalZoomPicker();
- }
-
- void dismissZoomControl() {
- mZoomManager.dismissZoomPicker();
- }
-
- float getDefaultZoomScale() {
- return mZoomManager.getDefaultScale();
- }
-
- /**
- * Return the overview scale of the WebView
- * @return The overview scale.
- */
- float getZoomOverviewScale() {
- return mZoomManager.getZoomOverviewScale();
+ return mProvider.getZoomControls();
}
/**
@@ -7949,7 +1499,7 @@ public class WebView extends AbsoluteLayout
*/
public boolean canZoomIn() {
checkThread();
- return mZoomManager.canZoomIn();
+ return mProvider.canZoomIn();
}
/**
@@ -7957,7 +1507,7 @@ public class WebView extends AbsoluteLayout
*/
public boolean canZoomOut() {
checkThread();
- return mZoomManager.canZoomOut();
+ return mProvider.canZoomOut();
}
/**
@@ -7966,7 +1516,7 @@ public class WebView extends AbsoluteLayout
*/
public boolean zoomIn() {
checkThread();
- return mZoomManager.zoomIn();
+ return mProvider.zoomIn();
}
/**
@@ -7975,2576 +1525,434 @@ public class WebView extends AbsoluteLayout
*/
public boolean zoomOut() {
checkThread();
- return mZoomManager.zoomOut();
- }
-
- /**
- * This selects the best clickable target at mLastTouchX and mLastTouchY
- * and calls showCursorTimed on the native side
- */
- private void updateSelection() {
- if (mNativeClass == 0 || sDisableNavcache) {
- return;
- }
- mPrivateHandler.removeMessages(UPDATE_SELECTION);
- // mLastTouchX and mLastTouchY are the point in the current viewport
- int contentX = viewToContentX(mLastTouchX + mScrollX);
- int contentY = viewToContentY(mLastTouchY + mScrollY);
- int slop = viewToContentDimension(mNavSlop);
- Rect rect = new Rect(contentX - slop, contentY - slop,
- contentX + slop, contentY + slop);
- nativeSelectBestAt(rect);
- mInitialHitTestResult = hitTestResult(null);
- }
-
- /**
- * Scroll the focused text field to match the WebTextView
- * @param xPercent New x position of the WebTextView from 0 to 1.
- */
- /*package*/ void scrollFocusedTextInputX(float xPercent) {
- if (!inEditingMode() || mWebViewCore == null) {
- return;
- }
- mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, 0,
- new Float(xPercent));
- }
-
- /**
- * Scroll the focused textarea vertically to match the WebTextView
- * @param y New y position of the WebTextView in view coordinates
- */
- /* package */ void scrollFocusedTextInputY(int y) {
- if (!inEditingMode() || mWebViewCore == null) {
- return;
- }
- mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, 0, viewToContentDimension(y));
- }
-
- /**
- * Set our starting point and time for a drag from the WebTextView.
- */
- /*package*/ void initiateTextFieldDrag(float x, float y, long eventTime) {
- if (!inEditingMode()) {
- return;
- }
- mLastTouchX = Math.round(x + mWebTextView.getLeft() - mScrollX);
- mLastTouchY = Math.round(y + mWebTextView.getTop() - mScrollY);
- mLastTouchTime = eventTime;
- if (!mScroller.isFinished()) {
- abortAnimation();
- }
- mSnapScrollMode = SNAP_NONE;
- mVelocityTracker = VelocityTracker.obtain();
- mTouchMode = TOUCH_DRAG_START_MODE;
+ return mProvider.zoomOut();
}
/**
- * Given a motion event from the WebTextView, set its location to our
- * coordinates, and handle the event.
+ * @deprecated This method is now obsolete.
*/
- /*package*/ boolean textFieldDrag(MotionEvent event) {
- if (!inEditingMode()) {
- return false;
- }
- mDragFromTextInput = true;
- event.offsetLocation((mWebTextView.getLeft() - mScrollX),
- (mWebTextView.getTop() - mScrollY));
- boolean result = onTouchEvent(event);
- mDragFromTextInput = false;
- return result;
+ @Deprecated
+ public void debugDump() {
+ checkThread();
+ mProvider.debugDump();
}
- /**
- * Due a touch up from a WebTextView. This will be handled by webkit to
- * change the selection.
- * @param event MotionEvent in the WebTextView's coordinates.
- */
- /*package*/ void touchUpOnTextField(MotionEvent event) {
- if (!inEditingMode()) {
- return;
- }
- int x = viewToContentX((int) event.getX() + mWebTextView.getLeft());
- int y = viewToContentY((int) event.getY() + mWebTextView.getTop());
- int slop = viewToContentDimension(mNavSlop);
- nativeMotionUp(x, y, slop);
- }
+ //-------------------------------------------------------------------------
+ // Interface for WebView providers
+ //-------------------------------------------------------------------------
/**
- * Called when pressing the center key or trackball on a textfield.
+ * Used by providers to obtain the underlying implementation, e.g. when the appliction
+ * responds to WebViewClient.onCreateWindow() request.
+ *
+ * @hide WebViewProvider is not public API.
*/
- /*package*/ void centerKeyPressOnTextField() {
- mWebViewCore.sendMessage(EventHub.CLICK, nativeCursorFramePointer(),
- nativeCursorNodePointer());
- }
-
- private void doShortPress() {
- if (mNativeClass == 0) {
- return;
- }
- if (mPreventDefault == PREVENT_DEFAULT_YES) {
- return;
- }
- mTouchMode = TOUCH_DONE_MODE;
- updateSelection();
- switchOutDrawHistory();
- // mLastTouchX and mLastTouchY are the point in the current viewport
- int contentX = viewToContentX(mLastTouchX + mScrollX);
- int contentY = viewToContentY(mLastTouchY + mScrollY);
- int slop = viewToContentDimension(mNavSlop);
- if (sDisableNavcache && !mTouchHighlightRegion.isEmpty()) {
- // set mTouchHighlightRequested to 0 to cause an immediate
- // drawing of the touch rings
- mTouchHighlightRequested = 0;
- invalidate(mTouchHighlightRegion.getBounds());
- mPrivateHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- removeTouchHighlight();
- }
- }, ViewConfiguration.getPressedStateDuration());
- }
- if (mFocusedNode != null && mFocusedNode.mIntentUrl != null) {
- playSoundEffect(SoundEffectConstants.CLICK);
- overrideLoading(mFocusedNode.mIntentUrl);
- } else if (sDisableNavcache) {
- WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
- // use "0" as generation id to inform WebKit to use the same x/y as
- // it used when processing GET_TOUCH_HIGHLIGHT_RECTS
- touchUpData.mMoveGeneration = 0;
- mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData);
- } else if (nativePointInNavCache(contentX, contentY, slop)) {
- WebViewCore.MotionUpData motionUpData = new WebViewCore
- .MotionUpData();
- motionUpData.mFrame = nativeCacheHitFramePointer();
- motionUpData.mNode = nativeCacheHitNodePointer();
- motionUpData.mBounds = nativeCacheHitNodeBounds();
- motionUpData.mX = contentX;
- motionUpData.mY = contentY;
- mWebViewCore.sendMessageAtFrontOfQueue(EventHub.VALID_NODE_BOUNDS,
- motionUpData);
- } else {
- doMotionUp(contentX, contentY);
- }
- }
-
- private void doMotionUp(int contentX, int contentY) {
- int slop = viewToContentDimension(mNavSlop);
- if (nativeMotionUp(contentX, contentY, slop) && mLogEvent) {
- EventLog.writeEvent(EventLogTags.BROWSER_SNAP_CENTER);
- }
- if (nativeHasCursorNode() && !nativeCursorIsTextInput()) {
- playSoundEffect(SoundEffectConstants.CLICK);
- }
- }
-
- void sendPluginDrawMsg() {
- mWebViewCore.sendMessage(EventHub.PLUGIN_SURFACE_READY);
+ public WebViewProvider getWebViewProvider() {
+ return mProvider;
}
/**
- * Returns plugin bounds if x/y in content coordinates corresponds to a
- * plugin. Otherwise a NULL rectangle is returned.
+ * Callback interface, allows the provider implementation to access non-public methods
+ * and fields, and make super-class calls in this WebView instance.
+ * @hide Only for use by WebViewProvider implementations
*/
- Rect getPluginBounds(int x, int y) {
- int slop = viewToContentDimension(mNavSlop);
- if (nativePointInNavCache(x, y, slop) && nativeCacheHitIsPlugin()) {
- return nativeCacheHitNodeBounds();
- } else {
- return null;
- }
- }
-
- /*
- * Return true if the rect (e.g. plugin) is fully visible and maximized
- * inside the WebView.
- */
- boolean isRectFitOnScreen(Rect rect) {
- final int rectWidth = rect.width();
- final int rectHeight = rect.height();
- final int viewWidth = getViewWidth();
- final int viewHeight = getViewHeightWithTitle();
- float scale = Math.min((float) viewWidth / rectWidth, (float) viewHeight / rectHeight);
- scale = mZoomManager.computeScaleWithLimits(scale);
- return !mZoomManager.willScaleTriggerZoom(scale)
- && contentToViewX(rect.left) >= mScrollX
- && contentToViewX(rect.right) <= mScrollX + viewWidth
- && contentToViewY(rect.top) >= mScrollY
- && contentToViewY(rect.bottom) <= mScrollY + viewHeight;
- }
-
- /*
- * Maximize and center the rectangle, specified in the document coordinate
- * space, inside the WebView. If the zoom doesn't need to be changed, do an
- * animated scroll to center it. If the zoom needs to be changed, find the
- * zoom center and do a smooth zoom transition. The rect is in document
- * coordinates
- */
- void centerFitRect(Rect rect) {
- final int rectWidth = rect.width();
- final int rectHeight = rect.height();
- final int viewWidth = getViewWidth();
- final int viewHeight = getViewHeightWithTitle();
- float scale = Math.min((float) viewWidth / rectWidth, (float) viewHeight
- / rectHeight);
- scale = mZoomManager.computeScaleWithLimits(scale);
- if (!mZoomManager.willScaleTriggerZoom(scale)) {
- pinScrollTo(contentToViewX(rect.left + rectWidth / 2) - viewWidth / 2,
- contentToViewY(rect.top + rectHeight / 2) - viewHeight / 2,
- true, 0);
- } else {
- float actualScale = mZoomManager.getScale();
- float oldScreenX = rect.left * actualScale - mScrollX;
- float rectViewX = rect.left * scale;
- float rectViewWidth = rectWidth * scale;
- float newMaxWidth = mContentWidth * scale;
- float newScreenX = (viewWidth - rectViewWidth) / 2;
- // pin the newX to the WebView
- if (newScreenX > rectViewX) {
- newScreenX = rectViewX;
- } else if (newScreenX > (newMaxWidth - rectViewX - rectViewWidth)) {
- newScreenX = viewWidth - (newMaxWidth - rectViewX);
- }
- float zoomCenterX = (oldScreenX * scale - newScreenX * actualScale)
- / (scale - actualScale);
- float oldScreenY = rect.top * actualScale + getTitleHeight()
- - mScrollY;
- float rectViewY = rect.top * scale + getTitleHeight();
- float rectViewHeight = rectHeight * scale;
- float newMaxHeight = mContentHeight * scale + getTitleHeight();
- float newScreenY = (viewHeight - rectViewHeight) / 2;
- // pin the newY to the WebView
- if (newScreenY > rectViewY) {
- newScreenY = rectViewY;
- } else if (newScreenY > (newMaxHeight - rectViewY - rectViewHeight)) {
- newScreenY = viewHeight - (newMaxHeight - rectViewY);
- }
- float zoomCenterY = (oldScreenY * scale - newScreenY * actualScale)
- / (scale - actualScale);
- mZoomManager.setZoomCenter(zoomCenterX, zoomCenterY);
- mZoomManager.startZoomAnimation(scale, false);
- }
- }
-
- // Called by JNI to handle a touch on a node representing an email address,
- // address, or phone number
- private void overrideLoading(String url) {
- mCallbackProxy.uiOverrideUrlLoading(url);
- }
-
- @Override
- public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
- // FIXME: If a subwindow is showing find, and the user touches the
- // background window, it can steal focus.
- if (mFindIsUp) return false;
- boolean result = false;
- if (inEditingMode()) {
- result = mWebTextView.requestFocus(direction,
- previouslyFocusedRect);
- } else {
- result = super.requestFocus(direction, previouslyFocusedRect);
- if (mWebViewCore.getSettings().getNeedInitialFocus() && !isInTouchMode()) {
- // For cases such as GMail, where we gain focus from a direction,
- // we want to move to the first available link.
- // FIXME: If there are no visible links, we may not want to
- int fakeKeyDirection = 0;
- switch(direction) {
- case View.FOCUS_UP:
- fakeKeyDirection = KeyEvent.KEYCODE_DPAD_UP;
- break;
- case View.FOCUS_DOWN:
- fakeKeyDirection = KeyEvent.KEYCODE_DPAD_DOWN;
- break;
- case View.FOCUS_LEFT:
- fakeKeyDirection = KeyEvent.KEYCODE_DPAD_LEFT;
- break;
- case View.FOCUS_RIGHT:
- fakeKeyDirection = KeyEvent.KEYCODE_DPAD_RIGHT;
- break;
- default:
- return result;
- }
- if (mNativeClass != 0 && !nativeHasCursorNode()) {
- navHandledKey(fakeKeyDirection, 1, true, 0);
- }
- }
+ public class PrivateAccess {
+ // ---- Access to super-class methods ----
+ public int super_getScrollBarStyle() {
+ return WebView.super.getScrollBarStyle();
}
- return result;
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
- int heightMode = MeasureSpec.getMode(heightMeasureSpec);
- int heightSize = MeasureSpec.getSize(heightMeasureSpec);
- int widthMode = MeasureSpec.getMode(widthMeasureSpec);
- int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-
- int measuredHeight = heightSize;
- int measuredWidth = widthSize;
-
- // Grab the content size from WebViewCore.
- int contentHeight = contentToViewDimension(mContentHeight);
- int contentWidth = contentToViewDimension(mContentWidth);
-
-// Log.d(LOGTAG, "------- measure " + heightMode);
-
- if (heightMode != MeasureSpec.EXACTLY) {
- mHeightCanMeasure = true;
- measuredHeight = contentHeight;
- if (heightMode == MeasureSpec.AT_MOST) {
- // If we are larger than the AT_MOST height, then our height can
- // no longer be measured and we should scroll internally.
- if (measuredHeight > heightSize) {
- measuredHeight = heightSize;
- mHeightCanMeasure = false;
- measuredHeight |= MEASURED_STATE_TOO_SMALL;
- }
- }
- } else {
- mHeightCanMeasure = false;
- }
- if (mNativeClass != 0) {
- nativeSetHeightCanMeasure(mHeightCanMeasure);
- }
- // For the width, always use the given size unless unspecified.
- if (widthMode == MeasureSpec.UNSPECIFIED) {
- mWidthCanMeasure = true;
- measuredWidth = contentWidth;
- } else {
- if (measuredWidth < contentWidth) {
- measuredWidth |= MEASURED_STATE_TOO_SMALL;
- }
- mWidthCanMeasure = false;
+ public void super_scrollTo(int scrollX, int scrollY) {
+ WebView.super.scrollTo(scrollX, scrollY);
}
- synchronized (this) {
- setMeasuredDimension(measuredWidth, measuredHeight);
+ public void super_computeScroll() {
+ WebView.super.computeScroll();
}
- }
- @Override
- public boolean requestChildRectangleOnScreen(View child,
- Rect rect,
- boolean immediate) {
- if (mNativeClass == 0) {
- return false;
- }
- // don't scroll while in zoom animation. When it is done, we will adjust
- // the necessary components (e.g., WebTextView if it is in editing mode)
- if (mZoomManager.isFixedLengthAnimationInProgress()) {
- return false;
+ public boolean super_performLongClick() {
+ return WebView.super.performLongClick();
}
- rect.offset(child.getLeft() - child.getScrollX(),
- child.getTop() - child.getScrollY());
-
- Rect content = new Rect(viewToContentX(mScrollX),
- viewToContentY(mScrollY),
- viewToContentX(mScrollX + getWidth()
- - getVerticalScrollbarWidth()),
- viewToContentY(mScrollY + getViewHeightWithTitle()));
- content = nativeSubtractLayers(content);
- int screenTop = contentToViewY(content.top);
- int screenBottom = contentToViewY(content.bottom);
- int height = screenBottom - screenTop;
- int scrollYDelta = 0;
-
- if (rect.bottom > screenBottom) {
- int oneThirdOfScreenHeight = height / 3;
- if (rect.height() > 2 * oneThirdOfScreenHeight) {
- // If the rectangle is too tall to fit in the bottom two thirds
- // of the screen, place it at the top.
- scrollYDelta = rect.top - screenTop;
- } else {
- // If the rectangle will still fit on screen, we want its
- // top to be in the top third of the screen.
- scrollYDelta = rect.top - (screenTop + oneThirdOfScreenHeight);
- }
- } else if (rect.top < screenTop) {
- scrollYDelta = rect.top - screenTop;
+ public boolean super_setFrame(int left, int top, int right, int bottom) {
+ return WebView.super.setFrame(left, top, right, bottom);
}
- int screenLeft = contentToViewX(content.left);
- int screenRight = contentToViewX(content.right);
- int width = screenRight - screenLeft;
- int scrollXDelta = 0;
-
- if (rect.right > screenRight && rect.left > screenLeft) {
- if (rect.width() > width) {
- scrollXDelta += (rect.left - screenLeft);
- } else {
- scrollXDelta += (rect.right - screenRight);
- }
- } else if (rect.left < screenLeft) {
- scrollXDelta -= (screenLeft - rect.left);
+ public boolean super_dispatchKeyEvent(KeyEvent event) {
+ return WebView.super.dispatchKeyEvent(event);
}
- if ((scrollYDelta | scrollXDelta) != 0) {
- return pinScrollBy(scrollXDelta, scrollYDelta, !immediate, 0);
+ public boolean super_onGenericMotionEvent(MotionEvent event) {
+ return WebView.super.onGenericMotionEvent(event);
}
- return false;
- }
-
- /* package */ void replaceTextfieldText(int oldStart, int oldEnd,
- String replace, int newStart, int newEnd) {
- WebViewCore.ReplaceTextData arg = new WebViewCore.ReplaceTextData();
- arg.mReplace = replace;
- arg.mNewStart = newStart;
- arg.mNewEnd = newEnd;
- mTextGeneration++;
- arg.mTextGeneration = mTextGeneration;
- mWebViewCore.sendMessage(EventHub.REPLACE_TEXT, oldStart, oldEnd, arg);
- }
-
- /* package */ void passToJavaScript(String currentText, KeyEvent event) {
- // check if mWebViewCore has been destroyed
- if (mWebViewCore == null) {
- return;
+ public boolean super_requestFocus(int direction, Rect previouslyFocusedRect) {
+ return WebView.super.requestFocus(direction, previouslyFocusedRect);
}
- WebViewCore.JSKeyData arg = new WebViewCore.JSKeyData();
- arg.mEvent = event;
- arg.mCurrentText = currentText;
- // Increase our text generation number, and pass it to webcore thread
- mTextGeneration++;
- mWebViewCore.sendMessage(EventHub.PASS_TO_JS, mTextGeneration, 0, arg);
- // WebKit's document state is not saved until about to leave the page.
- // To make sure the host application, like Browser, has the up to date
- // document state when it goes to background, we force to save the
- // document state.
- mWebViewCore.removeMessages(EventHub.SAVE_DOCUMENT_STATE);
- mWebViewCore.sendMessageDelayed(EventHub.SAVE_DOCUMENT_STATE,
- cursorData(), 1000);
- }
-
- /**
- * @hide
- */
- public synchronized WebViewCore getWebViewCore() {
- return mWebViewCore;
- }
- /**
- * Used only by TouchEventQueue to store pending touch events.
- */
- private static class QueuedTouch {
- long mSequence;
- MotionEvent mEvent; // Optional
- TouchEventData mTed; // Optional
-
- QueuedTouch mNext;
-
- public QueuedTouch set(TouchEventData ted) {
- mSequence = ted.mSequence;
- mTed = ted;
- mEvent = null;
- mNext = null;
- return this;
+ public void super_setLayoutParams(ViewGroup.LayoutParams params) {
+ WebView.super.setLayoutParams(params);
}
- public QueuedTouch set(MotionEvent ev, long sequence) {
- mEvent = MotionEvent.obtain(ev);
- mSequence = sequence;
- mTed = null;
- mNext = null;
- return this;
+ // ---- Access to non-public methods ----
+ public void overScrollBy(int deltaX, int deltaY,
+ int scrollX, int scrollY,
+ int scrollRangeX, int scrollRangeY,
+ int maxOverScrollX, int maxOverScrollY,
+ boolean isTouchEvent) {
+ WebView.this.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY,
+ maxOverScrollX, maxOverScrollY, isTouchEvent);
}
- public QueuedTouch add(QueuedTouch other) {
- if (other.mSequence < mSequence) {
- other.mNext = this;
- return other;
- }
-
- QueuedTouch insertAt = this;
- while (insertAt.mNext != null && insertAt.mNext.mSequence < other.mSequence) {
- insertAt = insertAt.mNext;
- }
- other.mNext = insertAt.mNext;
- insertAt.mNext = other;
- return this;
+ public void awakenScrollBars(int duration) {
+ WebView.this.awakenScrollBars(duration);
}
- }
- /**
- * WebView handles touch events asynchronously since some events must be passed to WebKit
- * for potentially slower processing. TouchEventQueue serializes touch events regardless
- * of which path they take to ensure that no events are ever processed out of order
- * by WebView.
- */
- private class TouchEventQueue {
- private long mNextTouchSequence = Long.MIN_VALUE + 1;
- private long mLastHandledTouchSequence = Long.MIN_VALUE;
- private long mIgnoreUntilSequence = Long.MIN_VALUE + 1;
-
- // Events waiting to be processed.
- private QueuedTouch mTouchEventQueue;
-
- // Known events that are waiting on a response before being enqueued.
- private QueuedTouch mPreQueue;
-
- // Pool of QueuedTouch objects saved for later use.
- private QueuedTouch mQueuedTouchRecycleBin;
- private int mQueuedTouchRecycleCount;
-
- private long mLastEventTime = Long.MAX_VALUE;
- private static final int MAX_RECYCLED_QUEUED_TOUCH = 15;
-
- // milliseconds until we abandon hope of getting all of a previous gesture
- private static final int QUEUED_GESTURE_TIMEOUT = 1000;
-
- private QueuedTouch obtainQueuedTouch() {
- if (mQueuedTouchRecycleBin != null) {
- QueuedTouch result = mQueuedTouchRecycleBin;
- mQueuedTouchRecycleBin = result.mNext;
- mQueuedTouchRecycleCount--;
- return result;
- }
- return new QueuedTouch();
+ public void awakenScrollBars(int duration, boolean invalidate) {
+ WebView.this.awakenScrollBars(duration, invalidate);
}
- /**
- * Allow events with any currently missing sequence numbers to be skipped in processing.
- */
- public void ignoreCurrentlyMissingEvents() {
- mIgnoreUntilSequence = mNextTouchSequence;
-
- // Run any events we have available and complete, pre-queued or otherwise.
- runQueuedAndPreQueuedEvents();
+ public float getVerticalScrollFactor() {
+ return WebView.this.getVerticalScrollFactor();
}
- private void runQueuedAndPreQueuedEvents() {
- QueuedTouch qd = mPreQueue;
- boolean fromPreQueue = true;
- while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
- handleQueuedTouch(qd);
- QueuedTouch recycleMe = qd;
- if (fromPreQueue) {
- mPreQueue = qd.mNext;
- } else {
- mTouchEventQueue = qd.mNext;
- }
- recycleQueuedTouch(recycleMe);
- mLastHandledTouchSequence++;
-
- long nextPre = mPreQueue != null ? mPreQueue.mSequence : Long.MAX_VALUE;
- long nextQueued = mTouchEventQueue != null ?
- mTouchEventQueue.mSequence : Long.MAX_VALUE;
- fromPreQueue = nextPre < nextQueued;
- qd = fromPreQueue ? mPreQueue : mTouchEventQueue;
- }
+ public float getHorizontalScrollFactor() {
+ return WebView.this.getHorizontalScrollFactor();
}
- /**
- * Add a TouchEventData to the pre-queue.
- *
- * An event in the pre-queue is an event that we know about that
- * has been sent to webkit, but that we haven't received back and
- * enqueued into the normal touch queue yet. If webkit ever times
- * out and we need to ignore currently missing events, we'll run
- * events from the pre-queue to patch the holes.
- *
- * @param ted TouchEventData to pre-queue
- */
- public void preQueueTouchEventData(TouchEventData ted) {
- QueuedTouch newTouch = obtainQueuedTouch().set(ted);
- if (mPreQueue == null) {
- mPreQueue = newTouch;
- } else {
- QueuedTouch insertionPoint = mPreQueue;
- while (insertionPoint.mNext != null &&
- insertionPoint.mNext.mSequence < newTouch.mSequence) {
- insertionPoint = insertionPoint.mNext;
- }
- newTouch.mNext = insertionPoint.mNext;
- insertionPoint.mNext = newTouch;
- }
+ public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
+ WebView.this.setMeasuredDimension(measuredWidth, measuredHeight);
}
- private void recycleQueuedTouch(QueuedTouch qd) {
- if (mQueuedTouchRecycleCount < MAX_RECYCLED_QUEUED_TOUCH) {
- qd.mNext = mQueuedTouchRecycleBin;
- mQueuedTouchRecycleBin = qd;
- mQueuedTouchRecycleCount++;
- }
+ public void onScrollChanged(int l, int t, int oldl, int oldt) {
+ WebView.this.onScrollChanged(l, t, oldl, oldt);
}
- /**
- * Reset the touch event queue. This will dump any pending events
- * and reset the sequence numbering.
- */
- public void reset() {
- mNextTouchSequence = Long.MIN_VALUE + 1;
- mLastHandledTouchSequence = Long.MIN_VALUE;
- mIgnoreUntilSequence = Long.MIN_VALUE + 1;
- while (mTouchEventQueue != null) {
- QueuedTouch recycleMe = mTouchEventQueue;
- mTouchEventQueue = mTouchEventQueue.mNext;
- recycleQueuedTouch(recycleMe);
- }
- while (mPreQueue != null) {
- QueuedTouch recycleMe = mPreQueue;
- mPreQueue = mPreQueue.mNext;
- recycleQueuedTouch(recycleMe);
- }
+ public int getHorizontalScrollbarHeight() {
+ return WebView.this.getHorizontalScrollbarHeight();
}
- /**
- * Return the next valid sequence number for tagging incoming touch events.
- * @return The next touch event sequence number
- */
- public long nextTouchSequence() {
- return mNextTouchSequence++;
+ // ---- Access to (non-public) fields ----
+ /** Raw setter for the scroll X value, without invoking onScrollChanged handlers etc. */
+ public void setScrollXRaw(int scrollX) {
+ WebView.this.mScrollX = scrollX;
}
- /**
- * Enqueue a touch event in the form of TouchEventData.
- * The sequence number will be read from the mSequence field of the argument.
- *
- * If the touch event's sequence number is the next in line to be processed, it will
- * be handled before this method returns. Any subsequent events that have already
- * been queued will also be processed in their proper order.
- *
- * @param ted Touch data to be processed in order.
- * @return true if the event was processed before returning, false if it was just enqueued.
- */
- public boolean enqueueTouchEvent(TouchEventData ted) {
- // Remove from the pre-queue if present
- QueuedTouch preQueue = mPreQueue;
- if (preQueue != null) {
- // On exiting this block, preQueue is set to the pre-queued QueuedTouch object
- // if it was present in the pre-queue, and removed from the pre-queue itself.
- if (preQueue.mSequence == ted.mSequence) {
- mPreQueue = preQueue.mNext;
- } else {
- QueuedTouch prev = preQueue;
- preQueue = null;
- while (prev.mNext != null) {
- if (prev.mNext.mSequence == ted.mSequence) {
- preQueue = prev.mNext;
- prev.mNext = preQueue.mNext;
- break;
- } else {
- prev = prev.mNext;
- }
- }
- }
- }
-
- if (ted.mSequence < mLastHandledTouchSequence) {
- // Stale event and we already moved on; drop it. (Should not be common.)
- Log.w(LOGTAG, "Stale touch event " + MotionEvent.actionToString(ted.mAction) +
- " received from webcore; ignoring");
- return false;
- }
-
- if (dropStaleGestures(ted.mMotionEvent, ted.mSequence)) {
- return false;
- }
-
- // dropStaleGestures above might have fast-forwarded us to
- // an event we have already.
- runNextQueuedEvents();
-
- if (mLastHandledTouchSequence + 1 == ted.mSequence) {
- if (preQueue != null) {
- recycleQueuedTouch(preQueue);
- preQueue = null;
- }
- handleQueuedTouchEventData(ted);
-
- mLastHandledTouchSequence++;
-
- // Do we have any more? Run them if so.
- runNextQueuedEvents();
- } else {
- // Reuse the pre-queued object if we had it.
- QueuedTouch qd = preQueue != null ? preQueue : obtainQueuedTouch().set(ted);
- mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
- }
- return true;
+ /** Raw setter for the scroll Y value, without invoking onScrollChanged handlers etc. */
+ public void setScrollYRaw(int scrollY) {
+ WebView.this.mScrollY = scrollY;
}
- /**
- * Enqueue a touch event in the form of a MotionEvent from the framework.
- *
- * If the touch event's sequence number is the next in line to be processed, it will
- * be handled before this method returns. Any subsequent events that have already
- * been queued will also be processed in their proper order.
- *
- * @param ev MotionEvent to be processed in order
- */
- public void enqueueTouchEvent(MotionEvent ev) {
- final long sequence = nextTouchSequence();
-
- if (dropStaleGestures(ev, sequence)) {
- return;
- }
-
- // dropStaleGestures above might have fast-forwarded us to
- // an event we have already.
- runNextQueuedEvents();
+ }
- if (mLastHandledTouchSequence + 1 == sequence) {
- handleQueuedMotionEvent(ev);
+ //-------------------------------------------------------------------------
+ // Private internal stuff
+ //-------------------------------------------------------------------------
- mLastHandledTouchSequence++;
+ // Cache the factory both for efficiency, and ensure any one process gets all webviews from the
+ // same provider.
+ private static WebViewFactoryProvider sProviderFactory;
- // Do we have any more? Run them if so.
- runNextQueuedEvents();
- } else {
- QueuedTouch qd = obtainQueuedTouch().set(ev, sequence);
- mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
- }
- }
+ private WebViewProvider mProvider;
- private void runNextQueuedEvents() {
- QueuedTouch qd = mTouchEventQueue;
- while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
- handleQueuedTouch(qd);
- QueuedTouch recycleMe = qd;
- qd = qd.mNext;
- recycleQueuedTouch(recycleMe);
- mLastHandledTouchSequence++;
- }
- mTouchEventQueue = qd;
+ private void ensureProviderCreated() {
+ checkThread();
+ if (mProvider == null) {
+ if (DEBUG) Log.v(LOGTAG, "instantiating webview provider instance");
+ // As this can get called during the base class constructor chain, pass the minimum
+ // number of dependencies here; the rest are deferred to init().
+ mProvider = getFactory().createWebView(this, new PrivateAccess());
}
+ }
- private boolean dropStaleGestures(MotionEvent ev, long sequence) {
- if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && !mConfirmMove) {
- // This is to make sure that we don't attempt to process a tap
- // or long press when webkit takes too long to get back to us.
- // The movement will be properly confirmed when we process the
- // enqueued event later.
- final int dx = Math.round(ev.getX()) - mLastTouchX;
- final int dy = Math.round(ev.getY()) - mLastTouchY;
- if (dx * dx + dy * dy > mTouchSlopSquare) {
- mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
- mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
- }
- }
-
- if (mTouchEventQueue == null) {
- return sequence <= mLastHandledTouchSequence;
- }
-
- // If we have a new down event and it's been a while since the last event
- // we saw, catch up as best we can and keep going.
- if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN) {
- long eventTime = ev.getEventTime();
- long lastHandledEventTime = mLastEventTime;
- if (eventTime > lastHandledEventTime + QUEUED_GESTURE_TIMEOUT) {
- Log.w(LOGTAG, "Got ACTION_DOWN but still waiting on stale event. " +
- "Catching up.");
- runQueuedAndPreQueuedEvents();
-
- // Drop leftovers that we truly don't have.
- QueuedTouch qd = mTouchEventQueue;
- while (qd != null && qd.mSequence < sequence) {
- QueuedTouch recycleMe = qd;
- qd = qd.mNext;
- recycleQueuedTouch(recycleMe);
- }
- mTouchEventQueue = qd;
- mLastHandledTouchSequence = sequence - 1;
- }
- }
-
- if (mIgnoreUntilSequence - 1 > mLastHandledTouchSequence) {
- QueuedTouch qd = mTouchEventQueue;
- while (qd != null && qd.mSequence < mIgnoreUntilSequence) {
- QueuedTouch recycleMe = qd;
- qd = qd.mNext;
- recycleQueuedTouch(recycleMe);
- }
- mTouchEventQueue = qd;
- mLastHandledTouchSequence = mIgnoreUntilSequence - 1;
- }
-
- if (mPreQueue != null) {
- // Drop stale prequeued events
- QueuedTouch qd = mPreQueue;
- while (qd != null && qd.mSequence < mIgnoreUntilSequence) {
- QueuedTouch recycleMe = qd;
- qd = qd.mNext;
- recycleQueuedTouch(recycleMe);
- }
- mPreQueue = qd;
- }
-
- return sequence <= mLastHandledTouchSequence;
- }
+ private static synchronized WebViewFactoryProvider getFactory() {
+ // For now the main purpose of this function (and the factory abstration) is to keep
+ // us honest and minimize usage of WebViewClassic internals when binding the proxy.
+ checkThread();
+ if (sProviderFactory != null) return sProviderFactory;
- private void handleQueuedTouch(QueuedTouch qt) {
- if (qt.mTed != null) {
- handleQueuedTouchEventData(qt.mTed);
- } else {
- handleQueuedMotionEvent(qt.mEvent);
- qt.mEvent.recycle();
- }
+ sProviderFactory = getFactoryByName(DEFAULT_WEB_VIEW_FACTORY);
+ if (sProviderFactory == null) {
+ if (DEBUG) Log.v (LOGTAG, "Falling back to explicit linkage");
+ sProviderFactory = new WebViewClassic.Factory();
}
+ return sProviderFactory;
+ }
- private void handleQueuedMotionEvent(MotionEvent ev) {
- mLastEventTime = ev.getEventTime();
- int action = ev.getActionMasked();
- if (ev.getPointerCount() > 1) { // Multi-touch
- handleMultiTouchInWebView(ev);
- } else {
- final ScaleGestureDetector detector = mZoomManager.getMultiTouchGestureDetector();
- if (detector != null && mPreventDefault != PREVENT_DEFAULT_YES) {
- // ScaleGestureDetector needs a consistent event stream to operate properly.
- // It won't take any action with fewer than two pointers, but it needs to
- // update internal bookkeeping state.
- detector.onTouchEvent(ev);
- }
-
- handleTouchEventCommon(ev, action, Math.round(ev.getX()), Math.round(ev.getY()));
- }
+ private static WebViewFactoryProvider getFactoryByName(String providerName) {
+ try {
+ if (DEBUG) Log.v(LOGTAG, "attempt to load class " + providerName);
+ Class<?> c = Class.forName(providerName);
+ if (DEBUG) Log.v(LOGTAG, "instantiating factory");
+ return (WebViewFactoryProvider) c.newInstance();
+ } catch (ClassNotFoundException e) {
+ Log.e(LOGTAG, "error loading " + providerName, e);
+ } catch (IllegalAccessException e) {
+ Log.e(LOGTAG, "error loading " + providerName, e);
+ } catch (InstantiationException e) {
+ Log.e(LOGTAG, "error loading " + providerName, e);
}
+ return null;
+ }
- private void handleQueuedTouchEventData(TouchEventData ted) {
- if (ted.mMotionEvent != null) {
- mLastEventTime = ted.mMotionEvent.getEventTime();
- }
- if (!ted.mReprocess) {
- if (ted.mAction == MotionEvent.ACTION_DOWN
- && mPreventDefault == PREVENT_DEFAULT_MAYBE_YES) {
- // if prevent default is called from WebCore, UI
- // will not handle the rest of the touch events any
- // more.
- mPreventDefault = ted.mNativeResult ? PREVENT_DEFAULT_YES
- : PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN;
- } else if (ted.mAction == MotionEvent.ACTION_MOVE
- && mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN) {
- // the return for the first ACTION_MOVE will decide
- // whether UI will handle touch or not. Currently no
- // support for alternating prevent default
- mPreventDefault = ted.mNativeResult ? PREVENT_DEFAULT_YES
- : PREVENT_DEFAULT_NO;
- }
- if (mPreventDefault == PREVENT_DEFAULT_YES) {
- mTouchHighlightRegion.setEmpty();
- }
- } else {
- if (ted.mPoints.length > 1) { // multi-touch
- if (!ted.mNativeResult && mPreventDefault != PREVENT_DEFAULT_YES) {
- mPreventDefault = PREVENT_DEFAULT_NO;
- handleMultiTouchInWebView(ted.mMotionEvent);
- } else {
- mPreventDefault = PREVENT_DEFAULT_YES;
- }
- return;
- }
-
- // prevent default is not called in WebCore, so the
- // message needs to be reprocessed in UI
- if (!ted.mNativeResult) {
- // Following is for single touch.
- switch (ted.mAction) {
- case MotionEvent.ACTION_DOWN:
- mLastDeferTouchX = ted.mPointsInView[0].x;
- mLastDeferTouchY = ted.mPointsInView[0].y;
- mDeferTouchMode = TOUCH_INIT_MODE;
- break;
- case MotionEvent.ACTION_MOVE: {
- // no snapping in defer process
- int x = ted.mPointsInView[0].x;
- int y = ted.mPointsInView[0].y;
-
- if (mDeferTouchMode != TOUCH_DRAG_MODE) {
- mDeferTouchMode = TOUCH_DRAG_MODE;
- mLastDeferTouchX = x;
- mLastDeferTouchY = y;
- startScrollingLayer(x, y);
- startDrag();
- }
- int deltaX = pinLocX((int) (mScrollX
- + mLastDeferTouchX - x))
- - mScrollX;
- int deltaY = pinLocY((int) (mScrollY
- + mLastDeferTouchY - y))
- - mScrollY;
- doDrag(deltaX, deltaY);
- if (deltaX != 0) mLastDeferTouchX = x;
- if (deltaY != 0) mLastDeferTouchY = y;
- break;
- }
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if (mDeferTouchMode == TOUCH_DRAG_MODE) {
- // no fling in defer process
- mScroller.springBack(mScrollX, mScrollY, 0,
- computeMaxScrollX(), 0,
- computeMaxScrollY());
- invalidate();
- WebViewCore.resumePriority();
- WebViewCore.resumeUpdatePicture(mWebViewCore);
- }
- mDeferTouchMode = TOUCH_DONE_MODE;
- break;
- case WebViewCore.ACTION_DOUBLETAP:
- // doDoubleTap() needs mLastTouchX/Y as anchor
- mLastDeferTouchX = ted.mPointsInView[0].x;
- mLastDeferTouchY = ted.mPointsInView[0].y;
- mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
- mDeferTouchMode = TOUCH_DONE_MODE;
- break;
- case WebViewCore.ACTION_LONGPRESS:
- HitTestResult hitTest = getHitTestResult();
- if (hitTest != null && hitTest.mType
- != HitTestResult.UNKNOWN_TYPE) {
- performLongClick();
- }
- mDeferTouchMode = TOUCH_DONE_MODE;
- break;
- }
- }
- }
+ private static void checkThread() {
+ if (Looper.myLooper() != Looper.getMainLooper()) {
+ Throwable throwable = new Throwable(
+ "Warning: A WebView method was called on thread '" +
+ Thread.currentThread().getName() + "'. " +
+ "All WebView methods must be called on the UI thread. " +
+ "Future versions of WebView may not support use on other threads.");
+ Log.w(LOGTAG, Log.getStackTraceString(throwable));
+ StrictMode.onWebViewMethodCalledOnWrongThread(throwable);
}
}
//-------------------------------------------------------------------------
- // Methods can be called from a separate thread, like WebViewCore
- // If it needs to call the View system, it has to send message.
+ // Override View methods
//-------------------------------------------------------------------------
- /**
- * General handler to receive message coming from webkit thread
- */
- class PrivateHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- // exclude INVAL_RECT_MSG_ID since it is frequently output
- if (DebugFlags.WEB_VIEW && msg.what != INVAL_RECT_MSG_ID) {
- if (msg.what >= FIRST_PRIVATE_MSG_ID
- && msg.what <= LAST_PRIVATE_MSG_ID) {
- Log.v(LOGTAG, HandlerPrivateDebugString[msg.what
- - FIRST_PRIVATE_MSG_ID]);
- } else if (msg.what >= FIRST_PACKAGE_MSG_ID
- && msg.what <= LAST_PACKAGE_MSG_ID) {
- Log.v(LOGTAG, HandlerPackageDebugString[msg.what
- - FIRST_PACKAGE_MSG_ID]);
- } else {
- Log.v(LOGTAG, Integer.toString(msg.what));
- }
- }
- if (mWebViewCore == null) {
- // after WebView's destroy() is called, skip handling messages.
- return;
- }
- if (mBlockWebkitViewMessages
- && msg.what != WEBCORE_INITIALIZED_MSG_ID) {
- // Blocking messages from webkit
- return;
- }
- switch (msg.what) {
- case REMEMBER_PASSWORD: {
- mDatabase.setUsernamePassword(
- msg.getData().getString("host"),
- msg.getData().getString("username"),
- msg.getData().getString("password"));
- ((Message) msg.obj).sendToTarget();
- break;
- }
- case NEVER_REMEMBER_PASSWORD: {
- mDatabase.setUsernamePassword(
- msg.getData().getString("host"), null, null);
- ((Message) msg.obj).sendToTarget();
- break;
- }
- case PREVENT_DEFAULT_TIMEOUT: {
- // if timeout happens, cancel it so that it won't block UI
- // to continue handling touch events
- if ((msg.arg1 == MotionEvent.ACTION_DOWN
- && mPreventDefault == PREVENT_DEFAULT_MAYBE_YES)
- || (msg.arg1 == MotionEvent.ACTION_MOVE
- && mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN)) {
- cancelWebCoreTouchEvent(
- viewToContentX(mLastTouchX + mScrollX),
- viewToContentY(mLastTouchY + mScrollY),
- true);
- }
- break;
- }
- case SCROLL_SELECT_TEXT: {
- if (mAutoScrollX == 0 && mAutoScrollY == 0) {
- mSentAutoScrollMessage = false;
- break;
- }
- if (mCurrentScrollingLayerId == 0) {
- pinScrollBy(mAutoScrollX, mAutoScrollY, true, 0);
- } else {
- scrollLayerTo(mScrollingLayerRect.left + mAutoScrollX,
- mScrollingLayerRect.top + mAutoScrollY);
- }
- sendEmptyMessageDelayed(
- SCROLL_SELECT_TEXT, SELECT_SCROLL_INTERVAL);
- break;
- }
- case UPDATE_SELECTION: {
- if (mTouchMode == TOUCH_INIT_MODE
- || mTouchMode == TOUCH_SHORTPRESS_MODE
- || mTouchMode == TOUCH_SHORTPRESS_START_MODE) {
- updateSelection();
- }
- break;
- }
- case SWITCH_TO_SHORTPRESS: {
- if (mTouchMode == TOUCH_INIT_MODE) {
- if (!sDisableNavcache
- && mPreventDefault != PREVENT_DEFAULT_YES) {
- mTouchMode = TOUCH_SHORTPRESS_START_MODE;
- updateSelection();
- } else {
- // set to TOUCH_SHORTPRESS_MODE so that it won't
- // trigger double tap any more
- mTouchMode = TOUCH_SHORTPRESS_MODE;
- }
- } else if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
- mTouchMode = TOUCH_DONE_MODE;
- }
- break;
- }
- case SWITCH_TO_LONGPRESS: {
- if (sDisableNavcache) {
- removeTouchHighlight();
- }
- if (inFullScreenMode() || mDeferTouchProcess) {
- TouchEventData ted = new TouchEventData();
- ted.mAction = WebViewCore.ACTION_LONGPRESS;
- ted.mIds = new int[1];
- ted.mIds[0] = 0;
- ted.mPoints = new Point[1];
- ted.mPoints[0] = new Point(viewToContentX(mLastTouchX + mScrollX),
- viewToContentY(mLastTouchY + mScrollY));
- ted.mPointsInView = new Point[1];
- ted.mPointsInView[0] = new Point(mLastTouchX, mLastTouchY);
- // metaState for long press is tricky. Should it be the
- // state when the press started or when the press was
- // released? Or some intermediary key state? For
- // simplicity for now, we don't set it.
- ted.mMetaState = 0;
- ted.mReprocess = mDeferTouchProcess;
- ted.mNativeLayer = nativeScrollableLayer(
- ted.mPoints[0].x, ted.mPoints[0].y,
- ted.mNativeLayerRect, null);
- ted.mSequence = mTouchEventQueue.nextTouchSequence();
- mTouchEventQueue.preQueueTouchEventData(ted);
- mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
- } else if (mPreventDefault != PREVENT_DEFAULT_YES) {
- mTouchMode = TOUCH_DONE_MODE;
- performLongClick();
- }
- break;
- }
- case RELEASE_SINGLE_TAP: {
- doShortPress();
- break;
- }
- case SCROLL_TO_MSG_ID: {
- // arg1 = animate, arg2 = onlyIfImeIsShowing
- // obj = Point(x, y)
- if (msg.arg2 == 1) {
- // This scroll is intended to bring the textfield into
- // view, but is only necessary if the IME is showing
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm == null || !imm.isAcceptingText()
- || (!imm.isActive(WebView.this) && (!inEditingMode()
- || !imm.isActive(mWebTextView)))) {
- break;
- }
- }
- final Point p = (Point) msg.obj;
- if (msg.arg1 == 1) {
- spawnContentScrollTo(p.x, p.y);
- } else {
- setContentScrollTo(p.x, p.y);
- }
- break;
- }
- case UPDATE_ZOOM_RANGE: {
- WebViewCore.ViewState viewState = (WebViewCore.ViewState) msg.obj;
- // mScrollX contains the new minPrefWidth
- mZoomManager.updateZoomRange(viewState, getViewWidth(), viewState.mScrollX);
- break;
- }
- case UPDATE_ZOOM_DENSITY: {
- final float density = (Float) msg.obj;
- mZoomManager.updateDefaultZoomDensity(density);
- break;
- }
- case REPLACE_BASE_CONTENT: {
- nativeReplaceBaseContent(msg.arg1);
- break;
- }
- case NEW_PICTURE_MSG_ID: {
- // called for new content
- final WebViewCore.DrawData draw = (WebViewCore.DrawData) msg.obj;
- setNewPicture(draw, true);
- break;
- }
- case WEBCORE_INITIALIZED_MSG_ID:
- // nativeCreate sets mNativeClass to a non-zero value
- String drawableDir = BrowserFrame.getRawResFilename(
- BrowserFrame.DRAWABLEDIR, mContext);
- WindowManager windowManager =
- (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
- Display display = windowManager.getDefaultDisplay();
- nativeCreate(msg.arg1, drawableDir,
- ActivityManager.isHighEndGfx(display));
- if (mDelaySetPicture != null) {
- setNewPicture(mDelaySetPicture, true);
- mDelaySetPicture = null;
- }
- if (mIsPaused) {
- nativeSetPauseDrawing(mNativeClass, true);
- }
- break;
- case UPDATE_TEXTFIELD_TEXT_MSG_ID:
- // Make sure that the textfield is currently focused
- // and representing the same node as the pointer.
- if (msg.arg2 == mTextGeneration) {
- String text = (String) msg.obj;
- if (null == text) {
- text = "";
- }
- if (inEditingMode() &&
- mWebTextView.isSameTextField(msg.arg1)) {
- mWebTextView.setTextAndKeepSelection(text);
- } else if (mInputConnection != null &&
- mFieldPointer == msg.arg1) {
- mInputConnection.setTextAndKeepSelection(text);
- }
- }
- break;
- case REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID:
- displaySoftKeyboard(true);
- // fall through to UPDATE_TEXT_SELECTION_MSG_ID
- case UPDATE_TEXT_SELECTION_MSG_ID:
- updateTextSelectionFromMessage(msg.arg1, msg.arg2,
- (WebViewCore.TextSelectionData) msg.obj);
- break;
- case FORM_DID_BLUR:
- if (inEditingMode()
- && mWebTextView.isSameTextField(msg.arg1)) {
- hideSoftKeyboard();
- }
- break;
- case RETURN_LABEL:
- if (inEditingMode()
- && mWebTextView.isSameTextField(msg.arg1)) {
- mWebTextView.setHint((String) msg.obj);
- InputMethodManager imm
- = InputMethodManager.peekInstance();
- // The hint is propagated to the IME in
- // onCreateInputConnection. If the IME is already
- // active, restart it so that its hint text is updated.
- if (imm != null && imm.isActive(mWebTextView)) {
- imm.restartInput(mWebTextView);
- }
- }
- break;
- case UNHANDLED_NAV_KEY:
- navHandledKey(msg.arg1, 1, false, 0);
- break;
- case UPDATE_TEXT_ENTRY_MSG_ID:
- // this is sent after finishing resize in WebViewCore. Make
- // sure the text edit box is still on the screen.
- if (inEditingMode() && nativeCursorIsTextInput()) {
- updateWebTextViewPosition();
- }
- break;
- case CLEAR_TEXT_ENTRY:
- clearTextEntry();
- break;
- case INVAL_RECT_MSG_ID: {
- Rect r = (Rect)msg.obj;
- if (r == null) {
- invalidate();
- } else {
- // we need to scale r from content into view coords,
- // which viewInvalidate() does for us
- viewInvalidate(r.left, r.top, r.right, r.bottom);
- }
- break;
- }
- case REQUEST_FORM_DATA:
- AutoCompleteAdapter adapter = (AutoCompleteAdapter) msg.obj;
- if (mWebTextView.isSameTextField(msg.arg1)) {
- mWebTextView.setAdapterCustom(adapter);
- }
- break;
-
- case LONG_PRESS_CENTER:
- // as this is shared by keydown and trackballdown, reset all
- // the states
- mGotCenterDown = false;
- mTrackballDown = false;
- performLongClick();
- break;
-
- case WEBCORE_NEED_TOUCH_EVENTS:
- mForwardTouchEvents = (msg.arg1 != 0);
- break;
-
- case PREVENT_TOUCH_ID:
- if (inFullScreenMode()) {
- break;
- }
- TouchEventData ted = (TouchEventData) msg.obj;
-
- if (mTouchEventQueue.enqueueTouchEvent(ted)) {
- // WebCore is responding to us; remove pending timeout.
- // It will be re-posted when needed.
- removeMessages(PREVENT_DEFAULT_TIMEOUT);
- }
- break;
-
- case REQUEST_KEYBOARD:
- if (msg.arg1 == 0) {
- hideSoftKeyboard();
- } else {
- displaySoftKeyboard(false);
- }
- break;
-
- case DRAG_HELD_MOTIONLESS:
- mHeldMotionless = MOTIONLESS_TRUE;
- invalidate();
- // fall through to keep scrollbars awake
-
- case AWAKEN_SCROLL_BARS:
- if (mTouchMode == TOUCH_DRAG_MODE
- && mHeldMotionless == MOTIONLESS_TRUE) {
- awakenScrollBars(ViewConfiguration
- .getScrollDefaultDelay(), false);
- mPrivateHandler.sendMessageDelayed(mPrivateHandler
- .obtainMessage(AWAKEN_SCROLL_BARS),
- ViewConfiguration.getScrollDefaultDelay());
- }
- break;
-
- case DO_MOTION_UP:
- doMotionUp(msg.arg1, msg.arg2);
- break;
-
- case SCREEN_ON:
- setKeepScreenOn(msg.arg1 == 1);
- break;
-
- case ENTER_FULLSCREEN_VIDEO:
- int layerId = msg.arg1;
-
- String url = (String) msg.obj;
- if (mHTML5VideoViewProxy != null) {
- mHTML5VideoViewProxy.enterFullScreenVideo(layerId, url);
- }
- break;
-
- case EXIT_FULLSCREEN_VIDEO:
- if (mHTML5VideoViewProxy != null) {
- mHTML5VideoViewProxy.exitFullScreenVideo();
- }
- break;
-
- case SHOW_FULLSCREEN: {
- View view = (View) msg.obj;
- int orientation = msg.arg1;
- int npp = msg.arg2;
-
- if (inFullScreenMode()) {
- Log.w(LOGTAG, "Should not have another full screen.");
- dismissFullScreenMode();
- }
- mFullScreenHolder = new PluginFullScreenHolder(WebView.this, orientation, npp);
- mFullScreenHolder.setContentView(view);
- mFullScreenHolder.show();
- invalidate();
-
- break;
- }
- case HIDE_FULLSCREEN:
- dismissFullScreenMode();
- break;
-
- case DOM_FOCUS_CHANGED:
- if (inEditingMode()) {
- nativeClearCursor();
- rebuildWebTextView();
- }
- break;
-
- case SHOW_RECT_MSG_ID: {
- WebViewCore.ShowRectData data = (WebViewCore.ShowRectData) msg.obj;
- int x = mScrollX;
- int left = contentToViewX(data.mLeft);
- int width = contentToViewDimension(data.mWidth);
- int maxWidth = contentToViewDimension(data.mContentWidth);
- int viewWidth = getViewWidth();
- if (width < viewWidth) {
- // center align
- x += left + width / 2 - mScrollX - viewWidth / 2;
- } else {
- x += (int) (left + data.mXPercentInDoc * width
- - mScrollX - data.mXPercentInView * viewWidth);
- }
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "showRectMsg=(left=" + left + ",width=" +
- width + ",maxWidth=" + maxWidth +
- ",viewWidth=" + viewWidth + ",x="
- + x + ",xPercentInDoc=" + data.mXPercentInDoc +
- ",xPercentInView=" + data.mXPercentInView+ ")");
- }
- // use the passing content width to cap x as the current
- // mContentWidth may not be updated yet
- x = Math.max(0,
- (Math.min(maxWidth, x + viewWidth)) - viewWidth);
- int top = contentToViewY(data.mTop);
- int height = contentToViewDimension(data.mHeight);
- int maxHeight = contentToViewDimension(data.mContentHeight);
- int viewHeight = getViewHeight();
- int y = (int) (top + data.mYPercentInDoc * height -
- data.mYPercentInView * viewHeight);
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "showRectMsg=(top=" + top + ",height=" +
- height + ",maxHeight=" + maxHeight +
- ",viewHeight=" + viewHeight + ",y="
- + y + ",yPercentInDoc=" + data.mYPercentInDoc +
- ",yPercentInView=" + data.mYPercentInView+ ")");
- }
- // use the passing content height to cap y as the current
- // mContentHeight may not be updated yet
- y = Math.max(0,
- (Math.min(maxHeight, y + viewHeight) - viewHeight));
- // We need to take into account the visible title height
- // when scrolling since y is an absolute view position.
- y = Math.max(0, y - getVisibleTitleHeightImpl());
- scrollTo(x, y);
- }
- break;
-
- case CENTER_FIT_RECT:
- centerFitRect((Rect)msg.obj);
- break;
-
- case SET_SCROLLBAR_MODES:
- mHorizontalScrollBarMode = msg.arg1;
- mVerticalScrollBarMode = msg.arg2;
- break;
-
- case SELECTION_STRING_CHANGED:
- if (mAccessibilityInjector != null) {
- String selectionString = (String) msg.obj;
- mAccessibilityInjector.onSelectionStringChange(selectionString);
- }
- break;
-
- case HIT_TEST_RESULT:
- WebKitHitTest hit = (WebKitHitTest) msg.obj;
- mFocusedNode = hit;
- setTouchHighlightRects(hit);
- setHitTestResult(hit);
- break;
-
- case SAVE_WEBARCHIVE_FINISHED:
- SaveWebArchiveMessage saveMessage = (SaveWebArchiveMessage)msg.obj;
- if (saveMessage.mCallback != null) {
- saveMessage.mCallback.onReceiveValue(saveMessage.mResultFile);
- }
- break;
-
- case SET_AUTOFILLABLE:
- mAutoFillData = (WebViewCore.AutoFillData) msg.obj;
- if (mWebTextView != null) {
- mWebTextView.setAutoFillable(mAutoFillData.getQueryId());
- rebuildWebTextView();
- }
- break;
-
- case AUTOFILL_COMPLETE:
- if (mWebTextView != null) {
- // Clear the WebTextView adapter when AutoFill finishes
- // so that the drop down gets cleared.
- mWebTextView.setAdapterCustom(null);
- }
- break;
-
- case SELECT_AT:
- nativeSelectAt(msg.arg1, msg.arg2);
- break;
-
- case COPY_TO_CLIPBOARD:
- copyToClipboard((String) msg.obj);
- break;
-
- case INIT_EDIT_FIELD:
- if (mInputConnection != null) {
- TextFieldInitData initData = (TextFieldInitData) msg.obj;
- mTextGeneration = 0;
- mFieldPointer = initData.mFieldPointer;
- mInputConnection.initEditorInfo(initData);
- mInputConnection.setTextAndKeepSelection(initData.mText);
- }
- break;
-
- case REPLACE_TEXT:{
- String text = (String)msg.obj;
- int start = msg.arg1;
- int end = msg.arg2;
- int cursorPosition = start + text.length();
- replaceTextfieldText(start, end, text,
- cursorPosition, cursorPosition);
- break;
- }
-
- case UPDATE_MATCH_COUNT: {
- if (mFindCallback != null) {
- mFindCallback.updateMatchCount(msg.arg1, msg.arg2,
- (String) msg.obj);
- }
- break;
- }
- case CLEAR_CARET_HANDLE:
- selectionDone();
- break;
-
- case KEY_PRESS:
- mWebViewCore.sendMessage(EventHub.KEY_PRESS, msg.arg1);
- break;
-
- default:
- super.handleMessage(msg);
- break;
- }
- }
- }
+ // TODO: Add a test that enumerates all methods in ViewDelegte & ScrollDelegate, and ensures
+ // there's a corresponding override (or better, caller) for each of them in here.
- private void setHitTestTypeFromUrl(String url) {
- String substr = null;
- if (url.startsWith(SCHEME_GEO)) {
- mInitialHitTestResult.mType = HitTestResult.GEO_TYPE;
- substr = url.substring(SCHEME_GEO.length());
- } else if (url.startsWith(SCHEME_TEL)) {
- mInitialHitTestResult.mType = HitTestResult.PHONE_TYPE;
- substr = url.substring(SCHEME_TEL.length());
- } else if (url.startsWith(SCHEME_MAILTO)) {
- mInitialHitTestResult.mType = HitTestResult.EMAIL_TYPE;
- substr = url.substring(SCHEME_MAILTO.length());
- } else {
- mInitialHitTestResult.mType = HitTestResult.SRC_ANCHOR_TYPE;
- mInitialHitTestResult.mExtra = url;
- return;
- }
- try {
- mInitialHitTestResult.mExtra = URLDecoder.decode(substr, "UTF-8");
- } catch (Throwable e) {
- Log.w(LOGTAG, "Failed to decode URL! " + substr, e);
- mInitialHitTestResult.mType = HitTestResult.UNKNOWN_TYPE;
- }
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mProvider.getViewDelegate().onAttachedToWindow();
}
- private void setHitTestResult(WebKitHitTest hit) {
- if (hit == null) {
- mInitialHitTestResult = null;
- return;
- }
- mInitialHitTestResult = new HitTestResult();
- if (hit.mLinkUrl != null) {
- setHitTestTypeFromUrl(hit.mLinkUrl);
- if (hit.mImageUrl != null
- && mInitialHitTestResult.mType == HitTestResult.SRC_ANCHOR_TYPE) {
- mInitialHitTestResult.mType = HitTestResult.SRC_IMAGE_ANCHOR_TYPE;
- mInitialHitTestResult.mExtra = hit.mImageUrl;
- }
- } else if (hit.mImageUrl != null) {
- mInitialHitTestResult.mType = HitTestResult.IMAGE_TYPE;
- mInitialHitTestResult.mExtra = hit.mImageUrl;
- } else if (hit.mEditable) {
- mInitialHitTestResult.mType = HitTestResult.EDIT_TEXT_TYPE;
- } else if (hit.mIntentUrl != null) {
- setHitTestTypeFromUrl(hit.mIntentUrl);
- }
+ @Override
+ protected void onDetachedFromWindow() {
+ mProvider.getViewDelegate().onDetachedFromWindow();
+ super.onDetachedFromWindow();
}
- private boolean shouldDrawHighlightRect() {
- if (mFocusedNode == null || mInitialHitTestResult == null) {
- return false;
- }
- if (mTouchHighlightRegion.isEmpty()) {
- return false;
- }
- if (mFocusedNode.mHasFocus && !isInTouchMode()) {
- return !mFocusedNode.mEditable;
- }
- if (mInitialHitTestResult.mType == HitTestResult.UNKNOWN_TYPE) {
- return false;
- }
- long delay = System.currentTimeMillis() - mTouchHighlightRequested;
- if (delay < ViewConfiguration.getTapTimeout()) {
- Rect r = mTouchHighlightRegion.getBounds();
- postInvalidateDelayed(delay, r.left, r.top, r.right, r.bottom);
- return false;
- }
- return true;
+ @Override
+ public void setLayoutParams(ViewGroup.LayoutParams params) {
+ mProvider.getViewDelegate().setLayoutParams(params);
}
-
- private FocusTransitionDrawable mFocusTransition = null;
- static class FocusTransitionDrawable extends Drawable {
- Region mPreviousRegion;
- Region mNewRegion;
- float mProgress = 0;
- WebView mWebView;
- Paint mPaint;
- int mMaxAlpha;
- Point mTranslate;
-
- public FocusTransitionDrawable(WebView view) {
- mWebView = view;
- mPaint = new Paint(mWebView.mTouchHightlightPaint);
- mMaxAlpha = mPaint.getAlpha();
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- }
-
- @Override
- public void setAlpha(int alpha) {
- }
-
- @Override
- public int getOpacity() {
- return 0;
- }
-
- public void setProgress(float p) {
- mProgress = p;
- if (mWebView.mFocusTransition == this) {
- if (mProgress == 1f)
- mWebView.mFocusTransition = null;
- mWebView.invalidate();
- }
- }
-
- public float getProgress() {
- return mProgress;
- }
-
- @Override
- public void draw(Canvas canvas) {
- if (mTranslate == null) {
- Rect bounds = mPreviousRegion.getBounds();
- Point from = new Point(bounds.centerX(), bounds.centerY());
- mNewRegion.getBounds(bounds);
- Point to = new Point(bounds.centerX(), bounds.centerY());
- mTranslate = new Point(from.x - to.x, from.y - to.y);
- }
- int alpha = (int) (mProgress * mMaxAlpha);
- RegionIterator iter = new RegionIterator(mPreviousRegion);
- Rect r = new Rect();
- mPaint.setAlpha(mMaxAlpha - alpha);
- float tx = mTranslate.x * mProgress;
- float ty = mTranslate.y * mProgress;
- int save = canvas.save(Canvas.MATRIX_SAVE_FLAG);
- canvas.translate(-tx, -ty);
- while (iter.next(r)) {
- canvas.drawRect(r, mPaint);
- }
- canvas.restoreToCount(save);
- iter = new RegionIterator(mNewRegion);
- r = new Rect();
- mPaint.setAlpha(alpha);
- save = canvas.save(Canvas.MATRIX_SAVE_FLAG);
- tx = mTranslate.x - tx;
- ty = mTranslate.y - ty;
- canvas.translate(tx, ty);
- while (iter.next(r)) {
- canvas.drawRect(r, mPaint);
- }
- canvas.restoreToCount(save);
- }
- };
-
- private boolean shouldAnimateTo(WebKitHitTest hit) {
- // TODO: Don't be annoying or throw out the animation entirely
- return false;
+ @Override
+ public void setOverScrollMode(int mode) {
+ super.setOverScrollMode(mode);
+ // This method may called in the constructor chain, before the WebView provider is
+ // created. (Fortunately, this is the only method we override that can get called by
+ // any of the base class constructors).
+ ensureProviderCreated();
+ mProvider.getViewDelegate().setOverScrollMode(mode);
}
- private void setTouchHighlightRects(WebKitHitTest hit) {
- FocusTransitionDrawable transition = null;
- if (shouldAnimateTo(hit)) {
- transition = new FocusTransitionDrawable(this);
- }
- Rect[] rects = hit != null ? hit.mTouchRects : null;
- if (!mTouchHighlightRegion.isEmpty()) {
- invalidate(mTouchHighlightRegion.getBounds());
- if (transition != null) {
- transition.mPreviousRegion = new Region(mTouchHighlightRegion);
- }
- mTouchHighlightRegion.setEmpty();
- }
- if (rects != null) {
- mTouchHightlightPaint.setColor(hit.mTapHighlightColor);
- for (Rect rect : rects) {
- Rect viewRect = contentToViewRect(rect);
- // some sites, like stories in nytimes.com, set
- // mouse event handler in the top div. It is not
- // user friendly to highlight the div if it covers
- // more than half of the screen.
- if (viewRect.width() < getWidth() >> 1
- || viewRect.height() < getHeight() >> 1) {
- mTouchHighlightRegion.union(viewRect);
- } else {
- Log.w(LOGTAG, "Skip the huge selection rect:"
- + viewRect);
- }
- }
- invalidate(mTouchHighlightRegion.getBounds());
- if (transition != null && transition.mPreviousRegion != null) {
- transition.mNewRegion = new Region(mTouchHighlightRegion);
- mFocusTransition = transition;
- ObjectAnimator animator = ObjectAnimator.ofFloat(
- mFocusTransition, "progress", 1f);
- animator.start();
- }
- }
+ @Override
+ public void setScrollBarStyle(int style) {
+ mProvider.getViewDelegate().setScrollBarStyle(style);
+ super.setScrollBarStyle(style);
}
- /** @hide Called by JNI when pages are swapped (only occurs with hardware
- * acceleration) */
- protected void pageSwapCallback(boolean notifyAnimationStarted) {
- mWebViewCore.resumeWebKitDraw();
- if (inEditingMode()) {
- didUpdateWebTextViewDimensions(ANYWHERE);
- }
- if (notifyAnimationStarted) {
- mWebViewCore.sendMessage(EventHub.NOTIFY_ANIMATION_STARTED);
- }
+ @Override
+ protected int computeHorizontalScrollRange() {
+ return mProvider.getScrollDelegate().computeHorizontalScrollRange();
}
- void setNewPicture(final WebViewCore.DrawData draw, boolean updateBaseLayer) {
- if (mNativeClass == 0) {
- if (mDelaySetPicture != null) {
- throw new IllegalStateException("Tried to setNewPicture with"
- + " a delay picture already set! (memory leak)");
- }
- // Not initialized yet, delay set
- mDelaySetPicture = draw;
- return;
- }
- WebViewCore.ViewState viewState = draw.mViewState;
- boolean isPictureAfterFirstLayout = viewState != null;
-
- if (updateBaseLayer) {
- setBaseLayer(draw.mBaseLayer, draw.mInvalRegion,
- getSettings().getShowVisualIndicator(),
- isPictureAfterFirstLayout);
- }
- final Point viewSize = draw.mViewSize;
- // We update the layout (i.e. request a layout from the
- // view system) if the last view size that we sent to
- // WebCore matches the view size of the picture we just
- // received in the fixed dimension.
- final boolean updateLayout = viewSize.x == mLastWidthSent
- && viewSize.y == mLastHeightSent;
- // Don't send scroll event for picture coming from webkit,
- // since the new picture may cause a scroll event to override
- // the saved history scroll position.
- mSendScrollEvent = false;
- recordNewContentSize(draw.mContentSize.x,
- draw.mContentSize.y, updateLayout);
- if (isPictureAfterFirstLayout) {
- // Reset the last sent data here since dealing with new page.
- mLastWidthSent = 0;
- mZoomManager.onFirstLayout(draw);
- int scrollX = viewState.mShouldStartScrolledRight
- ? getContentWidth() : viewState.mScrollX;
- int scrollY = viewState.mScrollY;
- setContentScrollTo(scrollX, scrollY);
- if (!mDrawHistory) {
- // As we are on a new page, remove the WebTextView. This
- // is necessary for page loads driven by webkit, and in
- // particular when the user was on a password field, so
- // the WebTextView was visible.
- clearTextEntry();
- }
- }
- mSendScrollEvent = true;
-
- if (DebugFlags.WEB_VIEW) {
- Rect b = draw.mInvalRegion.getBounds();
- Log.v(LOGTAG, "NEW_PICTURE_MSG_ID {" +
- b.left+","+b.top+","+b.right+","+b.bottom+"}");
- }
- invalidateContentRect(draw.mInvalRegion.getBounds());
-
- if (mPictureListener != null) {
- mPictureListener.onNewPicture(WebView.this, capturePicture());
- }
-
- // update the zoom information based on the new picture
- mZoomManager.onNewPicture(draw);
-
- if (draw.mFocusSizeChanged && inEditingMode()) {
- mFocusSizeChanged = true;
- }
- if (isPictureAfterFirstLayout) {
- mViewManager.postReadyToDrawAll();
- }
+ @Override
+ protected int computeHorizontalScrollOffset() {
+ return mProvider.getScrollDelegate().computeHorizontalScrollOffset();
}
- /**
- * Used when receiving messages for REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID
- * and UPDATE_TEXT_SELECTION_MSG_ID. Update the selection of WebTextView.
- */
- private void updateTextSelectionFromMessage(int nodePointer,
- int textGeneration, WebViewCore.TextSelectionData data) {
- if (textGeneration == mTextGeneration) {
- if (inEditingMode()
- && mWebTextView.isSameTextField(nodePointer)) {
- mWebTextView.setSelectionFromWebKit(data.mStart, data.mEnd);
- } else if (mInputConnection != null && mFieldPointer == nodePointer) {
- mInputConnection.setSelection(data.mStart, data.mEnd);
- }
- }
- nativeSetTextSelection(mNativeClass, data.mSelectTextPtr);
-
- if (data.mSelectTextPtr != 0 &&
- (data.mStart != data.mEnd ||
- (mFieldPointer == nodePointer && mFieldPointer != 0))) {
- mIsCaretSelection = (data.mStart == data.mEnd);
- if (!mSelectingText) {
- setupWebkitSelect();
- } else if (!mSelectionStarted) {
- syncSelectionCursors();
- }
- if (mIsCaretSelection) {
- resetCaretTimer();
- }
- } else {
- selectionDone();
- }
- invalidate();
- }
-
- // Class used to use a dropdown for a <select> element
- private class InvokeListBox implements Runnable {
- // Whether the listbox allows multiple selection.
- private boolean mMultiple;
- // Passed in to a list with multiple selection to tell
- // which items are selected.
- private int[] mSelectedArray;
- // Passed in to a list with single selection to tell
- // where the initial selection is.
- private int mSelection;
-
- private Container[] mContainers;
-
- // Need these to provide stable ids to my ArrayAdapter,
- // which normally does not have stable ids. (Bug 1250098)
- private class Container extends Object {
- /**
- * Possible values for mEnabled. Keep in sync with OptionStatus in
- * WebViewCore.cpp
- */
- final static int OPTGROUP = -1;
- final static int OPTION_DISABLED = 0;
- final static int OPTION_ENABLED = 1;
-
- String mString;
- int mEnabled;
- int mId;
-
- @Override
- public String toString() {
- return mString;
- }
- }
-
- /**
- * Subclass ArrayAdapter so we can disable OptionGroupLabels,
- * and allow filtering.
- */
- private class MyArrayListAdapter extends ArrayAdapter<Container> {
- public MyArrayListAdapter() {
- super(mContext,
- mMultiple ? com.android.internal.R.layout.select_dialog_multichoice :
- com.android.internal.R.layout.webview_select_singlechoice,
- mContainers);
- }
-
- @Override
- public View getView(int position, View convertView,
- ViewGroup parent) {
- // Always pass in null so that we will get a new CheckedTextView
- // Otherwise, an item which was previously used as an <optgroup>
- // element (i.e. has no check), could get used as an <option>
- // element, which needs a checkbox/radio, but it would not have
- // one.
- convertView = super.getView(position, null, parent);
- Container c = item(position);
- if (c != null && Container.OPTION_ENABLED != c.mEnabled) {
- // ListView does not draw dividers between disabled and
- // enabled elements. Use a LinearLayout to provide dividers
- LinearLayout layout = new LinearLayout(mContext);
- layout.setOrientation(LinearLayout.VERTICAL);
- if (position > 0) {
- View dividerTop = new View(mContext);
- dividerTop.setBackgroundResource(
- android.R.drawable.divider_horizontal_bright);
- layout.addView(dividerTop);
- }
-
- if (Container.OPTGROUP == c.mEnabled) {
- // Currently select_dialog_multichoice uses CheckedTextViews.
- // If that changes, the class cast will no longer be valid.
- if (mMultiple) {
- Assert.assertTrue(convertView instanceof CheckedTextView);
- ((CheckedTextView) convertView).setCheckMarkDrawable(null);
- }
- } else {
- // c.mEnabled == Container.OPTION_DISABLED
- // Draw the disabled element in a disabled state.
- convertView.setEnabled(false);
- }
-
- layout.addView(convertView);
- if (position < getCount() - 1) {
- View dividerBottom = new View(mContext);
- dividerBottom.setBackgroundResource(
- android.R.drawable.divider_horizontal_bright);
- layout.addView(dividerBottom);
- }
- return layout;
- }
- return convertView;
- }
-
- @Override
- public boolean hasStableIds() {
- // AdapterView's onChanged method uses this to determine whether
- // to restore the old state. Return false so that the old (out
- // of date) state does not replace the new, valid state.
- return false;
- }
-
- private Container item(int position) {
- if (position < 0 || position >= getCount()) {
- return null;
- }
- return getItem(position);
- }
-
- @Override
- public long getItemId(int position) {
- Container item = item(position);
- if (item == null) {
- return -1;
- }
- return item.mId;
- }
-
- @Override
- public boolean areAllItemsEnabled() {
- return false;
- }
-
- @Override
- public boolean isEnabled(int position) {
- Container item = item(position);
- if (item == null) {
- return false;
- }
- return Container.OPTION_ENABLED == item.mEnabled;
- }
- }
-
- private InvokeListBox(String[] array, int[] enabled, int[] selected) {
- mMultiple = true;
- mSelectedArray = selected;
-
- int length = array.length;
- mContainers = new Container[length];
- for (int i = 0; i < length; i++) {
- mContainers[i] = new Container();
- mContainers[i].mString = array[i];
- mContainers[i].mEnabled = enabled[i];
- mContainers[i].mId = i;
- }
- }
-
- private InvokeListBox(String[] array, int[] enabled, int selection) {
- mSelection = selection;
- mMultiple = false;
-
- int length = array.length;
- mContainers = new Container[length];
- for (int i = 0; i < length; i++) {
- mContainers[i] = new Container();
- mContainers[i].mString = array[i];
- mContainers[i].mEnabled = enabled[i];
- mContainers[i].mId = i;
- }
- }
+ @Override
+ protected int computeVerticalScrollRange() {
+ return mProvider.getScrollDelegate().computeVerticalScrollRange();
+ }
- /*
- * Whenever the data set changes due to filtering, this class ensures
- * that the checked item remains checked.
- */
- private class SingleDataSetObserver extends DataSetObserver {
- private long mCheckedId;
- private ListView mListView;
- private Adapter mAdapter;
-
- /*
- * Create a new observer.
- * @param id The ID of the item to keep checked.
- * @param l ListView for getting and clearing the checked states
- * @param a Adapter for getting the IDs
- */
- public SingleDataSetObserver(long id, ListView l, Adapter a) {
- mCheckedId = id;
- mListView = l;
- mAdapter = a;
- }
-
- @Override
- public void onChanged() {
- // The filter may have changed which item is checked. Find the
- // item that the ListView thinks is checked.
- int position = mListView.getCheckedItemPosition();
- long id = mAdapter.getItemId(position);
- if (mCheckedId != id) {
- // Clear the ListView's idea of the checked item, since
- // it is incorrect
- mListView.clearChoices();
- // Search for mCheckedId. If it is in the filtered list,
- // mark it as checked
- int count = mAdapter.getCount();
- for (int i = 0; i < count; i++) {
- if (mAdapter.getItemId(i) == mCheckedId) {
- mListView.setItemChecked(i, true);
- break;
- }
- }
- }
- }
- }
+ @Override
+ protected int computeVerticalScrollOffset() {
+ return mProvider.getScrollDelegate().computeVerticalScrollOffset();
+ }
- @Override
- public void run() {
- final ListView listView = (ListView) LayoutInflater.from(mContext)
- .inflate(com.android.internal.R.layout.select_dialog, null);
- final MyArrayListAdapter adapter = new MyArrayListAdapter();
- AlertDialog.Builder b = new AlertDialog.Builder(mContext)
- .setView(listView).setCancelable(true)
- .setInverseBackgroundForced(true);
-
- if (mMultiple) {
- b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mWebViewCore.sendMessage(
- EventHub.LISTBOX_CHOICES,
- adapter.getCount(), 0,
- listView.getCheckedItemPositions());
- }});
- b.setNegativeButton(android.R.string.cancel,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mWebViewCore.sendMessage(
- EventHub.SINGLE_LISTBOX_CHOICE, -2, 0);
- }});
- }
- mListBoxDialog = b.create();
- listView.setAdapter(adapter);
- listView.setFocusableInTouchMode(true);
- // There is a bug (1250103) where the checks in a ListView with
- // multiple items selected are associated with the positions, not
- // the ids, so the items do not properly retain their checks when
- // filtered. Do not allow filtering on multiple lists until
- // that bug is fixed.
-
- listView.setTextFilterEnabled(!mMultiple);
- if (mMultiple) {
- listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
- int length = mSelectedArray.length;
- for (int i = 0; i < length; i++) {
- listView.setItemChecked(mSelectedArray[i], true);
- }
- } else {
- listView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View v,
- int position, long id) {
- // Rather than sending the message right away, send it
- // after the page regains focus.
- mListBoxMessage = Message.obtain(null,
- EventHub.SINGLE_LISTBOX_CHOICE, (int) id, 0);
- mListBoxDialog.dismiss();
- mListBoxDialog = null;
- }
- });
- if (mSelection != -1) {
- listView.setSelection(mSelection);
- listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
- listView.setItemChecked(mSelection, true);
- DataSetObserver observer = new SingleDataSetObserver(
- adapter.getItemId(mSelection), listView, adapter);
- adapter.registerDataSetObserver(observer);
- }
- }
- mListBoxDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- mWebViewCore.sendMessage(
- EventHub.SINGLE_LISTBOX_CHOICE, -2, 0);
- mListBoxDialog = null;
- }
- });
- mListBoxDialog.show();
- }
+ @Override
+ protected int computeVerticalScrollExtent() {
+ return mProvider.getScrollDelegate().computeVerticalScrollExtent();
}
- private Message mListBoxMessage;
+ @Override
+ public void computeScroll() {
+ mProvider.getScrollDelegate().computeScroll();
+ }
- /*
- * Request a dropdown menu for a listbox with multiple selection.
- *
- * @param array Labels for the listbox.
- * @param enabledArray State for each element in the list. See static
- * integers in Container class.
- * @param selectedArray Which positions are initally selected.
- */
- void requestListBox(String[] array, int[] enabledArray, int[]
- selectedArray) {
- mPrivateHandler.post(
- new InvokeListBox(array, enabledArray, selectedArray));
+ @Override
+ public boolean onHoverEvent(MotionEvent event) {
+ return mProvider.getViewDelegate().onHoverEvent(event);
}
- /*
- * Request a dropdown menu for a listbox with single selection or a single
- * <select> element.
- *
- * @param array Labels for the listbox.
- * @param enabledArray State for each element in the list. See static
- * integers in Container class.
- * @param selection Which position is initally selected.
- */
- void requestListBox(String[] array, int[] enabledArray, int selection) {
- mPrivateHandler.post(
- new InvokeListBox(array, enabledArray, selection));
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return mProvider.getViewDelegate().onTouchEvent(event);
}
- // called by JNI
- private void sendMoveFocus(int frame, int node) {
- mWebViewCore.sendMessage(EventHub.SET_MOVE_FOCUS,
- new WebViewCore.CursorData(frame, node, 0, 0));
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ return mProvider.getViewDelegate().onGenericMotionEvent(event);
}
- // called by JNI
- private void sendMoveMouse(int frame, int node, int x, int y) {
- mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE,
- new WebViewCore.CursorData(frame, node, x, y));
+ @Override
+ public boolean onTrackballEvent(MotionEvent event) {
+ return mProvider.getViewDelegate().onTrackballEvent(event);
}
- /*
- * Send a mouse move event to the webcore thread.
- *
- * @param removeFocus Pass true to remove the WebTextView, if present.
- * @param stopPaintingCaret Stop drawing the blinking caret if true.
- * called by JNI
- */
- @SuppressWarnings("unused")
- private void sendMoveMouseIfLatest(boolean removeFocus, boolean stopPaintingCaret) {
- if (removeFocus) {
- clearTextEntry();
- }
- mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE_IF_LATEST,
- stopPaintingCaret ? 1 : 0, 0,
- cursorData());
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ return mProvider.getViewDelegate().onKeyDown(keyCode, event);
}
- /**
- * Called by JNI to send a message to the webcore thread that the user
- * touched the webpage.
- * @param touchGeneration Generation number of the touch, to ignore touches
- * after a new one has been generated.
- * @param frame Pointer to the frame holding the node that was touched.
- * @param node Pointer to the node touched.
- * @param x x-position of the touch.
- * @param y y-position of the touch.
- */
- private void sendMotionUp(int touchGeneration,
- int frame, int node, int x, int y) {
- WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
- touchUpData.mMoveGeneration = touchGeneration;
- touchUpData.mFrame = frame;
- touchUpData.mNode = node;
- touchUpData.mX = x;
- touchUpData.mY = y;
- touchUpData.mNativeLayer = nativeScrollableLayer(
- x, y, touchUpData.mNativeLayerRect, null);
- mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData);
- }
-
-
- private int getScaledMaxXScroll() {
- int width;
- if (mHeightCanMeasure == false) {
- width = getViewWidth() / 4;
- } else {
- Rect visRect = new Rect();
- calcOurVisibleRect(visRect);
- width = visRect.width() / 2;
- }
- // FIXME the divisor should be retrieved from somewhere
- return viewToContentX(width);
- }
-
- private int getScaledMaxYScroll() {
- int height;
- if (mHeightCanMeasure == false) {
- height = getViewHeight() / 4;
- } else {
- Rect visRect = new Rect();
- calcOurVisibleRect(visRect);
- height = visRect.height() / 2;
- }
- // FIXME the divisor should be retrieved from somewhere
- // the closest thing today is hard-coded into ScrollView.java
- // (from ScrollView.java, line 363) int maxJump = height/2;
- return Math.round(height * mZoomManager.getInvScale());
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ return mProvider.getViewDelegate().onKeyUp(keyCode, event);
}
- /**
- * Called by JNI to invalidate view
- */
- private void viewInvalidate() {
- invalidate();
+ @Override
+ public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
+ return mProvider.getViewDelegate().onKeyMultiple(keyCode, repeatCount, event);
}
- /**
- * Pass the key directly to the page. This assumes that
- * nativePageShouldHandleShiftAndArrows() returned true.
- */
- private void letPageHandleNavKey(int keyCode, long time, boolean down, int metaState) {
- int keyEventAction;
- int eventHubAction;
- if (down) {
- keyEventAction = KeyEvent.ACTION_DOWN;
- eventHubAction = EventHub.KEY_DOWN;
- playSoundEffect(keyCodeToSoundsEffect(keyCode));
- } else {
- keyEventAction = KeyEvent.ACTION_UP;
- eventHubAction = EventHub.KEY_UP;
- }
+ /*
+ TODO: These are not currently implemented in WebViewClassic, but it seems inconsistent not
+ to be delegating them too.
- KeyEvent event = new KeyEvent(time, time, keyEventAction, keyCode,
- 1, (metaState & KeyEvent.META_SHIFT_ON)
- | (metaState & KeyEvent.META_ALT_ON)
- | (metaState & KeyEvent.META_SYM_ON)
- , KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0);
- mWebViewCore.sendMessage(eventHubAction, event);
+ @Override
+ public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+ return mProvider.getViewDelegate().onKeyPreIme(keyCode, event);
}
-
- // return true if the key was handled
- private boolean navHandledKey(int keyCode, int count, boolean noScroll,
- long time) {
- if (mNativeClass == 0) {
- return false;
- }
- mInitialHitTestResult = null;
- mLastCursorTime = time;
- mLastCursorBounds = cursorRingBounds();
- boolean keyHandled
- = nativeMoveCursor(keyCode, count, noScroll) == false;
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "navHandledKey mLastCursorBounds=" + mLastCursorBounds
- + " mLastCursorTime=" + mLastCursorTime
- + " handled=" + keyHandled);
- }
- if (keyHandled == false) {
- return keyHandled;
- }
- Rect contentCursorRingBounds = cursorRingBounds();
- if (contentCursorRingBounds.isEmpty()) return keyHandled;
- Rect viewCursorRingBounds = contentToViewRect(contentCursorRingBounds);
- // set last touch so that context menu related functions will work
- mLastTouchX = (viewCursorRingBounds.left + viewCursorRingBounds.right) / 2;
- mLastTouchY = (viewCursorRingBounds.top + viewCursorRingBounds.bottom) / 2;
- if (mHeightCanMeasure == false) {
- return keyHandled;
- }
- Rect visRect = new Rect();
- calcOurVisibleRect(visRect);
- Rect outset = new Rect(visRect);
- int maxXScroll = visRect.width() / 2;
- int maxYScroll = visRect.height() / 2;
- outset.inset(-maxXScroll, -maxYScroll);
- if (Rect.intersects(outset, viewCursorRingBounds) == false) {
- return keyHandled;
- }
- // FIXME: Necessary because ScrollView/ListView do not scroll left/right
- int maxH = Math.min(viewCursorRingBounds.right - visRect.right,
- maxXScroll);
- if (maxH > 0) {
- pinScrollBy(maxH, 0, true, 0);
- } else {
- maxH = Math.max(viewCursorRingBounds.left - visRect.left,
- -maxXScroll);
- if (maxH < 0) {
- pinScrollBy(maxH, 0, true, 0);
- }
- }
- if (mLastCursorBounds.isEmpty()) return keyHandled;
- if (mLastCursorBounds.equals(contentCursorRingBounds)) {
- return keyHandled;
- }
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "navHandledKey contentCursorRingBounds="
- + contentCursorRingBounds);
- }
- requestRectangleOnScreen(viewCursorRingBounds);
- return keyHandled;
+ @Override
+ public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+ return mProvider.getViewDelegate().onKeyLongPress(keyCode, event);
}
-
- /**
- * @return Whether accessibility script has been injected.
- */
- private boolean accessibilityScriptInjected() {
- // TODO: Maybe the injected script should announce its presence in
- // the page meta-tag so the nativePageShouldHandleShiftAndArrows
- // will check that as one of the conditions it looks for
- return mAccessibilityScriptInjected;
+ @Override
+ public boolean onKeyShortcut(int keyCode, KeyEvent event) {
+ return mProvider.getViewDelegate().onKeyShortcut(keyCode, event);
}
+ */
- /**
- * Set the background color. It's white by default. Pass
- * zero to make the view transparent.
- * @param color the ARGB color described by Color.java
- */
+ @Deprecated
@Override
- public void setBackgroundColor(int color) {
- mBackgroundColor = color;
- mWebViewCore.sendMessage(EventHub.SET_BACKGROUND_COLOR, color);
+ public boolean shouldDelayChildPressedState() {
+ return mProvider.getViewDelegate().shouldDelayChildPressedState();
}
- /**
- * @deprecated This method is now obsolete.
- */
- @Deprecated
- public void debugDump() {
- checkThread();
- nativeDebugDump();
- mWebViewCore.sendMessage(EventHub.DUMP_NAVTREE);
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ mProvider.getViewDelegate().onInitializeAccessibilityNodeInfo(info);
}
- /**
- * Draw the HTML page into the specified canvas. This call ignores any
- * view-specific zoom, scroll offset, or other changes. It does not draw
- * any view-specific chrome, such as progress or URL bars.
- *
- * @hide only needs to be accessible to Browser and testing
- */
- public void drawPage(Canvas canvas) {
- calcOurContentVisibleRectF(mVisibleContentRect);
- nativeDraw(canvas, mVisibleContentRect, 0, 0, false);
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+ mProvider.getViewDelegate().onInitializeAccessibilityEvent(event);
}
- /**
- * Enable the communication b/t the webView and VideoViewProxy
- *
- * @hide only used by the Browser
- */
- public void setHTML5VideoViewProxy(HTML5VideoViewProxy proxy) {
- mHTML5VideoViewProxy = proxy;
+ /** @hide */
+ @Override
+ protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
+ int l, int t, int r, int b) {
+ mProvider.getViewDelegate().onDrawVerticalScrollBar(canvas, scrollBar, l, t, r, b);
}
- /**
- * Set the time to wait between passing touches to WebCore. See also the
- * TOUCH_SENT_INTERVAL member for further discussion.
- *
- * @hide This is only used by the DRT test application.
- */
- public void setTouchInterval(int interval) {
- mCurrentTouchInterval = interval;
+ @Override
+ protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
+ mProvider.getViewDelegate().onOverScrolled(scrollX, scrollY, clampedX, clampedY);
}
- /**
- * Copy text into the clipboard. This is called indirectly from
- * WebViewCore.
- * @param text The text to put into the clipboard.
- */
- private void copyToClipboard(String text) {
- ClipboardManager cm = (ClipboardManager)getContext()
- .getSystemService(Context.CLIPBOARD_SERVICE);
- ClipData clip = ClipData.newPlainText(getTitle(), text);
- cm.setPrimaryClip(clip);
+ @Override
+ protected void onWindowVisibilityChanged(int visibility) {
+ super.onWindowVisibilityChanged(visibility);
+ mProvider.getViewDelegate().onWindowVisibilityChanged(visibility);
}
- /**
- * Update our cache with updatedText.
- * @param updatedText The new text to put in our cache.
- * @hide
- */
- protected void updateCachedTextfield(String updatedText) {
- // Also place our generation number so that when we look at the cache
- // we recognize that it is up to date.
- nativeUpdateCachedTextfield(updatedText, mTextGeneration);
+ @Override
+ protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+ // Not using short-circuit OR: provider does suppress base-class call.
+ return mProvider.getViewDelegate().drawChild(canvas, child, drawingTime) |
+ super.drawChild(canvas, child, drawingTime);
}
- /*package*/ void autoFillForm(int autoFillQueryId) {
- mWebViewCore.sendMessage(EventHub.AUTOFILL_FORM, autoFillQueryId, /* unused */0);
+ @Override
+ protected void onDraw(Canvas canvas) {
+ mProvider.getViewDelegate().onDraw(canvas);
}
- /* package */ ViewManager getViewManager() {
- return mViewManager;
+ @Override
+ public boolean performLongClick() {
+ return mProvider.getViewDelegate().performLongClick();
}
- private static void checkThread() {
- if (Looper.myLooper() != Looper.getMainLooper()) {
- Throwable throwable = new Throwable(
- "Warning: A WebView method was called on thread '" +
- Thread.currentThread().getName() + "'. " +
- "All WebView methods must be called on the UI thread. " +
- "Future versions of WebView may not support use on other threads.");
- Log.w(LOGTAG, Log.getStackTraceString(throwable));
- StrictMode.onWebViewMethodCalledOnWrongThread(throwable);
- }
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ mProvider.getViewDelegate().onConfigurationChanged(newConfig);
}
- /** @hide send content invalidate */
- protected void contentInvalidateAll() {
- if (mWebViewCore != null && !mBlockWebkitViewMessages) {
- mWebViewCore.sendMessage(EventHub.CONTENT_INVALIDATE_ALL);
- }
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ return mProvider.getViewDelegate().onCreateInputConnection(outAttrs);
}
- /** @hide discard all textures from tiles */
- protected void discardAllTextures() {
- nativeDiscardAllTextures();
+ @Override
+ protected void onVisibilityChanged(View changedView, int visibility) {
+ super.onVisibilityChanged(changedView, visibility);
+ mProvider.getViewDelegate().onVisibilityChanged(changedView, visibility);
}
- /**
- * Begin collecting per-tile profiling data
- *
- * @hide only used by profiling tests
- */
- public void tileProfilingStart() {
- nativeTileProfilingStart();
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ mProvider.getViewDelegate().onWindowFocusChanged(hasWindowFocus);
+ super.onWindowFocusChanged(hasWindowFocus);
}
- /**
- * Return per-tile profiling data
- *
- * @hide only used by profiling tests
- */
- public float tileProfilingStop() {
- return nativeTileProfilingStop();
+
+ @Override
+ protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
+ mProvider.getViewDelegate().onFocusChanged(focused, direction, previouslyFocusedRect);
+ super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
- /** @hide only used by profiling tests */
- public void tileProfilingClear() {
- nativeTileProfilingClear();
+ /** @hide */
+ @Override
+ protected boolean setFrame(int left, int top, int right, int bottom) {
+ return mProvider.getViewDelegate().setFrame(left, top, right, bottom);
}
- /** @hide only used by profiling tests */
- public int tileProfilingNumFrames() {
- return nativeTileProfilingNumFrames();
+
+ @Override
+ protected void onSizeChanged(int w, int h, int ow, int oh) {
+ super.onSizeChanged(w, h, ow, oh);
+ mProvider.getViewDelegate().onSizeChanged(w, h, ow, oh);
}
- /** @hide only used by profiling tests */
- public int tileProfilingNumTilesInFrame(int frame) {
- return nativeTileProfilingNumTilesInFrame(frame);
+
+ @Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ super.onScrollChanged(l, t, oldl, oldt);
+ mProvider.getViewDelegate().onScrollChanged(l, t, oldl, oldt);
}
- /** @hide only used by profiling tests */
- public int tileProfilingGetInt(int frame, int tile, String key) {
- return nativeTileProfilingGetInt(frame, tile, key);
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ return mProvider.getViewDelegate().dispatchKeyEvent(event);
}
- /** @hide only used by profiling tests */
- public float tileProfilingGetFloat(int frame, int tile, String key) {
- return nativeTileProfilingGetFloat(frame, tile, key);
+
+ @Override
+ public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
+ return mProvider.getViewDelegate().requestFocus(direction, previouslyFocusedRect);
}
- /**
- * Checks the focused content for an editable text field. This can be
- * text input or ContentEditable.
- * @return true if the focused item is an editable text field.
- */
- boolean focusCandidateIsEditableText() {
- boolean isEditable = false;
- // TODO: reverse sDisableNavcache so that its name is positive
- boolean isNavcacheEnabled = !sDisableNavcache;
- if (isNavcacheEnabled) {
- isEditable = nativeFocusCandidateIsEditableText(mNativeClass);
- } else if (mFocusedNode != null) {
- isEditable = mFocusedNode.mEditable;
- }
- return isEditable;
+ @Deprecated
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ mProvider.getViewDelegate().onMeasure(widthMeasureSpec, heightMeasureSpec);
}
- // TODO: Remove this
- Rect cursorRingBounds() {
- if (sDisableNavcache) {
- return new Rect();
- }
- return nativeGetCursorRingBounds();
- }
-
- private native int nativeCacheHitFramePointer();
- private native boolean nativeCacheHitIsPlugin();
- private native Rect nativeCacheHitNodeBounds();
- private native int nativeCacheHitNodePointer();
- /* package */ native void nativeClearCursor();
- private native void nativeCreate(int ptr, String drawableDir, boolean isHighEndGfx);
- private native int nativeCursorFramePointer();
- private native Rect nativeCursorNodeBounds();
- private native int nativeCursorNodePointer();
- private native boolean nativeCursorIntersects(Rect visibleRect);
- private native boolean nativeCursorIsAnchor();
- private native boolean nativeCursorIsTextInput();
- private native Point nativeCursorPosition();
- private native String nativeCursorText();
- /**
- * Returns true if the native cursor node says it wants to handle key events
- * (ala plugins). This can only be called if mNativeClass is non-zero!
- */
- private native boolean nativeCursorWantsKeyEvents();
- private native void nativeDebugDump();
- private native void nativeDestroy();
+ @Override
+ public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) {
+ return mProvider.getViewDelegate().requestChildRectangleOnScreen(child, rect, immediate);
+ }
- /**
- * Draw the picture set with a background color and extra. If
- * "splitIfNeeded" is true and the return value is not 0, the return value
- * MUST be passed to WebViewCore with SPLIT_PICTURE_SET message so that the
- * native allocation can be freed.
- */
- private native int nativeDraw(Canvas canvas, RectF visibleRect,
- int color, int extra, boolean splitIfNeeded);
- private native void nativeDumpDisplayTree(String urlOrNull);
- private native boolean nativeEvaluateLayersAnimations(int nativeInstance);
- private native int nativeGetDrawGLFunction(int nativeInstance, Rect rect,
- Rect viewRect, RectF visibleRect, float scale, int extras);
- private native void nativeUpdateDrawGLFunction(Rect rect, Rect viewRect,
- RectF visibleRect, float scale);
- private native void nativeExtendSelection(int x, int y);
- /* package */ native int nativeFocusCandidateFramePointer();
- /* package */ native boolean nativeFocusCandidateHasNextTextfield();
- /* package */ native boolean nativeFocusCandidateIsPassword();
- private native boolean nativeFocusCandidateIsRtlText();
- private native boolean nativeFocusCandidateIsTextInput();
- private native boolean nativeFocusCandidateIsEditableText(int nativeClass);
- /* package */ native int nativeFocusCandidateMaxLength();
- /* package */ native boolean nativeFocusCandidateIsAutoComplete();
- /* package */ native boolean nativeFocusCandidateIsSpellcheck();
- /* package */ native String nativeFocusCandidateName();
- private native Rect nativeFocusCandidateNodeBounds();
- /**
- * @return A Rect with left, top, right, bottom set to the corresponding
- * padding values in the focus candidate, if it is a textfield/textarea with
- * a style. Otherwise return null. This is not actually a rectangle; Rect
- * is being used to pass four integers.
- */
- private native Rect nativeFocusCandidatePaddingRect();
- /* package */ native int nativeFocusCandidatePointer();
- private native String nativeFocusCandidateText();
- /* package */ native float nativeFocusCandidateTextSize();
- /* package */ native int nativeFocusCandidateLineHeight();
- /**
- * Returns an integer corresponding to WebView.cpp::type.
- * See WebTextView.setType()
- */
- private native int nativeFocusCandidateType();
- private native int nativeFocusCandidateLayerId();
- private native boolean nativeFocusIsPlugin();
- private native Rect nativeFocusNodeBounds();
- /* package */ native int nativeFocusNodePointer();
- private native Rect nativeGetCursorRingBounds();
- private native String nativeGetSelection();
- private native boolean nativeHasCursorNode();
- private native boolean nativeHasFocusNode();
- private native void nativeHideCursor();
- private native boolean nativeHitSelection(int x, int y);
- private native String nativeImageURI(int x, int y);
- private native Rect nativeLayerBounds(int layer);
- /* package */ native boolean nativeMoveCursorToNextTextInput();
- // return true if the page has been scrolled
- private native boolean nativeMotionUp(int x, int y, int slop);
- // returns false if it handled the key
- private native boolean nativeMoveCursor(int keyCode, int count,
- boolean noScroll);
- private native int nativeMoveGeneration();
- /**
- * @return true if the page should get the shift and arrow keys, rather
- * than select text/navigation.
- *
- * If the focus is a plugin, or if the focus and cursor match and are
- * a contentEditable element, then the page should handle these keys.
- */
- private native boolean nativePageShouldHandleShiftAndArrows();
- private native boolean nativePointInNavCache(int x, int y, int slop);
- private native void nativeSelectBestAt(Rect rect);
- private native void nativeSelectAt(int x, int y);
- private native void nativeSetExtendSelection();
- private native void nativeSetFindIsUp(boolean isUp);
- private native void nativeSetHeightCanMeasure(boolean measure);
- private native boolean nativeSetBaseLayer(int nativeInstance,
- int layer, Region invalRegion,
- boolean showVisualIndicator, boolean isPictureAfterFirstLayout);
- private native int nativeGetBaseLayer();
- private native void nativeShowCursorTimed();
- private native void nativeReplaceBaseContent(int content);
- private native void nativeCopyBaseContentToPicture(Picture pict);
- private native boolean nativeHasContent();
- private native void nativeSetSelectionPointer(int nativeInstance,
- boolean set, float scale, int x, int y);
- private native boolean nativeStartSelection(int x, int y);
- private native void nativeStopGL();
- private native Rect nativeSubtractLayers(Rect content);
- private native int nativeTextGeneration();
- private native void nativeDiscardAllTextures();
- private native void nativeTileProfilingStart();
- private native float nativeTileProfilingStop();
- private native void nativeTileProfilingClear();
- private native int nativeTileProfilingNumFrames();
- private native int nativeTileProfilingNumTilesInFrame(int frame);
- private native int nativeTileProfilingGetInt(int frame, int tile, String key);
- private native float nativeTileProfilingGetFloat(int frame, int tile, String key);
- // Never call this version except by updateCachedTextfield(String) -
- // we always want to pass in our generation number.
- private native void nativeUpdateCachedTextfield(String updatedText,
- int generation);
- private native boolean nativeWordSelection(int x, int y);
- // return NO_LEFTEDGE means failure.
- static final int NO_LEFTEDGE = -1;
- native int nativeGetBlockLeftEdge(int x, int y, float scale);
-
- private native void nativeUseHardwareAccelSkia(boolean enabled);
-
- // Returns a pointer to the scrollable LayerAndroid at the given point.
- private native int nativeScrollableLayer(int x, int y, Rect scrollRect,
- Rect scrollBounds);
- /**
- * Scroll the specified layer.
- * @param layer Id of the layer to scroll, as determined by nativeScrollableLayer.
- * @param newX Destination x position to which to scroll.
- * @param newY Destination y position to which to scroll.
- * @return True if the layer is successfully scrolled.
- */
- private native boolean nativeScrollLayer(int layer, int newX, int newY);
- private native void nativeSetIsScrolling(boolean isScrolling);
- private native int nativeGetBackgroundColor();
- native boolean nativeSetProperty(String key, String value);
- native String nativeGetProperty(String key);
- /**
- * See {@link ComponentCallbacks2} for the trim levels and descriptions
- */
- private static native void nativeOnTrimMemory(int level);
- private static native void nativeSetPauseDrawing(int instance, boolean pause);
- private static native boolean nativeDisableNavcache();
- private static native void nativeSetTextSelection(int instance, int selection);
- private static native int nativeGetHandleLayerId(int instance, int handle,
- Rect cursorLocation);
- private static native boolean nativeIsBaseFirst(int instance);
+ @Override
+ public void setBackgroundColor(int color) {
+ mProvider.getViewDelegate().setBackgroundColor(color);
+ }
}
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 46c8353..e6cee42 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,6 +84,7 @@ import android.view.ScaleGestureDetector;
import android.view.SoundEffectConstants;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.View.MeasureSpec;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
@@ -98,6 +99,8 @@ import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.webkit.HTML5VideoInline;
import android.webkit.WebTextView.AutoCompleteAdapter;
+import android.webkit.WebView.HitTestResult;
+import android.webkit.WebView.PictureListener;
import android.webkit.WebViewCore.DrawData;
import android.webkit.WebViewCore.EventHub;
import android.webkit.WebViewCore.TextFieldInitData;
@@ -343,17 +346,19 @@ import java.util.regex.Pattern;
* {@link WebChromeClient#getVideoLoadingProgressView()} is optional.
* </p>
*
- *
+ * @hide
*/
+// TODO: Remove duplicated API documentation and @hide from fields and methods, and
+// checkThread() call. (All left in for now to ease branch merging.)
+// TODO: Check if any WebView published API methods are called from within here, and if so
+// we should bounce the call out via the proxy to enable any sub-class to override it.
@Widget
-public class WebView extends AbsoluteLayout
- implements ViewTreeObserver.OnGlobalFocusChangeListener,
- ViewGroup.OnHierarchyChangeListener {
-
+public final class WebViewClassic implements WebViewProvider, WebViewProvider.ScrollDelegate,
+ WebViewProvider.ViewDelegate {
private class InnerGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
@Override
public void onGlobalLayout() {
- if (isShown()) {
+ if (mWebView.isShown()) {
setGLRectViewport();
}
}
@@ -362,7 +367,7 @@ public class WebView extends AbsoluteLayout
private class InnerScrollChangedListener implements ViewTreeObserver.OnScrollChangedListener {
@Override
public void onScrollChanged() {
- if (isShown()) {
+ if (mWebView.isShown()) {
setGLRectViewport();
}
}
@@ -382,7 +387,7 @@ public class WebView extends AbsoluteLayout
private int mMaxLength;
public WebViewInputConnection() {
- super(WebView.this, true);
+ super(mWebView, true);
}
@Override
@@ -490,17 +495,17 @@ public class WebView extends AbsoluteLayout
boolean handled = true;
switch (editorAction) {
case EditorInfo.IME_ACTION_NEXT:
- WebView.this.requestFocus(FOCUS_FORWARD);
+ mWebView.requestFocus(View.FOCUS_FORWARD);
break;
case EditorInfo.IME_ACTION_PREVIOUS:
- WebView.this.requestFocus(FOCUS_BACKWARD);
+ mWebView.requestFocus(View.FOCUS_BACKWARD);
break;
case EditorInfo.IME_ACTION_DONE:
- WebView.this.hideSoftKeyboard();
+ WebViewClassic.this.hideSoftKeyboard();
break;
case EditorInfo.IME_ACTION_GO:
case EditorInfo.IME_ACTION_SEARCH:
- WebView.this.hideSoftKeyboard();
+ WebViewClassic.this.hideSoftKeyboard();
String text = getEditable().toString();
passToJavaScript(text, new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_ENTER));
@@ -686,26 +691,26 @@ public class WebView extends AbsoluteLayout
if (imm != null) {
// Since the text has changed, do not allow the IME to replace the
// existing text as though it were a completion.
- imm.restartInput(WebView.this);
+ imm.restartInput(mWebView);
}
}
}
- private class PastePopupWindow extends PopupWindow implements OnClickListener {
+ private class PastePopupWindow extends PopupWindow implements View.OnClickListener {
private ViewGroup mContentView;
private TextView mPasteTextView;
public PastePopupWindow() {
- super(WebView.this.mContext, null,
+ super(mContext, null,
com.android.internal.R.attr.textSelectHandleWindowStyle);
setClippingEnabled(true);
- LinearLayout linearLayout = new LinearLayout(WebView.this.getContext());
+ LinearLayout linearLayout = new LinearLayout(mContext);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
mContentView = linearLayout;
mContentView.setBackgroundResource(
com.android.internal.R.drawable.text_edit_paste_window);
- LayoutInflater inflater = (LayoutInflater)WebView.this.mContext.
+ LayoutInflater inflater = (LayoutInflater)mContext.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup.LayoutParams wrapContent = new ViewGroup.LayoutParams(
@@ -739,7 +744,7 @@ public class WebView extends AbsoluteLayout
x = windowLeft;
}
if (!isShowing()) {
- showAtLocation(WebView.this, Gravity.NO_GRAVITY, x, y);
+ showAtLocation(mWebView, Gravity.NO_GRAVITY, x, y);
}
update(x, y, width, height);
}
@@ -792,29 +797,6 @@ public class WebView extends AbsoluteLayout
private int mFieldPointer;
private PastePopupWindow mPasteWindow;
- /**
- * Transportation object for returning WebView across thread boundaries.
- */
- public class WebViewTransport {
- private WebView mWebview;
-
- /**
- * Set the WebView to the transportation object.
- * @param webview The WebView to transport.
- */
- public synchronized void setWebView(WebView webview) {
- mWebview = webview;
- }
-
- /**
- * Return the WebView object.
- * @return WebView The transported WebView object.
- */
- public synchronized WebView getWebView() {
- return mWebview;
- }
- }
-
private static class OnTrimMemoryListener implements ComponentCallbacks2 {
private static OnTrimMemoryListener sInstance = null;
@@ -848,15 +830,15 @@ public class WebView extends AbsoluteLayout
// at native side.
// Here we just need to clean up the Surface Texture which is static.
HTML5VideoInline.cleanupSurfaceTexture();
- WebView.nativeOnTrimMemory(level);
+ WebViewClassic.nativeOnTrimMemory(level);
}
}
// A final CallbackProxy shared by WebViewCore and BrowserFrame.
- private final CallbackProxy mCallbackProxy;
+ private CallbackProxy mCallbackProxy;
- private final WebViewDatabase mDatabase;
+ private WebViewDatabase mDatabase;
// SSL certificate for the main top-level page (if secure)
private SslCertificate mCertificate;
@@ -877,7 +859,7 @@ public class WebView extends AbsoluteLayout
/* package */ void incrementTextGeneration() { mTextGeneration++; }
// Used by WebViewCore to create child views.
- /* package */ final ViewManager mViewManager;
+ /* package */ ViewManager mViewManager;
// Used to display in full screen mode
PluginFullScreenHolder mFullScreenHolder;
@@ -1373,102 +1355,6 @@ public class WebView extends AbsoluteLayout
// Used to notify listeners of a new picture.
private PictureListener mPictureListener;
- /**
- * Interface to listen for new pictures as they change.
- * @deprecated This interface is now obsolete.
- */
- @Deprecated
- public interface PictureListener {
- /**
- * Notify the listener that the picture has changed.
- * @param view The WebView that owns the picture.
- * @param picture The new picture.
- * @deprecated Due to internal changes, the picture does not include
- * composited layers such as fixed position elements or scrollable divs.
- * While the PictureListener API can still be used to detect changes in
- * the WebView content, you are advised against its usage until a replacement
- * is provided in a future Android release
- */
- @Deprecated
- public void onNewPicture(WebView view, Picture picture);
- }
-
- public static class HitTestResult {
- /**
- * Default HitTestResult, where the target is unknown
- */
- public static final int UNKNOWN_TYPE = 0;
- /**
- * @deprecated This type is no longer used.
- */
- @Deprecated
- public static final int ANCHOR_TYPE = 1;
- /**
- * HitTestResult for hitting a phone number
- */
- public static final int PHONE_TYPE = 2;
- /**
- * HitTestResult for hitting a map address
- */
- public static final int GEO_TYPE = 3;
- /**
- * HitTestResult for hitting an email address
- */
- public static final int EMAIL_TYPE = 4;
- /**
- * HitTestResult for hitting an HTML::img tag
- */
- public static final int IMAGE_TYPE = 5;
- /**
- * @deprecated This type is no longer used.
- */
- @Deprecated
- public static final int IMAGE_ANCHOR_TYPE = 6;
- /**
- * HitTestResult for hitting a HTML::a tag with src=http
- */
- public static final int SRC_ANCHOR_TYPE = 7;
- /**
- * HitTestResult for hitting a HTML::a tag with src=http + HTML::img
- */
- public static final int SRC_IMAGE_ANCHOR_TYPE = 8;
- /**
- * HitTestResult for hitting an edit text area
- */
- public static final int EDIT_TEXT_TYPE = 9;
-
- private int mType;
- private String mExtra;
-
- HitTestResult() {
- mType = UNKNOWN_TYPE;
- }
-
- private void setType(int type) {
- mType = type;
- }
-
- private void setExtra(String extra) {
- mExtra = extra;
- }
-
- /**
- * Gets the type of the hit test result.
- * @return See the XXX_TYPE constants defined in this class.
- */
- public int getType() {
- return mType;
- }
-
- /**
- * Gets additional type-dependant information about the result, see
- * {@link WebView#getHitTestResult()} for details.
- * @return may either be null or contain extra information about this result.
- */
- public String getExtra() {
- return mExtra;
- }
- }
/**
* Refer to {@link WebView#requestFocusNodeHref(Message)} for more information
@@ -1479,43 +1365,10 @@ public class WebView extends AbsoluteLayout
static final String SRC = "src";
}
- /**
- * Construct a new WebView with a Context object.
- * @param context A Context object used to access application assets.
- */
- public WebView(Context context) {
- this(context, null);
- }
-
- /**
- * Construct a new WebView with layout parameters.
- * @param context A Context object used to access application assets.
- * @param attrs An AttributeSet passed to our parent.
- */
- public WebView(Context context, AttributeSet attrs) {
- this(context, attrs, com.android.internal.R.attr.webViewStyle);
- }
-
- /**
- * Construct a new WebView with layout parameters and a default style.
- * @param context A Context object used to access application assets.
- * @param attrs An AttributeSet passed to our parent.
- * @param defStyle The default style resource ID.
- */
- public WebView(Context context, AttributeSet attrs, int defStyle) {
- this(context, attrs, defStyle, false);
- }
-
- /**
- * Construct a new WebView with layout parameters and a default style.
- * @param context A Context object used to access application assets.
- * @param attrs An AttributeSet passed to our parent.
- * @param defStyle The default style resource ID.
- * @param privateBrowsing If true the web view will be initialized in private mode.
- */
- public WebView(Context context, AttributeSet attrs, int defStyle,
- boolean privateBrowsing) {
- this(context, attrs, defStyle, null, privateBrowsing);
+ public WebViewClassic(WebView webView, WebView.PrivateAccess privateAccess) {
+ mWebView = webView;
+ mWebViewPrivate = privateAccess;
+ mContext = webView.getContext();
}
/**
@@ -1523,22 +1376,16 @@ public class WebView extends AbsoluteLayout
* of custom Javscript interfaces to be added to the WebView at initialization
* time. This guarantees that these interfaces will be available when the JS
* context is initialized.
- * @param context A Context object used to access application assets.
- * @param attrs An AttributeSet passed to our parent.
- * @param defStyle The default style resource ID.
* @param javaScriptInterfaces is a Map of interface names, as keys, and
* object implementing those interfaces, as values.
* @param privateBrowsing If true the web view will be initialized in private mode.
* @hide This is an implementation detail.
*/
- protected WebView(Context context, AttributeSet attrs, int defStyle,
- Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
- super(context, attrs, defStyle);
+ @Override
+ public void init(Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
checkThread();
- if (context == null) {
- throw new IllegalArgumentException("Invalid context argument");
- }
+ Context context = mContext;
// Used by the chrome stack to find application paths
JniUtil.setContext(context);
@@ -1567,6 +1414,98 @@ public class WebView extends AbsoluteLayout
mAutoFillData = new WebViewCore.AutoFillData();
}
+ // === START: WebView Proxy binding ===
+ // Keep the webview proxy / SPI related stuff in this section, to minimize merge conflicts.
+
+ static class Factory implements WebViewFactoryProvider, WebViewFactoryProvider.Statics {
+ @Override
+ public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) {
+ return new WebViewClassic(webView, privateAccess);
+ }
+
+ @Override
+ public Statics getStatics() { return this; }
+
+ @Override
+ public String findAddress(String addr) {
+ return WebViewClassic.findAddress(addr);
+ }
+ @Override
+ public void setPlatformNotificationsEnabled(boolean enable) {
+ if (enable) {
+ WebViewClassic.enablePlatformNotifications();
+ } else {
+ WebViewClassic.disablePlatformNotifications();
+ }
+ }
+
+ }
+
+ // The webview that is bound to this WebViewClassic instance. Primarily needed for supplying
+ // as the first param in the WebViewClient and WebChromeClient callbacks.
+ final private WebView mWebView;
+ // Callback interface, provides priviledged access into the WebView instance.
+ final private WebView.PrivateAccess mWebViewPrivate;
+ // Cached reference to mWebView.getContext(), for convenience.
+ final private Context mContext;
+
+ /**
+ * @return The webview proxy that this classic webview is bound to.
+ */
+ public WebView getWebView() {
+ return mWebView;
+ }
+
+ @Override
+ public ViewDelegate getViewDelegate() {
+ return this;
+ }
+
+ @Override
+ public ScrollDelegate getScrollDelegate() {
+ return this;
+ }
+
+ public static WebViewClassic fromWebView(WebView webView) {
+ return webView == null ? null : (WebViewClassic) webView.getWebViewProvider();
+ }
+
+ // Accessors, purely for convenience (and to reduce code churn during webview proxy migration).
+ int getScrollX() {
+ return mWebView.getScrollX();
+ }
+
+ int getScrollY() {
+ return mWebView.getScrollY();
+ }
+
+ int getWidth() {
+ return mWebView.getWidth();
+ }
+
+ int getHeight() {
+ return mWebView.getHeight();
+ }
+
+ Context getContext() {
+ return mContext;
+ }
+
+ void invalidate() {
+ mWebView.invalidate();
+ }
+
+ // Setters for the Scroll X & Y, without invoking the onScrollChanged etc code paths.
+ void setScrollXRaw(int mScrollX) {
+ mWebViewPrivate.setScrollXRaw(mScrollX);
+ }
+
+ void setScrollYRaw(int mScrollY) {
+ mWebViewPrivate.setScrollYRaw(mScrollY);
+ }
+
+ // === END: WebView Proxy binding ===
+
private static class TrustStorageListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
@@ -1703,7 +1642,7 @@ public class WebView extends AbsoluteLayout
* receiver to ensure that only ONE receiver exists for all WebView
* instances.
*/
- synchronized (WebView.class) {
+ synchronized (WebViewClassic.class) {
// if the receiver already exists then we do not need to register it
// again
@@ -1753,30 +1692,21 @@ public class WebView extends AbsoluteLayout
mZoomManager.updateMultiTouchSupport(context);
}
- // Setters for the Scroll X & Y, without invoking the onScrollChanged etc code paths.
- final void setScrollXRaw(int scrollX) {
- mScrollX = scrollX;
- }
-
- final void setScrollYRaw(int scrollY) {
- mScrollY = scrollY;
- }
-
private void init() {
- OnTrimMemoryListener.init(getContext());
+ OnTrimMemoryListener.init(mContext);
sDisableNavcache = nativeDisableNavcache();
- setWillNotDraw(false);
- setFocusable(true);
- setFocusableInTouchMode(true);
- setClickable(true);
- setLongClickable(true);
+ mWebView.setWillNotDraw(false);
+ mWebView.setFocusable(true);
+ mWebView.setFocusableInTouchMode(true);
+ mWebView.setClickable(true);
+ mWebView.setLongClickable(true);
- final ViewConfiguration configuration = ViewConfiguration.get(getContext());
+ final ViewConfiguration configuration = ViewConfiguration.get(mContext);
int slop = configuration.getScaledTouchSlop();
mTouchSlopSquare = slop * slop;
slop = configuration.getScaledDoubleTapSlop();
mDoubleTapSlopSquare = slop * slop;
- final float density = getContext().getResources().getDisplayMetrics().density;
+ final float density = mContext.getResources().getDisplayMetrics().density;
// use one line height, 16 based on our current default font, for how
// far we allow a touch be away from the edge of a link
mNavSlop = (int) (16 * density);
@@ -1789,7 +1719,7 @@ public class WebView extends AbsoluteLayout
mOverscrollDistance = configuration.getScaledOverscrollDistance();
mOverflingDistance = configuration.getScaledOverflingDistance();
- setScrollBarStyle(super.getScrollBarStyle());
+ setScrollBarStyle(mWebViewPrivate.super_getScrollBarStyle());
// Initially use a size of two, since the user is likely to only hold
// down two keys at a time (shift + another key)
mKeysPressed = new Vector<Integer>(2);
@@ -1811,11 +1741,11 @@ public class WebView extends AbsoluteLayout
if (AccessibilityManager.getInstance(mContext).isEnabled()
&& getSettings().getJavaScriptEnabled()) {
// exposing the TTS for now ...
- final Context ctx = getContext();
+ final Context ctx = mContext;
if (ctx != null) {
final String packageName = ctx.getPackageName();
if (packageName != null) {
- mTextToSpeech = new TextToSpeech(getContext(), null, null,
+ mTextToSpeech = new TextToSpeech(ctx, null, null,
packageName + ".**webview**", true);
addJavascriptInterface(mTextToSpeech, ALIAS_ACCESSIBILITY_JS_INTERFACE);
}
@@ -1837,33 +1767,34 @@ public class WebView extends AbsoluteLayout
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
info.setScrollable(isScrollableForAccessibility());
}
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
- super.onInitializeAccessibilityEvent(event);
event.setScrollable(isScrollableForAccessibility());
event.setScrollX(getScrollX());
event.setScrollY(getScrollY());
final int convertedContentWidth = contentToViewX(getContentWidth());
- final int adjustedViewWidth = getWidth() - mPaddingLeft - mPaddingRight;
+ final int adjustedViewWidth = getWidth() - mWebView.getPaddingLeft()
+ - mWebView.getPaddingLeft();
event.setMaxScrollX(Math.max(convertedContentWidth - adjustedViewWidth, 0));
final int convertedContentHeight = contentToViewY(getContentHeight());
- final int adjustedViewHeight = getHeight() - mPaddingTop - mPaddingBottom;
+ final int adjustedViewHeight = getHeight() - mWebView.getPaddingTop()
+ - mWebView.getPaddingBottom();
event.setMaxScrollY(Math.max(convertedContentHeight - adjustedViewHeight, 0));
}
private boolean isScrollableForAccessibility() {
- return (contentToViewX(getContentWidth()) > getWidth() - mPaddingLeft - mPaddingRight
- || contentToViewY(getContentHeight()) > getHeight() - mPaddingTop - mPaddingBottom);
+ return (contentToViewX(getContentWidth()) > getWidth() - mWebView.getPaddingLeft()
+ - mWebView.getPaddingRight()
+ || contentToViewY(getContentHeight()) > getHeight() - mWebView.getPaddingTop()
+ - mWebView.getPaddingBottom());
}
@Override
public void setOverScrollMode(int mode) {
- super.setOverScrollMode(mode);
- if (mode != OVER_SCROLL_NEVER) {
+ if (mode != View.OVER_SCROLL_NEVER) {
if (mOverScrollGlow == null) {
mOverScrollGlow = new OverScrollGlow(this);
}
@@ -1904,7 +1835,7 @@ public class WebView extends AbsoluteLayout
neverRemember.getData().putString("password", password);
neverRemember.obj = resumeMsg;
- new AlertDialog.Builder(getContext())
+ new AlertDialog.Builder(mContext)
.setTitle(com.android.internal.R.string.save_password_label)
.setMessage(com.android.internal.R.string.save_password_message)
.setPositiveButton(com.android.internal.R.string.save_password_notnow,
@@ -1949,7 +1880,6 @@ public class WebView extends AbsoluteLayout
} else {
mOverlayHorizontalScrollbar = mOverlayVerticalScrollbar = true;
}
- super.setScrollBarStyle(style);
}
/**
@@ -1994,19 +1924,28 @@ public class WebView extends AbsoluteLayout
* Note: this can be called from WebCoreThread.
*/
/* package */ int getViewWidth() {
- if (!isVerticalScrollBarEnabled() || mOverlayVerticalScrollbar) {
+ if (!mWebView.isVerticalScrollBarEnabled() || mOverlayVerticalScrollbar) {
return getWidth();
} else {
- return Math.max(0, getWidth() - getVerticalScrollbarWidth());
+ return Math.max(0, getWidth() - mWebView.getVerticalScrollbarWidth());
}
}
+ // Interface to enable the browser to override title bar handling.
+ public interface TitleBarDelegate {
+ int getTitleHeight();
+ public void onSetEmbeddedTitleBar(final View title);
+ }
+
/**
* Returns the height (in pixels) of the embedded title bar (if any). Does not care about
* scrolling
* @hide
*/
protected int getTitleHeight() {
+ if (mWebView instanceof TitleBarDelegate) {
+ return ((TitleBarDelegate) mWebView).getTitleHeight();
+ }
return mTitleBar != null ? mTitleBar.getHeight() : 0;
}
@@ -2037,7 +1976,7 @@ public class WebView extends AbsoluteLayout
return 0;
}
if (mCachedOverlappingActionModeHeight < 0) {
- getGlobalVisibleRect(mGlobalVisibleRect, mGlobalVisibleOffset);
+ mWebView.getGlobalVisibleRect(mGlobalVisibleRect, mGlobalVisibleOffset);
mCachedOverlappingActionModeHeight = Math.max(0,
mFindCallback.getActionModeGlobalBottom() - mGlobalVisibleRect.top);
}
@@ -2055,8 +1994,8 @@ public class WebView extends AbsoluteLayout
int getViewHeightWithTitle() {
int height = getHeight();
- if (isHorizontalScrollBarEnabled() && !mOverlayHorizontalScrollbar) {
- height -= getHorizontalScrollbarHeight();
+ if (mWebView.isHorizontalScrollBarEnabled() && !mOverlayHorizontalScrollbar) {
+ height -= mWebViewPrivate.getHorizontalScrollbarHeight();
}
return height;
}
@@ -2215,7 +2154,7 @@ public class WebView extends AbsoluteLayout
@Deprecated
public static void enablePlatformNotifications() {
checkThread();
- synchronized (WebView.class) {
+ synchronized (WebViewClassic.class) {
sNotificationsEnabled = true;
Context context = JniUtil.getContext();
if (context != null)
@@ -2232,7 +2171,7 @@ public class WebView extends AbsoluteLayout
@Deprecated
public static void disablePlatformNotifications() {
checkThread();
- synchronized (WebView.class) {
+ synchronized (WebViewClassic.class) {
sNotificationsEnabled = false;
Context context = JniUtil.getContext();
if (context != null)
@@ -3268,12 +3207,15 @@ public class WebView extends AbsoluteLayout
* @hide
*/
public void setEmbeddedTitleBar(View v) {
+ if (mWebView instanceof TitleBarDelegate) {
+ ((TitleBarDelegate) mWebView).onSetEmbeddedTitleBar(v);
+ }
if (mTitleBar == v) return;
if (mTitleBar != null) {
- removeView(mTitleBar);
+ mWebView.removeView(mTitleBar);
}
if (null != v) {
- addView(v, new AbsoluteLayout.LayoutParams(
+ mWebView.addView(v, new AbsoluteLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0));
}
@@ -3387,10 +3329,10 @@ public class WebView extends AbsoluteLayout
private void viewInvalidate(int l, int t, int r, int b) {
final float scale = mZoomManager.getScale();
final int dy = getTitleHeight();
- invalidate((int)Math.floor(l * scale),
- (int)Math.floor(t * scale) + dy,
- (int)Math.ceil(r * scale),
- (int)Math.ceil(b * scale) + dy);
+ mWebView.invalidate((int)Math.floor(l * scale),
+ (int)Math.floor(t * scale) + dy,
+ (int)Math.ceil(r * scale),
+ (int)Math.ceil(b * scale) + dy);
}
// Called by JNI to invalidate the View after a delay, given rectangle
@@ -3398,11 +3340,11 @@ public class WebView extends AbsoluteLayout
private void viewInvalidateDelayed(long delay, int l, int t, int r, int b) {
final float scale = mZoomManager.getScale();
final int dy = getTitleHeight();
- postInvalidateDelayed(delay,
- (int)Math.floor(l * scale),
- (int)Math.floor(t * scale) + dy,
- (int)Math.ceil(r * scale),
- (int)Math.ceil(b * scale) + dy);
+ mWebView.postInvalidateDelayed(delay,
+ (int)Math.floor(l * scale),
+ (int)Math.floor(t * scale) + dy,
+ (int)Math.ceil(r * scale),
+ (int)Math.ceil(b * scale) + dy);
}
private void invalidateContentRect(Rect r) {
@@ -3467,7 +3409,7 @@ public class WebView extends AbsoluteLayout
mLastVisibleRectSent.set(mVisibleRect);
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
}
- if (getGlobalVisibleRect(mGlobalVisibleRect)
+ if (mWebView.getGlobalVisibleRect(mGlobalVisibleRect)
&& !mGlobalVisibleRect.equals(mLastGlobalRect)) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "sendOurVisibleRect=(" + mGlobalVisibleRect.left + ","
@@ -3488,7 +3430,7 @@ public class WebView extends AbsoluteLayout
private Point mGlobalVisibleOffset = new Point();
// Sets r to be the visible rectangle of our webview in view coordinates
private void calcOurVisibleRect(Rect r) {
- getGlobalVisibleRect(r, mGlobalVisibleOffset);
+ mWebView.getGlobalVisibleRect(r, mGlobalVisibleOffset);
r.offset(-mGlobalVisibleOffset.x, -mGlobalVisibleOffset.y);
}
@@ -3610,7 +3552,7 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected int computeHorizontalScrollRange() {
+ public int computeHorizontalScrollRange() {
int range = computeRealHorizontalScrollRange();
// Adjust reported range if overscrolled to compress the scroll bars
@@ -3626,7 +3568,7 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected int computeHorizontalScrollOffset() {
+ public int computeHorizontalScrollOffset() {
return Math.max(getScrollX(), 0);
}
@@ -3640,7 +3582,7 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected int computeVerticalScrollRange() {
+ public int computeVerticalScrollRange() {
int range = computeRealVerticalScrollRange();
// Adjust reported range if overscrolled to compress the scroll bars
@@ -3656,18 +3598,18 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected int computeVerticalScrollOffset() {
+ public int computeVerticalScrollOffset() {
return Math.max(getScrollY() - getTitleHeight(), 0);
}
@Override
- protected int computeVerticalScrollExtent() {
+ public int computeVerticalScrollExtent() {
return getViewHeight();
}
/** @hide */
@Override
- protected void onDrawVerticalScrollBar(Canvas canvas,
+ public void onDrawVerticalScrollBar(Canvas canvas,
Drawable scrollBar,
int l, int t, int r, int b) {
if (getScrollY() < 0) {
@@ -3678,7 +3620,7 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX,
+ public void onOverScrolled(int scrollX, int scrollY, boolean clampedX,
boolean clampedY) {
// Special-case layer scrolling so that we do not trigger normal scroll
// updating.
@@ -3702,7 +3644,7 @@ public class WebView extends AbsoluteLayout
int oldX = getScrollX();
int oldY = getScrollY();
- super.scrollTo(scrollX, scrollY);
+ mWebViewPrivate.super_scrollTo(scrollX, scrollY);
if (mOverScrollGlow != null) {
mOverScrollGlow.pullGlow(getScrollX(), getScrollY(), oldX, oldY, maxX, maxY);
@@ -3847,16 +3789,15 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected void onWindowVisibilityChanged(int visibility) {
- super.onWindowVisibilityChanged(visibility);
+ public void onWindowVisibilityChanged(int visibility) {
updateDrawingState();
}
void updateDrawingState() {
if (mNativeClass == 0 || mIsPaused) return;
- if (getWindowVisibility() != VISIBLE) {
+ if (mWebView.getWindowVisibility() != View.VISIBLE) {
nativeSetPauseDrawing(mNativeClass, true);
- } else if (getVisibility() != VISIBLE) {
+ } else if (mWebView.getVisibility() != View.VISIBLE) {
nativeSetPauseDrawing(mNativeClass, true);
} else {
nativeSetPauseDrawing(mNativeClass, false);
@@ -4030,7 +3971,7 @@ public class WebView extends AbsoluteLayout
public boolean showFindDialog(String text, boolean showIme) {
checkThread();
FindActionModeCallback callback = new FindActionModeCallback(mContext);
- if (getParent() == null || startActionMode(callback) == null) {
+ if (mWebView.getParent() == null || mWebView.startActionMode(callback) == null) {
// Could not start the action mode, so end Find on page
return false;
}
@@ -4206,7 +4147,7 @@ public class WebView extends AbsoluteLayout
overflingDistance = 0;
}
- overScrollBy(x - oldX, y - oldY, oldX, oldY,
+ mWebViewPrivate.overScrollBy(x - oldX, y - oldY, oldX, oldY,
rangeX, rangeY,
overflingDistance, overflingDistance, false);
@@ -4234,7 +4175,7 @@ public class WebView extends AbsoluteLayout
}
}
} else {
- super.computeScroll();
+ mWebViewPrivate.super_computeScroll();
}
}
@@ -4257,7 +4198,7 @@ public class WebView extends AbsoluteLayout
mScrollingLayerRect.top = y;
mWebViewCore.sendMessage(WebViewCore.EventHub.SCROLL_LAYER, mCurrentScrollingLayerId,
mScrollingLayerRect);
- onScrollChanged(getScrollX(), getScrollY(), getScrollX(), getScrollY());
+ mWebViewPrivate.onScrollChanged(getScrollX(), getScrollY(), getScrollX(), getScrollY());
invalidate();
}
@@ -4288,10 +4229,10 @@ public class WebView extends AbsoluteLayout
// Log.d(LOGTAG, "startScroll: " + dx + " " + dy);
mScroller.startScroll(getScrollX(), getScrollY(), dx, dy,
animationDuration > 0 ? animationDuration : computeDuration(dx, dy));
- awakenScrollBars(mScroller.getDuration());
+ mWebViewPrivate.awakenScrollBars(mScroller.getDuration());
invalidate();
} else {
- scrollTo(x, y);
+ mWebView.scrollTo(x, y);
}
return true;
}
@@ -4314,7 +4255,7 @@ public class WebView extends AbsoluteLayout
Rect tempRect = new Rect();
calcOurVisibleRect(tempRect);
tempRect.offset(cx, cy);
- requestRectangleOnScreen(tempRect);
+ mWebView.requestRectangleOnScreen(tempRect);
}
// FIXME: We scroll horizontally no matter what because currently
// ScrollView and ListView will not scroll horizontally.
@@ -4337,7 +4278,7 @@ public class WebView extends AbsoluteLayout
// will reload it and get a new certificate set;
// if the new site is not secure, the certificate must be
// null, and that will be the case
- setCertificate(null);
+ mWebView.setCertificate(null);
// reset the flag since we set to true in if need after
// loading is see onPageFinished(Url)
@@ -4407,7 +4348,7 @@ public class WebView extends AbsoluteLayout
if (onDeviceScriptInjectionEnabled) {
ensureAccessibilityScriptInjectorInstance(false);
// neither script injected nor script injection opted out => we inject
- loadUrl(getScreenReaderInjectingJs());
+ mWebView.loadUrl(getScreenReaderInjectingJs());
// TODO: Set this flag after successfull script injection. Maybe upon injection
// the chooser should update the meta tag and we check it to declare success
mAccessibilityScriptInjected = true;
@@ -4421,7 +4362,7 @@ public class WebView extends AbsoluteLayout
} else if (axsParameterValue == ACCESSIBILITY_SCRIPT_INJECTION_PROVIDED) {
ensureAccessibilityScriptInjectorInstance(false);
// the URL provides accessibility but we still need to add our generic script
- loadUrl(getScreenReaderInjectingJs());
+ mWebView.loadUrl(getScreenReaderInjectingJs());
} else {
Log.e(LOGTAG, "Unknown URL value for the \"axs\" URL parameter: " + axsParameterValue);
}
@@ -4573,14 +4514,14 @@ public class WebView extends AbsoluteLayout
}
if (mHeightCanMeasure) {
- if (getMeasuredHeight() != contentToViewDimension(mContentHeight)
+ if (mWebView.getMeasuredHeight() != contentToViewDimension(mContentHeight)
|| updateLayout) {
- requestLayout();
+ mWebView.requestLayout();
}
} else if (mWidthCanMeasure) {
- if (getMeasuredWidth() != contentToViewDimension(mContentWidth)
+ if (mWebView.getMeasuredWidth() != contentToViewDimension(mContentWidth)
|| updateLayout) {
- requestLayout();
+ mWebView.requestLayout();
}
} else {
// If we don't request a layout, try to send our view size to the
@@ -4744,7 +4685,7 @@ public class WebView extends AbsoluteLayout
* @return A WebSettings object that can be used to control this WebView's
* settings.
*/
- public WebSettings getSettings() {
+ public WebSettingsClassic getSettings() {
checkThread();
return (mWebViewCore != null) ? mWebViewCore.getSettings() : null;
}
@@ -4792,7 +4733,7 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+ public boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (child == mTitleBar) {
// When drawing the title bar, move it horizontally to always show
// at the top of the WebView.
@@ -4806,7 +4747,7 @@ public class WebView extends AbsoluteLayout
mTitleBar.setBottom(newTop + mTitleBar.getHeight());
mTitleBar.setTop(newTop);
}
- return super.drawChild(canvas, child, drawingTime);
+ return false; // We never call invalidate(), so unconditionally returning false.
}
private void drawContent(Canvas canvas, boolean drawRings) {
@@ -4849,7 +4790,7 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected void onDraw(Canvas canvas) {
+ public void onDraw(Canvas canvas) {
if (inFullScreenMode()) {
return; // no need to draw anything if we aren't visible.
}
@@ -4933,10 +4874,10 @@ public class WebView extends AbsoluteLayout
@Override
public void setLayoutParams(ViewGroup.LayoutParams params) {
- if (params.height == LayoutParams.WRAP_CONTENT) {
+ if (params.height == AbsoluteLayout.LayoutParams.WRAP_CONTENT) {
mWrapContent = true;
}
- super.setLayoutParams(params);
+ mWebViewPrivate.super_setLayoutParams(params);
}
@Override
@@ -4944,7 +4885,7 @@ public class WebView extends AbsoluteLayout
// performLongClick() is the result of a delayed message. If we switch
// to windows overview, the WebView will be temporarily removed from the
// view system. In that case, do nothing.
- if (getParent() == null) return false;
+ if (mWebView.getParent() == null) return false;
// A multi-finger gesture can look like a long press; make sure we don't take
// long press actions if we're scaling.
@@ -4979,7 +4920,7 @@ public class WebView extends AbsoluteLayout
/* if long click brings up a context menu, the super function
* returns true and we're done. Otherwise, nothing happened when
* the user clicked. */
- if (super.performLongClick()) {
+ if (mWebViewPrivate.super_performLongClick()) {
return true;
}
/* In the case where the application hasn't already handled the long
@@ -4988,12 +4929,12 @@ public class WebView extends AbsoluteLayout
* FIXME: no animation code yet */
final boolean isSelecting = selectText();
if (isSelecting) {
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ mWebView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
} else if (focusCandidateIsEditableText()) {
mSelectCallback = new SelectActionModeCallback();
mSelectCallback.setWebView(this);
mSelectCallback.setTextSelected(false);
- startActionMode(mSelectCallback);
+ mWebView.startActionMode(mSelectCallback);
}
return isSelecting;
}
@@ -5020,7 +4961,7 @@ public class WebView extends AbsoluteLayout
private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
@Override
- protected void onConfigurationChanged(Configuration newConfig) {
+ public void onConfigurationChanged(Configuration newConfig) {
mCachedOverlappingActionModeHeight = -1;
if (mSelectingText && mOrientation != newConfig.orientation) {
selectionDone();
@@ -5131,7 +5072,7 @@ public class WebView extends AbsoluteLayout
private void onZoomAnimationStart() {
// If it is in password mode, turn it off so it does not draw misplaced.
if (inEditingMode()) {
- mWebTextView.setVisibility(INVISIBLE);
+ mWebTextView.setVisibility(View.INVISIBLE);
}
}
@@ -5141,7 +5082,7 @@ public class WebView extends AbsoluteLayout
&& didUpdateWebTextViewDimensions(FULLY_ON_SCREEN)) {
// If it is a password field, start drawing the WebTextView once
// again.
- mWebTextView.setVisibility(VISIBLE);
+ mWebTextView.setVisibility(View.VISIBLE);
}
}
@@ -5381,7 +5322,7 @@ public class WebView extends AbsoluteLayout
setScrollXRaw(pinLocX(getScrollX()));
setScrollYRaw(pinLocY(getScrollY()));
if (oldScrollX != getScrollX() || oldScrollY != getScrollY()) {
- onScrollChanged(getScrollX(), getScrollY(), oldScrollX, oldScrollY);
+ mWebViewPrivate.onScrollChanged(getScrollX(), getScrollY(), oldScrollX, oldScrollY);
} else {
sendOurVisibleRect();
}
@@ -5449,7 +5390,7 @@ public class WebView extends AbsoluteLayout
*/
private void displaySoftKeyboard(boolean isTextView) {
InputMethodManager imm = (InputMethodManager)
- getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
// bring it back to the default level scale so that user can enter text
boolean zoom = mZoomManager.getScale() < mZoomManager.getDefaultScale();
@@ -5472,15 +5413,15 @@ public class WebView extends AbsoluteLayout
// does not recognize that a textfield is in focus. In that
// case, use WebView as the targeted view.
// see http://b/issue?id=2457459
- imm.showSoftInput(this, 0);
+ imm.showSoftInput(mWebView, 0);
}
// Called by WebKit to instruct the UI to hide the keyboard
private void hideSoftKeyboard() {
InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null && (imm.isActive(this)
+ if (imm != null && (imm.isActive(mWebView)
|| (inEditingMode() && imm.isActive(mWebTextView)))) {
- imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
+ imm.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
}
}
@@ -5494,7 +5435,7 @@ public class WebView extends AbsoluteLayout
return; // always use WebKit's text entry
}
// If the WebView does not have focus, do nothing until it gains focus.
- if (!hasFocus() && (null == mWebTextView || !mWebTextView.hasFocus())) {
+ if (!mWebView.hasFocus() && (null == mWebTextView || !mWebTextView.hasFocus())) {
return;
}
boolean alreadyThere = inEditingMode();
@@ -5509,7 +5450,7 @@ public class WebView extends AbsoluteLayout
// At this point, we know we have found an input field, so go ahead
// and create the WebTextView if necessary.
if (mWebTextView == null) {
- mWebTextView = new WebTextView(mContext, WebView.this, mAutoFillData.getQueryId());
+ mWebTextView = new WebTextView(mContext, WebViewClassic.this, mAutoFillData.getQueryId());
// Initialize our generation number.
mTextGeneration = 0;
}
@@ -5535,7 +5476,7 @@ public class WebView extends AbsoluteLayout
imm.restartInput(mWebTextView);
mWebTextView.clearComposingText();
}
- if (isFocused()) {
+ if (mWebView.isFocused()) {
mWebTextView.requestFocus();
}
}
@@ -5626,7 +5567,7 @@ public class WebView extends AbsoluteLayout
private Message mUpdateMessage;
private boolean mAutoFillable;
private boolean mAutoComplete;
- private WebSettings mWebSettings;
+ private WebSettingsClassic mWebSettings;
public RequestFormData(String name, String url, Message msg,
boolean autoFillable, boolean autoComplete) {
@@ -5647,7 +5588,7 @@ public class WebView extends AbsoluteLayout
// on the AutoFill item being at the top of the drop down list. If you change
// the order, make sure to do it there too!
if (mWebSettings != null && mWebSettings.getAutoFillProfile() != null) {
- pastEntries.add(getResources().getText(
+ pastEntries.add(mWebView.getResources().getText(
com.android.internal.R.string.autofill_this_form).toString() +
" " +
mAutoFillData.getPreviewString());
@@ -5655,7 +5596,7 @@ public class WebView extends AbsoluteLayout
} else {
// There is no autofill profile set up yet, so add an option that
// will invite the user to set their profile up.
- pastEntries.add(getResources().getText(
+ pastEntries.add(mWebView.getResources().getText(
com.android.internal.R.string.setup_autofill).toString());
mWebTextView.setAutoFillProfileIsSet(false);
}
@@ -5869,7 +5810,7 @@ public class WebView extends AbsoluteLayout
}
}
if (navHandledKey(keyCode, 1, false, event.getEventTime())) {
- playSoundEffect(keyCodeToSoundsEffect(keyCode));
+ mWebView.playSoundEffect(keyCodeToSoundsEffect(keyCode));
return true;
}
// Bubble up the key event as WebView doesn't handle it
@@ -5964,7 +5905,7 @@ public class WebView extends AbsoluteLayout
if (!nativeCursorIsTextInput() && text != null
&& text.startsWith(SCHEME_TEL)) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(text));
- getContext().startActivity(intent);
+ mContext.startActivity(intent);
return true;
}
}
@@ -6035,7 +5976,7 @@ public class WebView extends AbsoluteLayout
}
WebViewCore.CursorData data = cursorData();
mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE, data);
- playSoundEffect(SoundEffectConstants.CLICK);
+ mWebView.playSoundEffect(SoundEffectConstants.CLICK);
if (nativeCursorIsTextInput()) {
rebuildWebTextView();
centerKeyPressOnTextField();
@@ -6073,13 +6014,13 @@ public class WebView extends AbsoluteLayout
mSelectCallback = new SelectActionModeCallback();
mSelectCallback.setTextSelected(!mIsCaretSelection);
mSelectCallback.setWebView(this);
- if (startActionMode(mSelectCallback) == null) {
+ if (mWebView.startActionMode(mSelectCallback) == null) {
// There is no ActionMode, so do not allow the user to modify a
// selection.
selectionDone();
return false;
}
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ mWebView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
return true;
}
@@ -6089,8 +6030,8 @@ public class WebView extends AbsoluteLayout
if (cm.hasPrimaryClip()) {
Rect cursorRect = contentToViewRect(mSelectCursorBase);
int[] location = new int[2];
- getLocationInWindow(location);
- cursorRect.offset(location[0] - mScrollX, location[1] - mScrollY);
+ mWebView.getLocationInWindow(location);
+ cursorRect.offset(location[0] - getScrollX(), location[1] - getScrollY());
if (mPasteWindow == null) {
mPasteWindow = new PastePopupWindow();
}
@@ -6209,7 +6150,7 @@ public class WebView extends AbsoluteLayout
, com.android.internal.R.string.text_copied
, Toast.LENGTH_SHORT).show();
copiedSomething = true;
- ClipboardManager cm = (ClipboardManager)getContext()
+ ClipboardManager cm = (ClipboardManager)mContext
.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setText(selection);
int[] handles = new int[4];
@@ -6238,7 +6179,7 @@ public class WebView extends AbsoluteLayout
* @hide This is an implementation detail
*/
public void pasteFromClipboard() {
- ClipboardManager cm = (ClipboardManager)getContext()
+ ClipboardManager cm = (ClipboardManager)mContext
.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = cm.getPrimaryClip();
if (clipData != null) {
@@ -6269,10 +6210,9 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- if (hasWindowFocus()) setActive(true);
- final ViewTreeObserver treeObserver = getViewTreeObserver();
+ public void onAttachedToWindow() {
+ if (mWebView.hasWindowFocus()) setActive(true);
+ final ViewTreeObserver treeObserver = mWebView.getViewTreeObserver();
if (mGlobalLayoutListener == null) {
mGlobalLayoutListener = new InnerGlobalLayoutListener();
treeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener);
@@ -6288,12 +6228,12 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected void onDetachedFromWindow() {
+ public void onDetachedFromWindow() {
clearHelpers();
mZoomManager.dismissZoomPicker();
- if (hasWindowFocus()) setActive(false);
+ if (mWebView.hasWindowFocus()) setActive(false);
- final ViewTreeObserver treeObserver = getViewTreeObserver();
+ final ViewTreeObserver treeObserver = mWebView.getViewTreeObserver();
if (mGlobalLayoutListener != null) {
treeObserver.removeGlobalOnLayoutListener(mGlobalLayoutListener);
mGlobalLayoutListener = null;
@@ -6304,13 +6244,10 @@ public class WebView extends AbsoluteLayout
}
removeAccessibilityApisFromJavaScript();
-
- super.onDetachedFromWindow();
}
@Override
- protected void onVisibilityChanged(View changedView, int visibility) {
- super.onVisibilityChanged(changedView, visibility);
+ public void onVisibilityChanged(View changedView, int visibility) {
// The zoomManager may be null if the webview is created from XML that
// specifies the view's visibility param as not visible (see http://b/2794841)
if (visibility != View.VISIBLE && mZoomManager != null) {
@@ -6319,37 +6256,9 @@ public class WebView extends AbsoluteLayout
updateDrawingState();
}
- /**
- * @deprecated WebView no longer needs to implement
- * ViewGroup.OnHierarchyChangeListener. This method does nothing now.
- */
- @Override
- // Cannot add @hide as this can always be accessed via the interface.
- @Deprecated
- public void onChildViewAdded(View parent, View child) {}
-
- /**
- * @deprecated WebView no longer needs to implement
- * ViewGroup.OnHierarchyChangeListener. This method does nothing now.
- */
- @Override
- // Cannot add @hide as this can always be accessed via the interface.
- @Deprecated
- public void onChildViewRemoved(View p, View child) {}
-
- /**
- * @deprecated WebView should not have implemented
- * ViewTreeObserver.OnGlobalFocusChangeListener. This method does nothing now.
- */
- @Override
- // Cannot add @hide as this can always be accessed via the interface.
- @Deprecated
- public void onGlobalFocusChanged(View oldFocus, View newFocus) {
- }
-
void setActive(boolean active) {
if (active) {
- if (hasFocus()) {
+ if (mWebView.hasFocus()) {
// If our window regained focus, and we have focus, then begin
// drawing the cursor ring
mDrawCursorRing = !inEditingMode();
@@ -6404,7 +6313,6 @@ public class WebView extends AbsoluteLayout
mPictureUpdatePausedForFocusChange = true;
}
}
- super.onWindowFocusChanged(hasWindowFocus);
}
/*
@@ -6424,7 +6332,7 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected void onFocusChanged(boolean focused, int direction,
+ public void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "MT focusChanged " + focused + ", " + direction);
@@ -6432,7 +6340,7 @@ public class WebView extends AbsoluteLayout
if (focused) {
// When we regain focus, if we have window focus, resume drawing
// the cursor ring
- if (hasWindowFocus()) {
+ if (mWebView.hasWindowFocus()) {
mDrawCursorRing = !inEditingMode();
setFocusControllerActive(true);
//} else {
@@ -6449,18 +6357,16 @@ public class WebView extends AbsoluteLayout
}
mKeysPressed.clear();
}
-
- super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
void setGLRectViewport() {
// Use the getGlobalVisibleRect() to get the intersection among the parents
// visible == false means we're clipped - send a null rect down to indicate that
// we should not draw
- boolean visible = getGlobalVisibleRect(mGLRectViewport);
+ boolean visible = mWebView.getGlobalVisibleRect(mGLRectViewport);
if (visible) {
// Then need to invert the Y axis, just for GL
- View rootView = getRootView();
+ View rootView = mWebView.getRootView();
int rootViewHeight = rootView.getHeight();
mViewRectViewport.set(mGLRectViewport);
int savedWebViewBottom = mGLRectViewport.bottom;
@@ -6480,8 +6386,8 @@ public class WebView extends AbsoluteLayout
* @hide
*/
@Override
- protected boolean setFrame(int left, int top, int right, int bottom) {
- boolean changed = super.setFrame(left, top, right, bottom);
+ public boolean setFrame(int left, int top, int right, int bottom) {
+ boolean changed = mWebViewPrivate.super_setFrame(left, top, right, bottom);
if (!changed && mHeightCanMeasure) {
// When mHeightCanMeasure is true, we will set mLastHeightSent to 0
// in WebViewCore after we get the first layout. We do call
@@ -6496,9 +6402,7 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected void onSizeChanged(int w, int h, int ow, int oh) {
- super.onSizeChanged(w, h, ow, oh);
-
+ public void onSizeChanged(int w, int h, int ow, int oh) {
// adjust the max viewport width depending on the view dimensions. This
// is to ensure the scaling is not going insane. So do not shrink it if
// the view size is temporarily smaller, e.g. when soft keyboard is up.
@@ -6518,8 +6422,7 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- super.onScrollChanged(l, t, oldl, oldt);
+ public void onScrollChanged(int l, int t, int oldl, int oldt) {
if (!mInOverScrollMode) {
sendOurVisibleRect();
// update WebKit if visible title bar height changed. The logic is same
@@ -6562,7 +6465,7 @@ public class WebView extends AbsoluteLayout
// not currently have a bounds.
return mWebTextView.dispatchKeyEvent(event);
} else {
- return super.dispatchKeyEvent(event);
+ return mWebViewPrivate.super_dispatchKeyEvent(event);
}
}
@@ -6674,7 +6577,7 @@ public class WebView extends AbsoluteLayout
@Override
public boolean onTouchEvent(MotionEvent ev) {
- if (mNativeClass == 0 || (!isClickable() && !isLongClickable())) {
+ if (mNativeClass == 0 || (!mWebView.isClickable() && !mWebView.isLongClickable())) {
return false;
}
@@ -6894,7 +6797,7 @@ public class WebView extends AbsoluteLayout
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "extend=" + contentX + "," + contentY);
}
- ViewParent parent = getParent();
+ ViewParent parent = mWebView.getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
@@ -7062,7 +6965,7 @@ public class WebView extends AbsoluteLayout
invalidate();
}
// keep the scrollbar on the screen even there is no scroll
- awakenScrollBars(ViewConfiguration.getScrollDefaultDelay(),
+ mWebViewPrivate.awakenScrollBars(ViewConfiguration.getScrollDefaultDelay(),
false);
// Post a message so that we'll keep them alive while we're not scrolling.
mPrivateHandler.sendMessageDelayed(mPrivateHandler
@@ -7077,7 +6980,7 @@ public class WebView extends AbsoluteLayout
break;
}
case MotionEvent.ACTION_UP: {
- if (!isFocused()) requestFocus();
+ if (!mWebView.isFocused()) mWebView.requestFocus();
// pass the touch events from UI thread to WebCore thread
if (shouldForwardTouchEvent()) {
TouchEventData ted = new TouchEventData();
@@ -7268,7 +7171,7 @@ public class WebView extends AbsoluteLayout
ted.mSequence = sequence;
mTouchEventQueue.preQueueTouchEventData(ted);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
- cancelLongPress();
+ mWebView.cancelLongPress();
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
}
@@ -7301,7 +7204,7 @@ public class WebView extends AbsoluteLayout
x = detector.getFocusX();
y = detector.getFocusY();
- cancelLongPress();
+ mWebView.cancelLongPress();
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
if (!mZoomManager.supportsPanDuringZoom()) {
return;
@@ -7433,7 +7336,7 @@ public class WebView extends AbsoluteLayout
mOverScrollGlow.setOverScrollDeltas(deltaX, deltaY);
}
- overScrollBy(deltaX, deltaY, oldX, oldY,
+ mWebViewPrivate.overScrollBy(deltaX, deltaY, oldX, oldY,
rangeX, rangeY,
mOverscrollDistance, mOverscrollDistance, true);
if (mOverScrollGlow != null && mOverScrollGlow.isAnimating()) {
@@ -7517,8 +7420,10 @@ public class WebView extends AbsoluteLayout
hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
}
if (hscroll != 0 || vscroll != 0) {
- final int vdelta = (int) (vscroll * getVerticalScrollFactor());
- final int hdelta = (int) (hscroll * getHorizontalScrollFactor());
+ final int vdelta = (int) (vscroll *
+ mWebViewPrivate.getVerticalScrollFactor());
+ final int hdelta = (int) (hscroll *
+ mWebViewPrivate.getHorizontalScrollFactor());
if (pinScrollBy(hdelta, vdelta, false, 0)) {
return true;
}
@@ -7526,7 +7431,7 @@ public class WebView extends AbsoluteLayout
}
}
}
- return super.onGenericMotionEvent(event);
+ return mWebViewPrivate.super_onGenericMotionEvent(event);
}
private long mTrackballFirstTime = 0;
@@ -7596,7 +7501,7 @@ public class WebView extends AbsoluteLayout
+ " time=" + time
+ " mLastCursorTime=" + mLastCursorTime);
}
- if (isInTouchMode()) requestFocusFromTouch();
+ if (mWebView.isInTouchMode()) mWebView.requestFocusFromTouch();
return false; // let common code in onKeyDown at it
}
if (ev.getAction() == MotionEvent.ACTION_UP) {
@@ -7740,7 +7645,7 @@ public class WebView extends AbsoluteLayout
}
letPageHandleNavKey(selectKeyCode, time, false, metaState);
} else if (navHandledKey(selectKeyCode, count, false, time)) {
- playSoundEffect(keyCodeToSoundsEffect(selectKeyCode));
+ mWebView.playSoundEffect(keyCodeToSoundsEffect(selectKeyCode));
}
mTrackballRemainsX = mTrackballRemainsY = 0;
}
@@ -7790,7 +7695,7 @@ public class WebView extends AbsoluteLayout
setScrollXRaw(x);
setScrollYRaw(y);
if (oldX != getScrollX() || oldY != getScrollY()) {
- onScrollChanged(getScrollX(), getScrollY(), oldX, oldY);
+ mWebViewPrivate.onScrollChanged(getScrollX(), getScrollY(), oldX, oldY);
return true;
} else {
return false;
@@ -7908,7 +7813,7 @@ public class WebView extends AbsoluteLayout
// Suppress scrollbars for layer scrolling.
if (mTouchMode != TOUCH_DRAG_LAYER_MODE) {
- awakenScrollBars(time);
+ mWebViewPrivate.awakenScrollBars(time);
}
invalidate();
@@ -8104,7 +8009,7 @@ public class WebView extends AbsoluteLayout
// set mTouchHighlightRequested to 0 to cause an immediate
// drawing of the touch rings
mTouchHighlightRequested = 0;
- invalidate(mTouchHighlightRegion.getBounds());
+ mWebView.invalidate(mTouchHighlightRegion.getBounds());
mPrivateHandler.postDelayed(new Runnable() {
@Override
public void run() {
@@ -8113,7 +8018,7 @@ public class WebView extends AbsoluteLayout
}, ViewConfiguration.getPressedStateDuration());
}
if (mFocusedNode != null && mFocusedNode.mIntentUrl != null) {
- playSoundEffect(SoundEffectConstants.CLICK);
+ mWebView.playSoundEffect(SoundEffectConstants.CLICK);
overrideLoading(mFocusedNode.mIntentUrl);
} else if (sDisableNavcache) {
WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
@@ -8142,7 +8047,7 @@ public class WebView extends AbsoluteLayout
EventLog.writeEvent(EventLogTags.BROWSER_SNAP_CENTER);
}
if (nativeHasCursorNode() && !nativeCursorIsTextInput()) {
- playSoundEffect(SoundEffectConstants.CLICK);
+ mWebView.playSoundEffect(SoundEffectConstants.CLICK);
}
}
@@ -8250,8 +8155,8 @@ public class WebView extends AbsoluteLayout
result = mWebTextView.requestFocus(direction,
previouslyFocusedRect);
} else {
- result = super.requestFocus(direction, previouslyFocusedRect);
- if (mWebViewCore.getSettings().getNeedInitialFocus() && !isInTouchMode()) {
+ result = mWebViewPrivate.super_requestFocus(direction, previouslyFocusedRect);
+ if (mWebViewCore.getSettings().getNeedInitialFocus() && !mWebView.isInTouchMode()) {
// For cases such as GMail, where we gain focus from a direction,
// we want to move to the first available link.
// FIXME: If there are no visible links, we may not want to
@@ -8281,9 +8186,7 @@ public class WebView extends AbsoluteLayout
}
@Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
@@ -8307,7 +8210,7 @@ public class WebView extends AbsoluteLayout
if (measuredHeight > heightSize) {
measuredHeight = heightSize;
mHeightCanMeasure = false;
- measuredHeight |= MEASURED_STATE_TOO_SMALL;
+ measuredHeight |= View.MEASURED_STATE_TOO_SMALL;
}
}
} else {
@@ -8322,13 +8225,13 @@ public class WebView extends AbsoluteLayout
measuredWidth = contentWidth;
} else {
if (measuredWidth < contentWidth) {
- measuredWidth |= MEASURED_STATE_TOO_SMALL;
+ measuredWidth |= View.MEASURED_STATE_TOO_SMALL;
}
mWidthCanMeasure = false;
}
synchronized (this) {
- setMeasuredDimension(measuredWidth, measuredHeight);
+ mWebViewPrivate.setMeasuredDimension(measuredWidth, measuredHeight);
}
}
@@ -8351,7 +8254,7 @@ public class WebView extends AbsoluteLayout
Rect content = new Rect(viewToContentX(getScrollX()),
viewToContentY(getScrollY()),
viewToContentX(getScrollX() + getWidth()
- - getVerticalScrollbarWidth()),
+ - mWebView.getVerticalScrollbarWidth()),
viewToContentY(getScrollY() + getViewHeightWithTitle()));
content = nativeSubtractLayers(content);
int screenTop = contentToViewY(content.top);
@@ -8901,7 +8804,7 @@ public class WebView extends AbsoluteLayout
break;
case WebViewCore.ACTION_LONGPRESS:
HitTestResult hitTest = getHitTestResult();
- if (hitTest != null && hitTest.mType
+ if (hitTest != null && hitTest.getType()
!= HitTestResult.UNKNOWN_TYPE) {
performLongClick();
}
@@ -9059,7 +8962,7 @@ public class WebView extends AbsoluteLayout
// view, but is only necessary if the IME is showing
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm == null || !imm.isAcceptingText()
- || (!imm.isActive(WebView.this) && (!inEditingMode()
+ || (!imm.isActive(mWebView) && (!inEditingMode()
|| !imm.isActive(mWebTextView)))) {
break;
}
@@ -9226,7 +9129,7 @@ public class WebView extends AbsoluteLayout
case AWAKEN_SCROLL_BARS:
if (mTouchMode == TOUCH_DRAG_MODE
&& mHeldMotionless == MOTIONLESS_TRUE) {
- awakenScrollBars(ViewConfiguration
+ mWebViewPrivate.awakenScrollBars(ViewConfiguration
.getScrollDefaultDelay(), false);
mPrivateHandler.sendMessageDelayed(mPrivateHandler
.obtainMessage(AWAKEN_SCROLL_BARS),
@@ -9239,7 +9142,7 @@ public class WebView extends AbsoluteLayout
break;
case SCREEN_ON:
- setKeepScreenOn(msg.arg1 == 1);
+ mWebView.setKeepScreenOn(msg.arg1 == 1);
break;
case ENTER_FULLSCREEN_VIDEO:
@@ -9266,7 +9169,7 @@ public class WebView extends AbsoluteLayout
Log.w(LOGTAG, "Should not have another full screen.");
dismissFullScreenMode();
}
- mFullScreenHolder = new PluginFullScreenHolder(WebView.this, orientation, npp);
+ mFullScreenHolder = new PluginFullScreenHolder(WebViewClassic.this, orientation, npp);
mFullScreenHolder.setContentView(view);
mFullScreenHolder.show();
invalidate();
@@ -9329,7 +9232,7 @@ public class WebView extends AbsoluteLayout
// We need to take into account the visible title height
// when scrolling since y is an absolute view position.
y = Math.max(0, y - getVisibleTitleHeightImpl());
- scrollTo(x, y);
+ mWebView.scrollTo(x, y);
}
break;
@@ -9432,24 +9335,24 @@ public class WebView extends AbsoluteLayout
private void setHitTestTypeFromUrl(String url) {
String substr = null;
if (url.startsWith(SCHEME_GEO)) {
- mInitialHitTestResult.mType = HitTestResult.GEO_TYPE;
+ mInitialHitTestResult.setType(HitTestResult.GEO_TYPE);
substr = url.substring(SCHEME_GEO.length());
} else if (url.startsWith(SCHEME_TEL)) {
- mInitialHitTestResult.mType = HitTestResult.PHONE_TYPE;
+ mInitialHitTestResult.setType(HitTestResult.PHONE_TYPE);
substr = url.substring(SCHEME_TEL.length());
} else if (url.startsWith(SCHEME_MAILTO)) {
- mInitialHitTestResult.mType = HitTestResult.EMAIL_TYPE;
+ mInitialHitTestResult.setType(HitTestResult.EMAIL_TYPE);
substr = url.substring(SCHEME_MAILTO.length());
} else {
- mInitialHitTestResult.mType = HitTestResult.SRC_ANCHOR_TYPE;
- mInitialHitTestResult.mExtra = url;
+ mInitialHitTestResult.setType(HitTestResult.SRC_ANCHOR_TYPE);
+ mInitialHitTestResult.setExtra(url);
return;
}
try {
- mInitialHitTestResult.mExtra = URLDecoder.decode(substr, "UTF-8");
+ mInitialHitTestResult.setExtra(URLDecoder.decode(substr, "UTF-8"));
} catch (Throwable e) {
Log.w(LOGTAG, "Failed to decode URL! " + substr, e);
- mInitialHitTestResult.mType = HitTestResult.UNKNOWN_TYPE;
+ mInitialHitTestResult.setType(HitTestResult.UNKNOWN_TYPE);
}
}
@@ -9462,15 +9365,15 @@ public class WebView extends AbsoluteLayout
if (hit.mLinkUrl != null) {
setHitTestTypeFromUrl(hit.mLinkUrl);
if (hit.mImageUrl != null
- && mInitialHitTestResult.mType == HitTestResult.SRC_ANCHOR_TYPE) {
- mInitialHitTestResult.mType = HitTestResult.SRC_IMAGE_ANCHOR_TYPE;
- mInitialHitTestResult.mExtra = hit.mImageUrl;
+ && mInitialHitTestResult.getType() == HitTestResult.SRC_ANCHOR_TYPE) {
+ mInitialHitTestResult.setType(HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
+ mInitialHitTestResult.setExtra(hit.mImageUrl);
}
} else if (hit.mImageUrl != null) {
- mInitialHitTestResult.mType = HitTestResult.IMAGE_TYPE;
- mInitialHitTestResult.mExtra = hit.mImageUrl;
+ mInitialHitTestResult.setType(HitTestResult.IMAGE_TYPE);
+ mInitialHitTestResult.setExtra(hit.mImageUrl);
} else if (hit.mEditable) {
- mInitialHitTestResult.mType = HitTestResult.EDIT_TEXT_TYPE;
+ mInitialHitTestResult.setType(HitTestResult.EDIT_TEXT_TYPE);
} else if (hit.mIntentUrl != null) {
setHitTestTypeFromUrl(hit.mIntentUrl);
}
@@ -9483,16 +9386,16 @@ public class WebView extends AbsoluteLayout
if (mTouchHighlightRegion.isEmpty()) {
return false;
}
- if (mFocusedNode.mHasFocus && !isInTouchMode()) {
+ if (mFocusedNode.mHasFocus && !mWebView.isInTouchMode()) {
return !mFocusedNode.mEditable;
}
- if (mInitialHitTestResult.mType == HitTestResult.UNKNOWN_TYPE) {
+ if (mInitialHitTestResult.getType() == HitTestResult.UNKNOWN_TYPE) {
return false;
}
long delay = System.currentTimeMillis() - mTouchHighlightRequested;
if (delay < ViewConfiguration.getTapTimeout()) {
Rect r = mTouchHighlightRegion.getBounds();
- postInvalidateDelayed(delay, r.left, r.top, r.right, r.bottom);
+ mWebView.postInvalidateDelayed(delay, r.left, r.top, r.right, r.bottom);
return false;
}
return true;
@@ -9504,12 +9407,12 @@ public class WebView extends AbsoluteLayout
Region mPreviousRegion;
Region mNewRegion;
float mProgress = 0;
- WebView mWebView;
+ WebViewClassic mWebView;
Paint mPaint;
int mMaxAlpha;
Point mTranslate;
- public FocusTransitionDrawable(WebView view) {
+ public FocusTransitionDrawable(WebViewClassic view) {
mWebView = view;
mPaint = new Paint(mWebView.mTouchHightlightPaint);
mMaxAlpha = mPaint.getAlpha();
@@ -9588,7 +9491,7 @@ public class WebView extends AbsoluteLayout
}
Rect[] rects = hit != null ? hit.mTouchRects : null;
if (!mTouchHighlightRegion.isEmpty()) {
- invalidate(mTouchHighlightRegion.getBounds());
+ mWebView.invalidate(mTouchHighlightRegion.getBounds());
if (transition != null) {
transition.mPreviousRegion = new Region(mTouchHighlightRegion);
}
@@ -9610,7 +9513,7 @@ public class WebView extends AbsoluteLayout
+ viewRect);
}
}
- invalidate(mTouchHighlightRegion.getBounds());
+ mWebView.invalidate(mTouchHighlightRegion.getBounds());
if (transition != null && transition.mPreviousRegion != null) {
transition.mNewRegion = new Region(mTouchHighlightRegion);
mFocusTransition = transition;
@@ -9621,6 +9524,11 @@ public class WebView extends AbsoluteLayout
}
}
+ // Interface to allow the profiled WebView to hook the page swap notifications.
+ public interface PageSwapDelegate {
+ void onPageSwapOccurred(boolean notifyAnimationStarted);
+ }
+
/** @hide Called by JNI when pages are swapped (only occurs with hardware
* acceleration) */
protected void pageSwapCallback(boolean notifyAnimationStarted) {
@@ -9631,6 +9539,10 @@ public class WebView extends AbsoluteLayout
if (notifyAnimationStarted) {
mWebViewCore.sendMessage(EventHub.NOTIFY_ANIMATION_STARTED);
}
+ if (mWebView instanceof PageSwapDelegate) {
+ // This provides a hook for ProfiledWebView to observe the tile page swaps.
+ ((PageSwapDelegate) mWebView).onPageSwapOccurred(notifyAnimationStarted);
+ }
}
void setNewPicture(final WebViewCore.DrawData draw, boolean updateBaseLayer) {
@@ -9690,7 +9602,7 @@ public class WebView extends AbsoluteLayout
invalidateContentRect(draw.mInvalRegion.getBounds());
if (mPictureListener != null) {
- mPictureListener.onNewPicture(WebView.this, capturePicture());
+ mPictureListener.onNewPicture(getWebView(), capturePicture());
}
// update the zoom information based on the new picture
@@ -9778,7 +9690,7 @@ public class WebView extends AbsoluteLayout
*/
private class MyArrayListAdapter extends ArrayAdapter<Container> {
public MyArrayListAdapter() {
- super(mContext,
+ super(WebViewClassic.this.mContext,
mMultiple ? com.android.internal.R.layout.select_dialog_multichoice :
com.android.internal.R.layout.webview_select_singlechoice,
mContainers);
@@ -10146,7 +10058,7 @@ public class WebView extends AbsoluteLayout
if (down) {
keyEventAction = KeyEvent.ACTION_DOWN;
eventHubAction = EventHub.KEY_DOWN;
- playSoundEffect(keyCodeToSoundsEffect(keyCode));
+ mWebView.playSoundEffect(keyCodeToSoundsEffect(keyCode));
} else {
keyEventAction = KeyEvent.ACTION_UP;
eventHubAction = EventHub.KEY_UP;
@@ -10217,7 +10129,7 @@ public class WebView extends AbsoluteLayout
Log.v(LOGTAG, "navHandledKey contentCursorRingBounds="
+ contentCursorRingBounds);
}
- requestRectangleOnScreen(viewCursorRingBounds);
+ mWebView.requestRectangleOnScreen(viewCursorRingBounds);
return keyHandled;
}
@@ -10289,7 +10201,7 @@ public class WebView extends AbsoluteLayout
* @param text The text to put into the clipboard.
*/
private void copyToClipboard(String text) {
- ClipboardManager cm = (ClipboardManager)getContext()
+ ClipboardManager cm = (ClipboardManager)mContext
.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(getTitle(), text);
cm.setPrimaryClip(clip);
@@ -10333,8 +10245,8 @@ public class WebView extends AbsoluteLayout
}
}
- /** @hide discard all textures from tiles */
- protected void discardAllTextures() {
+ /** @hide discard all textures from tiles. Used in Profiled WebView */
+ public void discardAllTextures() {
nativeDiscardAllTextures();
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 93fd92b..4bda5ef 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -39,7 +39,7 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
-import android.webkit.WebView.FocusNodeHref;
+import android.webkit.WebViewClassic.FocusNodeHref;
import junit.framework.Assert;
@@ -72,11 +72,12 @@ public final class WebViewCore {
*/
// The WebView that corresponds to this WebViewCore.
- private WebView mWebView;
+ // TODO: rename this field (and its getter) to mWebViewClassic or mWebViewImpl.
+ private WebViewClassic mWebView;
// Proxy for handling callbacks from native code
private final CallbackProxy mCallbackProxy;
// Settings object for maintaining all settings
- private final WebSettings mSettings;
+ private final WebSettingsClassic mSettings;
// Context for initializing the BrowserFrame with the proper assets.
private final Context mContext;
// The pointer to a native view object.
@@ -142,7 +143,7 @@ public final class WebViewCore {
// debugging other classes that require operation within the WebCore thread.
/* package */ static final String THREAD_NAME = "WebViewCoreThread";
- public WebViewCore(Context context, WebView w, CallbackProxy proxy,
+ public WebViewCore(Context context, WebViewClassic w, CallbackProxy proxy,
Map<String, Object> javascriptInterfaces) {
// No need to assign this in the WebCore thread.
mCallbackProxy = proxy;
@@ -179,7 +180,7 @@ public final class WebViewCore {
// ready.
mEventHub = new EventHub();
// Create a WebSettings object for maintaining all settings
- mSettings = new WebSettings(mContext, mWebView);
+ mSettings = new WebSettingsClassic(mContext, mWebView);
// The WebIconDatabase needs to be initialized within the UI thread so
// just request the instance here.
WebIconDatabase.getInstance();
@@ -234,7 +235,7 @@ public final class WebViewCore {
// WebCore thread.
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
- WebView.WEBCORE_INITIALIZED_MSG_ID,
+ WebViewClassic.WEBCORE_INITIALIZED_MSG_ID,
mNativeClass, 0).sendToTarget();
}
@@ -284,7 +285,7 @@ public final class WebViewCore {
BrowserFrame.sJavaBridge.resume();
}
- public WebSettings getSettings() {
+ public WebSettingsClassic getSettings() {
return mSettings;
}
@@ -329,7 +330,7 @@ public final class WebViewCore {
*/
private void formDidBlur(int nodePointer) {
if (mWebView == null) return;
- Message.obtain(mWebView.mPrivateHandler, WebView.FORM_DID_BLUR,
+ Message.obtain(mWebView.mPrivateHandler, WebViewClassic.FORM_DID_BLUR,
nodePointer, 0).sendToTarget();
}
@@ -338,7 +339,7 @@ public final class WebViewCore {
*/
private void focusNodeChanged(WebKitHitTest hitTest) {
if (mWebView == null) return;
- mWebView.mPrivateHandler.obtainMessage(WebView.HIT_TEST_RESULT, hitTest)
+ mWebView.mPrivateHandler.obtainMessage(WebViewClassic.HIT_TEST_RESULT, hitTest)
.sendToTarget();
}
@@ -508,7 +509,7 @@ public final class WebViewCore {
protected void enterFullscreenForVideoLayer(int layerId, String url) {
if (mWebView == null) return;
Message message = Message.obtain(mWebView.mPrivateHandler,
- WebView.ENTER_FULLSCREEN_VIDEO, layerId, 0);
+ WebViewClassic.ENTER_FULLSCREEN_VIDEO, layerId, 0);
message.obj = url;
message.sendToTarget();
}
@@ -520,7 +521,7 @@ public final class WebViewCore {
protected void exitFullscreenVideo() {
if (mWebView == null) return;
Message message = Message.obtain(mWebView.mPrivateHandler,
- WebView.EXIT_FULLSCREEN_VIDEO);
+ WebViewClassic.EXIT_FULLSCREEN_VIDEO);
message.sendToTarget();
}
@@ -886,7 +887,7 @@ public final class WebViewCore {
String mTitle;
Rect[] mTouchRects;
boolean mEditable;
- int mTapHighlightColor = WebView.HIGHLIGHT_COLOR;
+ int mTapHighlightColor = WebViewClassic.HIGHLIGHT_COLOR;
Rect[] mEnclosingParentRects;
boolean mHasFocus;
@@ -1270,7 +1271,7 @@ public final class WebViewCore {
msg.arg1, nodePointer);
if (label != null && label.length() > 0) {
Message.obtain(mWebView.mPrivateHandler,
- WebView.RETURN_LABEL, nodePointer,
+ WebViewClassic.RETURN_LABEL, nodePointer,
0, label).sendToTarget();
}
}
@@ -1373,7 +1374,7 @@ public final class WebViewCore {
break;
case VIEW_SIZE_CHANGED: {
- viewSizeChanged((WebView.ViewSizeData) msg.obj);
+ viewSizeChanged((WebViewClassic.ViewSizeData) msg.obj);
break;
}
case SET_SCROLL_OFFSET:
@@ -1529,7 +1530,7 @@ public final class WebViewCore {
ted.mMetaState);
Message.obtain(
mWebView.mPrivateHandler,
- WebView.PREVENT_TOUCH_ID,
+ WebViewClassic.PREVENT_TOUCH_ID,
ted.mAction,
ted.mNativeResult ? 1 : 0,
ted).sendToTarget();
@@ -1594,7 +1595,7 @@ public final class WebViewCore {
nativeUpdateFrameCache(mNativeClass);
// FIXME: this should provide a minimal rectangle
if (mWebView != null) {
- mWebView.postInvalidate();
+ mWebView.getWebView().postInvalidate();
}
sendUpdateTextEntry();
break;
@@ -1621,7 +1622,8 @@ public final class WebViewCore {
String modifiedSelectionString =
nativeModifySelection(mNativeClass, msg.arg1,
msg.arg2);
- mWebView.mPrivateHandler.obtainMessage(WebView.SELECTION_STRING_CHANGED,
+ mWebView.mPrivateHandler.obtainMessage(
+ WebViewClassic.SELECTION_STRING_CHANGED,
modifiedSelectionString).sendToTarget();
break;
@@ -1666,12 +1668,12 @@ public final class WebViewCore {
break;
case SAVE_WEBARCHIVE:
- WebView.SaveWebArchiveMessage saveMessage =
- (WebView.SaveWebArchiveMessage)msg.obj;
+ WebViewClassic.SaveWebArchiveMessage saveMessage =
+ (WebViewClassic.SaveWebArchiveMessage)msg.obj;
saveMessage.mResultFile =
saveWebArchive(saveMessage.mBasename, saveMessage.mAutoname);
mWebView.mPrivateHandler.obtainMessage(
- WebView.SAVE_WEBARCHIVE_FINISHED, saveMessage).sendToTarget();
+ WebViewClassic.SAVE_WEBARCHIVE_FINISHED, saveMessage).sendToTarget();
break;
case GEOLOCATION_PERMISSIONS_PROVIDE:
@@ -1684,7 +1686,7 @@ public final class WebViewCore {
case SPLIT_PICTURE_SET:
nativeSplitContent(mNativeClass, msg.arg1);
mWebView.mPrivateHandler.obtainMessage(
- WebView.REPLACE_BASE_CONTENT, msg.arg1, 0);
+ WebViewClassic.REPLACE_BASE_CONTENT, msg.arg1, 0);
mSplitPictureIsScheduled = false;
break;
@@ -1711,7 +1713,7 @@ public final class WebViewCore {
nativeUpdateFrameCache(mNativeClass);
}
Message message = mWebView.mPrivateHandler
- .obtainMessage(WebView.DO_MOTION_UP,
+ .obtainMessage(WebViewClassic.DO_MOTION_UP,
motionUpData.mX, motionUpData.mY);
mWebView.mPrivateHandler.sendMessageAtFrontOfQueue(
message);
@@ -1747,7 +1749,7 @@ public final class WebViewCore {
}
WebKitHitTest hit = performHitTest(d.mX, d.mY, d.mSlop, true);
mWebView.mPrivateHandler.obtainMessage(
- WebView.HIT_TEST_RESULT, hit)
+ WebViewClassic.HIT_TEST_RESULT, hit)
.sendToTarget();
break;
@@ -1757,7 +1759,7 @@ public final class WebViewCore {
case AUTOFILL_FORM:
nativeAutoFillForm(mNativeClass, msg.arg1);
- mWebView.mPrivateHandler.obtainMessage(WebView.AUTOFILL_COMPLETE, null)
+ mWebView.mPrivateHandler.obtainMessage(WebViewClassic.AUTOFILL_COMPLETE, null)
.sendToTarget();
break;
@@ -1788,7 +1790,7 @@ public final class WebViewCore {
handles[0], handles[1], handles[2],
handles[3]);
if (copiedText != null) {
- mWebView.mPrivateHandler.obtainMessage(WebView.COPY_TO_CLIPBOARD, copiedText)
+ mWebView.mPrivateHandler.obtainMessage(WebViewClassic.COPY_TO_CLIPBOARD, copiedText)
.sendToTarget();
}
break;
@@ -2058,7 +2060,7 @@ public final class WebViewCore {
}
if (mWebView != null && evt.isDown()) {
Message.obtain(mWebView.mPrivateHandler,
- WebView.UNHANDLED_NAV_KEY, keyCode,
+ WebViewClassic.UNHANDLED_NAV_KEY, keyCode,
0).sendToTarget();
}
return;
@@ -2081,7 +2083,7 @@ public final class WebViewCore {
private float mCurrentViewScale = 1.0f;
// notify webkit that our virtual view size changed size (after inv-zoom)
- private void viewSizeChanged(WebView.ViewSizeData data) {
+ private void viewSizeChanged(WebViewClassic.ViewSizeData data) {
int w = data.mWidth;
int h = data.mHeight;
int textwrapWidth = data.mTextWrapWidth;
@@ -2125,7 +2127,7 @@ public final class WebViewCore {
if (mSettings.getUseWideViewPort()) {
if (mViewportWidth == -1) {
// Fixed viewport width.
- width = WebView.DEFAULT_VIEWPORT_WIDTH;
+ width = WebViewClassic.DEFAULT_VIEWPORT_WIDTH;
} else if (mViewportWidth > 0) {
// Use website specified or desired fixed viewport width.
width = mViewportWidth;
@@ -2140,7 +2142,7 @@ public final class WebViewCore {
private void sendUpdateTextEntry() {
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
- WebView.UPDATE_TEXT_ENTRY_MSG_ID).sendToTarget();
+ WebViewClassic.UPDATE_TEXT_ENTRY_MSG_ID).sendToTarget();
}
}
@@ -2230,9 +2232,9 @@ public final class WebViewCore {
// If anything more complex than position has been touched, let's do a full draw
webkitDraw();
}
- mWebView.mPrivateHandler.removeMessages(WebView.INVAL_RECT_MSG_ID);
+ mWebView.mPrivateHandler.removeMessages(WebViewClassic.INVAL_RECT_MSG_ID);
mWebView.mPrivateHandler.sendMessageAtFrontOfQueue(mWebView.mPrivateHandler
- .obtainMessage(WebView.INVAL_RECT_MSG_ID));
+ .obtainMessage(WebViewClassic.INVAL_RECT_MSG_ID));
}
private Boolean m_skipDrawFlag = false;
@@ -2289,7 +2291,7 @@ public final class WebViewCore {
draw.mViewSize = new Point(mCurrentViewWidth, mCurrentViewHeight);
if (mSettings.getUseWideViewPort()) {
draw.mMinPrefWidth = Math.max(
- mViewportWidth == -1 ? WebView.DEFAULT_VIEWPORT_WIDTH
+ mViewportWidth == -1 ? WebViewClassic.DEFAULT_VIEWPORT_WIDTH
: (mViewportWidth == 0 ? mCurrentViewWidth
: mViewportWidth),
nativeGetContentMinPrefWidth(mNativeClass));
@@ -2304,7 +2306,7 @@ public final class WebViewCore {
}
if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID");
Message.obtain(mWebView.mPrivateHandler,
- WebView.NEW_PICTURE_MSG_ID, draw).sendToTarget();
+ WebViewClassic.NEW_PICTURE_MSG_ID, draw).sendToTarget();
}
}
@@ -2433,7 +2435,7 @@ public final class WebViewCore {
}
if (mWebView != null) {
Message msg = Message.obtain(mWebView.mPrivateHandler,
- WebView.SCROLL_TO_MSG_ID, animate ? 1 : 0,
+ WebViewClassic.SCROLL_TO_MSG_ID, animate ? 1 : 0,
onlyIfImeIsShowing ? 1 : 0, new Point(x, y));
if (mDrawIsScheduled) {
mEventHub.sendMessage(Message.obtain(null,
@@ -2457,7 +2459,7 @@ public final class WebViewCore {
private void sendViewInvalidate(int left, int top, int right, int bottom) {
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
- WebView.INVAL_RECT_MSG_ID,
+ WebViewClassic.INVAL_RECT_MSG_ID,
new Rect(left, top, right, bottom)).sendToTarget();
}
}
@@ -2473,7 +2475,7 @@ public final class WebViewCore {
// Gets the WebView corresponding to this WebViewCore. Note that the
// WebView object must only be used on the UI thread.
- /* package */ WebView getWebView() {
+ /* package */ WebViewClassic getWebView() {
return mWebView;
}
@@ -2499,9 +2501,9 @@ public final class WebViewCore {
}
// remove the touch highlight when moving to a new page
- if (WebView.sDisableNavcache) {
+ if (WebViewClassic.sDisableNavcache) {
mWebView.mPrivateHandler.sendEmptyMessage(
- WebView.HIT_TEST_RESULT);
+ WebViewClassic.HIT_TEST_RESULT);
}
// reset the scroll position, the restored offset and scales
@@ -2567,7 +2569,7 @@ public final class WebViewCore {
}
if (adjust != mWebView.getDefaultZoomScale()) {
Message.obtain(mWebView.mPrivateHandler,
- WebView.UPDATE_ZOOM_DENSITY, adjust).sendToTarget();
+ WebViewClassic.UPDATE_ZOOM_DENSITY, adjust).sendToTarget();
}
int defaultScale = (int) (adjust * 100);
@@ -2618,7 +2620,7 @@ public final class WebViewCore {
viewState.mScrollX = 0;
viewState.mShouldStartScrolledRight = false;
Message.obtain(mWebView.mPrivateHandler,
- WebView.UPDATE_ZOOM_RANGE, viewState).sendToTarget();
+ WebViewClassic.UPDATE_ZOOM_RANGE, viewState).sendToTarget();
return;
}
@@ -2689,7 +2691,7 @@ public final class WebViewCore {
mWebView.mLastHeightSent = 0;
// Send a negative scale to indicate that WebCore should reuse
// the current scale
- WebView.ViewSizeData data = new WebView.ViewSizeData();
+ WebViewClassic.ViewSizeData data = new WebViewClassic.ViewSizeData();
data.mWidth = mWebView.mLastWidthSent;
data.mHeight = 0;
// if mHeightCanMeasure is true, getUseWideViewPort() can't be
@@ -2713,7 +2715,7 @@ public final class WebViewCore {
// to WebViewCore
mWebView.mLastWidthSent = 0;
} else {
- WebView.ViewSizeData data = new WebView.ViewSizeData();
+ WebViewClassic.ViewSizeData data = new WebViewClassic.ViewSizeData();
// mViewScale as 0 means it is in zoom overview mode. So we don't
// know the exact scale. If mRestoredScale is non-zero, use it;
// otherwise just use mTextWrapScale as the initial scale.
@@ -2791,7 +2793,7 @@ public final class WebViewCore {
private void needTouchEvents(boolean need) {
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
- WebView.WEBCORE_NEED_TOUCH_EVENTS, need ? 1 : 0, 0)
+ WebViewClassic.WEBCORE_NEED_TOUCH_EVENTS, need ? 1 : 0, 0)
.sendToTarget();
}
}
@@ -2801,7 +2803,7 @@ public final class WebViewCore {
String text, int textGeneration) {
if (mWebView != null) {
Message msg = Message.obtain(mWebView.mPrivateHandler,
- WebView.UPDATE_TEXTFIELD_TEXT_MSG_ID, ptr,
+ WebViewClassic.UPDATE_TEXTFIELD_TEXT_MSG_ID, ptr,
textGeneration, text);
msg.getData().putBoolean("password", changeToPassword);
msg.sendToTarget();
@@ -2813,7 +2815,7 @@ public final class WebViewCore {
int textGeneration, int selectionPtr) {
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
- WebView.UPDATE_TEXT_SELECTION_MSG_ID, pointer, textGeneration,
+ WebViewClassic.UPDATE_TEXT_SELECTION_MSG_ID, pointer, textGeneration,
new TextSelectionData(start, end, selectionPtr)).sendToTarget();
}
}
@@ -2822,7 +2824,7 @@ public final class WebViewCore {
private void clearTextEntry() {
if (mWebView == null) return;
Message.obtain(mWebView.mPrivateHandler,
- WebView.CLEAR_TEXT_ENTRY).sendToTarget();
+ WebViewClassic.CLEAR_TEXT_ENTRY).sendToTarget();
}
// called by JNI
@@ -2836,9 +2838,9 @@ public final class WebViewCore {
text, inputType, isSpellCheckEnabled, nextFieldIsText, label,
maxLength);
Message.obtain(mWebView.mPrivateHandler,
- WebView.INIT_EDIT_FIELD, initData).sendToTarget();
+ WebViewClassic.INIT_EDIT_FIELD, initData).sendToTarget();
Message.obtain(mWebView.mPrivateHandler,
- WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer,
+ WebViewClassic.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer,
0, new TextSelectionData(start, end, selectionPtr))
.sendToTarget();
}
@@ -2850,7 +2852,7 @@ public final class WebViewCore {
return;
}
Message.obtain(mWebView.mPrivateHandler,
- WebView.UPDATE_MATCH_COUNT, matchIndex, matchCount,
+ WebViewClassic.UPDATE_MATCH_COUNT, matchIndex, matchCount,
findText).sendToTarget();
}
@@ -2892,14 +2894,14 @@ public final class WebViewCore {
private void requestKeyboard(boolean showKeyboard) {
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
- WebView.REQUEST_KEYBOARD, showKeyboard ? 1 : 0, 0)
+ WebViewClassic.REQUEST_KEYBOARD, showKeyboard ? 1 : 0, 0)
.sendToTarget();
}
}
private void setWebTextViewAutoFillable(int queryId, String preview) {
if (mWebView != null) {
- Message.obtain(mWebView.mPrivateHandler, WebView.SET_AUTOFILLABLE,
+ Message.obtain(mWebView.mPrivateHandler, WebViewClassic.SET_AUTOFILLABLE,
new AutoFillData(queryId, preview))
.sendToTarget();
}
@@ -2912,7 +2914,7 @@ public final class WebViewCore {
// called by JNI
private void keepScreenOn(boolean screenOn) {
if (mWebView != null) {
- Message message = mWebView.mPrivateHandler.obtainMessage(WebView.SCREEN_ON);
+ Message message = mWebView.mPrivateHandler.obtainMessage(WebViewClassic.SCREEN_ON);
message.arg1 = screenOn ? 1 : 0;
message.sendToTarget();
}
@@ -2952,7 +2954,7 @@ public final class WebViewCore {
return;
}
- Message message = mWebView.mPrivateHandler.obtainMessage(WebView.SHOW_FULLSCREEN);
+ Message message = mWebView.mPrivateHandler.obtainMessage(WebViewClassic.SHOW_FULLSCREEN);
message.obj = childView.mView;
message.arg1 = orientation;
message.arg2 = npp;
@@ -2964,7 +2966,7 @@ public final class WebViewCore {
if (mWebView == null) {
return;
}
- mWebView.mPrivateHandler.obtainMessage(WebView.HIDE_FULLSCREEN)
+ mWebView.mPrivateHandler.obtainMessage(WebViewClassic.HIDE_FULLSCREEN)
.sendToTarget();
}
@@ -3036,7 +3038,7 @@ public final class WebViewCore {
data.mXPercentInView = xPercentInView;
data.mYPercentInDoc = yPercentInDoc;
data.mYPercentInView = yPercentInView;
- Message.obtain(mWebView.mPrivateHandler, WebView.SHOW_RECT_MSG_ID,
+ Message.obtain(mWebView.mPrivateHandler, WebViewClassic.SHOW_RECT_MSG_ID,
data).sendToTarget();
}
}
@@ -3046,7 +3048,7 @@ public final class WebViewCore {
if (mWebView == null) {
return;
}
- mWebView.mPrivateHandler.obtainMessage(WebView.CENTER_FIT_RECT,
+ mWebView.mPrivateHandler.obtainMessage(WebViewClassic.CENTER_FIT_RECT,
new Rect(x, y, x + width, y + height)).sendToTarget();
}
@@ -3055,7 +3057,7 @@ public final class WebViewCore {
if (mWebView == null) {
return;
}
- mWebView.mPrivateHandler.obtainMessage(WebView.SET_SCROLLBAR_MODES,
+ mWebView.mPrivateHandler.obtainMessage(WebViewClassic.SET_SCROLLBAR_MODES,
hMode, vMode).sendToTarget();
}
@@ -3063,7 +3065,7 @@ public final class WebViewCore {
@SuppressWarnings("unused")
private void selectAt(int x, int y) {
if (mWebView != null) {
- mWebView.mPrivateHandler.obtainMessage(WebView.SELECT_AT, x, y).sendToTarget();
+ mWebView.mPrivateHandler.obtainMessage(WebViewClassic.SELECT_AT, x, y).sendToTarget();
}
}
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
new file mode 100644
index 0000000..22bf0bf
--- /dev/null
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+/**
+ * This is the main entry-point into the WebView back end implementations, which the WebView
+ * proxy class uses to instantiate all the other objects as needed. The backend must provide an
+ * implementation of this interface, and make it available to the WebView via mechanism TBD.
+ * @hide
+ */
+public interface WebViewFactoryProvider {
+
+ /**
+ * Construct a new WebView provider.
+ * @param webView the WebView instance bound to this implementation instance. Note it will not
+ * necessarily be fully constructed at the point of this call: defer real initialization to
+ * WebViewProvider.init().
+ * @param privateAccess provides access into WebView internal methods.
+ */
+ WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess);
+
+ Statics getStatics();
+
+ /**
+ * This Interface provides glue for implementing the backend of WebView static methods which
+ * cannot be implemented in-situ in the proxy class.
+ */
+ interface Statics {
+ /**
+ * Implements the API method:
+ * {@link android.webkit.WebView#findAddress(String)}
+ */
+ String findAddress(String addr);
+
+ /**
+ * Implements the API methods:
+ * {@link android.webkit.WebView#enablePlatformNotifications()}
+ * {@link android.webkit.WebView#disablePlatformNotifications()}
+ */
+ void setPlatformNotificationsEnabled(boolean enable);
+ }
+}
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
new file mode 100644
index 0000000..2e8ad6d
--- /dev/null
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Picture;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.net.http.SslCertificate;
+import android.os.Bundle;
+import android.os.Message;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.webkit.WebView.HitTestResult;
+import android.webkit.WebView.PictureListener;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ * WebView backend provider interface: this interface is the abstract backend to a WebView
+ * instance; each WebView object is bound to exactly one WebViewProvider object which implements
+ * the runtime behavior of that WebView.
+ *
+ * All methods must behave as per their namesake in {@link WebView}, unless otherwise noted.
+ *
+ * @hide Not part of the public API; only required by system implementors.
+ */
+public interface WebViewProvider {
+ //-------------------------------------------------------------------------
+ // Main interface for backend provider of the WebView class.
+ //-------------------------------------------------------------------------
+ /**
+ * Initialize this WebViewProvider instance. Called after the WebView has fully constructed.
+ * @param javaScriptInterfaces is a Map of interface names, as keys, and
+ * object implementing those interfaces, as values.
+ * @param privateBrowsing If true the web view will be initialized in private / incognito mode.
+ */
+ public void init(Map<String, Object> javaScriptInterfaces,
+ boolean privateBrowsing);
+
+ public void setHorizontalScrollbarOverlay(boolean overlay);
+
+ public void setVerticalScrollbarOverlay(boolean overlay);
+
+ public boolean overlayHorizontalScrollbar();
+
+ public boolean overlayVerticalScrollbar();
+
+ public int getVisibleTitleHeight();
+
+ public SslCertificate getCertificate();
+
+ public void setCertificate(SslCertificate certificate);
+
+ public void savePassword(String host, String username, String password);
+
+ public void setHttpAuthUsernamePassword(String host, String realm,
+ String username, String password);
+
+ public String[] getHttpAuthUsernamePassword(String host, String realm);
+
+ /**
+ * See {@link WebView#destroy()}.
+ * As well as releasing the internal state and resources held by the implementation,
+ * the provider should null all references it holds on the WebView proxy class, and ensure
+ * no further method calls are made to it.
+ */
+ public void destroy();
+
+ public void setNetworkAvailable(boolean networkUp);
+
+ public WebBackForwardList saveState(Bundle outState);
+
+ public boolean savePicture(Bundle b, final File dest);
+
+ public boolean restorePicture(Bundle b, File src);
+
+ public WebBackForwardList restoreState(Bundle inState);
+
+ public void loadUrl(String url, Map<String, String> additionalHttpHeaders);
+
+ public void loadUrl(String url);
+
+ public void postUrl(String url, byte[] postData);
+
+ public void loadData(String data, String mimeType, String encoding);
+
+ public void loadDataWithBaseURL(String baseUrl, String data,
+ String mimeType, String encoding, String historyUrl);
+
+ public void saveWebArchive(String filename);
+
+ public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback);
+
+ public void stopLoading();
+
+ public void reload();
+
+ public boolean canGoBack();
+
+ public void goBack();
+
+ public boolean canGoForward();
+
+ public void goForward();
+
+ public boolean canGoBackOrForward(int steps);
+
+ public void goBackOrForward(int steps);
+
+ public boolean isPrivateBrowsingEnabled();
+
+ public boolean pageUp(boolean top);
+
+ public boolean pageDown(boolean bottom);
+
+ public void clearView();
+
+ public Picture capturePicture();
+
+ public float getScale();
+
+ public void setInitialScale(int scaleInPercent);
+
+ public void invokeZoomPicker();
+
+ public HitTestResult getHitTestResult();
+
+ public void requestFocusNodeHref(Message hrefMsg);
+
+ public void requestImageRef(Message msg);
+
+ public String getUrl();
+
+ public String getOriginalUrl();
+
+ public String getTitle();
+
+ public Bitmap getFavicon();
+
+ public String getTouchIconUrl();
+
+ public int getProgress();
+
+ public int getContentHeight();
+
+ public int getContentWidth();
+
+ public void pauseTimers();
+
+ public void resumeTimers();
+
+ public void onPause();
+
+ public void onResume();
+
+ public boolean isPaused();
+
+ public void freeMemory();
+
+ public void clearCache(boolean includeDiskFiles);
+
+ public void clearFormData();
+
+ public void clearHistory();
+
+ public void clearSslPreferences();
+
+ public WebBackForwardList copyBackForwardList();
+
+ public void findNext(boolean forward);
+
+ public int findAll(String find);
+
+ public boolean showFindDialog(String text, boolean showIme);
+
+ public void clearMatches();
+
+ public void documentHasImages(Message response);
+
+ public void setWebViewClient(WebViewClient client);
+
+ public void setDownloadListener(DownloadListener listener);
+
+ public void setWebChromeClient(WebChromeClient client);
+
+ public void setPictureListener(PictureListener listener);
+
+ public void addJavascriptInterface(Object obj, String interfaceName);
+
+ public void removeJavascriptInterface(String interfaceName);
+
+ public WebSettings getSettings();
+
+ public void emulateShiftHeld();
+
+ public void setMapTrackballToArrowKeys(boolean setMap);
+
+ public void flingScroll(int vx, int vy);
+
+ public View getZoomControls();
+
+ public boolean canZoomIn();
+
+ public boolean canZoomOut();
+
+ public boolean zoomIn();
+
+ public boolean zoomOut();
+
+ public void debugDump();
+
+ //-------------------------------------------------------------------------
+ // Provider glue methods
+ //-------------------------------------------------------------------------
+
+ /**
+ * @return the ViewDelegate implementation. This provides the functionality to back all of
+ * the name-sake functions from the View and ViewGroup base classes of WebView.
+ */
+ /* package */ ViewDelegate getViewDelegate();
+
+ /**
+ * @return a ScrollDelegate implementation. Normally this would be same object as is
+ * returned by getViewDelegate().
+ */
+ /* package */ ScrollDelegate getScrollDelegate();
+
+ //-------------------------------------------------------------------------
+ // View / ViewGroup delegation methods
+ //-------------------------------------------------------------------------
+
+ /**
+ * Provides mechanism for the name-sake methods declared in View and ViewGroup to be delegated
+ * into the WebViewProvider instance.
+ * NOTE For many of these methods, the WebView will provide a super.Foo() call before or after
+ * making the call into the provider instance. This is done for convenience in the common case
+ * of maintaining backward compatibility. For remaining super class calls (e.g. where the
+ * provider may need to only conditionally make the call based on some internal state) see the
+ * {@link WebView.PrivateAccess} callback class.
+ */
+ // TODO: See if the pattern of the super-class calls can be rationalized at all, and document
+ // the remainder on the methods below.
+ interface ViewDelegate {
+ public boolean shouldDelayChildPressedState();
+
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
+
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event);
+
+ public void setOverScrollMode(int mode);
+
+ public void setScrollBarStyle(int style);
+
+ public void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t,
+ int r, int b);
+
+ public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY);
+
+ public void onWindowVisibilityChanged(int visibility);
+
+ public boolean drawChild(Canvas canvas, View child, long drawingTime);
+
+ public void onDraw(Canvas canvas);
+
+ public void setLayoutParams(LayoutParams layoutParams);
+
+ public boolean performLongClick();
+
+ public void onConfigurationChanged(Configuration newConfig);
+
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs);
+
+ public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event);
+
+ public boolean onKeyDown(int keyCode, KeyEvent event);
+
+ public boolean onKeyUp(int keyCode, KeyEvent event);
+
+ public void onAttachedToWindow();
+
+ public void onDetachedFromWindow();
+
+ public void onVisibilityChanged(View changedView, int visibility);
+
+ public void onWindowFocusChanged(boolean hasWindowFocus);
+
+ public void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect);
+
+ public boolean setFrame(int left, int top, int right, int bottom);
+
+ public void onSizeChanged(int w, int h, int ow, int oh);
+
+ public void onScrollChanged(int l, int t, int oldl, int oldt);
+
+ public boolean dispatchKeyEvent(KeyEvent event);
+
+ public boolean onTouchEvent(MotionEvent ev);
+
+ public boolean onHoverEvent(MotionEvent event);
+
+ public boolean onGenericMotionEvent(MotionEvent event);
+
+ public boolean onTrackballEvent(MotionEvent ev);
+
+ public boolean requestFocus(int direction, Rect previouslyFocusedRect);
+
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec);
+
+ public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate);
+
+ public void setBackgroundColor(int color);
+ }
+
+ interface ScrollDelegate {
+ // These methods are declared protected in the ViewGroup base class. This interface
+ // exists to promote them to public so they may be called by the WebView proxy class.
+ // TODO: Combine into ViewDelegate?
+ /**
+ * See {@link android.webkit.WebView#computeHorizontalScrollRange}
+ */
+ public int computeHorizontalScrollRange();
+
+ /**
+ * See {@link android.webkit.WebView#computeHorizontalScrollOffset}
+ */
+ public int computeHorizontalScrollOffset();
+
+ /**
+ * See {@link android.webkit.WebView#computeVerticalScrollRange}
+ */
+ public int computeVerticalScrollRange();
+
+ /**
+ * See {@link android.webkit.WebView#computeVerticalScrollOffset}
+ */
+ public int computeVerticalScrollOffset();
+
+ /**
+ * See {@link android.webkit.WebView#computeVerticalScrollExtent}
+ */
+ public int computeVerticalScrollExtent();
+
+ /**
+ * See {@link android.webkit.WebView#computeScroll}
+ */
+ public void computeScroll();
+ }
+}
diff --git a/core/java/android/webkit/ZoomControlEmbedded.java b/core/java/android/webkit/ZoomControlEmbedded.java
index e505614..d2a0561 100644
--- a/core/java/android/webkit/ZoomControlEmbedded.java
+++ b/core/java/android/webkit/ZoomControlEmbedded.java
@@ -25,12 +25,12 @@ import android.widget.ZoomButtonsController;
class ZoomControlEmbedded implements ZoomControlBase {
private final ZoomManager mZoomManager;
- private final WebView mWebView;
+ private final WebViewClassic mWebView;
// The controller is lazily initialized in getControls() for performance.
private ZoomButtonsController mZoomButtonsController;
- public ZoomControlEmbedded(ZoomManager zoomManager, WebView webView) {
+ public ZoomControlEmbedded(ZoomManager zoomManager, WebViewClassic webView) {
mZoomManager = zoomManager;
mWebView = webView;
}
@@ -41,7 +41,7 @@ class ZoomControlEmbedded implements ZoomControlBase {
mZoomButtonsController.setVisible(true);
if (mZoomManager.isDoubleTapEnabled()) {
- WebSettings settings = mWebView.getSettings();
+ WebSettingsClassic settings = mWebView.getSettings();
int count = settings.getDoubleTapToastCount();
if (mZoomManager.isInZoomOverview() && count > 0) {
settings.setDoubleTapToastCount(--count);
@@ -82,7 +82,7 @@ class ZoomControlEmbedded implements ZoomControlBase {
private ZoomButtonsController getControls() {
if (mZoomButtonsController == null) {
- mZoomButtonsController = new ZoomButtonsController(mWebView);
+ mZoomButtonsController = new ZoomButtonsController(mWebView.getWebView());
mZoomButtonsController.setOnZoomListener(new ZoomListener());
// ZoomButtonsController positions the buttons at the bottom, but in
// the middle. Change their layout parameters so they appear on the
diff --git a/core/java/android/webkit/ZoomControlExternal.java b/core/java/android/webkit/ZoomControlExternal.java
index d75313e..f5bfc05 100644
--- a/core/java/android/webkit/ZoomControlExternal.java
+++ b/core/java/android/webkit/ZoomControlExternal.java
@@ -35,9 +35,9 @@ class ZoomControlExternal implements ZoomControlBase {
private Runnable mZoomControlRunnable;
private final Handler mPrivateHandler = new Handler();
- private final WebView mWebView;
+ private final WebViewClassic mWebView;
- public ZoomControlExternal(WebView webView) {
+ public ZoomControlExternal(WebViewClassic webView) {
mWebView = webView;
}
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 369e883..e7b049e 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -50,7 +50,7 @@ class ZoomManager {
static final String LOGTAG = "webviewZoom";
- private final WebView mWebView;
+ private final WebViewClassic mWebView;
private final CallbackProxy mCallbackProxy;
// Widgets responsible for the on-screen zoom functions of the WebView.
@@ -211,7 +211,7 @@ class ZoomManager {
private boolean mHardwareAccelerated = false;
private boolean mInHWAcceleratedZoom = false;
- public ZoomManager(WebView webView, CallbackProxy callbackProxy) {
+ public ZoomManager(WebViewClassic webView, CallbackProxy callbackProxy) {
mWebView = webView;
mCallbackProxy = callbackProxy;
@@ -220,7 +220,7 @@ class ZoomManager {
* ESPN and Engadget always have wider mContentWidth no matter what the
* viewport size is.
*/
- setZoomOverviewWidth(WebView.DEFAULT_VIEWPORT_WIDTH);
+ setZoomOverviewWidth(WebViewClassic.DEFAULT_VIEWPORT_WIDTH);
mFocusMovementQueue = new FocusMovementQueue();
}
@@ -487,13 +487,13 @@ class ZoomManager {
// zoomScale, we can't use the WebView's pinLocX/Y functions directly.
float scale = zoomScale * mInvInitialZoomScale;
int tx = Math.round(scale * (mInitialScrollX + mZoomCenterX) - mZoomCenterX);
- tx = -WebView.pinLoc(tx, mWebView.getViewWidth(), Math.round(mWebView.getContentWidth()
+ tx = -WebViewClassic.pinLoc(tx, mWebView.getViewWidth(), Math.round(mWebView.getContentWidth()
* zoomScale)) + mWebView.getScrollX();
int titleHeight = mWebView.getTitleHeight();
int ty = Math.round(scale
* (mInitialScrollY + mZoomCenterY - titleHeight)
- (mZoomCenterY - titleHeight));
- ty = -(ty <= titleHeight ? Math.max(ty, 0) : WebView.pinLoc(ty
+ ty = -(ty <= titleHeight ? Math.max(ty, 0) : WebViewClassic.pinLoc(ty
- titleHeight, mWebView.getViewHeight(), Math.round(mWebView.getContentHeight()
* zoomScale)) + titleHeight) + mWebView.getScrollY();
@@ -630,7 +630,7 @@ class ZoomManager {
public void handleDoubleTap(float lastTouchX, float lastTouchY) {
// User takes action, set initial zoom overview to false.
mInitialZoomOverview = false;
- WebSettings settings = mWebView.getSettings();
+ WebSettingsClassic settings = mWebView.getSettings();
if (!isDoubleTapEnabled()) {
return;
}
@@ -690,7 +690,7 @@ class ZoomManager {
private void setZoomOverviewWidth(int width) {
if (width == 0) {
- mZoomOverviewWidth = WebView.DEFAULT_VIEWPORT_WIDTH;
+ mZoomOverviewWidth = WebViewClassic.DEFAULT_VIEWPORT_WIDTH;
} else {
mZoomOverviewWidth = width;
}
@@ -719,7 +719,7 @@ class ZoomManager {
final float readingScale = getReadingLevelScale();
int left = mWebView.getBlockLeftEdge(mAnchorX, mAnchorY, readingScale);
- if (left != WebView.NO_LEFTEDGE) {
+ if (left != WebViewClassic.NO_LEFTEDGE) {
// add a 5pt padding to the left edge.
int viewLeft = mWebView.contentToViewX(left < 5 ? 0 : (left - 5))
- mWebView.getScrollX();
@@ -728,7 +728,7 @@ class ZoomManager {
if (viewLeft > 0) {
mZoomCenterX = viewLeft * readingScale / (readingScale - mActualScale);
} else {
- mWebView.scrollBy(viewLeft, 0);
+ mWebView.getWebView().scrollBy(viewLeft, 0);
mZoomCenterX = 0;
}
}
@@ -955,7 +955,7 @@ class ZoomManager {
// cause its child View to reposition itself through ViewManager's
// scaleAll(), we need to post a Runnable to ensure requestLayout().
// Additionally, only update the text wrap scale if the width changed.
- mWebView.post(new PostScale(w != ow &&
+ mWebView.getWebView().post(new PostScale(w != ow &&
!mWebView.getSettings().getUseFixedViewport(), mInZoomOverview, w < ow));
}
@@ -1027,7 +1027,7 @@ class ZoomManager {
final int viewWidth = mWebView.getViewWidth();
final boolean zoomOverviewWidthChanged = setupZoomOverviewWidth(drawData, viewWidth);
final float newZoomOverviewScale = getZoomOverviewScale();
- WebSettings settings = mWebView.getSettings();
+ WebSettingsClassic settings = mWebView.getSettings();
if (zoomOverviewWidthChanged && settings.isNarrowColumnLayout() &&
settings.getUseFixedViewport() &&
(mInitialZoomOverview || mInZoomOverview)) {
@@ -1085,7 +1085,7 @@ class ZoomManager {
if (drawData.mContentSize.x > 0) {
// The webkitDraw for layers will not populate contentSize, and it'll be
// ignored for zoom overview width update.
- newZoomOverviewWidth = Math.min(WebView.sMaxViewportWidth,
+ newZoomOverviewWidth = Math.min(WebViewClassic.sMaxViewportWidth,
drawData.mContentSize.x);
}
} else {
@@ -1117,7 +1117,7 @@ class ZoomManager {
updateZoomRange(viewState, viewSize.x, drawData.mMinPrefWidth);
setupZoomOverviewWidth(drawData, mWebView.getViewWidth());
final float overviewScale = getZoomOverviewScale();
- WebSettings settings = mWebView.getSettings();
+ WebSettingsClassic settings = mWebView.getSettings();
if (!mMinZoomScaleFixed || settings.getUseWideViewPort()) {
mMinZoomScale = (mInitialScale > 0) ?
Math.min(mInitialScale, overviewScale) : overviewScale;
diff --git a/core/tests/coretests/src/android/webkit/ZoomManagerTest.java b/core/tests/coretests/src/android/webkit/ZoomManagerTest.java
index 1c9defe..7e0e0b2 100644
--- a/core/tests/coretests/src/android/webkit/ZoomManagerTest.java
+++ b/core/tests/coretests/src/android/webkit/ZoomManagerTest.java
@@ -24,8 +24,9 @@ public class ZoomManagerTest extends AndroidTestCase {
@Override
public void setUp() {
WebView webView = new WebView(this.getContext());
- CallbackProxy callbackProxy = new CallbackProxy(this.getContext(), webView);
- zoomManager = new ZoomManager(webView, callbackProxy);
+ WebViewClassic webViewClassic = WebViewClassic.fromWebView(webView);
+ CallbackProxy callbackProxy = new CallbackProxy(this.getContext(), webViewClassic);
+ zoomManager = new ZoomManager(webViewClassic, callbackProxy);
zoomManager.init(1.00f);
}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index 83c9c3d..856ebcc 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -45,8 +45,10 @@ import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
+import android.webkit.WebSettingsClassic;
import android.webkit.WebStorage;
import android.webkit.WebView;
+import android.webkit.WebViewClassic;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
@@ -112,10 +114,10 @@ public class TestShellActivity extends Activity implements LayoutTestController
case DUMP_AS_TEXT:
callback.arg1 = mDumpTopFrameAsText ? 1 : 0;
callback.arg2 = mDumpChildFramesAsText ? 1 : 0;
- mWebView.documentAsText(callback);
+ mWebViewClassic.documentAsText(callback);
break;
case EXT_REPR:
- mWebView.externalRepresentation(callback);
+ mWebViewClassic.externalRepresentation(callback);
break;
default:
finished();
@@ -144,6 +146,7 @@ public class TestShellActivity extends Activity implements LayoutTestController
CookieManager.setAcceptFileSchemeCookies(true);
mWebView = new WebView(this);
+ mWebViewClassic = WebViewClassic.fromWebView(mWebView);
mEventSender = new WebViewEventSender(mWebView);
mCallbackProxy = new CallbackProxy(mEventSender, this);
@@ -158,7 +161,7 @@ public class TestShellActivity extends Activity implements LayoutTestController
// Expose window.gc function to JavaScript. JSC build exposes
// this function by default, but V8 requires the flag to turn it on.
// WebView::setJsFlags is noop in JSC build.
- mWebView.setJsFlags("--expose_gc");
+ mWebViewClassic.setJsFlags("--expose_gc");
mHandler = new AsyncHandler();
@@ -168,7 +171,7 @@ public class TestShellActivity extends Activity implements LayoutTestController
}
// This is asynchronous, but it gets processed by WebCore before it starts loading pages.
- mWebView.useMockDeviceOrientation();
+ mWebViewClassic.useMockDeviceOrientation();
}
@Override
@@ -290,6 +293,7 @@ public class TestShellActivity extends Activity implements LayoutTestController
super.onDestroy();
mWebView.destroy();
mWebView = null;
+ mWebViewClassic = null;
}
@Override
@@ -531,8 +535,8 @@ public class TestShellActivity extends Activity implements LayoutTestController
public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
- mWebView.setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta,
- canProvideGamma, gamma);
+ WebViewClassic.fromWebView(mWebView).setMockDeviceOrientation(canProvideAlpha, alpha,
+ canProvideBeta, beta, canProvideGamma, gamma);
}
public void overridePreference(String key, boolean value) {
@@ -541,10 +545,10 @@ public class TestShellActivity extends Activity implements LayoutTestController
// WebView for the main frame. EventSender suffers from the same
// problem.
if (WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED.equals(key)) {
- mWebView.getSettings().setAppCacheEnabled(value);
+ mWebViewClassic.getSettings().setAppCacheEnabled(value);
} else if (WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY.equals(key)) {
// Cache the maximum possible number of pages.
- mWebView.getSettings().setPageCacheCapacity(Integer.MAX_VALUE);
+ mWebViewClassic.getSettings().setPageCacheCapacity(Integer.MAX_VALUE);
} else {
Log.w(LOGTAG, "LayoutTestController.overridePreference(): " +
"Unsupported preference '" + key + "'");
@@ -552,7 +556,7 @@ public class TestShellActivity extends Activity implements LayoutTestController
}
public void setXSSAuditorEnabled (boolean flag) {
- mWebView.getSettings().setXSSAuditorEnabled(flag);
+ mWebViewClassic.getSettings().setXSSAuditorEnabled(flag);
}
private final WebViewClient mViewClient = new WebViewClient(){
@@ -855,7 +859,7 @@ public class TestShellActivity extends Activity implements LayoutTestController
Bitmap bitmap = Bitmap.createBitmap(view.getContentWidth(), view.getContentHeight(),
Config.ARGB_8888);
canvas.setBitmap(bitmap);
- view.drawPage(canvas);
+ WebViewClassic.fromWebView(view).drawPage(canvas);
try {
FileOutputStream fos = new FileOutputStream(fileName);
if(!bitmap.compress(CompressFormat.PNG, 90, fos)) {
@@ -885,11 +889,11 @@ public class TestShellActivity extends Activity implements LayoutTestController
// single event rather than a stream of events (like what would generally happen in
// a real use of touch events in a WebView) and so if the WebView drops the event,
// the test will fail as the test expects one callback for every touch it synthesizes.
- webview.setTouchInterval(-1);
+ WebViewClassic.fromWebView(webview).setTouchInterval(-1);
}
public void setDefaultWebSettings(WebView webview) {
- WebSettings settings = webview.getSettings();
+ WebSettingsClassic settings = WebViewClassic.fromWebView(webview).getSettings();
settings.setAppCacheEnabled(true);
settings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
settings.setAppCacheMaxSize(Long.MAX_VALUE);
@@ -906,6 +910,7 @@ public class TestShellActivity extends Activity implements LayoutTestController
settings.setProperty("use_minimal_memory", "false");
}
+ private WebViewClassic mWebViewClassic;
private WebView mWebView;
private WebViewEventSender mEventSender;
private AsyncHandler mHandler;
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
index f59da37..fc22472 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
@@ -41,9 +41,11 @@ import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
+import android.webkit.WebSettingsClassic;
import android.webkit.WebStorage;
import android.webkit.WebStorage.QuotaUpdater;
import android.webkit.WebView;
+import android.webkit.WebViewClassic;
import android.webkit.WebViewClient;
import java.lang.Thread.UncaughtExceptionHandler;
@@ -369,11 +371,12 @@ public class LayoutTestsExecutor extends Activity {
* a real use of touch events in a WebView) and so if the WebView drops the event,
* the test will fail as the test expects one callback for every touch it synthesizes.
*/
- webView.setTouchInterval(-1);
+ WebViewClassic webViewClassic = WebViewClassic.fromWebView(webView);
+ webViewClassic.setTouchInterval(-1);
- webView.clearCache(true);
+ webViewClassic.clearCache(true);
- WebSettings webViewSettings = webView.getSettings();
+ WebSettingsClassic webViewSettings = webViewClassic.getSettings();
webViewSettings.setAppCacheEnabled(true);
webViewSettings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
// Use of larger values causes unexplained AppCache database corruption.
@@ -391,7 +394,7 @@ public class LayoutTestsExecutor extends Activity {
webViewSettings.setPageCacheCapacity(0);
// This is asynchronous, but it gets processed by WebCore before it starts loading pages.
- mCurrentWebView.useMockDeviceOrientation();
+ WebViewClassic.fromWebView(mCurrentWebView).useMockDeviceOrientation();
// Must do this after setting the AppCache path.
WebStorage.getInstance().deleteAllData();
@@ -625,10 +628,12 @@ public class LayoutTestsExecutor extends Activity {
String key = msg.getData().getString("key");
boolean value = msg.getData().getBoolean("value");
if (WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED.equals(key)) {
- mCurrentWebView.getSettings().setAppCacheEnabled(value);
+ WebViewClassic.fromWebView(mCurrentWebView).getSettings().
+ setAppCacheEnabled(value);
} else if (WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY.equals(key)) {
// Cache the maximum possible number of pages.
- mCurrentWebView.getSettings().setPageCacheCapacity(Integer.MAX_VALUE);
+ WebViewClassic.fromWebView(mCurrentWebView).getSettings().
+ setPageCacheCapacity(Integer.MAX_VALUE);
} else {
Log.w(LOG_TAG, "LayoutTestController.overridePreference(): " +
"Unsupported preference '" + key + "'");
@@ -656,7 +661,8 @@ public class LayoutTestsExecutor extends Activity {
break;
case MSG_SET_XSS_AUDITOR_ENABLED:
- mCurrentWebView.getSettings().setXSSAuditorEnabled(msg.arg1 == 1);
+ WebViewClassic.fromWebView(mCurrentWebView).getSettings().
+ setXSSAuditorEnabled(msg.arg1 == 1);
break;
case MSG_WAIT_UNTIL_DONE:
@@ -728,8 +734,8 @@ public class LayoutTestsExecutor extends Activity {
Log.i(LOG_TAG, mCurrentTestRelativePath + ": setMockDeviceOrientation(" + canProvideAlpha +
", " + alpha + ", " + canProvideBeta + ", " + beta + ", " + canProvideGamma +
", " + gamma + ")");
- mCurrentWebView.setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta,
- canProvideGamma, gamma);
+ WebViewClassic.fromWebView(mCurrentWebView).setMockDeviceOrientation(canProvideAlpha,
+ alpha, canProvideBeta, beta, canProvideGamma, gamma);
}
public void setXSSAuditorEnabled(boolean flag) {
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
index 3d2b98b..fd1c0ad 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
@@ -20,6 +20,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.webkit.WebView;
+import android.webkit.WebViewClassic;
import name.fraser.neil.plaintext.diff_match_patch;
@@ -233,7 +234,7 @@ public class TextResult extends AbstractResult {
*/
msg.arg1 = 1;
msg.arg2 = mDumpChildFramesAsText ? 1 : 0;
- webview.documentAsText(msg);
+ WebViewClassic.fromWebView(webview).documentAsText(msg);
}
@Override
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
index a38ac25..87baf76 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
@@ -20,8 +20,9 @@ import android.content.Context;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.util.Log;
-import android.webkit.WebSettings;
+import android.webkit.WebSettingsClassic;
import android.webkit.WebView;
+import android.webkit.WebViewClassic;
import android.widget.Toast;
import java.util.ArrayList;
@@ -29,7 +30,7 @@ import java.util.ArrayList;
import com.test.tilebenchmark.ProfileActivity.ProfileCallback;
import com.test.tilebenchmark.RunData.TileData;
-public class ProfiledWebView extends WebView {
+public class ProfiledWebView extends WebView implements WebViewClassic.PageSwapDelegate {
private static final String LOGTAG = "ProfiledWebView";
private int mSpeed;
@@ -80,7 +81,7 @@ public class ProfiledWebView extends WebView {
}
public void init(Context c) {
- WebSettings settings = getSettings();
+ WebSettingsClassic settings = getWebViewClassic().getSettings();
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(true);
settings.setEnableSmoothTransition(true);
@@ -118,7 +119,7 @@ public class ProfiledWebView extends WebView {
mCallback = callback;
mIsTesting = false;
mIsScrolling = false;
- WebSettings settings = getSettings();
+ WebSettingsClassic settings = getWebViewClassic().getSettings();
settings.setProperty("tree_updates", "0");
@@ -134,7 +135,7 @@ public class ProfiledWebView extends WebView {
// invalidate all content, and kick off redraw
Log.d("ProfiledWebView",
"kicking off test with callback registration, and tile discard...");
- discardAllTextures();
+ getWebViewClassic().discardAllTextures();
invalidate();
mIsScrolling = true;
mContentInvalMillis = System.currentTimeMillis();
@@ -142,30 +143,29 @@ public class ProfiledWebView extends WebView {
}.start();
} else {
mIsTesting = true;
- tileProfilingStart();
+ getWebViewClassic().tileProfilingStart();
}
}
/*
* Called after the manual contentInvalidateAll, after the tiles have all
* been redrawn.
+ * From PageSwapDelegate.
*/
@Override
- protected void pageSwapCallback(boolean startAnim) {
- super.pageSwapCallback(startAnim);
-
+ public void onPageSwapOccurred(boolean startAnim) {
if (!mIsTesting && mIsScrolling) {
// kick off testing
mContentInvalMillis = System.currentTimeMillis() - mContentInvalMillis;
Log.d("ProfiledWebView", "REDRAW TOOK " + mContentInvalMillis + "millis");
mIsTesting = true;
invalidate(); // ensure a redraw so that auto-scrolling can occur
- tileProfilingStart();
+ getWebViewClassic().tileProfilingStart();
}
}
private double animFramerate() {
- WebSettings settings = getSettings();
+ WebSettingsClassic settings = getWebViewClassic().getSettings();
String updatesString = settings.getProperty("tree_updates");
int updates = (updatesString == null) ? -1 : Integer.parseInt(updatesString);
@@ -180,7 +180,7 @@ public class ProfiledWebView extends WebView {
}
public void setDoubleBuffering(boolean useDoubleBuffering) {
- WebSettings settings = getSettings();
+ WebSettingsClassic settings = getWebViewClassic().getSettings();
settings.setProperty("use_double_buffering", useDoubleBuffering ? "true" : "false");
}
@@ -188,15 +188,15 @@ public class ProfiledWebView extends WebView {
* Called once the page has stopped scrolling
*/
public void stopScrollTest() {
- tileProfilingStop();
+ getWebViewClassic().tileProfilingStop();
mIsTesting = false;
if (mCallback == null) {
- tileProfilingClear();
+ getWebViewClassic().tileProfilingClear();
return;
}
- RunData data = new RunData(super.tileProfilingNumFrames());
+ RunData data = new RunData(getWebViewClassic().tileProfilingNumFrames());
// record the time spent (before scrolling) rendering the page
data.singleStats.put(getResources().getString(R.string.render_millis),
(double)mContentInvalMillis);
@@ -209,24 +209,24 @@ public class ProfiledWebView extends WebView {
for (int frame = 0; frame < data.frames.length; frame++) {
data.frames[frame] = new TileData[
- tileProfilingNumTilesInFrame(frame)];
+ getWebViewClassic().tileProfilingNumTilesInFrame(frame)];
for (int tile = 0; tile < data.frames[frame].length; tile++) {
- int left = tileProfilingGetInt(frame, tile, "left");
- int top = tileProfilingGetInt(frame, tile, "top");
- int right = tileProfilingGetInt(frame, tile, "right");
- int bottom = tileProfilingGetInt(frame, tile, "bottom");
+ int left = getWebViewClassic().tileProfilingGetInt(frame, tile, "left");
+ int top = getWebViewClassic().tileProfilingGetInt(frame, tile, "top");
+ int right = getWebViewClassic().tileProfilingGetInt(frame, tile, "right");
+ int bottom = getWebViewClassic().tileProfilingGetInt(frame, tile, "bottom");
- boolean isReady = super.tileProfilingGetInt(
+ boolean isReady = getWebViewClassic().tileProfilingGetInt(
frame, tile, "isReady") == 1;
- int level = tileProfilingGetInt(frame, tile, "level");
+ int level = getWebViewClassic().tileProfilingGetInt(frame, tile, "level");
- float scale = tileProfilingGetFloat(frame, tile, "scale");
+ float scale = getWebViewClassic().tileProfilingGetFloat(frame, tile, "scale");
data.frames[frame][tile] = data.new TileData(left, top, right, bottom,
isReady, level, scale);
}
}
- tileProfilingClear();
+ getWebViewClassic().tileProfilingClear();
mCallback.profileCallback(data);
}
@@ -244,4 +244,8 @@ public class ProfiledWebView extends WebView {
public void setAutoScrollSpeed(int speedInt) {
mSpeed = speedInt;
}
+
+ public WebViewClassic getWebViewClassic() {
+ return WebViewClassic.fromWebView(this);
+ }
}