| LEFT | RIGHT | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2015 Eyeo GmbH | 3  * Copyright (C) 2006-2015 Eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 44   private static final String TAG = "AdblockBrowser.AddOnBridge"; | 44   private static final String TAG = "AdblockBrowser.AddOnBridge"; | 
| 45   private static final String REQUEST_NAME = "AdblockPlus:Api"; | 45   private static final String REQUEST_NAME = "AdblockPlus:Api"; | 
| 46   // Handler+HandlerThread for posting delayed re-tries without interfering with | 46   // Handler+HandlerThread for posting delayed re-tries without interfering with | 
| 47   // other threads (e.g. the UI or Gecko thread) | 47   // other threads (e.g. the UI or Gecko thread) | 
| 48   private static final HandlerThread PRIVATE_HANDLER_THREAD; | 48   private static final HandlerThread PRIVATE_HANDLER_THREAD; | 
| 49   private static final Handler PRIVATE_HANDLER; | 49   private static final Handler PRIVATE_HANDLER; | 
| 50   // Global handler, for e.g. UI tasks | 50   // Global handler, for e.g. UI tasks | 
| 51   private static final HandlerThread GLOBAL_HANDLER_THREAD; | 51   private static final HandlerThread GLOBAL_HANDLER_THREAD; | 
| 52   private static final Handler GLOBAL_HANDLER; | 52   private static final Handler GLOBAL_HANDLER; | 
| 53   // Sometimes, the app is killed before the extension is able to save all chang
     es regarding | 53   // Sometimes, the app is killed before the extension is able to save all chang
     es regarding | 
| 54   // AddOnBridge requests. Given that, we need to store the uncompleted requests
      on SharedPrefs, | 54   // AddOnBridge requests. Given that, we need to store the pending requests on 
     SharedPrefs, | 
| 55   // so we can resend them to the extension once the app restarts | 55   // so we can resend them to the extension once the app restarts | 
| 56   // See https://issues.adblockplus.org/ticket/2853 | 56   // See https://issues.adblockplus.org/ticket/2853 | 
| 57   private static final AddOnEventListener ADD_ON_EVENT_LISTENER = new AddOnEvent
     Listener(); | 57   private static final AddOnEventListener ADD_ON_EVENT_LISTENER = new AddOnEvent
     Listener(); | 
| 58   private static final String ON_FILTERS_LOAD_EVENT = "Abb:OnFiltersLoad"; | 58   private static final String ON_FILTERS_LOAD_EVENT = "Abb:OnFiltersLoad"; | 
| 59   private static final String ON_FILTERS_SAVE_EVENT = "Abb:OnFiltersSave"; | 59   private static final String ON_FILTERS_SAVE_EVENT = "Abb:OnFiltersSave"; | 
| 60   private static final List<AddOnRequest> PENDING_REQUESTS = new ArrayList<>(); | 60   private static final List<AddOnRequest> PENDING_REQUESTS = new ArrayList<>(); | 
| 61   private static final String UNCOMPLETED_REQUESTS_PREFS_KEY = "UNCOMPLETED_REQU
     ESTS_PREFS_KEY"; | 61   private static final String PENDING_REQUESTS_PREFS_KEY = "PENDING_REQUESTS_PRE
     FS_KEY"; | 
| 62 | 62 | 
| 63   private static SharedPreferences sharedPrefs; | 63   private static SharedPreferences sharedPrefs; | 
| 64   private static boolean filtersLoaded; | 64   private static boolean filtersLoaded; | 
| 65 | 65 | 
| 66   static | 66   static | 
| 67   { | 67   { | 
| 68     PRIVATE_HANDLER_THREAD = new HandlerThread("abp-private-handler"); | 68     PRIVATE_HANDLER_THREAD = new HandlerThread("abp-private-handler"); | 
| 69     PRIVATE_HANDLER_THREAD.setDaemon(true); | 69     PRIVATE_HANDLER_THREAD.setDaemon(true); | 
| 70     PRIVATE_HANDLER_THREAD.start(); | 70     PRIVATE_HANDLER_THREAD.start(); | 
| 71     PRIVATE_HANDLER = new Handler(PRIVATE_HANDLER_THREAD.getLooper()); | 71     PRIVATE_HANDLER = new Handler(PRIVATE_HANDLER_THREAD.getLooper()); | 
| 72 | 72 | 
| 73     GLOBAL_HANDLER_THREAD = new HandlerThread("abp-global-handler"); | 73     GLOBAL_HANDLER_THREAD = new HandlerThread("abp-global-handler"); | 
| 74     GLOBAL_HANDLER_THREAD.setDaemon(true); | 74     GLOBAL_HANDLER_THREAD.setDaemon(true); | 
| 75     GLOBAL_HANDLER_THREAD.start(); | 75     GLOBAL_HANDLER_THREAD.start(); | 
| 76     GLOBAL_HANDLER = new Handler(GLOBAL_HANDLER_THREAD.getLooper()); | 76     GLOBAL_HANDLER = new Handler(GLOBAL_HANDLER_THREAD.getLooper()); | 
| 77   } | 77   } | 
| 78 | 78 | 
| 79   public static void init(Context context) | 79   public static void init(Context context) | 
| 80   { | 80   { | 
| 81     sharedPrefs = context.getSharedPreferences(AddOnBridge.class.getName(), Cont
     ext.MODE_PRIVATE); | 81     sharedPrefs = context.getSharedPreferences(AddOnBridge.class.getName(), Cont
     ext.MODE_PRIVATE); | 
| 82     EventDispatcher.getInstance().registerGeckoThreadListener(ADD_ON_EVENT_LISTE
     NER, ON_FILTERS_LOAD_EVENT, ON_FILTERS_SAVE_EVENT); | 82     EventDispatcher.getInstance().registerGeckoThreadListener(ADD_ON_EVENT_LISTE
     NER, ON_FILTERS_LOAD_EVENT, ON_FILTERS_SAVE_EVENT); | 
| 83     loadUncompletedRequests(); | 83     loadPendingRequests(); | 
| 84   } | 84   } | 
| 85 | 85 | 
| 86   public static void postToHandler(Runnable runnable) | 86   public static void postToHandler(Runnable runnable) | 
| 87   { | 87   { | 
| 88     GLOBAL_HANDLER.post(runnable); | 88     GLOBAL_HANDLER.post(runnable); | 
| 89   } | 89   } | 
| 90 | 90 | 
| 91   public static void postToHandlerDelayed(Runnable runnable, long delayMillis) | 91   public static void postToHandlerDelayed(Runnable runnable, long delayMillis) | 
| 92   { | 92   { | 
| 93     GLOBAL_HANDLER.postDelayed(runnable, delayMillis); | 93     GLOBAL_HANDLER.postDelayed(runnable, delayMillis); | 
| 94   } | 94   } | 
| 95 | 95 | 
| 96   private static void loadUncompletedRequests() | 96   private static void loadPendingRequests() | 
| 97   { | 97   { | 
| 98     PRIVATE_HANDLER.post(new Runnable() | 98     PRIVATE_HANDLER.post(new Runnable() | 
| 99     { | 99     { | 
| 100       @Override | 100       @Override | 
| 101       public void run() | 101       public void run() | 
| 102       { | 102       { | 
| 103         final String jsonString = sharedPrefs.getString(UNCOMPLETED_REQUESTS_PRE
     FS_KEY, null); | 103         final String jsonString = sharedPrefs.getString(PENDING_REQUESTS_PREFS_K
     EY, null); | 
| 104         PENDING_REQUESTS.addAll(0, jsonStringToRequestList(jsonString)); | 104         PENDING_REQUESTS.addAll(0, jsonStringToRequestList(jsonString)); | 
| 105       } | 105       } | 
| 106     }); | 106     }); | 
| 107   } | 107   } | 
| 108 | 108 | 
| 109   private static void sendOrEnqueueRequest(final AddOnRequest request) | 109   private static void sendOrEnqueueRequest(final AddOnRequest request) | 
| 110   { | 110   { | 
| 111     PRIVATE_HANDLER.post(new Runnable() | 111     PRIVATE_HANDLER.post(new Runnable() | 
| 112     { | 112     { | 
| 113       @Override | 113       @Override | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 134       { | 134       { | 
| 135         for (final AddOnRequest request : PENDING_REQUESTS) | 135         for (final AddOnRequest request : PENDING_REQUESTS) | 
| 136         { | 136         { | 
| 137           GeckoAppShell.sendRequestToGecko(request); | 137           GeckoAppShell.sendRequestToGecko(request); | 
| 138         } | 138         } | 
| 139         PENDING_REQUESTS.clear(); | 139         PENDING_REQUESTS.clear(); | 
| 140       } | 140       } | 
| 141     }); | 141     }); | 
| 142   } | 142   } | 
| 143 | 143 | 
| 144   private static void clearUncompletedRequests() | 144   private static void clearPendingRequests() | 
| 145   { | 145   { | 
| 146     PRIVATE_HANDLER.post(new Runnable() | 146     PRIVATE_HANDLER.post(new Runnable() | 
| 147     { | 147     { | 
| 148       @Override | 148       @Override | 
| 149       public void run() | 149       public void run() | 
| 150       { | 150       { | 
| 151         storeStringPref(UNCOMPLETED_REQUESTS_PREFS_KEY, null); | 151         storeStringPref(PENDING_REQUESTS_PREFS_KEY, null); | 
| 152       } | 152       } | 
| 153     }); | 153     }); | 
| 154   } | 154   } | 
| 155 | 155 | 
| 156   private static void storeUncompletedRequest(final AddOnRequest request) | 156   private static void storePendingRequest(final AddOnRequest request) | 
| 157   { | 157   { | 
| 158     PRIVATE_HANDLER.post(new Runnable() | 158     PRIVATE_HANDLER.post(new Runnable() | 
| 159     { | 159     { | 
| 160       @Override | 160       @Override | 
| 161       public void run() | 161       public void run() | 
| 162       { | 162       { | 
| 163         final String jsonString = sharedPrefs.getString(UNCOMPLETED_REQUESTS_PRE
     FS_KEY, null); | 163         final String jsonString = sharedPrefs.getString(PENDING_REQUESTS_PREFS_K
     EY, null); | 
| 164         try | 164         try | 
| 165         { | 165         { | 
| 166           final JSONArray jsonArray = jsonString != null ? new JSONArray(jsonStr
     ing) : new JSONArray(); | 166           final JSONArray jsonArray = jsonString != null ? new JSONArray(jsonStr
     ing) : new JSONArray(); | 
| 167           jsonArray.put(request.value); | 167           jsonArray.put(request.value); | 
| 168           storeStringPref(UNCOMPLETED_REQUESTS_PREFS_KEY, jsonArray.toString()); | 168           storeStringPref(PENDING_REQUESTS_PREFS_KEY, jsonArray.toString()); | 
| 169         } | 169         } | 
| 170         catch (JSONException e) | 170         catch (JSONException e) | 
| 171         { | 171         { | 
| 172           Log.e(TAG, "Failed to store uncompleted request with error: " + e.getM
     essage(), e); | 172           Log.e(TAG, "Failed to store pending request with error: " + e.getMessa
     ge(), e); | 
| 173         } | 173         } | 
| 174       } | 174       } | 
| 175     }); | 175     }); | 
| 176   } | 176   } | 
| 177 | 177 | 
| 178   private static List<AddOnRequest> jsonStringToRequestList(final String jsonStr
     ing) | 178   private static List<AddOnRequest> jsonStringToRequestList(final String jsonStr
     ing) | 
| 179   { | 179   { | 
| 180     final List<AddOnRequest> requestList = new ArrayList<>(); | 180     final List<AddOnRequest> requestList = new ArrayList<>(); | 
| 181     if (jsonString == null) | 181     if (jsonString == null) | 
| 182     { | 182     { | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 278     sendOrEnqueueRequest(request); | 278     sendOrEnqueueRequest(request); | 
| 279   } | 279   } | 
| 280 | 280 | 
| 281   public static void setBoolean(final AdblockPlusApiCallback callback, final Str
     ing name, | 281   public static void setBoolean(final AdblockPlusApiCallback callback, final Str
     ing name, | 
| 282       final boolean enable) | 282       final boolean enable) | 
| 283   { | 283   { | 
| 284     Log.d(TAG, "setBoolean " + enable + " for " + name); | 284     Log.d(TAG, "setBoolean " + enable + " for " + name); | 
| 285     final AddOnRequest request = | 285     final AddOnRequest request = | 
| 286         new AddOnRequest(createRequestData("set" + makeFirstCharacterUppercase(n
     ame), enable), callback); | 286         new AddOnRequest(createRequestData("set" + makeFirstCharacterUppercase(n
     ame), enable), callback); | 
| 287     sendOrEnqueueRequest(request); | 287     sendOrEnqueueRequest(request); | 
| 288     storeUncompletedRequest(request); | 288     storePendingRequest(request); | 
| 289   } | 289   } | 
| 290 | 290 | 
| 291   private static void callFunction(final AdblockPlusApiCallback callback, final 
     String name, | 291   private static void callFunction(final AdblockPlusApiCallback callback, final 
     String name, | 
| 292       final Map<String, Object> parameters) | 292       final Map<String, Object> parameters) | 
| 293   { | 293   { | 
| 294     // By default, requests are not stored on the uncompleted request prefs. Thi
     s should apply for | 294     // By default, requests are not stored on the pending request prefs. This sh
     ould apply for | 
| 295     // requests that doesn't result in save operations performed by the extensio
     n | 295     // requests that doesn't result in save operations performed by the extensio
     n | 
| 296     callFunction(callback, name, parameters, false); | 296     callFunction(callback, name, parameters, false); | 
| 297   } | 297   } | 
| 298 | 298 | 
| 299   private static void callFunction(final AdblockPlusApiCallback callback, final 
     String name, | 299   private static void callFunction(final AdblockPlusApiCallback callback, final 
     String name, | 
| 300       final Map<String, Object> parameters, boolean resendIfAborted) | 300       final Map<String, Object> parameters, boolean resendIfAborted) | 
| 301   { | 301   { | 
| 302     final JSONObject requestData = createRequestData(name); | 302     final JSONObject requestData = createRequestData(name); | 
| 303     try | 303     try | 
| 304     { | 304     { | 
| 305       for (Map.Entry<String, Object> entry : parameters.entrySet()) | 305       for (Map.Entry<String, Object> entry : parameters.entrySet()) | 
| 306       { | 306       { | 
| 307         requestData.put(entry.getKey(), entry.getValue()); | 307         requestData.put(entry.getKey(), entry.getValue()); | 
| 308       } | 308       } | 
| 309     } | 309     } | 
| 310     catch (JSONException e) | 310     catch (JSONException e) | 
| 311     { | 311     { | 
| 312       // we're only adding sane objects | 312       // we're only adding sane objects | 
| 313       Log.e(TAG, "Creating request data failed with: " + e.getMessage(), e); | 313       Log.e(TAG, "Creating request data failed with: " + e.getMessage(), e); | 
| 314     } | 314     } | 
| 315     final AddOnRequest request = new AddOnRequest(requestData, callback); | 315     final AddOnRequest request = new AddOnRequest(requestData, callback); | 
| 316     sendOrEnqueueRequest(request); | 316     sendOrEnqueueRequest(request); | 
| 317     if (resendIfAborted) | 317     if (resendIfAborted) | 
| 318     { | 318     { | 
| 319       storeUncompletedRequest(request); | 319       storePendingRequest(request); | 
| 320     } | 320     } | 
| 321   } | 321   } | 
| 322 | 322 | 
| 323   public static void querySubscriptionListStatus(final AdblockPlusApiCallback ca
     llback, | 323   public static void querySubscriptionListStatus(final AdblockPlusApiCallback ca
     llback, | 
| 324       final String url) | 324       final String url) | 
| 325   { | 325   { | 
| 326     Log.d(TAG, "querySubscriptionListStatus for " + url); | 326     Log.d(TAG, "querySubscriptionListStatus for " + url); | 
| 327     final Map<String, Object> parameters = new HashMap<String, Object>(); | 327     final Map<String, Object> parameters = new HashMap<String, Object>(); | 
| 328     parameters.put("url", url); | 328     parameters.put("url", url); | 
| 329     callFunction(callback, "isSubscriptionListed", parameters); | 329     callFunction(callback, "isSubscriptionListed", parameters); | 
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 455     { | 455     { | 
| 456       if (ON_FILTERS_LOAD_EVENT.equals(event)) | 456       if (ON_FILTERS_LOAD_EVENT.equals(event)) | 
| 457       { | 457       { | 
| 458         // The filters have been loaded by the extension. Given that, we can sen
     d all pending requests | 458         // The filters have been loaded by the extension. Given that, we can sen
     d all pending requests | 
| 459         filtersLoaded = true; | 459         filtersLoaded = true; | 
| 460         sendPendingRequests(); | 460         sendPendingRequests(); | 
| 461       } | 461       } | 
| 462       else if (ON_FILTERS_SAVE_EVENT.equals(event)) | 462       else if (ON_FILTERS_SAVE_EVENT.equals(event)) | 
| 463       { | 463       { | 
| 464         // All changes have been saved by the extension. That way, we can clear 
     our list of | 464         // All changes have been saved by the extension. That way, we can clear 
     our list of | 
| 465         // uncompleted requests | 465         // pending requests | 
| 466         // See https://issues.adblockplus.org/ticket/2853 | 466         // See https://issues.adblockplus.org/ticket/2853 | 
| 467         clearUncompletedRequests(); | 467         clearPendingRequests(); | 
| 468       } | 468       } | 
| 469     } | 469     } | 
| 470   } | 470   } | 
| 471 } | 471 } | 
| LEFT | RIGHT | 
|---|