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

Delta Between Two Patch Sets: adblockplussbrowser/src/org/adblockplus/sbrowser/contentblocker/engine/Engine.java

Issue 29445587: Issue 5223 - App is freezing sometimes (Closed)
Left Patch Set: Created May 22, 2017, 10:04 a.m.
Right Patch Set: Fixed formatting and set dialog = null Created June 26, 2017, 2:04 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
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-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 package org.adblockplus.sbrowser.contentblocker.engine; 18 package org.adblockplus.sbrowser.contentblocker.engine;
19
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.SharedPreferences;
23 import android.content.pm.PackageInfo;
24 import android.content.pm.PackageManager;
25 import android.content.pm.ResolveInfo;
26 import android.net.ConnectivityManager;
27 import android.net.NetworkInfo;
28 import android.net.Uri;
29 import android.os.AsyncTask;
30 import android.os.Handler;
31 import android.os.Looper;
32 import android.preference.PreferenceManager;
33 import android.text.TextUtils;
34 import android.util.Log;
35
36 import org.adblockplus.adblockplussbrowser.R;
37 19
38 import java.io.BufferedReader; 20 import java.io.BufferedReader;
39 import java.io.BufferedWriter; 21 import java.io.BufferedWriter;
40 import java.io.File; 22 import java.io.File;
41 import java.io.FileOutputStream; 23 import java.io.FileOutputStream;
42 import java.io.IOException; 24 import java.io.IOException;
43 import java.io.InputStream; 25 import java.io.InputStream;
44 import java.io.InputStreamReader; 26 import java.io.InputStreamReader;
45 import java.io.OutputStreamWriter; 27 import java.io.OutputStreamWriter;
46 import java.io.Writer; 28 import java.io.Writer;
47 import java.net.URI; 29 import java.net.URI;
48 import java.net.URISyntaxException; 30 import java.net.URISyntaxException;
49 import java.net.URL; 31 import java.net.URL;
50 import java.net.URLEncoder; 32 import java.net.URLEncoder;
51 import java.util.ArrayList; 33 import java.util.ArrayList;
52 import java.util.Collections; 34 import java.util.Collections;
53 import java.util.HashMap; 35 import java.util.HashMap;
54 import java.util.List; 36 import java.util.List;
55 import java.util.Map; 37 import java.util.Map;
56 import java.util.Set; 38 import java.util.Set;
57 import java.util.TreeSet; 39 import java.util.TreeSet;
58 import java.util.concurrent.LinkedBlockingQueue; 40 import java.util.concurrent.LinkedBlockingQueue;
59 import java.util.concurrent.TimeUnit; 41 import java.util.concurrent.TimeUnit;
60 import java.util.concurrent.locks.ReentrantLock; 42 import java.util.concurrent.locks.ReentrantLock;
61 import java.util.regex.Pattern; 43 import java.util.regex.Pattern;
62 44
45 import org.adblockplus.adblockplussbrowser.R;
46
47 import android.content.Context;
48 import android.content.Intent;
49 import android.content.SharedPreferences;
50 import android.content.pm.PackageInfo;
51 import android.content.pm.PackageManager;
52 import android.content.pm.ResolveInfo;
53 import android.net.ConnectivityManager;
54 import android.net.NetworkInfo;
55 import android.net.Uri;
56 import android.os.Handler;
57 import android.os.Looper;
58 import android.preference.PreferenceManager;
59 import android.text.TextUtils;
60 import android.util.Log;
61
63 public final class Engine 62 public final class Engine
64 { 63 {
65 private static final String TAG = Engine.class.getSimpleName(); 64 private static final String TAG = Engine.class.getSimpleName();
66 65
67 // TODO make use of this regex's 66 // TODO make use of this regex's
68 public static final Pattern RE_SUBSCRIPTION_HEADER = Pattern.compile( 67 public static final Pattern RE_SUBSCRIPTION_HEADER = Pattern.compile(
69 "\\[Adblock(?:\\s*Plus\\s*([\\d\\.]+)?)?\\]", Pattern.CASE_INSENSITIVE); 68 "\\[Adblock(?:\\s*Plus\\s*([\\d\\.]+)?)?\\]", Pattern.CASE_INSENSITIVE);
70 public static final Pattern RE_FILTER_META = Pattern.compile("^\\s*!\\s*(\\w+) \\s*:\\s*(.*)"); 69 public static final Pattern RE_FILTER_META = Pattern.compile("^\\s*!\\s*(\\w+) \\s*:\\s*(.*)");
71 public static final Pattern RE_FILTER_ELEMHIDE = Pattern 70 public static final Pattern RE_FILTER_ELEMHIDE = Pattern
72 .compile("^([^\\/\\*\\|\\@\"!]*?)#(\\@)?(?:([\\w\\-]+|\\*)((?:\\([\\w\\-]+ (?:[$^*]?=[^\\(\\)\"]*)?\\))*)|#([^{}]+))$"); 71 .compile("^([^\\/\\*\\|\\@\"!]*?)#(\\@)?(?:([\\w\\-]+|\\*)((?:\\([\\w\\-]+ (?:[$^*]?=[^\\(\\)\"]*)?\\))*)|#([^{}]+))$");
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 private static final int OLDEST_SAMSUNG_INTERNET_5_VERSIONCODE = 500000000; 104 private static final int OLDEST_SAMSUNG_INTERNET_5_VERSIONCODE = 500000000;
106 105
107 private final ReentrantLock accessLock = new ReentrantLock(); 106 private final ReentrantLock accessLock = new ReentrantLock();
108 private DefaultSubscriptions defaultSubscriptions; 107 private DefaultSubscriptions defaultSubscriptions;
109 private Subscriptions subscriptions; 108 private Subscriptions subscriptions;
110 private JSONPrefs jsonPrefs; 109 private JSONPrefs jsonPrefs;
111 private AppInfo appInfo; 110 private AppInfo appInfo;
112 private LinkedBlockingQueue<EngineEvent> engineEvents = new LinkedBlockingQueu e<EngineEvent>(); 111 private LinkedBlockingQueue<EngineEvent> engineEvents = new LinkedBlockingQueu e<EngineEvent>();
113 private Thread handlerThread; 112 private Thread handlerThread;
114 private Downloader downloader; 113 private Downloader downloader;
114 private SubscriptionUpdateCallback subscriptionUpdateCallback;
115 private final Context serviceContext; 115 private final Context serviceContext;
116 private boolean wasFirstRun = false; 116 private boolean wasFirstRun = false;
117 private long nextUpdateBroadcast = Long.MAX_VALUE; 117 private long nextUpdateBroadcast = Long.MAX_VALUE;
118 118
119 private Engine(final Context context) 119 private Engine(final Context context)
120 { 120 {
121 this.serviceContext = context; 121 this.serviceContext = context;
122 } 122 }
123 123
124 public String getPrefsDefault(final String key) 124 public String getPrefsDefault(final String key)
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } 182 }
183 catch (PackageManager.NameNotFoundException e) 183 catch (PackageManager.NameNotFoundException e)
184 { 184 {
185 // Should never happen, as checkAAStatusAndProceed() should not be called if the user 185 // Should never happen, as checkAAStatusAndProceed() should not be called if the user
186 // has no compatible SBrowser installed. Nevertheless we have to handle th e Exception. 186 // has no compatible SBrowser installed. Nevertheless we have to handle th e Exception.
187 Log.d(TAG, "No compatible Samsung Browser found.", e); 187 Log.d(TAG, "No compatible Samsung Browser found.", e);
188 return false; 188 return false;
189 } 189 }
190 } 190 }
191 191
192 public void setSubscriptionUpdateCallback(final SubscriptionUpdateCallback sub scriptionUpdateCallback)
193 {
194 this.subscriptionUpdateCallback = subscriptionUpdateCallback;
195 }
196
192 public void requestUpdateBroadcast() 197 public void requestUpdateBroadcast()
193 { 198 {
194 this.lock(); 199 this.nextUpdateBroadcast = System.currentTimeMillis() + BROADCAST_COMBINATIO N_DELAY_MILLIS;
195 try
196 {
197 this.nextUpdateBroadcast = System.currentTimeMillis() + BROADCAST_COMBINAT ION_DELAY_MILLIS;
198 }
199 finally
200 {
201 this.unlock();
202 }
203 } 200 }
204 201
205 private void writeFileAndSendUpdateBroadcast() 202 private void writeFileAndSendUpdateBroadcast()
206 { 203 {
207 createAndWriteFile(); 204 createAndWriteFile();
208 205
209 runOnUiThread(new Runnable() 206 runOnUiThread(new Runnable()
210 { 207 {
211 @Override 208 @Override
212 public void run() 209 public void run()
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 return false; 246 return false;
250 } 247 }
251 } 248 }
252 return false; 249 return false;
253 } 250 }
254 return current.isConnected(); 251 return current.isConnected();
255 } 252 }
256 253
257 public List<SubscriptionInfo> getListedSubscriptions() 254 public List<SubscriptionInfo> getListedSubscriptions()
258 { 255 {
256 return this.subscriptions.getSubscriptions(this);
257 }
258
259 public void changeSubscriptionState(final String id, final boolean enabled)
260 {
261 if (this.subscriptionUpdateCallback != null)
262 {
263 this.subscriptionUpdateCallback.subscriptionUpdateRequested(enabled);
264 }
265 this.engineEvents.add(new ChangeEnabledStateEvent(id, enabled));
266 }
267
268 public void subscriptionStateChanged() {
anton 2017/06/26 14:45:54 "{" should be on the next line. LGTM in general
269 if (this.subscriptionUpdateCallback != null)
270 {
271 this.subscriptionUpdateCallback.subscriptionUpdatedApplied();
272 }
273 }
274
275 void downloadFinished(final String id, final int responseCode, final String re sponse,
276 final Map<String, String> headers)
277 {
278 this.engineEvents.add(new DownloadFinishedEvent(id, responseCode, response, headers));
279 }
280
281 private void createAndWriteFile()
282 {
259 this.lock(); 283 this.lock();
260 try 284 try
261 { 285 {
262 return this.subscriptions.getSubscriptions(this); 286 Log.d(TAG, "Writing filters...");
287 final File filterFile = this.subscriptions.createAndWriteFile();
288 writeWhitelistedWebsites(this.serviceContext, filterFile);
289
290 final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferen ces(this.serviceContext);
291 final String key = this.serviceContext.getString(R.string.key_cached_filte r_path);
292 prefs.edit().putString(key, filterFile.getAbsolutePath()).commit();
293
294 Log.d(TAG, "Cleaning up cache...");
295 final File dummyFile = getDummyFilterFile(this.serviceContext);
296 final File[] cacheDirFiles = getFilterCacheDir(this.serviceContext).listFi les();
297 if (cacheDirFiles != null)
298 {
299 for (final File file : cacheDirFiles)
300 {
301 if (!file.equals(dummyFile) && !file.equals(filterFile))
302 {
303 Log.d(TAG, "Deleting file:" + file);
304 file.delete();
305 }
306 }
307 }
308 }
309 catch (IOException e)
310 {
311 Log.e(TAG, "Failed to write filters", e);
263 } 312 }
264 finally 313 finally
265 { 314 {
266 this.unlock(); 315 this.unlock();
267 } 316 }
268 }
269
270 public void changeSubscriptionState(final String id, final boolean enabled)
271 {
272 this.engineEvents.add(new ChangeEnabledStateEvent(id, enabled));
273 }
274
275 void downloadFinished(final String id, final int responseCode, final String re sponse,
276 final Map<String, String> headers)
277 {
278 this.engineEvents.add(new DownloadFinishedEvent(id, responseCode, response, headers));
279 }
280
281 private void createAndWriteFile()
282 {
283 new CreateAndWriteFileAsyncTask().execute(serviceContext, subscriptions);
diegocarloslima 2017/05/25 21:20:45 I might be wrong, but it seems that the freezing i
jens 2017/06/01 15:32:08 Acknowledged.
284 } 317 }
285 318
286 public static void runOnUiThread(final Runnable runnable) 319 public static void runOnUiThread(final Runnable runnable)
287 { 320 {
288 new Handler(Looper.getMainLooper()).post(runnable); 321 new Handler(Looper.getMainLooper()).post(runnable);
289 } 322 }
290 323
291 public boolean isAcceptableAdsEnabled() 324 public boolean isAcceptableAdsEnabled()
292 { 325 {
293 this.lock(); 326 this.lock();
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 Log.d(TAG, headers.toString()); 800 Log.d(TAG, headers.toString());
768 this.downloader.enqueueDownload(this.createDownloadURL(sub), sub.getId(), headers); 801 this.downloader.enqueueDownload(this.createDownloadURL(sub), sub.getId(), headers);
769 } 802 }
770 } 803 }
771 804
772 public void connectivityChanged() 805 public void connectivityChanged()
773 { 806 {
774 this.downloader.connectivityChanged(); 807 this.downloader.connectivityChanged();
775 } 808 }
776 809
777 private static class CreateAndWriteFileAsyncTask extends AsyncTask<Object, Voi d, Void> 810 public interface SubscriptionUpdateCallback
778 { 811 {
779 private static final String TAG = CreateAndWriteFileAsyncTask.class.getSimpl eName(); 812 void subscriptionUpdateRequested(boolean enabled);
780 813 void subscriptionUpdatedApplied();
781 @Override
782 protected Void doInBackground(Object... params)
783 {
784 final Context serviceContext = (Context) params[0];
785 final Subscriptions subscriptions = (Subscriptions) params[1];
786
787 createAndWriteFile(serviceContext, subscriptions);
788 return null;
789 }
790
791 private void createAndWriteFile(Context serviceContext, Subscriptions subscr iptions)
792 {
793 try
794 {
795 Log.d(TAG, "Writing filters...");
796 final File filterFile = subscriptions.createAndWriteFile();
797 writeWhitelistedWebsites(serviceContext, filterFile);
798
799 final SharedPreferences prefs = PreferenceManager.getDefaultSharedPrefer ences(serviceContext);
800 final String key = serviceContext.getString(R.string.key_cached_filter_p ath);
801 prefs.edit().putString(key, filterFile.getAbsolutePath()).commit();
802
803 Log.d(TAG, "Cleaning up cache...");
804 final File dummyFile = getDummyFilterFile(serviceContext);
805 final File[] cacheDirFiles = getFilterCacheDir(serviceContext).listFiles ();
806 if (cacheDirFiles != null)
807 {
808 for (final File file : cacheDirFiles)
809 {
810 if (!file.equals(dummyFile) && !file.equals(filterFile))
811 {
812 Log.d(TAG, "Deleting file:" + file);
813 file.delete();
814 }
815 }
816 }
817 }
818 catch (IOException e)
819 {
820 Log.e(TAG, "Failed to write filters", e);
821 }
822 }
823
824 private void writeWhitelistedWebsites(Context context, File filterFile) thro ws IOException
825 {
826 Log.d(TAG, "Writing whitelisted websites...");
827 final SharedPreferences prefs =
828 PreferenceManager.getDefaultSharedPreferences(context.getApplicationCo ntext());
829 final String key = context.getString(R.string.key_whitelisted_websites);
830
831 final Set<String> whitelistedWebsites = new TreeSet<>();
832 whitelistedWebsites.addAll(prefs.getStringSet(key, Collections.<String>emp tySet()));
833
834 try (BufferedWriter w = new BufferedWriter(
835 new OutputStreamWriter(new FileOutputStream(filterFile, true), Engine. CHARSET_UTF_8))) {
836 for (final String url : whitelistedWebsites) {
837 try {
838 final URI uri = new URI(url);
839 final String host = uri.getHost() != null ? uri.getHost() : uri.getP ath();
840 w.write("@@||" + host + "^$document");
841 w.write('\n');
842 } catch (URISyntaxException e) {
843 Log.w(TAG, "Failed to parse whitelisted website: " + url);
844 }
845 }
846 }
847 }
848
849 private static File getDummyFilterFile(Context context)
850 {
851 return new File(getFilterCacheDir(context), "dummy.txt");
852 }
853
854 private static File getFilterCacheDir(Context context)
855 {
856 return new File(context.getCacheDir(), "subscriptions");
857 }
858 } 814 }
859 } 815 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld