Index: src/org/adblockplus/sbrowser/contentblocker/engine/Engine.java |
=================================================================== |
--- a/src/org/adblockplus/sbrowser/contentblocker/engine/Engine.java |
+++ b/src/org/adblockplus/sbrowser/contentblocker/engine/Engine.java |
@@ -13,20 +13,24 @@ |
* |
* 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.sbrowser.contentblocker.engine; |
import java.io.BufferedReader; |
+import java.io.BufferedWriter; |
import java.io.File; |
+import java.io.FileOutputStream; |
import java.io.IOException; |
import java.io.InputStream; |
import java.io.InputStreamReader; |
+import java.io.OutputStreamWriter; |
+import java.io.Writer; |
import java.net.URL; |
import java.net.URLEncoder; |
import java.util.ArrayList; |
import java.util.HashMap; |
import java.util.List; |
import java.util.Map; |
import java.util.concurrent.LinkedBlockingQueue; |
import java.util.concurrent.TimeUnit; |
@@ -46,16 +50,18 @@ import android.os.Handler; |
import android.os.Looper; |
import android.preference.PreferenceManager; |
import android.util.Log; |
public final class Engine |
{ |
private static final String TAG = Engine.class.getSimpleName(); |
+ public static final String ABP_VERSION = "2.0"; |
Felix Dahlke
2016/09/30 07:11:41
I think we can safely hard code it (the way it was
diegocarloslima
2016/09/30 14:06:38
OK I'll revert that change
|
+ |
// TODO make use of this regex's |
public static final Pattern RE_SUBSCRIPTION_HEADER = Pattern.compile( |
"\\[Adblock(?:\\s*Plus\\s*([\\d\\.]+)?)?\\]", Pattern.CASE_INSENSITIVE); |
public static final Pattern RE_FILTER_META = Pattern.compile("^\\s*!\\s*(\\w+)\\s*:\\s*(.*)"); |
public static final Pattern RE_FILTER_ELEMHIDE = Pattern |
.compile("^([^\\/\\*\\|\\@\"!]*?)#(\\@)?(?:([\\w\\-]+|\\*)((?:\\([\\w\\-]+(?:[$^*]?=[^\\(\\)\"]*)?\\))*)|#([^{}]+))$"); |
public static final Pattern RE_FILTER_REGEXP = Pattern |
.compile("^(@@)?\\/.*\\/(?:\\$~?[\\w\\-]+(?:=[^,\\s]+)?(?:,~?[\\w\\-]+(?:=[^,\\s]+)?)*)?$"); |
@@ -159,16 +165,18 @@ public final class Engine |
finally |
{ |
this.unlock(); |
} |
} |
private void sendUpdateBroadcast() |
{ |
+ createAndWriteFile(); |
+ |
runOnUiThread(new Runnable() |
{ |
@Override |
public void run() |
{ |
final Intent intent = new Intent(); |
intent.setAction(ACTION_UPDATE); |
intent.setData(Uri.parse("package:" + Engine.this.serviceContext.getPackageName())); |
@@ -231,23 +239,32 @@ public final class Engine |
} |
void downloadFinished(final String id, final int responseCode, final String response, |
final Map<String, String> headers) |
{ |
this.engineEvents.add(new DownloadFinishedEvent(id, responseCode, response, headers)); |
} |
- public File createAndWriteFile() throws IOException |
+ public void createAndWriteFile() |
{ |
this.lock(); |
try |
{ |
Log.d(TAG, "Writing filters..."); |
- return this.subscriptions.createAndWriteFile(); |
+ final File filterFile = this.subscriptions.createAndWriteFile(); |
+ |
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.serviceContext); |
+ final String key = this.serviceContext.getString(R.string.key_cached_filter_path); |
+ prefs.edit().putString(key, filterFile.getAbsolutePath()).commit(); |
+ |
+ } |
+ catch (IOException e) |
+ { |
+ Log.e(TAG, "Failed to write filters", e); |
} |
finally |
{ |
this.unlock(); |
} |
} |
public static void runOnUiThread(final Runnable runnable) |
@@ -322,18 +339,18 @@ public final class Engine |
engine.defaultSubscriptions = DefaultSubscriptions.fromStream(subscriptionsXml); |
} |
finally |
{ |
subscriptionsXml.close(); |
} |
Log.d(TAG, "Finished reading 'subscriptions.xml'"); |
- engine.subscriptions = Subscriptions.initialize(engine, context.getFilesDir(), |
- context.getCacheDir()); |
+ engine.subscriptions = Subscriptions.initialize(engine, getSubscriptionsDir(context), |
+ getFilterCacheDir(context)); |
final InputStream prefsJson = context.getResources().openRawResource(R.raw.prefs); |
try |
{ |
engine.jsonPrefs = JSONPrefs.create(prefsJson); |
} |
finally |
{ |
@@ -388,16 +405,22 @@ public final class Engine |
engine.subscriptions.add(sub); |
} |
} |
Log.d(TAG, "Added " + additional + " additional default/built-in subscriptions"); |
engine.subscriptions.persistSubscriptions(); |
} |
+ final File cachedFilterFile = getCachedFilterFile(context); |
+ if (cachedFilterFile == null || !cachedFilterFile.exists()) |
+ { |
+ engine.sendUpdateBroadcast(); |
+ } |
+ |
engine.handlerThread = new Thread(new EventHandler(engine)); |
engine.handlerThread.setDaemon(true); |
engine.handlerThread.start(); |
engine.downloader = Downloader.create(context, engine); |
return engine; |
} |
@@ -419,16 +442,78 @@ public final class Engine |
final BufferedReader r = new BufferedReader(new InputStreamReader(instream, "UTF-8")); |
for (String line = r.readLine(); line != null; line = r.readLine()) |
{ |
list.add(line); |
} |
return list; |
} |
+ public static File getOrCreateCachedFilterFile(Context context) throws IOException |
+ { |
+ final File cachedFilterFile = getCachedFilterFile(context); |
+ if (cachedFilterFile != null && cachedFilterFile.exists()) |
+ { |
+ Log.d(TAG, "Cached filter file found: " + cachedFilterFile); |
+ return cachedFilterFile; |
+ } |
+ |
+ Log.d(TAG, "Cached filter file not found. Using dummy filter file"); |
+ final File dummyFilterFile = getDummyFilterFile(context); |
+ if (!dummyFilterFile.exists()) |
+ { |
+ Log.d(TAG, "Creating dummy filter file..."); |
+ dummyFilterFile.getParentFile().mkdirs(); |
+ final BufferedWriter writer = new BufferedWriter( |
+ new OutputStreamWriter(new FileOutputStream(dummyFilterFile), "UTF-8")); |
+ try |
+ { |
+ writeFilterHeaders(writer); |
+ } |
+ finally |
+ { |
+ writer.close(); |
+ } |
+ } |
+ return dummyFilterFile; |
+ } |
+ |
+ public static void writeFilterHeaders(Writer writer) throws IOException |
+ { |
+ writer.write("[Adblock Plus" + ABP_VERSION + "]\n"); |
Felix Dahlke
2016/09/30 07:11:41
Shouldn't there be a space between "Adblock Plus"
|
+ writer.write("! This file was automatically created.\n"); |
+ } |
+ |
+ private static File getCachedFilterFile(Context context) |
+ { |
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); |
+ final String cachedFilterPath = prefs.getString(context.getString(R.string.key_cached_filter_path), null); |
+ if (cachedFilterPath != null) |
+ { |
+ return new File(cachedFilterPath); |
+ } |
+ |
+ return null; |
+ } |
+ |
+ private static File getDummyFilterFile(Context context) |
+ { |
+ return new File(getFilterCacheDir(context), "dummy.txt"); |
+ } |
+ |
+ private static File getFilterCacheDir(Context context) |
+ { |
+ return new File(context.getCacheDir(), "subscriptions"); |
+ } |
+ |
+ private static File getSubscriptionsDir(Context context) |
+ { |
+ return new File(context.getFilesDir(), "subscriptions"); |
+ } |
+ |
URL createDownloadURL(final Subscription sub) throws IOException |
{ |
final StringBuilder sb = new StringBuilder(); |
sb.append(sub.getURL()); |
if (sub.getURL().getQuery() != null) |
{ |
sb.append('&'); |