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

Side by Side Diff: libadblockplus-android/src/org/adblockplus/libadblockplus/android/SingletonEngineProvider.java

Issue 29671734: Issue 6265 - Create shared AdblockEngine instance in AdblockWebView in background (Closed)
Patch Set: @deprecated in javadoc, order Created Jan. 19, 2018, 1:04 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « libadblockplus-android/src/org/adblockplus/libadblockplus/android/SingleInstanceEngineProvider.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
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/>.
16 */
17 package org.adblockplus.libadblockplus.android;
18
19 import org.adblockplus.libadblockplus.IsAllowedConnectionCallback;
20
21 import android.content.Context;
22 import android.content.SharedPreferences;
23 import android.net.ConnectivityManager;
24 import android.util.Log;
25
26 import java.util.Map;
27 import java.util.concurrent.CountDownLatch;
28 import java.util.concurrent.atomic.AtomicInteger;
29
30 /**
31 * Provides single instance of AdblockEngine
32 */
33 public class SingletonEngineProvider implements AdblockEngineProvider
34 {
35 private static final String TAG = Utils.getTag(SingletonEngineProvider.class);
36
37 private Context context;
38 private String basePath;
39 private boolean developmentBuild;
40 private String preloadedPreferenceName;
41 private Map<String, Integer> urlToResourceIdMap;
42 private AdblockEngine engine;
43 private CountDownLatch engineCreated;
44 private Long v8IsolateProviderPtr;
45 private Runnable engineCreatedCallback;
46 private Runnable engineDisposedCallback;
47
48 /*
49 Simple ARC management for AdblockEngine
50 Use `retain` and `release`
51 */
52
53 private AtomicInteger referenceCounter = new AtomicInteger(0);
54
55 /**
56 * Init with context
57 * @param context application context
58 * @param basePath file system root to store files
59 *
60 * Adblock Plus library will download subscription files and s tore them on
61 * the path passed. The path should exist and the directory co ntent should not be
62 * cleared out occasionally. Using `context.getCacheDir().getA bsolutePath()` is not
63 * recommended because it can be cleared by the system.
64 * @param developmentBuild debug or release?
65 */
66 public SingletonEngineProvider(Context context, String basePath, boolean devel opmentBuild)
67 {
68 this.context = context.getApplicationContext();
69 this.basePath = basePath;
70 this.developmentBuild = developmentBuild;
71 }
72
73 @Override
74 public AdblockEngine getAdblockEngine()
75 {
76 return engine;
77 }
78
79 /**
80 * Use preloaded subscriptions
81 * @param preferenceName Shared Preferences name to store intercepted requests stats
82 * @param urlToResourceIdMap
83 */
84 public SingletonEngineProvider preloadSubscriptions(String preferenceName,
85 Map<String, Integer> urlTo ResourceIdMap)
86 {
87 this.preloadedPreferenceName = preferenceName;
88 this.urlToResourceIdMap = urlToResourceIdMap;
89 return this;
90 }
91
92 public SingletonEngineProvider useV8IsolateProvider(long ptr)
93 {
94 this.v8IsolateProviderPtr = ptr;
95 return this;
96 }
97
98 public SingletonEngineProvider setEngineCreatedCallback(Runnable callback)
99 {
100 this.engineCreatedCallback = callback;
101 return this;
102 }
103
104 public SingletonEngineProvider setEngineDisposedCallback(Runnable callback)
105 {
106 this.engineDisposedCallback = callback;
107 return this;
108 }
109
110 private void createAdblock()
111 {
112 ConnectivityManager connectivityManager =
113 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVIC E);
114 IsAllowedConnectionCallback isAllowedConnectionCallback =
115 new IsAllowedConnectionCallbackImpl(connectivityManager);
116
117 Log.d(TAG, "Creating adblock engine ...");
118
119 AdblockEngine.Builder builder = AdblockEngine
120 .builder(
121 AdblockEngine.generateAppInfo(context, developmentBuild),
122 basePath)
123 .setIsAllowedConnectionCallback(isAllowedConnectionCallback)
124 .enableElementHiding(true);
125
126 if (v8IsolateProviderPtr != null)
127 {
128 builder.useV8IsolateProvider(v8IsolateProviderPtr);
129 }
130
131 // if preloaded subscriptions provided
132 if (preloadedPreferenceName != null)
133 {
134 SharedPreferences preloadedSubscriptionsPrefs = context.getSharedPreferenc es(
135 preloadedPreferenceName,
136 Context.MODE_PRIVATE);
137 builder.preloadSubscriptions(
138 context,
139 urlToResourceIdMap,
140 new AndroidWebRequestResourceWrapper.SharedPrefsStorage(preloadedSubscri ptionsPrefs));
141 }
142
143 engine = builder.build();
144
145 Log.d(TAG, "AdblockHelper engine created");
146
147 // sometimes we need to init AdblockEngine instance, eg. set user settings
148 if (engineCreatedCallback != null)
149 {
150 engineCreatedCallback.run();
151 }
152 }
153
154 /**
155 * Wait until everything is ready (used for `retain(true)`)
156 * Warning: locks current thread
157 */
158 public void waitForReady()
159 {
160 if (engineCreated == null)
161 {
162 throw new RuntimeException("AdblockHelper Plus usage exception: call retai n(true) first");
163 }
164
165 try
166 {
167 Log.d(TAG, "Waiting for ready ...");
168 engineCreated.await();
169 Log.d(TAG, "Ready");
170 }
171 catch (InterruptedException e)
172 {
173 Log.w(TAG, "Interrupted", e);
174 }
175 }
176
177 private void disposeAdblock()
178 {
179 Log.w(TAG, "Disposing adblock engine");
180
181 engine.dispose();
182 engine = null;
183
184 // sometimes we need to deinit something after AdblockEngine instance dispos ed
185 // eg. release user settings
186 if (engineDisposedCallback != null)
187 {
188 engineDisposedCallback.run();
189 }
190 }
191
192 /**
193 * Get registered clients count
194 * @return registered clients count
195 */
196 public int getCounter()
197 {
198 return referenceCounter.get();
199 }
200
201 /**
202 * Register AdblockHelper engine client
203 * @param asynchronous If `true` engines will be created in background thread without locking of
204 * current thread. Use waitForReady() before getAdblockEng ine() later.
205 * If `false` locks current thread.
206 * @return if a new instance is allocated
207 */
208 public synchronized boolean retain(boolean asynchronous)
209 {
210 boolean firstInstance = false;
211
212 if (referenceCounter.getAndIncrement() == 0)
213 {
214 firstInstance = true;
215
216 if (!asynchronous)
217 {
218 createAdblock();
219 }
220 else
221 {
222 // latch is required for async (see `waitForReady()`)
223 engineCreated = new CountDownLatch(1);
224
225 new Thread(new Runnable()
226 {
227 @Override
228 public void run()
229 {
230 createAdblock();
231
232 // unlock waiting client thread
233 engineCreated.countDown();
234 }
235 }).start();
236 }
237 }
238 return firstInstance;
239 }
240
241 /**
242 * Unregister AdblockHelper engine client
243 * @return `true` if the last instance is destroyed
244 */
245 public synchronized boolean release()
246 {
247 boolean lastInstance = false;
248
249 if (referenceCounter.decrementAndGet() == 0)
250 {
251 lastInstance = true;
252
253 if (engineCreated != null)
254 {
255 // retained asynchronously
256 waitForReady();
257 disposeAdblock();
258
259 // to unlock waiting client in waitForReady()
260 engineCreated.countDown();
261 engineCreated = null;
262 }
263 else
264 {
265 disposeAdblock();
266 }
267 }
268 return lastInstance;
269 }
270 }
OLDNEW
« no previous file with comments | « libadblockplus-android/src/org/adblockplus/libadblockplus/android/SingleInstanceEngineProvider.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld