Merge "async find-on-page implementation via WebKit"
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
index fffa90b..10b0885 100644
--- a/core/java/android/webkit/FindActionModeCallback.java
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -43,7 +43,9 @@
private Resources mResources;
private boolean mMatchesFound;
private int mNumberOfMatches;
+ private int mActiveMatchIndex;
private ActionMode mActionMode;
+ private String mLastFind;
FindActionModeCallback(Context context) {
mCustomView = LayoutInflater.from(context).inflate(
@@ -132,16 +134,13 @@
mWebView.clearMatches();
mMatches.setVisibility(View.GONE);
mMatchesFound = false;
+ mLastFind = null;
} else {
mMatchesFound = true;
- mMatches.setVisibility(View.VISIBLE);
- mNumberOfMatches = mWebView.findAll(find.toString());
- if (0 == mNumberOfMatches) {
- mMatches.setText(mResources.getString(
- com.android.internal.R.string.no_matches));
- } else {
- updateMatchesString();
- }
+ mMatches.setVisibility(View.INVISIBLE);
+ mNumberOfMatches = 0;
+ mLastFind = find.toString();
+ mWebView.findAllAsync(mLastFind);
}
}
@@ -151,17 +150,31 @@
mInput.showSoftInput(mEditText, 0);
}
+ public void updateMatchCount(int matchIndex, int matchCount,
+ String findText) {
+ if (mLastFind != null && mLastFind.equals(findText)) {
+ mNumberOfMatches = matchCount;
+ mActiveMatchIndex = matchIndex;
+ updateMatchesString();
+ } else {
+ mMatches.setVisibility(View.INVISIBLE);
+ mNumberOfMatches = 0;
+ }
+ }
+
/*
* Update the string which tells the user how many matches were found, and
* which match is currently highlighted.
- * Not to be called when mNumberOfMatches is 0.
*/
private void updateMatchesString() {
- String template = mResources.getQuantityString(
+ if (mNumberOfMatches == 0) {
+ mMatches.setText(com.android.internal.R.string.no_matches);
+ } else {
+ mMatches.setText(mResources.getQuantityString(
com.android.internal.R.plurals.matches_found, mNumberOfMatches,
- mWebView.findIndex() + 1, mNumberOfMatches);
-
- mMatches.setText(template);
+ mActiveMatchIndex + 1, mNumberOfMatches));
+ }
+ mMatches.setVisibility(View.VISIBLE);
}
// OnLongClickListener implementation
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index a35106a..2304c25 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -914,7 +914,7 @@
static final int REPLACE_BASE_CONTENT = 123;
static final int FORM_DID_BLUR = 124;
static final int RETURN_LABEL = 125;
- static final int FIND_AGAIN = 126;
+ 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;
@@ -979,7 +979,7 @@
"REPLACE_BASE_CONTENT", // = 123;
"FORM_DID_BLUR", // = 124;
"RETURN_LABEL", // = 125;
- "FIND_AGAIN", // = 126;
+ "UPDATE_MATCH_COUNT", // = 126;
"CENTER_FIT_RECT", // = 127;
"REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID", // = 128;
"SET_SCROLLBAR_MODES", // = 129;
@@ -1021,9 +1021,8 @@
// keep these in sync with their counterparts in WebView.cpp
private static final int DRAW_EXTRAS_NONE = 0;
- private static final int DRAW_EXTRAS_FIND = 1;
- private static final int DRAW_EXTRAS_SELECTION = 2;
- private static final int DRAW_EXTRAS_CURSOR_RING = 3;
+ 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;
@@ -3711,7 +3710,7 @@
public void findNext(boolean forward) {
checkThread();
if (0 == mNativeClass) return; // client isn't initialized
- nativeFindNext(forward);
+ mWebViewCore.sendMessage(EventHub.FIND_NEXT, forward ? 1 : 0);
}
/*
@@ -3721,13 +3720,40 @@
* 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
- int result = find != null ? nativeFindAll(find.toLowerCase(),
- find.toUpperCase(), find.equalsIgnoreCase(mLastFind)) : 0;
- invalidate();
mLastFind = find;
- return result;
+ 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;
}
/**
@@ -3763,6 +3789,7 @@
}
if (text != null) {
mFindCallback.setText(text);
+ mFindCallback.findAll();
}
return true;
}
@@ -3782,14 +3809,6 @@
nativeSetFindIsUp(isUp);
}
- /**
- * Return the index of the currently highlighted match.
- */
- int findIndex() {
- if (0 == mNativeClass) return -1;
- return nativeFindIndex();
- }
-
// Used to know whether the find dialog is open. Affects whether
// or not we draw the highlights for matches.
private boolean mFindIsUp;
@@ -3856,10 +3875,11 @@
checkThread();
if (mNativeClass == 0)
return;
- nativeSetFindIsEmpty();
- invalidate();
+ mWebViewCore.removeMessages(EventHub.FIND_ALL);
+ mWebViewCore.sendMessage(EventHub.FIND_ALL, null);
}
+
/**
* Called when the find ActionMode ends.
*/
@@ -4954,12 +4974,12 @@
// decide which adornments to draw
int extras = DRAW_EXTRAS_NONE;
- if (mFindIsUp) {
- extras = DRAW_EXTRAS_FIND;
- } else if (mSelectingText) {
- extras = DRAW_EXTRAS_SELECTION;
- } else if (drawCursorRing) {
- extras = DRAW_EXTRAS_CURSOR_RING;
+ 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
@@ -8884,13 +8904,6 @@
}
break;
- case FIND_AGAIN:
- // Ignore if find has been dismissed.
- if (mFindIsUp && mFindCallback != null) {
- mFindCallback.findAll();
- }
- break;
-
case DRAG_HELD_MOTIONLESS:
mHeldMotionless = MOTIONLESS_TRUE;
invalidate();
@@ -9095,6 +9108,14 @@
break;
}
+ case UPDATE_MATCH_COUNT: {
+ if (mFindCallback != null) {
+ mFindCallback.updateMatchCount(msg.arg1, msg.arg2,
+ (String) msg.obj);
+ }
+ break;
+ }
+
default:
super.handleMessage(msg);
break;
@@ -9931,9 +9952,6 @@
private native void nativeUpdateDrawGLFunction(Rect rect, Rect viewRect,
RectF visibleRect, float scale);
private native void nativeExtendSelection(int x, int y);
- private native int nativeFindAll(String findLower, String findUpper,
- boolean sameAsLastSearch);
- private native void nativeFindNext(boolean forward);
/* package */ native int nativeFocusCandidateFramePointer();
/* package */ native boolean nativeFocusCandidateHasNextTextfield();
/* package */ native boolean nativeFocusCandidateIsPassword();
@@ -9991,9 +10009,7 @@
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 int nativeFindIndex();
private native void nativeSetExtendSelection();
- private native void nativeSetFindIsEmpty();
private native void nativeSetFindIsUp(boolean isUp);
private native void nativeSetHeightCanMeasure(boolean measure);
private native boolean nativeSetBaseLayer(int nativeInstance,
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index b6c5612..4b1ae37 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1001,6 +1001,15 @@
"REMOVE_JS_INTERFACE", // = 149;
};
+ static class FindAllRequest {
+ public FindAllRequest(String text) {
+ mSearchText = text;
+ mMatchCount = -1;
+ }
+ public String mSearchText;
+ public int mMatchCount;
+ }
+
/**
* @hide
*/
@@ -1142,6 +1151,10 @@
// for updating state on trust storage change
static final int TRUST_STORAGE_UPDATED = 220;
+ // find-on-page controls
+ static final int FIND_ALL = 220;
+ static final int FIND_NEXT = 221;
+
// Private handler for WebCore messages.
private Handler mHandler;
// Message queue for containing messages before the WebCore thread is
@@ -1785,6 +1798,22 @@
case SELECT_ALL:
nativeSelectAll(mNativeClass);
break;
+ case FIND_ALL: {
+ FindAllRequest request = (FindAllRequest) msg.obj;
+ if (request == null) {
+ nativeFindAll(mNativeClass, null);
+ } else {
+ request.mMatchCount = nativeFindAll(
+ mNativeClass, request.mSearchText);
+ synchronized(request) {
+ request.notify();
+ }
+ }
+ break;
+ }
+ case FIND_NEXT:
+ nativeFindNext(mNativeClass, msg.arg1 != 0);
+ break;
}
}
};
@@ -2783,13 +2812,6 @@
}
// called by JNI
- private void sendFindAgain() {
- if (mWebView == null) return;
- Message.obtain(mWebView.mPrivateHandler,
- WebView.FIND_AGAIN).sendToTarget();
- }
-
- // called by JNI
private void initEditField(int pointer, String text, int start, int end) {
if (mWebView == null) {
return;
@@ -2802,6 +2824,17 @@
.sendToTarget();
}
+ // called by JNI
+ private void updateMatchCount(int matchIndex, int matchCount,
+ String findText) {
+ if (mWebView == null) {
+ return;
+ }
+ Message.obtain(mWebView.mPrivateHandler,
+ WebView.UPDATE_MATCH_COUNT, matchIndex, matchCount,
+ findText).sendToTarget();
+ }
+
private native void nativeUpdateFrameCacheIfLoading(int nativeClass);
private native void nativeRevealSelection(int nativeClass);
private native String nativeRequestLabel(int nativeClass, int framePtr,
@@ -3055,6 +3088,8 @@
private native void nativeAutoFillForm(int nativeClass, int queryId);
private native void nativeScrollLayer(int nativeClass, int layer, Rect rect);
+ private native int nativeFindAll(int nativeClass, String text);
+ private native void nativeFindNext(int nativeClass, boolean forward);
/**
* Deletes editable text between two points. Note that the selection may