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

Side by Side Diff: src/org/adblockplus/android/ABPEngine.java

Issue 5697499218051072: Usage of new API, cleanups (reduced) (Closed)
Patch Set: Addressed new review issues Created April 28, 2014, 8:34 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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
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.android; 18 package org.adblockplus.android;
19 19
20 import org.adblockplus.android.updater.UpdaterActivity; 20 import java.util.List;
21 21
22 import android.app.Notification; 22 import org.adblockplus.libadblockplus.AppInfo;
23 import android.app.NotificationManager; 23 import org.adblockplus.libadblockplus.EventCallback;
24 import android.app.PendingIntent; 24 import org.adblockplus.libadblockplus.Filter;
25 import org.adblockplus.libadblockplus.FilterChangeCallback;
26 import org.adblockplus.libadblockplus.FilterEngine;
27 import org.adblockplus.libadblockplus.JsEngine;
28 import org.adblockplus.libadblockplus.LogSystem;
29 import org.adblockplus.libadblockplus.Subscription;
30 import org.adblockplus.libadblockplus.UpdaterCallback;
31 import org.adblockplus.libadblockplus.WebRequest;
32
25 import android.content.Context; 33 import android.content.Context;
26 import android.content.Intent;
27 import android.content.pm.PackageInfo; 34 import android.content.pm.PackageInfo;
28 import android.content.pm.PackageManager.NameNotFoundException; 35 import android.content.pm.PackageManager.NameNotFoundException;
29 import android.os.Build.VERSION; 36 import android.os.Build.VERSION;
30 import android.support.v4.app.NotificationCompat;
31 import android.util.Log; 37 import android.util.Log;
32 38
33 public class ABPEngine 39 public final class ABPEngine
34 { 40 {
35 private final static String TAG = "ABPEngine"; 41 private static final String TAG = Utils.getTag(ABPEngine.class);
36 private static final int NOTIFICATION_ID = R.string.app_name + 1; 42
37 43 private final Context context;
38 private Context context; 44
39 45 /**
40 public ABPEngine(Context context, String basePath) 46 * The fields below are volatile because:
47 *
48 * I encountered JNI related bugs/crashes caused by JNI backed Java objects. I t seemed that under
49 * certain conditions the objects were optimized away which resulted in crashe s when trying to
50 * release the object, sometimes even on access.
51 *
52 * The only solution that really worked was to declare the variables holding t he references
53 * volatile, this seems to prevent the JNI from 'optimizing away' those object s (as a volatile
54 * variable might be changed at any time from any thread).
55 */
56 private volatile JsEngine jsEngine;
57 private volatile FilterEngine filterEngine;
58 private volatile LogSystem logSystem;
59 private volatile WebRequest webRequest;
60 private volatile EventCallback updateCallback;
61 private volatile UpdaterCallback updaterCallback;
62 private volatile FilterChangeCallback filterChangeCallback;
63
64 private ABPEngine(final Context context)
41 { 65 {
42 this.context = context; 66 this.context = context;
43 String version; 67 }
68
69 public static AppInfo generateAppInfo(final Context context)
70 {
71 String version = "0";
44 try 72 try
45 { 73 {
46 final PackageInfo info = context.getPackageManager().getPackageInfo(contex t.getPackageName(), 0); 74 final PackageInfo info = context.getPackageManager().getPackageInfo(contex t.getPackageName(), 0);
47 version = info.versionName + "." + info.versionCode; 75 version = info.versionName + "." + info.versionCode;
48 } catch (NameNotFoundException e) 76 }
77 catch (final NameNotFoundException e)
49 { 78 {
50 Log.e(TAG, "Failed to get the application version number", e); 79 Log.e(TAG, "Failed to get the application version number", e);
51 version = "0";
52 } 80 }
53 final String sdkVersion = String.valueOf(VERSION.SDK_INT); 81 final String sdkVersion = String.valueOf(VERSION.SDK_INT);
54 final String locale = context.getResources().getConfiguration().locale.toStr ing(); 82 final String locale = context.getResources().getConfiguration().locale.toStr ing();
55 final boolean developmentBuild = !context.getResources().getBoolean(R.bool.d ef_release); 83 final boolean developmentBuild = !context.getResources().getBoolean(R.bool.d ef_release);
56 initialize(basePath, version, sdkVersion, locale, developmentBuild); 84
57 } 85 return AppInfo.builder()
58 86 .setVersion(version)
59 public void onFilterChanged(String url, String status, long time) 87 .setApplicationVersion(sdkVersion)
60 { 88 .setLocale(locale)
61 context.sendBroadcast(new Intent(AdblockPlus.BROADCAST_SUBSCRIPTION_STATUS). putExtra("url", url).putExtra("status", status).putExtra("time", time)); 89 .setDevelopmentBuild(developmentBuild)
62 } 90 .build();
63 91 }
64 /** 92
65 * Called when update event occurred. 93 public static ABPEngine create(final Context context, final AppInfo appInfo, f inal String basePath)
66 * @param url Update download address 94 {
67 */ 95 final ABPEngine engine = new ABPEngine(context);
68 public void onUpdateEvent(String url, String error) 96
69 { 97 engine.jsEngine = new JsEngine(appInfo);
70 Notification notification = getNotification(url, error); 98 engine.jsEngine.setDefaultFileSystem(basePath);
71 NotificationManager notificationManager = (NotificationManager) context.getS ystemService(Context.NOTIFICATION_SERVICE); 99
72 notificationManager.notify(NOTIFICATION_ID, notification); 100 engine.logSystem = new AndroidLogSystem();
73 } 101 engine.jsEngine.setLogSystem(engine.logSystem);
74 102
75 private native void initialize(String basePath, String version, String sdkVers ion, String locale, boolean developmentBuild); 103 engine.webRequest = new AndroidWebRequest();
76 104 engine.jsEngine.setWebRequest(engine.webRequest);
77 public native void release(); 105
78 106 engine.updateCallback = new AndroidUpdateAvailableCallback(context);
79 public native boolean isFirstRun(); 107 engine.jsEngine.setEventCallback("updateAvailable", engine.updateCallback);
80 108
81 public native Subscription[] getListedSubscriptions(); 109 engine.filterEngine = new FilterEngine(engine.jsEngine);
82 110 engine.filterChangeCallback = new AndroidFilterChangeCallback(context);
83 public native Subscription[] getRecommendedSubscriptions(); 111 engine.filterEngine.setFilterChangeCallback(engine.filterChangeCallback);
84 112
85 public native void addSubscription(String url); 113 engine.updaterCallback = new AndroidUpdaterCallback(context);
86 114
87 public native void removeSubscription(String url); 115 return engine;
88 116 }
89 public native void refreshSubscription(String url); 117
90 118 public void dispose()
91 public native void actualizeSubscriptionStatus(String url); 119 {
92 120 // Safe disposing (just in case)
93 public native void setAcceptableAdsEnabled(boolean enabled); 121 if (this.filterEngine != null)
94 122 {
95 public native String getDocumentationLink(); 123 this.filterEngine.dispose();
96 124 this.filterEngine = null;
97 public native boolean matches(String url, String contentType, String[] documen tUrls); 125 }
98 126
99 public native String[] getSelectorsForDomain(String domain); 127 if (this.jsEngine != null)
100 128 {
101 public native void checkUpdates(); 129 this.jsEngine.dispose();
102 130 this.jsEngine = null;
103 private Notification getNotification(String url, String error) 131 }
104 { 132
105 final PendingIntent emptyIntent = PendingIntent.getActivity(context, 0, new Intent(), 0); 133 if (this.logSystem != null)
106 134 {
107 NotificationCompat.Builder builder = new NotificationCompat.Builder(context) ; 135 this.logSystem.dispose();
108 builder.setContentTitle(context.getText(R.string.app_name)); 136 this.logSystem = null;
109 builder.setSmallIcon(R.drawable.ic_stat_warning); 137 }
110 builder.setWhen(System.currentTimeMillis()); 138
111 builder.setAutoCancel(true); 139 if (this.webRequest != null)
112 builder.setOnlyAlertOnce(true); 140 {
113 builder.setContentIntent(emptyIntent); 141 this.webRequest.dispose();
114 142 this.webRequest = null;
115 if (url != null) 143 }
116 { 144
117 builder.setSmallIcon(R.drawable.ic_stat_download); 145 if (this.updateCallback != null)
118 146 {
119 147 this.updateCallback.dispose();
120 Intent intent = new Intent(context, UpdaterActivity.class).addFlags(Intent .FLAG_ACTIVITY_NEW_TASK); 148 this.updateCallback = null;
121 intent.setAction("download"); 149 }
122 intent.putExtra("url", url); 150
123 PendingIntent updateIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 151 if (this.updaterCallback != null)
124 builder.setContentIntent(updateIntent); 152 {
125 builder.setContentText(context.getString(R.string.msg_update_available)); 153 this.updaterCallback.dispose();
126 } 154 this.updaterCallback = null;
127 else if (error != null) 155 }
128 { 156
129 //TODO Should we show error message to the user? 157 if (this.filterChangeCallback != null)
130 builder.setContentText(context.getString(R.string.msg_update_fail)); 158 {
131 } 159 this.filterChangeCallback.dispose();
132 else 160 this.filterChangeCallback = null;
133 { 161 }
134 builder.setContentText(context.getString(R.string.msg_update_missing)); 162 }
135 } 163
136 164 public boolean isFirstRun()
137 Notification notification = builder.getNotification(); 165 {
138 return notification; 166 return this.filterEngine.isFirstRun();
139 } 167 }
140 168
141 static 169 private static org.adblockplus.android.Subscription convertJsSubscription(fina l Subscription jsSubscription)
142 { 170 {
143 System.loadLibrary("adblockplus-jni"); 171 final org.adblockplus.android.Subscription subscription = new org.adblockplu s.android.Subscription();
172
173 subscription.title = jsSubscription.getProperty("title").toString();
174 subscription.url = jsSubscription.getProperty("url").toString();
175
176 return subscription;
177 }
178
179 private static org.adblockplus.android.Subscription[] convertJsSubscriptions(f inal List<Subscription> jsSubscriptions)
180 {
181 final org.adblockplus.android.Subscription[] subscriptions = new org.adblock plus.android.Subscription[jsSubscriptions.size()];
182
183 for (int i = 0; i < subscriptions.length; i++)
184 {
185 subscriptions[i] = convertJsSubscription(jsSubscriptions.get(i));
186 }
187
188 return subscriptions;
189 }
190
191 public org.adblockplus.android.Subscription[] getRecommendedSubscriptions()
192 {
193 return convertJsSubscriptions(this.filterEngine.fetchAvailableSubscriptions( ));
194 }
195
196 public org.adblockplus.android.Subscription[] getListedSubscriptions()
197 {
198 return convertJsSubscriptions(this.filterEngine.getListedSubscriptions());
199 }
200
201 public void setSubscription(final String url)
202 {
203 Subscription sub = null;
204 for (final Subscription s : this.filterEngine.getListedSubscriptions())
205 {
206 if (url.equals(s.getProperty("url").toString()))
207 {
208 sub = s;
209 }
210 s.removeFromList();
211 }
212 if (sub != null)
213 {
214 sub.addToList();
215 }
216 }
217
218 public void refreshSubscriptions()
219 {
220 for (final Subscription s : this.filterEngine.getListedSubscriptions())
221 {
222 s.updateFilters();
223 }
224 }
225
226 public void setAcceptableAdsEnabled(final boolean enabled)
227 {
228 final String url = this.filterEngine.getPref("subscriptions_exceptionsurl"). toString();
229 final Subscription sub = this.filterEngine.getSubscription(url);
230 if (sub != null)
231 {
232 if (enabled)
233 {
234 sub.addToList();
235 }
236 else
237 {
238 sub.removeFromList();
239 }
240 }
241 }
242
243 public String getDocumentationLink()
244 {
245 return this.filterEngine.getPref("documentation_link").toString();
246 }
247
248 public boolean matches(final String fullUrl, final String contentType, final S tring[] referrerChainArray)
249 {
250 final Filter filter = this.filterEngine.matches(fullUrl, contentType, referr erChainArray);
251
252 if (filter == null)
253 {
254 return false;
255 }
256
257 // hack: if there is no referrer, block only if filter is domain-specific
258 // (to re-enable in-app ads blocking, proposed on 12.11.2012 Monday meeting)
259 // (documentUrls contains the referrers on Android)
260 if (referrerChainArray.length == 0 && (filter.getProperty("text").toString() ).contains("||"))
261 {
262 return false;
263 }
264
265 return filter.getType() != Filter.Type.EXCEPTION;
266 }
267
268 public void checkForUpdates()
269 {
270 this.filterEngine.forceUpdateCheck(this.updaterCallback);
271 }
272
273 public void updateSubscriptionStatus(final String url)
274 {
275 final Subscription sub = this.filterEngine.getSubscription(url);
276 if (sub != null)
277 {
278 Utils.updateSubscriptionStatus(this.context, sub);
279 }
144 } 280 }
145 } 281 }
OLDNEW
« no previous file with comments | « src/org/adblockplus/ChunkedOutputStream.java ('k') | src/org/adblockplus/android/AboutDialog.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld