| Left: | ||
| Right: | 
| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * This file is part of Adblock Plus <http://adblockplus.org/>, | 2 * This file is part of Adblock Plus <http://adblockplus.org/>, | 
| 3 * Copyright (C) 2006-2014 Eyeo GmbH | 3 * Copyright (C) 2006-2014 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 15 matching lines...) Expand all Loading... | |
| 26 import java.util.ArrayList; | 26 import java.util.ArrayList; | 
| 27 import java.util.Calendar; | 27 import java.util.Calendar; | 
| 28 import java.util.LinkedHashMap; | 28 import java.util.LinkedHashMap; | 
| 29 import java.util.List; | 29 import java.util.List; | 
| 30 import java.util.Map; | 30 import java.util.Map; | 
| 31 import java.util.TimeZone; | 31 import java.util.TimeZone; | 
| 32 import java.util.regex.Pattern; | 32 import java.util.regex.Pattern; | 
| 33 | 33 | 
| 34 import org.adblockplus.android.updater.AlarmReceiver; | 34 import org.adblockplus.android.updater.AlarmReceiver; | 
| 35 | 35 | 
| 36 import com.github.rjeschke.neetutils.Strings; | |
| 37 | |
| 36 import android.app.ActivityManager; | 38 import android.app.ActivityManager; | 
| 37 import android.app.ActivityManager.RunningServiceInfo; | 39 import android.app.ActivityManager.RunningServiceInfo; | 
| 38 import android.app.AlarmManager; | 40 import android.app.AlarmManager; | 
| 39 import android.app.Application; | 41 import android.app.Application; | 
| 40 import android.app.PendingIntent; | 42 import android.app.PendingIntent; | 
| 41 import android.content.Context; | 43 import android.content.Context; | 
| 42 import android.content.Intent; | 44 import android.content.Intent; | 
| 43 import android.content.SharedPreferences; | 45 import android.content.SharedPreferences; | 
| 44 import android.content.SharedPreferences.Editor; | 46 import android.content.SharedPreferences.Editor; | 
| 45 import android.content.pm.PackageInfo; | 47 import android.content.pm.PackageInfo; | 
| 46 import android.content.pm.PackageManager; | 48 import android.content.pm.PackageManager; | 
| 47 import android.content.pm.PackageManager.NameNotFoundException; | 49 import android.content.pm.PackageManager.NameNotFoundException; | 
| 48 import android.net.ConnectivityManager; | 50 import android.net.ConnectivityManager; | 
| 49 import android.net.NetworkInfo; | 51 import android.net.NetworkInfo; | 
| 50 import android.net.Uri; | 52 import android.net.Uri; | 
| 51 import android.os.Build; | 53 import android.os.Build; | 
| 52 import android.preference.PreferenceManager; | 54 import android.preference.PreferenceManager; | 
| 53 import android.provider.Settings; | 55 import android.provider.Settings; | 
| 54 import android.util.Log; | 56 import android.util.Log; | 
| 55 | 57 | 
| 56 public class AdblockPlus extends Application | 58 public class AdblockPlus extends Application | 
| 57 { | 59 { | 
| 58 private final static String TAG = "Application"; | 60 private final static String TAG = Utils.getTag(AdblockPlus.class); | 
| 59 | 61 | 
| 60 private final static Pattern RE_JS = Pattern.compile(".*\\.js$", Pattern.CASE_ INSENSITIVE); | 62 private final static Pattern RE_JS = Pattern.compile(".*\\.js$", Pattern.CASE_ INSENSITIVE); | 
| 61 private final static Pattern RE_CSS = Pattern.compile(".*\\.css$", Pattern.CAS E_INSENSITIVE); | 63 private final static Pattern RE_CSS = Pattern.compile(".*\\.css$", Pattern.CAS E_INSENSITIVE); | 
| 62 private final static Pattern RE_IMAGE = Pattern.compile(".*\\.(?:gif|png|jpe?g |bmp|ico)$", Pattern.CASE_INSENSITIVE); | 64 private final static Pattern RE_IMAGE = Pattern.compile(".*\\.(?:gif|png|jpe?g |bmp|ico)$", Pattern.CASE_INSENSITIVE); | 
| 63 private final static Pattern RE_FONT = Pattern.compile(".*\\.(?:ttf|woff)$", P attern.CASE_INSENSITIVE); | 65 private final static Pattern RE_FONT = Pattern.compile(".*\\.(?:ttf|woff)$", P attern.CASE_INSENSITIVE); | 
| 64 private final static Pattern RE_HTML = Pattern.compile(".*\\.html?$", Pattern. CASE_INSENSITIVE); | 66 private final static Pattern RE_HTML = Pattern.compile(".*\\.html?$", Pattern. CASE_INSENSITIVE); | 
| 65 | 67 | 
| 66 /** | 68 /** | 
| 69 * Update notification id. | |
| 70 */ | |
| 71 public final static int UPDATE_NOTIFICATION_ID = R.string.app_name + 1; | |
| 
 
Felix Dahlke
2014/04/16 15:24:25
Should be "static final", not "final" static, acco
 
René Jeschke
2014/04/16 17:51:47
Done.
 
 | |
| 72 /** | |
| 67 * Broadcasted when filtering is enabled or disabled. | 73 * Broadcasted when filtering is enabled or disabled. | 
| 68 */ | 74 */ | 
| 69 public static final String BROADCAST_FILTERING_CHANGE = "org.adblockplus.andro id.filtering.status"; | 75 public final static String BROADCAST_FILTERING_CHANGE = "org.adblockplus.andro id.filtering.status"; | 
| 70 /** | 76 /** | 
| 71 * Broadcasted when subscription status changes. | 77 * Broadcasted when subscription status changes. | 
| 72 */ | 78 */ | 
| 73 public final static String BROADCAST_SUBSCRIPTION_STATUS = "org.adblockplus.an droid.subscription.status"; | 79 public final static String BROADCAST_SUBSCRIPTION_STATUS = "org.adblockplus.an droid.subscription.status"; | 
| 74 /** | 80 /** | 
| 75 * Broadcasted when filter match check is performed. | 81 * Broadcasted when filter match check is performed. | 
| 76 */ | 82 */ | 
| 77 public final static String BROADCAST_FILTER_MATCHES = "org.adblockplus.android .filter.matches"; | 83 public final static String BROADCAST_FILTER_MATCHES = "org.adblockplus.android .filter.matches"; | 
| 78 | |
| 79 /** | 84 /** | 
| 80 * Cached list of recommended subscriptions. | 85 * Cached list of recommended subscriptions. | 
| 81 */ | 86 */ | 
| 82 private Subscription[] subscriptions; | 87 private Subscription[] subscriptions; | 
| 83 | |
| 84 /** | 88 /** | 
| 85 * Indicates whether filtering is enabled or not. | 89 * Indicates whether filtering is enabled or not. | 
| 86 */ | 90 */ | 
| 87 private boolean filteringEnabled = false; | 91 private boolean filteringEnabled = false; | 
| 88 | 92 | 
| 89 private ABPEngine abpEngine; | 93 private ABPEngine abpEngine; | 
| 90 | 94 | 
| 91 private static AdblockPlus instance; | 95 private static AdblockPlus instance; | 
| 92 | 96 | 
| 93 private static class ReferrerMappingCache extends LinkedHashMap<String, String > | 97 private static class ReferrerMappingCache extends LinkedHashMap<String, String > | 
| 94 { | 98 { | 
| 95 private static final long serialVersionUID = 1L; | 99 private final static long serialVersionUID = 1L; | 
| 96 private static final int MAX_SIZE = 5000; | 100 private final static int MAX_SIZE = 5000; | 
| 97 | 101 | 
| 98 public ReferrerMappingCache() | 102 public ReferrerMappingCache() | 
| 99 { | 103 { | 
| 100 super(MAX_SIZE + 1, 0.75f, true); | 104 super(MAX_SIZE + 1, 0.75f, true); | 
| 101 } | 105 } | 
| 102 | 106 | 
| 103 @Override | 107 @Override | 
| 104 protected boolean removeEldestEntry(Map.Entry<String, String> eldest) | 108 protected boolean removeEldestEntry(final Map.Entry<String, String> eldest) | 
| 105 { | 109 { | 
| 106 return size() > MAX_SIZE; | 110 return this.size() > MAX_SIZE; | 
| 
 
Felix Dahlke
2014/04/16 15:24:25
Same as in other files, also below.
 
René Jeschke
2014/04/16 17:51:47
Done.
 
 | |
| 107 } | 111 } | 
| 108 }; | 112 }; | 
| 109 | 113 | 
| 110 private ReferrerMappingCache referrerMapping = new ReferrerMappingCache(); | 114 private final ReferrerMappingCache referrerMapping = new ReferrerMappingCache( ); | 
| 111 | 115 | 
| 112 /** | 116 /** | 
| 113 * Returns pointer to itself (singleton pattern). | 117 * Returns pointer to itself (singleton pattern). | 
| 114 */ | 118 */ | 
| 115 public static AdblockPlus getApplication() | 119 public static AdblockPlus getApplication() | 
| 116 { | 120 { | 
| 117 return instance; | 121 return instance; | 
| 118 } | 122 } | 
| 119 | 123 | 
| 120 public int getBuildNumber() | 124 public int getBuildNumber() | 
| 121 { | 125 { | 
| 122 int buildNumber = -1; | 126 int buildNumber = -1; | 
| 123 try | 127 try | 
| 124 { | 128 { | 
| 125 PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0); | 129 final PackageInfo pi = this.getPackageManager().getPackageInfo(this.getPac kageName(), 0); | 
| 126 buildNumber = pi.versionCode; | 130 buildNumber = pi.versionCode; | 
| 127 } | 131 } | 
| 128 catch (NameNotFoundException e) | 132 catch (final NameNotFoundException e) | 
| 129 { | 133 { | 
| 130 // ignore - this shouldn't happen | 134 // ignore - this shouldn't happen | 
| 131 Log.e(TAG, e.getMessage(), e); | 135 Log.e(TAG, e.getMessage(), e); | 
| 132 } | 136 } | 
| 133 return buildNumber; | 137 return buildNumber; | 
| 134 } | 138 } | 
| 135 | 139 | 
| 136 /** | 140 /** | 
| 137 * Opens Android application settings | 141 * Opens Android application settings | 
| 138 */ | 142 */ | 
| 139 public static void showAppDetails(Context context) | 143 public static void showAppDetails(final Context context) | 
| 140 { | 144 { | 
| 141 String packageName = context.getPackageName(); | 145 final String packageName = context.getPackageName(); | 
| 142 Intent intent = new Intent(); | 146 | 
| 143 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) | 147 final Intent intent = new Intent(); | 
| 144 { | 148 intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | 
| 145 // above 2.3 | 149 | 
| 146 intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | 150 final Uri uri = Uri.fromParts("package", packageName, null); | 
| 147 Uri uri = Uri.fromParts("package", packageName, null); | 151 intent.setData(uri); | 
| 148 intent.setData(uri); | |
| 149 } | |
| 150 else | |
| 151 { | |
| 152 // below 2.3 | |
| 153 final String appPkgName = (Build.VERSION.SDK_INT == Build.VERSION_CODES.FR OYO ? "pkg" : "com.android.settings.ApplicationPkgName"); | |
| 154 intent.setAction(Intent.ACTION_VIEW); | |
| 155 intent.setClassName("com.android.settings", "com.android.settings.Installe dAppDetails"); | |
| 156 intent.putExtra(appPkgName, packageName); | |
| 157 } | |
| 158 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | 152 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | 
| 153 | |
| 159 context.startActivity(intent); | 154 context.startActivity(intent); | 
| 160 } | 155 } | 
| 161 | 156 | 
| 162 /** | 157 /** | 
| 163 * Returns device name in user-friendly format | 158 * Returns device name in user-friendly format | 
| 164 */ | 159 */ | 
| 165 public static String getDeviceName() | 160 public static String getDeviceName() | 
| 166 { | 161 { | 
| 167 String manufacturer = Build.MANUFACTURER; | 162 final String manufacturer = Build.MANUFACTURER; | 
| 168 String model = Build.MODEL; | 163 final String model = Build.MODEL; | 
| 169 if (model.startsWith(manufacturer)) | 164 if (model.startsWith(manufacturer)) | 
| 170 return capitalize(model); | 165 { | 
| 
 
Felix Dahlke
2014/04/16 15:24:25
Same as in other files, also below.
 
René Jeschke
2014/04/16 17:51:47
Done.
 
 | |
| 166 return Utils.capitalizeString(model); | |
| 167 } | |
| 171 else | 168 else | 
| 172 return capitalize(manufacturer) + " " + model; | 169 { | 
| 170 return Utils.capitalizeString(manufacturer) + " " + model; | |
| 171 } | |
| 173 } | 172 } | 
| 174 | 173 | 
| 175 public static void appendRawTextFile(Context context, StringBuilder text, int id) | 174 public static void appendRawTextFile(final Context context, final StringBuilde r text, final int id) | 
| 176 { | 175 { | 
| 177 InputStream inputStream = context.getResources().openRawResource(id); | 176 // TODO: What about closing the resources? | 
| 178 InputStreamReader in = new InputStreamReader(inputStream); | 177 final InputStream inputStream = context.getResources().openRawResource(id); | 
| 179 BufferedReader buf = new BufferedReader(in); | 178 final InputStreamReader in = new InputStreamReader(inputStream); | 
| 179 final BufferedReader buf = new BufferedReader(in); | |
| 180 String line; | 180 String line; | 
| 181 try | 181 try | 
| 182 { | 182 { | 
| 183 while ((line = buf.readLine()) != null) | 183 while ((line = buf.readLine()) != null) | 
| 184 { | |
| 184 text.append(line); | 185 text.append(line); | 
| 186 } | |
| 185 } | 187 } | 
| 186 catch (IOException e) | 188 catch (final IOException e) | 
| 187 { | 189 { | 
| 190 // TODO: How about real logging? | |
| 188 e.printStackTrace(); | 191 e.printStackTrace(); | 
| 189 } | 192 } | 
| 190 } | 193 } | 
| 191 | 194 | 
| 192 private static String capitalize(String s) | |
| 193 { | |
| 194 if (s == null || s.length() == 0) | |
| 195 return ""; | |
| 196 char first = s.charAt(0); | |
| 197 if (Character.isUpperCase(first)) | |
| 198 return s; | |
| 199 else | |
| 200 return Character.toUpperCase(first) + s.substring(1); | |
| 201 } | |
| 202 | |
| 203 /** | 195 /** | 
| 204 * Checks if device has a WiFi connection available. | 196 * Checks if device has a WiFi connection available. | 
| 205 */ | 197 */ | 
| 206 public static boolean isWiFiConnected(Context context) | 198 public static boolean isWiFiConnected(final Context context) | 
| 207 { | 199 { | 
| 208 ConnectivityManager connectivityManager = (ConnectivityManager) context.getS ystemService(Context.CONNECTIVITY_SERVICE); | 200 final ConnectivityManager connectivityManager = (ConnectivityManager)context .getSystemService(Context.CONNECTIVITY_SERVICE); | 
| 
 
Felix Dahlke
2014/04/16 15:24:25
Why remove the space after the cast? More common/c
 
 | |
| 209 NetworkInfo networkInfo = null; | 201 NetworkInfo networkInfo = null; | 
| 210 if (connectivityManager != null) | 202 if (connectivityManager != null) | 
| 211 { | 203 { | 
| 212 networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_ WIFI); | 204 networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_ WIFI); | 
| 213 } | 205 } | 
| 214 return networkInfo == null ? false : networkInfo.isConnected(); | 206 return networkInfo == null ? false : networkInfo.isConnected(); | 
| 215 } | 207 } | 
| 216 | 208 | 
| 217 /** | 209 /** | 
| 218 * Checks if ProxyService is running. | 210 * Checks if ProxyService is running. | 
| 219 * | 211 * | 
| 220 * @return true if service is running | 212 * @return true if service is running | 
| 221 */ | 213 */ | 
| 222 public boolean isServiceRunning() | 214 public boolean isServiceRunning() | 
| 223 { | 215 { | 
| 224 ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVIC E); | 216 final ActivityManager manager = (ActivityManager)this.getSystemService(ACTIV ITY_SERVICE); | 
| 217 | |
| 225 // Actually it returns not only running services, so extra check is required | 218 // Actually it returns not only running services, so extra check is required | 
| 226 for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VAL UE)) | 219 for (final RunningServiceInfo service : manager.getRunningServices(Integer.M AX_VALUE)) | 
| 227 { | 220 { | 
| 228 if (service.service.getClassName().equals(ProxyService.class.getCanonicalN ame()) && service.pid > 0) | 221 if (service.service.getClassName().equals(ProxyService.class.getCanonicalN ame()) && service.pid > 0) | 
| 222 { | |
| 229 return true; | 223 return true; | 
| 224 } | |
| 230 } | 225 } | 
| 231 return false; | 226 return false; | 
| 232 } | 227 } | 
| 233 | 228 | 
| 234 /** | 229 /** | 
| 235 * Checks if application can write to external storage. | 230 * Checks if application can write to external storage. | 
| 236 */ | 231 */ | 
| 237 public boolean checkWriteExternalPermission() | 232 public boolean checkWriteExternalPermission() | 
| 238 { | 233 { | 
| 239 String permission = "android.permission.WRITE_EXTERNAL_STORAGE"; | 234 final String permission = "android.permission.WRITE_EXTERNAL_STORAGE"; | 
| 240 int res = checkCallingOrSelfPermission(permission); | 235 final int res = this.checkCallingOrSelfPermission(permission); | 
| 241 return res == PackageManager.PERMISSION_GRANTED; | 236 return res == PackageManager.PERMISSION_GRANTED; | 
| 242 } | 237 } | 
| 243 | 238 | 
| 244 public boolean isFirstRun() | 239 public boolean isFirstRun() | 
| 245 { | 240 { | 
| 246 return abpEngine.isFirstRun(); | 241 return this.abpEngine.isFirstRun(); | 
| 247 } | 242 } | 
| 248 | 243 | 
| 249 /** | 244 /** | 
| 250 * Returns list of known subscriptions. | 245 * Returns list of known subscriptions. | 
| 251 */ | 246 */ | 
| 252 public Subscription[] getRecommendedSubscriptions() | 247 public Subscription[] getRecommendedSubscriptions() | 
| 253 { | 248 { | 
| 254 if (subscriptions == null) | 249 // TODO: Why don't we re-check? | 
| 255 subscriptions = abpEngine.getRecommendedSubscriptions(); | 250 if (this.subscriptions == null) | 
| 256 return subscriptions; | 251 { | 
| 252 this.subscriptions = this.abpEngine.getRecommendedSubscriptions(); | |
| 253 } | |
| 254 return this.subscriptions; | |
| 257 } | 255 } | 
| 258 | 256 | 
| 259 /** | 257 /** | 
| 260 * Returns list of enabled subscriptions. | 258 * Returns list of enabled subscriptions. | 
| 261 */ | 259 */ | 
| 262 public Subscription[] getListedSubscriptions() | 260 public Subscription[] getListedSubscriptions() | 
| 263 { | 261 { | 
| 264 return abpEngine.getListedSubscriptions(); | 262 return this.abpEngine.getListedSubscriptions(); | 
| 265 } | 263 } | 
| 266 | 264 | 
| 267 /** | 265 /** | 
| 268 * Adds provided subscription and removes previous subscriptions if any. | 266 * Adds provided subscription and removes previous subscriptions if any. | 
| 269 * | 267 * | 
| 270 * @param url | 268 * @param url | 
| 271 * URL of subscription to add | 269 * URL of subscription to add | 
| 272 */ | 270 */ | 
| 273 public void setSubscription(String url) | 271 public void setSubscription(final String url) | 
| 274 { | 272 { | 
| 275 Subscription[] subscriptions = abpEngine.getListedSubscriptions(); | 273 this.abpEngine.setSubscription(url); | 
| 276 for (Subscription subscription : subscriptions) | |
| 277 { | |
| 278 abpEngine.removeSubscription(subscription.url); | |
| 279 } | |
| 280 abpEngine.addSubscription(url); | |
| 281 } | 274 } | 
| 282 | 275 | 
| 283 /** | 276 /** | 
| 284 * Forces subscriptions refresh. | 277 * Forces subscriptions refresh. | 
| 285 */ | 278 */ | 
| 286 public void refreshSubscriptions() | 279 public void refreshSubscriptions() | 
| 287 { | 280 { | 
| 288 Subscription[] subscriptions = abpEngine.getListedSubscriptions(); | 281 this.abpEngine.refreshSubscriptions(); | 
| 289 for (Subscription subscription : subscriptions) | |
| 290 { | |
| 291 abpEngine.refreshSubscription(subscription.url); | |
| 292 } | |
| 293 } | 282 } | 
| 294 | 283 | 
| 295 /** | 284 /** | 
| 296 * Enforces subscription status update. | 285 * Enforces subscription status update. | 
| 297 * | 286 * | 
| 298 * @param url Subscription url | 287 * @param url | 
| 288 * Subscription url | |
| 
 
Felix Dahlke
2014/04/16 15:24:25
Why this weird break? Same below.
 
 | |
| 299 */ | 289 */ | 
| 300 public void actualizeSubscriptionStatus(String url) | 290 public void updateSubscriptionStatus(final String url) | 
| 301 { | 291 { | 
| 302 abpEngine.actualizeSubscriptionStatus(url); | 292 this.abpEngine.updateSubscriptionStatus(url); | 
| 303 } | 293 } | 
| 304 | 294 | 
| 305 | |
| 306 /** | 295 /** | 
| 307 * Enables or disables Acceptable Ads | 296 * Enables or disables Acceptable Ads | 
| 308 */ | 297 */ | 
| 309 public void setAcceptableAdsEnabled(boolean enabled) | 298 public void setAcceptableAdsEnabled(final boolean enabled) | 
| 310 { | 299 { | 
| 311 abpEngine.setAcceptableAdsEnabled(enabled); | 300 this.abpEngine.setAcceptableAdsEnabled(enabled); | 
| 312 } | 301 } | 
| 313 | 302 | 
| 314 public String getAcceptableAdsUrl() | 303 public String getAcceptableAdsUrl() | 
| 315 { | 304 { | 
| 316 final String documentationLink = abpEngine.getDocumentationLink(); | 305 final String documentationLink = this.abpEngine.getDocumentationLink(); | 
| 317 final String locale = getResources().getConfiguration().locale.toString().re place("_", "-"); | 306 final String locale = this.getResources().getConfiguration().locale.toString ().replace("_", "-"); | 
| 318 return documentationLink.replace("%LINK%", "acceptable_ads").replace("%LANG% ", locale); | 307 return documentationLink.replace("%LINK%", "acceptable_ads").replace("%LANG% ", locale); | 
| 319 } | 308 } | 
| 320 | 309 | 
| 321 public void setNotifiedAboutAcceptableAds(boolean notified) | 310 public void setNotifiedAboutAcceptableAds(final boolean notified) | 
| 322 { | 311 { | 
| 323 final SharedPreferences preferences = PreferenceManager.getDefaultSharedPref erences(this); | 312 final SharedPreferences preferences = PreferenceManager.getDefaultSharedPref erences(this); | 
| 324 final Editor editor = preferences.edit(); | 313 final Editor editor = preferences.edit(); | 
| 325 editor.putBoolean("notified_about_acceptable_ads", notified); | 314 editor.putBoolean("notified_about_acceptable_ads", notified); | 
| 326 editor.commit(); | 315 editor.commit(); | 
| 327 } | 316 } | 
| 328 | 317 | 
| 329 public boolean isNotifiedAboutAcceptableAds() | 318 public boolean isNotifiedAboutAcceptableAds() | 
| 330 { | 319 { | 
| 331 final SharedPreferences preferences = PreferenceManager.getDefaultSharedPref erences(this); | 320 final SharedPreferences preferences = PreferenceManager.getDefaultSharedPref erences(this); | 
| 332 return preferences.getBoolean("notified_about_acceptable_ads", false); | 321 return preferences.getBoolean("notified_about_acceptable_ads", false); | 
| 333 } | 322 } | 
| 334 | 323 | 
| 335 /** | 324 /** | 
| 336 * Returns ElemHide selectors for domain. | 325 * Returns ElemHide selectors for domain. | 
| 337 * | 326 * | 
| 338 * @param domain The domain | 327 * @param domain | 
| 328 * The domain | |
| 339 * @return A list of CSS selectors | 329 * @return A list of CSS selectors | 
| 340 */ | 330 */ | 
| 341 public String[] getSelectorsForDomain(final String domain) | 331 public String[] getSelectorsForDomain(final String domain) | 
| 342 { | 332 { | 
| 343 /* We need to ignore element hiding rules here to work around two bugs: | 333 /* | 
| 334 * We need to ignore element hiding rules here to work around two bugs: | |
| 335 * | |
| 344 * 1. CSS is being injected even when there's an exception rule with $elemhi de | 336 * 1. CSS is being injected even when there's an exception rule with $elemhi de | 
| 337 * | |
| 345 * 2. The injected CSS causes blank pages in Chrome for Android | 338 * 2. The injected CSS causes blank pages in Chrome for Android | 
| 346 * | 339 * | 
| 347 * Starting with 1.1.2, we ignored element hiding rules after download anywa y, to keep the | 340 * | 
| 348 * memory usage down. Doing this with libadblockplus is trickier, but would be the clean | 341 * Starting with 1.1.2, we ignored element hiding rules after download anywa y, to keep the memory usage down. Doing this with libadblockplus is | 
| 
 
Felix Dahlke
2014/04/16 15:24:25
As before, please don't make code that adheres to
 
René Jeschke
2014/04/16 17:51:47
Done.
 
 | |
| 349 * solution. */ | 342 * trickier, but would be the clean solution. | 
| 343 */ | |
| 350 return null; | 344 return null; | 
| 351 /* | 345 /* | 
| 
 
Felix Dahlke
2014/04/16 15:24:25
We don't want to leave commented out code around,
 
René Jeschke
2014/04/16 17:51:47
Done.
 
 | |
| 352 if (!filteringEnabled) | 346 * if (!filteringEnabled) return null; | 
| 353 return null; | 347 * | 
| 354 | 348 * return abpEngine.getSelectorsForDomain(domain); | 
| 355 return abpEngine.getSelectorsForDomain(domain); | 349 */ | 
| 356 */ | |
| 357 } | 350 } | 
| 358 | 351 | 
| 359 /** | 352 /** | 
| 360 * Checks if filters match request parameters. | 353 * Checks if filters match request parameters. | 
| 361 * | 354 * | 
| 362 * @param url | 355 * @param url | 
| 363 * Request URL | 356 * Request URL | 
| 364 * @param query | 357 * @param query | 
| 365 * Request query string | 358 * Request query string | 
| 366 * @param referrer | 359 * @param referrer | 
| 367 * Request referrer header | 360 * Request referrer header | 
| 368 * @param accept | 361 * @param accept | 
| 369 * Request accept header | 362 * Request accept header | 
| 370 * @return true if matched filter was found | 363 * @return true if matched filter was found | 
| 371 * @throws Exception | 364 * @throws Exception | 
| 372 */ | 365 */ | 
| 373 public boolean matches(String url, String query, String referrer, String accep t) | 366 public boolean matches(final String url, final String query, final String refe rrer, final String accept) | 
| 374 { | 367 { | 
| 375 final String fullUrl = !"".equals(query) ? url + "?" + query : url; | 368 final String fullUrl = !"".equals(query) ? url + "?" + query : url; | 
| 376 if (referrer != null) | 369 if (referrer != null) | 
| 377 referrerMapping.put(fullUrl, referrer); | 370 { | 
| 371 this.referrerMapping.put(fullUrl, referrer); | |
| 372 } | |
| 378 | 373 | 
| 379 if (!filteringEnabled) | 374 if (!this.filteringEnabled) | 
| 375 { | |
| 380 return false; | 376 return false; | 
| 377 } | |
| 381 | 378 | 
| 382 String contentType = null; | 379 String contentType = null; | 
| 383 | 380 | 
| 384 if (accept != null) | 381 if (accept != null) | 
| 385 { | 382 { | 
| 386 if (accept.contains("text/css")) | 383 if (accept.contains("text/css")) | 
| 384 { | |
| 387 contentType = "STYLESHEET"; | 385 contentType = "STYLESHEET"; | 
| 386 } | |
| 388 else if (accept.contains("image/*")) | 387 else if (accept.contains("image/*")) | 
| 388 { | |
| 389 contentType = "IMAGE"; | 389 contentType = "IMAGE"; | 
| 390 } | |
| 390 else if (accept.contains("text/html")) | 391 else if (accept.contains("text/html")) | 
| 392 { | |
| 391 contentType = "SUBDOCUMENT"; | 393 contentType = "SUBDOCUMENT"; | 
| 394 } | |
| 392 } | 395 } | 
| 393 | 396 | 
| 394 if (contentType == null) | 397 if (contentType == null) | 
| 395 { | 398 { | 
| 396 if (RE_JS.matcher(url).matches()) | 399 if (RE_JS.matcher(url).matches()) | 
| 400 { | |
| 397 contentType = "SCRIPT"; | 401 contentType = "SCRIPT"; | 
| 402 } | |
| 398 else if (RE_CSS.matcher(url).matches()) | 403 else if (RE_CSS.matcher(url).matches()) | 
| 404 { | |
| 399 contentType = "STYLESHEET"; | 405 contentType = "STYLESHEET"; | 
| 406 } | |
| 400 else if (RE_IMAGE.matcher(url).matches()) | 407 else if (RE_IMAGE.matcher(url).matches()) | 
| 408 { | |
| 401 contentType = "IMAGE"; | 409 contentType = "IMAGE"; | 
| 410 } | |
| 402 else if (RE_FONT.matcher(url).matches()) | 411 else if (RE_FONT.matcher(url).matches()) | 
| 412 { | |
| 403 contentType = "FONT"; | 413 contentType = "FONT"; | 
| 414 } | |
| 404 else if (RE_HTML.matcher(url).matches()) | 415 else if (RE_HTML.matcher(url).matches()) | 
| 416 { | |
| 405 contentType = "SUBDOCUMENT"; | 417 contentType = "SUBDOCUMENT"; | 
| 418 } | |
| 406 } | 419 } | 
| 407 if (contentType == null) | 420 if (contentType == null) | 
| 421 { | |
| 408 contentType = "OTHER"; | 422 contentType = "OTHER"; | 
| 423 } | |
| 409 | 424 | 
| 410 final List<String> referrerChain = buildReferrerChain(referrer); | 425 final List<String> referrerChain = this.buildReferrerChain(referrer); | 
| 411 Log.d("Referrer chain", fullUrl + ": " + referrerChain.toString()); | 426 Log.d("Referrer chain", fullUrl + ": " + referrerChain.toString()); | 
| 412 String[] referrerChainArray = referrerChain.toArray(new String[referrerChain .size()]); | 427 final String[] referrerChainArray = referrerChain.toArray(new String[referre rChain.size()]); | 
| 413 return abpEngine.matches(fullUrl, contentType, referrerChainArray); | 428 return this.abpEngine.matches(fullUrl, contentType, referrerChainArray); | 
| 414 } | 429 } | 
| 415 | 430 | 
| 416 private List<String> buildReferrerChain(String url) | 431 private List<String> buildReferrerChain(String url) | 
| 417 { | 432 { | 
| 418 final List<String> referrerChain = new ArrayList<String>(); | 433 final List<String> referrerChain = new ArrayList<String>(); | 
| 419 // We need to limit the chain length to ensure we don't block indefinitely i f there's | 434 // We need to limit the chain length to ensure we don't block indefinitely i f there's a referrer loop. | 
| 420 // a referrer loop. | |
| 421 final int maxChainLength = 10; | 435 final int maxChainLength = 10; | 
| 422 for (int i = 0; i < maxChainLength && url != null; i++) | 436 for (int i = 0; i < maxChainLength && url != null; i++) | 
| 423 { | 437 { | 
| 424 referrerChain.add(0, url); | 438 referrerChain.add(0, url); | 
| 425 url = referrerMapping.get(url); | 439 url = this.referrerMapping.get(url); | 
| 426 } | 440 } | 
| 427 return referrerChain; | 441 return referrerChain; | 
| 428 } | 442 } | 
| 429 | 443 | 
| 430 /** | 444 /** | 
| 431 * Checks if filtering is enabled. | 445 * Checks if filtering is enabled. | 
| 432 */ | 446 */ | 
| 433 public boolean isFilteringEnabled() | 447 public boolean isFilteringEnabled() | 
| 434 { | 448 { | 
| 435 return filteringEnabled; | 449 return this.filteringEnabled; | 
| 436 } | 450 } | 
| 437 | 451 | 
| 438 /** | 452 /** | 
| 439 * Enables or disables filtering. | 453 * Enables or disables filtering. | 
| 440 */ | 454 */ | 
| 441 public void setFilteringEnabled(boolean enable) | 455 public void setFilteringEnabled(final boolean enable) | 
| 442 { | 456 { | 
| 443 filteringEnabled = enable; | 457 this.filteringEnabled = enable; | 
| 444 sendBroadcast(new Intent(BROADCAST_FILTERING_CHANGE).putExtra("enabled", fil teringEnabled)); | 458 this.sendBroadcast(new Intent(BROADCAST_FILTERING_CHANGE).putExtra("enabled" , this.filteringEnabled)); | 
| 445 } | 459 } | 
| 446 | 460 | 
| 447 /** | 461 /** | 
| 448 * Starts ABP engine. It also initiates subscription refresh if it is enabled | 462 * Starts ABP engine. It also initiates subscription refresh if it is enabled in user settings. | 
| 449 * in user settings. | |
| 450 */ | 463 */ | 
| 451 public void startEngine() | 464 public void startEngine() | 
| 452 { | 465 { | 
| 453 if (abpEngine == null) | 466 if (this.abpEngine == null) | 
| 454 { | 467 { | 
| 455 File basePath = getFilesDir(); | 468 final File basePath = this.getFilesDir(); | 
| 456 abpEngine = new ABPEngine(this, basePath.getAbsolutePath()); | 469 this.abpEngine = ABPEngine.create(AdblockPlus.getApplication(), ABPEngine. generateAppInfo(this), basePath.getAbsolutePath()); | 
| 457 } | 470 } | 
| 458 } | 471 } | 
| 459 | 472 | 
| 460 /** | 473 /** | 
| 461 * Stops ABP engine. | 474 * Stops ABP engine. | 
| 462 */ | 475 */ | 
| 463 public void stopEngine() | 476 public void stopEngine() | 
| 464 { | 477 { | 
| 465 if (abpEngine != null) | 478 if (this.abpEngine != null) | 
| 466 { | 479 { | 
| 467 abpEngine.release(); | 480 this.abpEngine.dispose(); | 
| 468 abpEngine = null; | 481 this.abpEngine = null; | 
| 469 Log.i(TAG, "stopEngine"); | 482 Log.i(TAG, "stopEngine"); | 
| 470 } | 483 } | 
| 471 } | 484 } | 
| 472 | 485 | 
| 473 /** | 486 /** | 
| 474 * Initiates immediate interactive check for available update. | 487 * Initiates immediate interactive check for available update. | 
| 475 */ | 488 */ | 
| 476 public void checkUpdates() | 489 public void checkUpdates() | 
| 477 { | 490 { | 
| 478 abpEngine.checkUpdates(); | 491 this.abpEngine.checkForUpdates(); | 
| 479 } | 492 } | 
| 480 | 493 | 
| 481 /** | 494 /** | 
| 482 * Sets Alarm to call updater after specified number of minutes or after one | 495 * Sets Alarm to call updater after specified number of minutes or after one d ay if minutes are set to 0. | 
| 483 * day if | |
| 484 * minutes are set to 0. | |
| 485 * | 496 * | 
| 486 * @param minutes | 497 * @param minutes | 
| 487 * number of minutes to wait | 498 * number of minutes to wait | 
| 488 */ | 499 */ | 
| 489 public void scheduleUpdater(int minutes) | 500 public void scheduleUpdater(final int minutes) | 
| 490 { | 501 { | 
| 491 Calendar updateTime = Calendar.getInstance(); | 502 final Calendar updateTime = Calendar.getInstance(); | 
| 492 | 503 | 
| 493 if (minutes == 0) | 504 if (minutes == 0) | 
| 494 { | 505 { | 
| 495 // Start update checks at 10:00 GMT... | 506 // Start update checks at 10:00 GMT... | 
| 496 updateTime.setTimeZone(TimeZone.getTimeZone("GMT")); | 507 updateTime.setTimeZone(TimeZone.getTimeZone("GMT")); | 
| 497 updateTime.set(Calendar.HOUR_OF_DAY, 10); | 508 updateTime.set(Calendar.HOUR_OF_DAY, 10); | 
| 498 updateTime.set(Calendar.MINUTE, 0); | 509 updateTime.set(Calendar.MINUTE, 0); | 
| 499 // ...next day | 510 // ...next day | 
| 500 updateTime.add(Calendar.HOUR_OF_DAY, 24); | 511 updateTime.add(Calendar.HOUR_OF_DAY, 24); | 
| 501 // Spread out the “mass downloading” for 6 hours | 512 // Spread out the “mass downloading” for 6 hours | 
| 502 updateTime.add(Calendar.MINUTE, (int) (Math.random() * 60 * 6)); | 513 updateTime.add(Calendar.MINUTE, (int)(Math.random() * 60 * 6)); | 
| 503 } | 514 } | 
| 504 else | 515 else | 
| 505 { | 516 { | 
| 506 updateTime.add(Calendar.MINUTE, minutes); | 517 updateTime.add(Calendar.MINUTE, minutes); | 
| 507 } | 518 } | 
| 508 | 519 | 
| 509 Intent updater = new Intent(this, AlarmReceiver.class); | 520 final Intent updater = new Intent(this, AlarmReceiver.class); | 
| 510 PendingIntent recurringUpdate = PendingIntent.getBroadcast(this, 0, updater, PendingIntent.FLAG_CANCEL_CURRENT); | 521 final PendingIntent recurringUpdate = PendingIntent.getBroadcast(this, 0, up dater, PendingIntent.FLAG_CANCEL_CURRENT); | 
| 511 // Set non-waking alarm | 522 // Set non-waking alarm | 
| 512 AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE) ; | 523 final AlarmManager alarms = (AlarmManager)this.getSystemService(Context.ALAR M_SERVICE); | 
| 513 alarms.set(AlarmManager.RTC, updateTime.getTimeInMillis(), recurringUpdate); | 524 alarms.set(AlarmManager.RTC, updateTime.getTimeInMillis(), recurringUpdate); | 
| 514 } | 525 } | 
| 515 | 526 | 
| 516 @Override | 527 @Override | 
| 517 public void onCreate() | 528 public void onCreate() | 
| 518 { | 529 { | 
| 519 super.onCreate(); | 530 super.onCreate(); | 
| 520 instance = this; | 531 instance = this; | 
| 521 | 532 | 
| 522 // Check for crash report | 533 // Check for crash report | 
| 523 try | 534 try | 
| 524 { | 535 { | 
| 525 InputStreamReader reportFile = new InputStreamReader(openFileInput(CrashHa ndler.REPORT_FILE)); | 536 final InputStreamReader reportFile = new InputStreamReader(this.openFileIn put(CrashHandler.REPORT_FILE)); | 
| 526 final char[] buffer = new char[0x1000]; | 537 final char[] buffer = new char[4096]; | 
| 
 
Felix Dahlke
2014/04/16 15:24:25
Why this? Hex is not that hard to read.
 
René Jeschke
2014/04/16 17:51:47
Because is totally does not make any sense here. W
 
 | |
| 527 StringBuilder out = new StringBuilder(); | 538 final StringBuilder out = new StringBuilder(); | 
| 528 int read; | 539 int read; | 
| 540 | |
| 
 
Felix Dahlke
2014/04/16 15:24:25
Empty lines are also arguably an unrelated change,
 
René Jeschke
2014/04/16 17:51:47
Done.
 
 | |
| 529 do | 541 do | 
| 530 { | 542 { | 
| 531 read = reportFile.read(buffer, 0, buffer.length); | 543 read = reportFile.read(buffer, 0, buffer.length); | 
| 532 if (read > 0) | 544 if (read > 0) | 
| 545 { | |
| 533 out.append(buffer, 0, read); | 546 out.append(buffer, 0, read); | 
| 547 } | |
| 534 } | 548 } | 
| 535 while (read >= 0); | 549 while (read >= 0); | 
| 536 String report = out.toString(); | 550 | 
| 537 if (!"".equals(report)) | 551 final String report = out.toString(); | 
| 552 if (!Strings.isEmpty(report)) | |
| 538 { | 553 { | 
| 539 final Intent intent = new Intent(this, CrashReportDialog.class); | 554 final Intent intent = new Intent(this, CrashReportDialog.class); | 
| 540 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | 555 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | 
| 541 intent.putExtra("report", report); | 556 intent.putExtra("report", report); | 
| 542 startActivity(intent); | 557 this.startActivity(intent); | 
| 543 } | 558 } | 
| 544 } | 559 } | 
| 545 catch (FileNotFoundException e) | 560 catch (final FileNotFoundException e) | 
| 546 { | 561 { | 
| 547 // ignore | 562 // ignore | 
| 548 } | 563 } | 
| 549 catch (IOException e) | 564 catch (final IOException e) | 
| 550 { | 565 { | 
| 551 // TODO Auto-generated catch block | |
| 552 Log.e(TAG, e.getMessage(), e); | 566 Log.e(TAG, e.getMessage(), e); | 
| 553 } | 567 } | 
| 554 | 568 | 
| 555 // Set crash handler | 569 // Set crash handler | 
| 556 Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(this)); | 570 Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(this)); | 
| 557 | 571 | 
| 558 // Initiate update check | 572 // Initiate update check | 
| 559 scheduleUpdater(0); | 573 this.scheduleUpdater(0); | 
| 560 } | 574 } | 
| 561 } | 575 } | 
| OLD | NEW |