Skip to content

Commit b6ad5b1

Browse files
Victoria LeaseAndroid (Google) Code Review
authored andcommitted
Merge "async find-on-page implementation via WebKit"
2 parents 2b2c573 + 47d0ee9 commit b6ad5b1

File tree

3 files changed

+122
-58
lines changed

3 files changed

+122
-58
lines changed

core/java/android/webkit/FindActionModeCallback.java

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
4343
private Resources mResources;
4444
private boolean mMatchesFound;
4545
private int mNumberOfMatches;
46+
private int mActiveMatchIndex;
4647
private ActionMode mActionMode;
48+
private String mLastFind;
4749

4850
FindActionModeCallback(Context context) {
4951
mCustomView = LayoutInflater.from(context).inflate(
@@ -132,16 +134,13 @@ void findAll() {
132134
mWebView.clearMatches();
133135
mMatches.setVisibility(View.GONE);
134136
mMatchesFound = false;
137+
mLastFind = null;
135138
} else {
136139
mMatchesFound = true;
137-
mMatches.setVisibility(View.VISIBLE);
138-
mNumberOfMatches = mWebView.findAll(find.toString());
139-
if (0 == mNumberOfMatches) {
140-
mMatches.setText(mResources.getString(
141-
com.android.internal.R.string.no_matches));
142-
} else {
143-
updateMatchesString();
144-
}
140+
mMatches.setVisibility(View.INVISIBLE);
141+
mNumberOfMatches = 0;
142+
mLastFind = find.toString();
143+
mWebView.findAllAsync(mLastFind);
145144
}
146145
}
147146

@@ -151,17 +150,31 @@ public void showSoftInput() {
151150
mInput.showSoftInput(mEditText, 0);
152151
}
153152

153+
public void updateMatchCount(int matchIndex, int matchCount,
154+
String findText) {
155+
if (mLastFind != null && mLastFind.equals(findText)) {
156+
mNumberOfMatches = matchCount;
157+
mActiveMatchIndex = matchIndex;
158+
updateMatchesString();
159+
} else {
160+
mMatches.setVisibility(View.INVISIBLE);
161+
mNumberOfMatches = 0;
162+
}
163+
}
164+
154165
/*
155166
* Update the string which tells the user how many matches were found, and
156167
* which match is currently highlighted.
157-
* Not to be called when mNumberOfMatches is 0.
158168
*/
159169
private void updateMatchesString() {
160-
String template = mResources.getQuantityString(
170+
if (mNumberOfMatches == 0) {
171+
mMatches.setText(com.android.internal.R.string.no_matches);
172+
} else {
173+
mMatches.setText(mResources.getQuantityString(
161174
com.android.internal.R.plurals.matches_found, mNumberOfMatches,
162-
mWebView.findIndex() + 1, mNumberOfMatches);
163-
164-
mMatches.setText(template);
175+
mActiveMatchIndex + 1, mNumberOfMatches));
176+
}
177+
mMatches.setVisibility(View.VISIBLE);
165178
}
166179

167180
// OnLongClickListener implementation

core/java/android/webkit/WebView.java

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ public void onTrimMemory(int level) {
914914
static final int REPLACE_BASE_CONTENT = 123;
915915
static final int FORM_DID_BLUR = 124;
916916
static final int RETURN_LABEL = 125;
917-
static final int FIND_AGAIN = 126;
917+
static final int UPDATE_MATCH_COUNT = 126;
918918
static final int CENTER_FIT_RECT = 127;
919919
static final int REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID = 128;
920920
static final int SET_SCROLLBAR_MODES = 129;
@@ -979,7 +979,7 @@ public void onTrimMemory(int level) {
979979
"REPLACE_BASE_CONTENT", // = 123;
980980
"FORM_DID_BLUR", // = 124;
981981
"RETURN_LABEL", // = 125;
982-
"FIND_AGAIN", // = 126;
982+
"UPDATE_MATCH_COUNT", // = 126;
983983
"CENTER_FIT_RECT", // = 127;
984984
"REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID", // = 128;
985985
"SET_SCROLLBAR_MODES", // = 129;
@@ -1021,9 +1021,8 @@ public void onTrimMemory(int level) {
10211021

10221022
// keep these in sync with their counterparts in WebView.cpp
10231023
private static final int DRAW_EXTRAS_NONE = 0;
1024-
private static final int DRAW_EXTRAS_FIND = 1;
1025-
private static final int DRAW_EXTRAS_SELECTION = 2;
1026-
private static final int DRAW_EXTRAS_CURSOR_RING = 3;
1024+
private static final int DRAW_EXTRAS_SELECTION = 1;
1025+
private static final int DRAW_EXTRAS_CURSOR_RING = 2;
10271026

10281027
// keep this in sync with WebCore:ScrollbarMode in WebKit
10291028
private static final int SCROLLBAR_AUTO = 0;
@@ -3711,7 +3710,7 @@ public WebBackForwardList copyBackForwardList() {
37113710
public void findNext(boolean forward) {
37123711
checkThread();
37133712
if (0 == mNativeClass) return; // client isn't initialized
3714-
nativeFindNext(forward);
3713+
mWebViewCore.sendMessage(EventHub.FIND_NEXT, forward ? 1 : 0);
37153714
}
37163715

37173716
/*
@@ -3721,13 +3720,40 @@ public void findNext(boolean forward) {
37213720
* that were found.
37223721
*/
37233722
public int findAll(String find) {
3723+
return findAllBody(find, false);
3724+
}
3725+
3726+
/**
3727+
* @hide
3728+
*/
3729+
public void findAllAsync(String find) {
3730+
findAllBody(find, true);
3731+
}
3732+
3733+
private int findAllBody(String find, boolean isAsync) {
37243734
checkThread();
37253735
if (0 == mNativeClass) return 0; // client isn't initialized
3726-
int result = find != null ? nativeFindAll(find.toLowerCase(),
3727-
find.toUpperCase(), find.equalsIgnoreCase(mLastFind)) : 0;
3728-
invalidate();
37293736
mLastFind = find;
3730-
return result;
3737+
mWebViewCore.removeMessages(EventHub.FIND_ALL);
3738+
WebViewCore.FindAllRequest request = new
3739+
WebViewCore.FindAllRequest(find);
3740+
if (isAsync) {
3741+
mWebViewCore.sendMessage(EventHub.FIND_ALL, request);
3742+
return 0; // no need to wait for response
3743+
}
3744+
synchronized(request) {
3745+
try {
3746+
mWebViewCore.sendMessageAtFrontOfQueue(EventHub.FIND_ALL,
3747+
request);
3748+
while (request.mMatchCount == -1) {
3749+
request.wait();
3750+
}
3751+
}
3752+
catch (InterruptedException e) {
3753+
return 0;
3754+
}
3755+
}
3756+
return request.mMatchCount;
37313757
}
37323758

37333759
/**
@@ -3763,6 +3789,7 @@ public boolean showFindDialog(String text, boolean showIme) {
37633789
}
37643790
if (text != null) {
37653791
mFindCallback.setText(text);
3792+
mFindCallback.findAll();
37663793
}
37673794
return true;
37683795
}
@@ -3782,14 +3809,6 @@ private void setFindIsUp(boolean isUp) {
37823809
nativeSetFindIsUp(isUp);
37833810
}
37843811

3785-
/**
3786-
* Return the index of the currently highlighted match.
3787-
*/
3788-
int findIndex() {
3789-
if (0 == mNativeClass) return -1;
3790-
return nativeFindIndex();
3791-
}
3792-
37933812
// Used to know whether the find dialog is open. Affects whether
37943813
// or not we draw the highlights for matches.
37953814
private boolean mFindIsUp;
@@ -3856,10 +3875,11 @@ public void clearMatches() {
38563875
checkThread();
38573876
if (mNativeClass == 0)
38583877
return;
3859-
nativeSetFindIsEmpty();
3860-
invalidate();
3878+
mWebViewCore.removeMessages(EventHub.FIND_ALL);
3879+
mWebViewCore.sendMessage(EventHub.FIND_ALL, null);
38613880
}
38623881

3882+
38633883
/**
38643884
* Called when the find ActionMode ends.
38653885
*/
@@ -4954,12 +4974,12 @@ && nativeEvaluateLayersAnimations(mNativeClass)) {
49544974

49554975
// decide which adornments to draw
49564976
int extras = DRAW_EXTRAS_NONE;
4957-
if (mFindIsUp) {
4958-
extras = DRAW_EXTRAS_FIND;
4959-
} else if (mSelectingText) {
4960-
extras = DRAW_EXTRAS_SELECTION;
4961-
} else if (drawCursorRing) {
4962-
extras = DRAW_EXTRAS_CURSOR_RING;
4977+
if (!mFindIsUp) {
4978+
if (mSelectingText) {
4979+
extras = DRAW_EXTRAS_SELECTION;
4980+
} else if (drawCursorRing) {
4981+
extras = DRAW_EXTRAS_CURSOR_RING;
4982+
}
49634983
}
49644984
if (DebugFlags.WEB_VIEW) {
49654985
Log.v(LOGTAG, "mFindIsUp=" + mFindIsUp
@@ -8884,13 +8904,6 @@ public void handleMessage(Message msg) {
88848904
}
88858905
break;
88868906

8887-
case FIND_AGAIN:
8888-
// Ignore if find has been dismissed.
8889-
if (mFindIsUp && mFindCallback != null) {
8890-
mFindCallback.findAll();
8891-
}
8892-
break;
8893-
88948907
case DRAG_HELD_MOTIONLESS:
88958908
mHeldMotionless = MOTIONLESS_TRUE;
88968909
invalidate();
@@ -9095,6 +9108,14 @@ public void handleMessage(Message msg) {
90959108
break;
90969109
}
90979110

9111+
case UPDATE_MATCH_COUNT: {
9112+
if (mFindCallback != null) {
9113+
mFindCallback.updateMatchCount(msg.arg1, msg.arg2,
9114+
(String) msg.obj);
9115+
}
9116+
break;
9117+
}
9118+
90989119
default:
90999120
super.handleMessage(msg);
91009121
break;
@@ -9931,9 +9952,6 @@ private native int nativeGetDrawGLFunction(int nativeInstance, Rect rect,
99319952
private native void nativeUpdateDrawGLFunction(Rect rect, Rect viewRect,
99329953
RectF visibleRect, float scale);
99339954
private native void nativeExtendSelection(int x, int y);
9934-
private native int nativeFindAll(String findLower, String findUpper,
9935-
boolean sameAsLastSearch);
9936-
private native void nativeFindNext(boolean forward);
99379955
/* package */ native int nativeFocusCandidateFramePointer();
99389956
/* package */ native boolean nativeFocusCandidateHasNextTextfield();
99399957
/* package */ native boolean nativeFocusCandidateIsPassword();
@@ -9991,9 +10009,7 @@ private native boolean nativeMoveCursor(int keyCode, int count,
999110009
private native boolean nativePointInNavCache(int x, int y, int slop);
999210010
private native void nativeSelectBestAt(Rect rect);
999310011
private native void nativeSelectAt(int x, int y);
9994-
private native int nativeFindIndex();
999510012
private native void nativeSetExtendSelection();
9996-
private native void nativeSetFindIsEmpty();
999710013
private native void nativeSetFindIsUp(boolean isUp);
999810014
private native void nativeSetHeightCanMeasure(boolean measure);
999910015
private native boolean nativeSetBaseLayer(int nativeInstance,

core/java/android/webkit/WebViewCore.java

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,15 @@ static class GeolocationPermissionsData {
10011001
"REMOVE_JS_INTERFACE", // = 149;
10021002
};
10031003

1004+
static class FindAllRequest {
1005+
public FindAllRequest(String text) {
1006+
mSearchText = text;
1007+
mMatchCount = -1;
1008+
}
1009+
public String mSearchText;
1010+
public int mMatchCount;
1011+
}
1012+
10041013
/**
10051014
* @hide
10061015
*/
@@ -1142,6 +1151,10 @@ public class EventHub {
11421151
// for updating state on trust storage change
11431152
static final int TRUST_STORAGE_UPDATED = 220;
11441153

1154+
// find-on-page controls
1155+
static final int FIND_ALL = 220;
1156+
static final int FIND_NEXT = 221;
1157+
11451158
// Private handler for WebCore messages.
11461159
private Handler mHandler;
11471160
// Message queue for containing messages before the WebCore thread is
@@ -1785,6 +1798,22 @@ public void handleMessage(Message msg) {
17851798
case SELECT_ALL:
17861799
nativeSelectAll(mNativeClass);
17871800
break;
1801+
case FIND_ALL: {
1802+
FindAllRequest request = (FindAllRequest) msg.obj;
1803+
if (request == null) {
1804+
nativeFindAll(mNativeClass, null);
1805+
} else {
1806+
request.mMatchCount = nativeFindAll(
1807+
mNativeClass, request.mSearchText);
1808+
synchronized(request) {
1809+
request.notify();
1810+
}
1811+
}
1812+
break;
1813+
}
1814+
case FIND_NEXT:
1815+
nativeFindNext(mNativeClass, msg.arg1 != 0);
1816+
break;
17881817
}
17891818
}
17901819
};
@@ -2782,13 +2811,6 @@ private void clearTextEntry() {
27822811
WebView.CLEAR_TEXT_ENTRY).sendToTarget();
27832812
}
27842813

2785-
// called by JNI
2786-
private void sendFindAgain() {
2787-
if (mWebView == null) return;
2788-
Message.obtain(mWebView.mPrivateHandler,
2789-
WebView.FIND_AGAIN).sendToTarget();
2790-
}
2791-
27922814
// called by JNI
27932815
private void initEditField(int pointer, String text, int start, int end) {
27942816
if (mWebView == null) {
@@ -2802,6 +2824,17 @@ private void initEditField(int pointer, String text, int start, int end) {
28022824
.sendToTarget();
28032825
}
28042826

2827+
// called by JNI
2828+
private void updateMatchCount(int matchIndex, int matchCount,
2829+
String findText) {
2830+
if (mWebView == null) {
2831+
return;
2832+
}
2833+
Message.obtain(mWebView.mPrivateHandler,
2834+
WebView.UPDATE_MATCH_COUNT, matchIndex, matchCount,
2835+
findText).sendToTarget();
2836+
}
2837+
28052838
private native void nativeUpdateFrameCacheIfLoading(int nativeClass);
28062839
private native void nativeRevealSelection(int nativeClass);
28072840
private native String nativeRequestLabel(int nativeClass, int framePtr,
@@ -3055,6 +3088,8 @@ private native WebKitHitTest nativeHitTest(int nativeClass, int x, int y,
30553088

30563089
private native void nativeAutoFillForm(int nativeClass, int queryId);
30573090
private native void nativeScrollLayer(int nativeClass, int layer, Rect rect);
3091+
private native int nativeFindAll(int nativeClass, String text);
3092+
private native void nativeFindNext(int nativeClass, boolean forward);
30583093

30593094
/**
30603095
* Deletes editable text between two points. Note that the selection may

0 commit comments

Comments
 (0)