Merge "Remove defunct searchbox implementation from webview." into jb-mr1-dev

This commit is contained in:
Selim Gurun
2012-09-11 11:01:31 -07:00
committed by Android (Google) Code Review
5 changed files with 1 additions and 473 deletions

View File

@@ -107,9 +107,6 @@ class BrowserFrame extends Handler {
// Key store handler when Chromium HTTP stack is used.
private KeyStoreHandler mKeyStoreHandler = null;
// Implementation of the searchbox API.
private final SearchBoxImpl mSearchBox;
// message ids
// a message posted when a frame loading is completed
static final int FRAME_COMPLETED = 1001;
@@ -255,8 +252,6 @@ class BrowserFrame extends Handler {
mDatabase = WebViewDatabaseClassic.getInstance(appContext);
mWebViewCore = w;
mSearchBox = new SearchBoxImpl(mWebViewCore, mCallbackProxy);
AssetManager am = context.getAssets();
nativeCreateFrame(w, am, proxy.getBackForwardList());
@@ -1217,10 +1212,6 @@ class BrowserFrame extends Handler {
}
}
/*package*/ SearchBox getSearchBox() {
return mSearchBox;
}
/**
* Called by JNI when processing the X-Auto-Login header.
*/

View File

@@ -117,11 +117,8 @@ class CallbackProxy extends Handler {
private static final int ADD_HISTORY_ITEM = 135;
private static final int HISTORY_INDEX_CHANGED = 136;
private static final int AUTH_CREDENTIALS = 137;
private static final int NOTIFY_SEARCHBOX_LISTENERS = 139;
private static final int AUTO_LOGIN = 140;
private static final int CLIENT_CERT_REQUEST = 141;
private static final int SEARCHBOX_IS_SUPPORTED_CALLBACK = 142;
private static final int SEARCHBOX_DISPATCH_COMPLETE_CALLBACK = 143;
private static final int PROCEEDED_AFTER_SSL_ERROR = 144;
// Message triggered by the client to resume execution
@@ -871,14 +868,6 @@ class CallbackProxy extends Handler {
host, realm, username, password);
break;
}
case NOTIFY_SEARCHBOX_LISTENERS: {
SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox();
@SuppressWarnings("unchecked")
List<String> suggestions = (List<String>) msg.obj;
searchBox.handleSuggestions(msg.getData().getString("query"), suggestions);
break;
}
case AUTO_LOGIN: {
if (mWebViewClient != null) {
String realm = msg.getData().getString("realm");
@@ -889,19 +878,6 @@ class CallbackProxy extends Handler {
}
break;
}
case SEARCHBOX_IS_SUPPORTED_CALLBACK: {
SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox();
Boolean supported = (Boolean) msg.obj;
searchBox.handleIsSupportedCallback(supported);
break;
}
case SEARCHBOX_DISPATCH_COMPLETE_CALLBACK: {
SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox();
Boolean success = (Boolean) msg.obj;
searchBox.handleDispatchCompleteCallback(msg.getData().getString("function"),
msg.getData().getInt("id"), success);
break;
}
}
}
@@ -1629,29 +1605,6 @@ class CallbackProxy extends Handler {
return mContext instanceof Activity;
}
void onSearchboxSuggestionsReceived(String query, List<String> suggestions) {
Message msg = obtainMessage(NOTIFY_SEARCHBOX_LISTENERS);
msg.obj = suggestions;
msg.getData().putString("query", query);
sendMessage(msg);
}
void onIsSupportedCallback(boolean isSupported) {
Message msg = obtainMessage(SEARCHBOX_IS_SUPPORTED_CALLBACK);
msg.obj = Boolean.valueOf(isSupported);
sendMessage(msg);
}
void onSearchboxDispatchCompleteCallback(String function, int id, boolean success) {
Message msg = obtainMessage(SEARCHBOX_DISPATCH_COMPLETE_CALLBACK);
msg.obj = Boolean.valueOf(success);
msg.getData().putString("function", function);
msg.getData().putInt("id", id);
sendMessage(msg);
}
private synchronized void sendMessageToUiThreadSync(Message msg) {
sendMessage(msg);
WebCoreThreadWatchdog.pause();

View File

@@ -1,109 +0,0 @@
/*
* Copyright (C) 2011 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 java.util.List;
/**
* Defines the interaction between the browser/renderer and the page running on
* a given WebView frame, if the page supports the chromium SearchBox API.
*
* http://dev.chromium.org/searchbox
*
* The browser or container app can query the page for search results using
* SearchBox.query() and receive suggestions by registering a listener on the
* SearchBox object.
*
* @hide
*/
public interface SearchBox {
/**
* Sets the current searchbox query. Note that the caller must call
* onchange() to ensure that the search page processes this query.
*/
void setQuery(String query);
/**
* Verbatim is true if the caller suggests that the search page
* treat the current query as a verbatim search query (as opposed to a
* partially typed search query). As with setQuery, onchange() must be
* called to ensure that the search page processes the query.
*/
void setVerbatim(boolean verbatim);
/**
* These attributes must contain the offset to the characters that immediately
* follow the start and end of the selection in the search box. If there is
* no such selection, then both selectionStart and selectionEnd must be the offset
* to the character that immediately follows the text entry cursor. In the case
* that there is no explicit text entry cursor, the cursor is
* implicitly at the end of the input.
*/
void setSelection(int selectionStart, int selectionEnd);
/**
* Sets the dimensions of the view (if any) that overlaps the current
* window object. This is to ensure that the page renders results in
* a manner that allows them to not be obscured by such a view. Note
* that a call to onresize() is required if these dimensions change.
*/
void setDimensions(int x, int y, int width, int height);
/**
* Notify the search page of any changes to the searchbox. Such as
* a change in the typed query (onchange), the user commiting a given query
* (onsubmit), or a change in size of a suggestions dropdown (onresize).
*
* @param listener an optional listener to notify of the success of the operation,
* indicating if the javascript function existed and could be called or not.
* It will be called on the UI thread.
*/
void onchange(SearchBoxListener listener);
void onsubmit(SearchBoxListener listener);
void onresize(SearchBoxListener listener);
void oncancel(SearchBoxListener listener);
/**
* Add and remove listeners to the given Searchbox. Listeners are notified
* of any suggestions to the query that the underlying search engine might
* provide.
*/
void addSearchBoxListener(SearchBoxListener l);
void removeSearchBoxListener(SearchBoxListener l);
/**
* Indicates if the searchbox API is supported in the current page.
*/
void isSupported(IsSupportedCallback callback);
/**
* Listeners (if any) will be called on the thread that created the
* webview.
*/
public abstract class SearchBoxListener {
public void onSuggestionsReceived(String query, List<String> suggestions) {}
public void onChangeComplete(boolean called) {}
public void onSubmitComplete(boolean called) {}
public void onResizeComplete(boolean called) {}
public void onCancelComplete(boolean called) {}
}
interface IsSupportedCallback {
void searchBoxIsSupported(boolean supported);
}
}

View File

@@ -1,304 +0,0 @@
/*
* Copyright (C) 2011 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.text.TextUtils;
import android.util.Log;
import android.webkit.WebViewCore.EventHub;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
/**
* The default implementation of the SearchBox interface. Implemented
* as a java bridge object and a javascript adapter that is called into
* by the page hosted in the frame.
*/
final class SearchBoxImpl implements SearchBox {
private static final String TAG = "WebKit.SearchBoxImpl";
/* package */ static final String JS_INTERFACE_NAME = "searchBoxJavaBridge_";
/* package */ static final String JS_BRIDGE
= "(function()"
+ "{"
+ "if (!window.chrome) {"
+ " window.chrome = {};"
+ "}"
+ "if (!window.chrome.searchBox) {"
+ " var sb = window.chrome.searchBox = {};"
+ " sb.setSuggestions = function(suggestions) {"
+ " if (window.searchBoxJavaBridge_) {"
+ " window.searchBoxJavaBridge_.setSuggestions(JSON.stringify(suggestions));"
+ " }"
+ " };"
+ " sb.setValue = function(valueArray) { sb.value = valueArray[0]; };"
+ " sb.value = '';"
+ " sb.x = 0;"
+ " sb.y = 0;"
+ " sb.width = 0;"
+ " sb.height = 0;"
+ " sb.selectionStart = 0;"
+ " sb.selectionEnd = 0;"
+ " sb.verbatim = false;"
+ "}"
+ "})();";
private static final String SET_QUERY_SCRIPT
= "if (window.chrome && window.chrome.searchBox) {"
+ " window.chrome.searchBox.setValue(%s);"
+ "}";
private static final String SET_VERBATIM_SCRIPT
= "if (window.chrome && window.chrome.searchBox) {"
+ " window.chrome.searchBox.verbatim = %1$s;"
+ "}";
private static final String SET_SELECTION_SCRIPT
= "if (window.chrome && window.chrome.searchBox) {"
+ " var f = window.chrome.searchBox;"
+ " f.selectionStart = %d"
+ " f.selectionEnd = %d"
+ "}";
private static final String SET_DIMENSIONS_SCRIPT
= "if (window.chrome && window.chrome.searchBox) { "
+ " var f = window.chrome.searchBox;"
+ " f.x = %d;"
+ " f.y = %d;"
+ " f.width = %d;"
+ " f.height = %d;"
+ "}";
private static final String DISPATCH_EVENT_SCRIPT
= "if (window.chrome && window.chrome.searchBox && window.chrome.searchBox.on%1$s) {"
+ " window.chrome.searchBox.on%1$s();"
+ " window.searchBoxJavaBridge_.dispatchCompleteCallback('%1$s', %2$d, true);"
+ "} else {"
+ " window.searchBoxJavaBridge_.dispatchCompleteCallback('%1$s', %2$d, false);"
+ "}";
private static final String EVENT_CHANGE = "change";
private static final String EVENT_SUBMIT = "submit";
private static final String EVENT_RESIZE = "resize";
private static final String EVENT_CANCEL = "cancel";
private static final String IS_SUPPORTED_SCRIPT
= "if (window.searchBoxJavaBridge_) {"
+ " if (window.chrome && window.chrome.sv) {"
+ " window.searchBoxJavaBridge_.isSupportedCallback(true);"
+ " } else {"
+ " window.searchBoxJavaBridge_.isSupportedCallback(false);"
+ " }}";
private final List<SearchBoxListener> mListeners;
private final WebViewCore mWebViewCore;
private final CallbackProxy mCallbackProxy;
private IsSupportedCallback mSupportedCallback;
private int mNextEventId = 1;
private final HashMap<Integer, SearchBoxListener> mEventCallbacks;
SearchBoxImpl(WebViewCore webViewCore, CallbackProxy callbackProxy) {
mListeners = new ArrayList<SearchBoxListener>();
mWebViewCore = webViewCore;
mCallbackProxy = callbackProxy;
mEventCallbacks = new HashMap<Integer, SearchBoxListener>();
}
@Override
public void setQuery(String query) {
final String formattedQuery = jsonSerialize(query);
if (formattedQuery != null) {
final String js = String.format(SET_QUERY_SCRIPT, formattedQuery);
dispatchJs(js);
}
}
@Override
public void setVerbatim(boolean verbatim) {
final String js = String.format(SET_VERBATIM_SCRIPT, String.valueOf(verbatim));
dispatchJs(js);
}
@Override
public void setSelection(int selectionStart, int selectionEnd) {
final String js = String.format(SET_SELECTION_SCRIPT, selectionStart, selectionEnd);
dispatchJs(js);
}
@Override
public void setDimensions(int x, int y, int width, int height) {
final String js = String.format(SET_DIMENSIONS_SCRIPT, x, y, width, height);
dispatchJs(js);
}
@Override
public void onchange(SearchBoxListener callback) {
dispatchEvent(EVENT_CHANGE, callback);
}
@Override
public void onsubmit(SearchBoxListener callback) {
dispatchEvent(EVENT_SUBMIT, callback);
}
@Override
public void onresize(SearchBoxListener callback) {
dispatchEvent(EVENT_RESIZE, callback);
}
@Override
public void oncancel(SearchBoxListener callback) {
dispatchEvent(EVENT_CANCEL, callback);
}
private void dispatchEvent(String eventName, SearchBoxListener callback) {
int eventId;
if (callback != null) {
synchronized(this) {
eventId = mNextEventId++;
mEventCallbacks.put(eventId, callback);
}
} else {
eventId = 0;
}
final String js = String.format(DISPATCH_EVENT_SCRIPT, eventName, eventId);
dispatchJs(js);
}
private void dispatchJs(String js) {
mWebViewCore.sendMessage(EventHub.EXECUTE_JS, js);
}
@Override
public void addSearchBoxListener(SearchBoxListener l) {
synchronized (mListeners) {
mListeners.add(l);
}
}
@Override
public void removeSearchBoxListener(SearchBoxListener l) {
synchronized (mListeners) {
mListeners.remove(l);
}
}
@Override
public void isSupported(IsSupportedCallback callback) {
mSupportedCallback = callback;
dispatchJs(IS_SUPPORTED_SCRIPT);
}
// Called by Javascript through the Java bridge.
public void isSupportedCallback(boolean isSupported) {
mCallbackProxy.onIsSupportedCallback(isSupported);
}
public void handleIsSupportedCallback(boolean isSupported) {
IsSupportedCallback callback = mSupportedCallback;
mSupportedCallback = null;
if (callback != null) {
callback.searchBoxIsSupported(isSupported);
}
}
// Called by Javascript through the Java bridge.
public void dispatchCompleteCallback(String function, int id, boolean successful) {
mCallbackProxy.onSearchboxDispatchCompleteCallback(function, id, successful);
}
public void handleDispatchCompleteCallback(String function, int id, boolean successful) {
if (id != 0) {
SearchBoxListener listener;
synchronized(this) {
listener = mEventCallbacks.get(id);
mEventCallbacks.remove(id);
}
if (listener != null) {
if (TextUtils.equals(EVENT_CHANGE, function)) {
listener.onChangeComplete(successful);
} else if (TextUtils.equals(EVENT_SUBMIT, function)) {
listener.onSubmitComplete(successful);
} else if (TextUtils.equals(EVENT_RESIZE, function)) {
listener.onResizeComplete(successful);
} else if (TextUtils.equals(EVENT_CANCEL, function)) {
listener.onCancelComplete(successful);
}
}
}
}
// This is used as a hackish alternative to javascript escaping.
// There appears to be no such functionality in the core framework.
private static String jsonSerialize(String query) {
JSONStringer stringer = new JSONStringer();
try {
stringer.array().value(query).endArray();
} catch (JSONException e) {
Log.w(TAG, "Error serializing query : " + query);
return null;
}
return stringer.toString();
}
// Called by Javascript through the Java bridge.
public void setSuggestions(String jsonArguments) {
if (jsonArguments == null) {
return;
}
String query = null;
List<String> suggestions = new ArrayList<String>();
try {
JSONObject suggestionsJson = new JSONObject(jsonArguments);
query = suggestionsJson.getString("query");
final JSONArray suggestionsArray = suggestionsJson.getJSONArray("suggestions");
for (int i = 0; i < suggestionsArray.length(); ++i) {
final JSONObject suggestion = suggestionsArray.getJSONObject(i);
final String value = suggestion.getString("value");
if (value != null) {
suggestions.add(value);
}
// We currently ignore the "type" of the suggestion. This isn't
// documented anywhere in the API documents.
// final String type = suggestions.getString("type");
}
} catch (JSONException je) {
Log.w(TAG, "Error parsing json [" + jsonArguments + "], exception = " + je);
return;
}
mCallbackProxy.onSearchboxSuggestionsReceived(query, suggestions);
}
/* package */ void handleSuggestions(String query, List<String> suggestions) {
synchronized (mListeners) {
for (int i = mListeners.size() - 1; i >= 0; i--) {
mListeners.get(i).onSuggestionsReceived(query, suggestions);
}
}
}
}

View File

@@ -5367,10 +5367,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
* This is an implementation detail.
*/
public SearchBox getSearchBox() {
if ((mWebViewCore == null) || (mWebViewCore.getBrowserFrame() == null)) {
return null;
}
return mWebViewCore.getBrowserFrame().getSearchBox();
return null;
}
/**