Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7821cd6 authored by Mathew Inwood's avatar Mathew Inwood
Browse files

SearchBox API changes, to know when calls succeeded.

Depends on change: I5af94c8df8f24dfafb02c4052381aa547c72684c
(due to SearchBox API change).

Change-Id: If283ecdfa62aecb1fa697b1a2cd43b771b908d72
parent f7537bcc
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ class CallbackProxy extends Handler {
    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;

    // Message triggered by the client to resume execution
    private static final int NOTIFY                              = 200;
@@ -821,6 +822,13 @@ class CallbackProxy extends Handler {
                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;
            }
        }
    }

@@ -1641,4 +1649,13 @@ class CallbackProxy extends Handler {
        msg.obj = new Boolean(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);
    }
}
+14 −6
Original line number Diff line number Diff line
@@ -68,11 +68,15 @@ public interface SearchBox {
     * 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();
    void onsubmit();
    void onresize();
    void oncancel();
    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
@@ -91,8 +95,12 @@ public interface SearchBox {
     * Listeners (if any) will be called on the thread that created the
     * webview.
     */
    interface SearchBoxListener {
        void onSuggestionsReceived(String query, List<String> suggestions);
    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 {
+64 −16
Original line number Diff line number Diff line
@@ -16,10 +16,12 @@

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;
@@ -69,7 +71,7 @@ final class SearchBoxImpl implements SearchBox {

    private static final String SET_VERBATIM_SCRIPT
            =  "if (window.chrome && window.chrome.searchBox) {"
            + "  window.chrome.searchBox.verbatim = %s;"
            + "  window.chrome.searchBox.verbatim = %1$s;"
            + "}";

    private static final String SET_SELECTION_SCRIPT
@@ -89,13 +91,21 @@ final class SearchBoxImpl implements SearchBox {
            + "}";

    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(); }";
            = "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.searchBox && "
            + "  window.chrome.searchBox.onsubmit) {"
            + "  if (window.chrome && window.chrome.sv) {"
            + "    window.searchBoxJavaBridge_.isSupportedCallback(true);"
            + "  } else {"
            + "    window.searchBoxJavaBridge_.isSupportedCallback(false);"
@@ -105,11 +115,14 @@ final class SearchBoxImpl implements SearchBox {
    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
@@ -141,27 +154,36 @@ final class SearchBoxImpl implements SearchBox {
    }

    @Override
    public void onchange() {
        dispatchEvent("change");
    public void onchange(SearchBoxListener callback) {
        dispatchEvent(EVENT_CHANGE, callback);
    }

    @Override
    public void onsubmit() {
        dispatchEvent("submit");
    public void onsubmit(SearchBoxListener callback) {
        dispatchEvent(EVENT_SUBMIT, callback);
    }

    @Override
    public void onresize() {
        dispatchEvent("resize");
    public void onresize(SearchBoxListener callback) {
        dispatchEvent(EVENT_RESIZE, callback);
    }

    @Override
    public void oncancel() {
        dispatchEvent("cancel");
    public void oncancel(SearchBoxListener callback) {
        dispatchEvent(EVENT_CANCEL, callback);
    }

    private void dispatchEvent(String eventName) {
        final String js = String.format(DISPATCH_EVENT_SCRIPT, eventName);
    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);
    }

@@ -202,9 +224,35 @@ final class SearchBoxImpl implements SearchBox {
        }
    }

    // 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 String jsonSerialize(String query) {
    private static String jsonSerialize(String query) {
        JSONStringer stringer = new JSONStringer();
        try {
            stringer.array().value(query).endArray();
+1 −1
Original line number Diff line number Diff line
@@ -248,7 +248,7 @@ public final class WebViewCore {

    /* Get the BrowserFrame component. This is used for subwindow creation and
     * is called only from BrowserFrame in the WebCore thread. */
    /* package */ BrowserFrame getBrowserFrame() {
    /* package */ synchronized BrowserFrame getBrowserFrame() {
        return mBrowserFrame;
    }