Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: mobile/android/thirdparty/org/adblockplus/browser/AddOnBridge.java

Issue 4920541991403520: Create a minimal settings UI (Closed)
Patch Set: Cleanup of AddOnBridge Created March 22, 2015, 12:13 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mobile/android/thirdparty/org/adblockplus/browser/AddOnBridge.java
diff --git a/mobile/android/thirdparty/org/adblockplus/browser/AddOnBridge.java b/mobile/android/thirdparty/org/adblockplus/browser/AddOnBridge.java
new file mode 100644
index 0000000000000000000000000000000000000000..b650c0be025e505f1733457e1e4243240bb9b7aa
--- /dev/null
+++ b/mobile/android/thirdparty/org/adblockplus/browser/AddOnBridge.java
@@ -0,0 +1,249 @@
+/*
+ * This file is part of Adblock Plus <https://adblockplus.org/>,
+ * Copyright (C) 2006-2015 Eyeo GmbH
+ *
+ * Adblock Plus is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Adblock Plus is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.adblockplus.browser;
+
+import android.annotation.SuppressLint;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.util.GeckoRequest;
+import org.mozilla.gecko.util.NativeJSObject;
+
+@SuppressLint("DefaultLocale")
+public class AddOnBridge
+{
+ private static final String TAG = "AdblockBrowser.AddonBridge";
+ private static final String REQUEST_NAME = "AdblockPlus:Api";
+ // Timeout for ready checking (in seconds)
+ private static final int QUERY_READY_STATE_TIMEOUT = 45;
+ // How long to wait between retries (in milliseconds)
+ private static final int QUERY_READY_STATE_DELAY = 250;
+ // Handler+HandlerThread for posting delayed re-tries without interfering with
+ // other threads (e.g. the UI or Gecko thread)
+ private static final HandlerThread HANDLER_THREAD;
+ private static final Handler HANDLER;
+
+ static
+ {
+ HANDLER_THREAD = new HandlerThread("abp-addon-bridge");
Felix Dahlke 2015/03/22 15:51:45 "abp-bridge" would do. Technically, there's no dif
René Jeschke 2015/03/22 16:44:55 Done.
+ HANDLER_THREAD.setDaemon(true);
+ HANDLER_THREAD.start();
+ HANDLER = new Handler(HANDLER_THREAD.getLooper());
+ }
+
+ public static boolean getBooleanFromJSObject(final NativeJSObject obj, final String name,
Felix Dahlke 2015/03/22 15:51:45 Naming Nit: getBooleanFromJsObject, likewise get*F
René Jeschke 2015/03/22 16:44:55 Done.
+ final boolean defaultValue)
+ {
+ try
+ {
+ return obj.getBoolean(name);
+ }
+ catch (final Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ public static String getStringFromJSObject(final NativeJSObject obj, final String name,
+ final String defaultValue)
+ {
+ try
+ {
+ return obj.getString(name);
+ }
+ catch (final Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ private static JSONObject createRequestData(final String action)
+ {
+ final JSONObject obj = new JSONObject();
+ try
+ {
+ obj.put("action", action.toLowerCase());
+ }
+ catch (JSONException e)
+ {
+ // we're only adding sane objects
+ Log.e(TAG, "Creating request data failed with: " + e.getMessage(), e);
+ }
+ return obj;
+ }
+
+ private static JSONObject createRequestData(final String action, final boolean enable)
Felix Dahlke 2015/03/22 15:51:45 s/enable/parameter/?
+ {
+ final JSONObject obj = new JSONObject();
+ try
+ {
+ obj.put("action", action.toLowerCase());
+ obj.put("enable", enable);
+ }
+ catch (JSONException e)
+ {
+ // we're only adding sane objects
+ Log.e(TAG, "Creating request data failed with: " + e.getMessage(), e);
+ }
+ return obj;
+ }
+
+ public static void queryBoolean(final AdblockPlusApiCallback callback, final String action)
Felix Dahlke 2015/03/22 15:51:45 IMHO this is a bit confusing: queryBoolean sounds
René Jeschke 2015/03/22 16:44:55 It is called 'query' because it does not 'get' a b
Felix Dahlke 2015/03/22 17:44:34 OK, fair enough.
+ {
+ Log.d(TAG, "queryBoolean for " + action);
+ GeckoAppShell.sendRequestToGecko(
+ new ChainedRequest(
+ createRequestData(action),
+ callback));
+ }
+
+ public static void setBoolean(final AdblockPlusApiCallback callback, final String action,
+ final boolean enable)
+ {
+ Log.d(TAG, "setBoolean " + enable + " for " + action);
+ GeckoAppShell.sendRequestToGecko(
+ new ChainedRequest(
+ createRequestData(action, enable),
+ callback));
+ }
+
+ private static class ChainedRequest extends GeckoRequest
+ {
+ private final JSONObject value;
+ private final AdblockPlusApiCallback apiCallback;
+ private final boolean initCheck;
+ private final long creationTime;
+
+ public ChainedRequest(final JSONObject value, final AdblockPlusApiCallback callback,
+ final boolean checkInitState, final long creationTime)
Felix Dahlke 2015/03/22 15:51:45 I don't fully understand this one -
René Jeschke 2015/03/22 16:44:55 We start an asynchronous chain of requests here: T
Felix Dahlke 2015/03/22 17:44:34 Alright, get it now - so we're checking for filter
+ {
+ super(AddOnBridge.REQUEST_NAME,
+ checkInitState ? createRequestData("query_ready_state") : value);
+ this.value = value;
+ this.apiCallback = callback;
+ this.initCheck = checkInitState;
+ this.creationTime = creationTime;
+ }
+
+ public ChainedRequest(final JSONObject value, final AdblockPlusApiCallback callback)
+ {
+ this(value, callback, true, System.currentTimeMillis());
+ }
+
+ public ChainedRequest cloneForRetry()
+ {
+ return new ChainedRequest(this.value, this.apiCallback, true, this.creationTime);
+ }
+
+ public ChainedRequest cloneForRequest()
+ {
+ return new ChainedRequest(this.value, this.apiCallback, false, this.creationTime);
+ }
+
+ private void callSuccessFunction(final NativeJSObject jsObject)
Felix Dahlke 2015/03/22 15:51:45 "invokeSuccessCallback"?
René Jeschke 2015/03/22 16:44:55 Ok
+ {
+ try
+ {
+ if (this.apiCallback != null)
+ {
+ this.apiCallback.onApiRequestSucceeded(jsObject);
+ }
+ }
+ catch (final Exception e)
+ {
+ Log.e(TAG, "onApiRequestSucceeded threw exception: " + e.getMessage(), e);
+ }
+ }
+
+ private void callFailureFunction(final String msg)
+ {
+ if (this.apiCallback != null)
+ {
+ this.apiCallback.onApiRequestFailed(msg);
+ }
+ }
+
+ private void callFailureFunction(final NativeJSObject jsObject)
+ {
+ callFailureFunction(getStringFromJSObject(jsObject, "error", "unknown error"));
+ }
+
+ private void maybeReTry()
Felix Dahlke 2015/03/22 15:51:45 How about "attemptRetry"?
René Jeschke 2015/03/22 16:44:55 Yup.
+ {
+ if (System.currentTimeMillis() - this.creationTime > (QUERY_READY_STATE_TIMEOUT * 1000))
+ {
+ this.callFailureFunction("query_ready_state timeout");
+ }
Felix Dahlke 2015/03/22 15:51:45 Shouldn't we return here, or am I missing somethin
René Jeschke 2015/03/22 16:44:55 Yeah, already changed.
+
+ final ChainedRequest next = this.cloneForRetry();
+ HANDLER.postDelayed(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ GeckoAppShell.sendRequestToGecko(next);
+ }
+ }, QUERY_READY_STATE_DELAY);
+ }
+
+ @Override
+ public void onError()
+ {
+ if (this.initCheck)
+ {
+ this.maybeReTry();
+ }
+ else
+ {
+ this.callFailureFunction("GeckoRequest error");
+ }
+ }
+
+ @Override
+ public void onResponse(final NativeJSObject jsObject)
+ {
+ if (this.initCheck)
+ {
+ if (getBooleanFromJSObject(jsObject, "success", false)
+ && getBooleanFromJSObject(jsObject, "value", false))
+ {
+ GeckoAppShell.sendRequestToGecko(this.cloneForRequest());
Felix Dahlke 2015/03/22 15:51:45 So.... Not entirely sure I understand what initChe
René Jeschke 2015/03/22 16:44:55 Yes, we are. onResponse() happens on the main Gec
+ }
+ else
+ {
+ this.maybeReTry();
+ }
+ }
+ else
+ {
+ if (getBooleanFromJSObject(jsObject, "success", false))
+ {
+ this.callSuccessFunction(jsObject);
+ }
+ else
+ {
+ this.callFailureFunction(jsObject);
+ }
+ }
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld