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 |
@@ -21,22 +21,27 @@ 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.URI; |
+import java.net.URISyntaxException; |
import java.net.URL; |
import java.net.URLEncoder; |
import java.util.ArrayList; |
+import java.util.Collections; |
import java.util.HashMap; |
import java.util.List; |
import java.util.Map; |
+import java.util.Set; |
+import java.util.TreeSet; |
import java.util.concurrent.LinkedBlockingQueue; |
import java.util.concurrent.TimeUnit; |
import java.util.concurrent.locks.ReentrantLock; |
import java.util.regex.Pattern; |
import org.adblockplus.adblockplussbrowser.R; |
import android.content.Context; |
@@ -72,17 +77,17 @@ public final class Engine |
public static final String USER_EXCEPTIONS_TITLE = "__exceptions"; |
public static final String ACTION_OPEN_SETTINGS = "com.samsung.android.sbrowser.contentBlocker.ACTION_SETTING"; |
public static final String ACTION_UPDATE = "com.samsung.android.sbrowser.contentBlocker.ACTION_UPDATE"; |
public static final String EASYLIST_URL = "https://easylist-downloads.adblockplus.org/easylist.txt"; |
public static final String SUBSCRIPTIONS_EXCEPTIONSURL = "subscriptions_exceptionsurl"; |
- private static final String URL_ENCODE_CHARSET = "UTF-8"; |
+ public static final String CHARSET_UTF_8 = "UTF-8"; |
private static final String PREFS_KEY_PREVIOUS_VERSION = "key_previous_version"; |
// The value below specifies an interval of [x, 2*x[, where x = |
// INITIAL_UPDATE_CHECK_DELAY_SECONDS |
private static final long INITIAL_UPDATE_CHECK_DELAY_SECONDS = 5; |
private static final long UPDATE_CHECK_INTERVAL_MINUTES = 30; |
private static final long BROADCAST_COMBINATION_DELAY_MILLIS = 2500; |
@@ -148,30 +153,30 @@ public final class Engine |
.queryIntentActivities(new Intent(ACTION_OPEN_SETTINGS), 0).size() > 0; |
} |
catch (final Throwable t) |
{ |
return false; |
} |
} |
- void requestUpdateBroadcast() |
+ public void requestUpdateBroadcast() |
{ |
this.lock(); |
try |
{ |
this.nextUpdateBroadcast = System.currentTimeMillis() + BROADCAST_COMBINATION_DELAY_MILLIS; |
} |
finally |
{ |
this.unlock(); |
} |
} |
- private void sendUpdateBroadcast() |
+ private void writeFileAndSendUpdateBroadcast() |
{ |
createAndWriteFile(); |
runOnUiThread(new Runnable() |
{ |
@Override |
public void run() |
{ |
@@ -237,23 +242,24 @@ 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 void createAndWriteFile() |
+ private void createAndWriteFile() |
{ |
this.lock(); |
try |
{ |
Log.d(TAG, "Writing filters..."); |
final File filterFile = this.subscriptions.createAndWriteFile(); |
+ writeWhitelistedWebsites(this.serviceContext, filterFile); |
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(); |
Log.d(TAG, "Cleaning up cache..."); |
final File dummyFile = getDummyFilterFile(this.serviceContext); |
final File[] cacheDirFiles = getFilterCacheDir(this.serviceContext).listFiles(); |
@@ -420,43 +426,43 @@ public final class Engine |
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.writeFileAndSendUpdateBroadcast(); |
} |
engine.handlerThread = new Thread(new EventHandler(engine)); |
engine.handlerThread.setDaemon(true); |
engine.handlerThread.start(); |
engine.downloader = Downloader.create(context, engine); |
return engine; |
} |
public static String readFileAsString(InputStream instream) throws IOException |
{ |
final StringBuilder sb = new StringBuilder(); |
- final BufferedReader r = new BufferedReader(new InputStreamReader(instream, "UTF-8")); |
+ final BufferedReader r = new BufferedReader(new InputStreamReader(instream, CHARSET_UTF_8)); |
for (int ch = r.read(); ch != -1; ch = r.read()) |
{ |
sb.append((char) ch); |
} |
return sb.toString(); |
} |
public static List<String> readLines(InputStream instream) throws IOException |
{ |
final ArrayList<String> list = new ArrayList<String>(); |
- final BufferedReader r = new BufferedReader(new InputStreamReader(instream, "UTF-8")); |
+ final BufferedReader r = new BufferedReader(new InputStreamReader(instream, CHARSET_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 |
@@ -470,17 +476,17 @@ public final class Engine |
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")); |
+ new OutputStreamWriter(new FileOutputStream(dummyFilterFile), CHARSET_UTF_8)); |
try |
{ |
writeFilterHeaders(writer); |
} |
finally |
{ |
writer.close(); |
} |
@@ -489,16 +495,52 @@ public final class Engine |
} |
public static void writeFilterHeaders(Writer writer) throws IOException |
{ |
writer.write("[Adblock Plus 2.0]\n"); |
writer.write("! This file was automatically created.\n"); |
} |
+ private static void writeWhitelistedWebsites(Context context, File filterFile) throws IOException |
+ { |
+ Log.d(TAG, "Writing whitelisted websites..."); |
+ final SharedPreferences prefs = |
+ PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); |
+ final String key = context.getString(R.string.key_whitelisted_websites); |
+ |
+ final Set<String> whitelistedWebsites = new TreeSet<String>(); |
+ whitelistedWebsites.addAll(prefs.getStringSet(key, Collections.<String>emptySet())); |
+ |
+ final BufferedWriter w = new BufferedWriter( |
+ new OutputStreamWriter(new FileOutputStream(filterFile, true), CHARSET_UTF_8)); |
+ try |
+ { |
+ for (final String url : whitelistedWebsites) |
+ { |
+ try |
+ { |
+ final URI uri = new URI(url); |
+ final String host = uri.getHost() != null ? uri.getHost() : uri.getPath(); |
+ w.write("@@||" + host + "^$document"); |
+ w.write('\n'); |
+ } |
+ catch (URISyntaxException e) |
+ { |
+ Log.w(TAG, "Failed to parse whitelisted website: " + url); |
+ continue; |
+ } |
+ } |
+ } |
+ finally |
+ { |
+ w.close(); |
+ } |
+ } |
+ |
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); |
} |
@@ -531,27 +573,27 @@ public final class Engine |
sb.append('&'); |
} |
else |
{ |
sb.append('?'); |
} |
sb.append("addonName="); |
- sb.append(URLEncoder.encode(this.appInfo.addonName, URL_ENCODE_CHARSET)); |
+ sb.append(URLEncoder.encode(this.appInfo.addonName, CHARSET_UTF_8)); |
sb.append("&addonVersion="); |
- sb.append(URLEncoder.encode(this.appInfo.addonVersion, URL_ENCODE_CHARSET)); |
+ sb.append(URLEncoder.encode(this.appInfo.addonVersion, CHARSET_UTF_8)); |
sb.append("&application="); |
- sb.append(URLEncoder.encode(this.appInfo.application, URL_ENCODE_CHARSET)); |
+ sb.append(URLEncoder.encode(this.appInfo.application, CHARSET_UTF_8)); |
sb.append("&applicationVersion="); |
- sb.append(URLEncoder.encode(this.appInfo.applicationVersion, URL_ENCODE_CHARSET)); |
+ sb.append(URLEncoder.encode(this.appInfo.applicationVersion, CHARSET_UTF_8)); |
sb.append("&platform="); |
- sb.append(URLEncoder.encode(this.appInfo.platform, URL_ENCODE_CHARSET)); |
+ sb.append(URLEncoder.encode(this.appInfo.platform, CHARSET_UTF_8)); |
sb.append("&platformVersion="); |
- sb.append(URLEncoder.encode(this.appInfo.platformVersion, URL_ENCODE_CHARSET)); |
+ sb.append(URLEncoder.encode(this.appInfo.platformVersion, CHARSET_UTF_8)); |
sb.append("&lastVersion="); |
sb.append(sub.getVersion()); |
sb.append("&downloadCount="); |
final long downloadCount = sub.getDownloadCount(); |
if (downloadCount < 5) |
{ |
sb.append(downloadCount); |
} |
@@ -621,17 +663,17 @@ public final class Engine |
this.engine.subscriptions.checkForUpdates(); |
} |
if (currentTime > this.engine.nextUpdateBroadcast) |
{ |
this.engine.nextUpdateBroadcast = Long.MAX_VALUE; |
Log.d(TAG, "Sending update broadcast"); |
- this.engine.sendUpdateBroadcast(); |
+ this.engine.writeFileAndSendUpdateBroadcast(); |
} |
} |
finally |
{ |
engine.unlock(); |
} |
} |
catch (final InterruptedException e) |