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

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

Issue 29678581: Issue 6000 - Rename "libadblockplus-android" (Closed)
Patch Set: Created Jan. 24, 2018, 6:53 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
(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 shared between registered clients
32 */
33 public class SingleInstanceEngineProvider implements AdblockEngineProvider
34 {
35 private static final String TAG = Utils.getTag(SingleInstanceEngineProvider.cl ass);
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 SingleInstanceEngineProvider(Context context, String basePath, boolean developmentBuild)
67 {
68 this.context = context.getApplicationContext();
69 this.basePath = basePath;
70 this.developmentBuild = developmentBuild;
71 }
72
73 /**
74 * Use preloaded subscriptions
75 * @param preferenceName Shared Preferences name to store intercepted requests stats
76 * @param urlToResourceIdMap
77 */
78 public SingleInstanceEngineProvider preloadSubscriptions(String preferenceName ,
79 Map<String, Integer> urlToResourceIdMap)
80 {
81 this.preloadedPreferenceName = preferenceName;
82 this.urlToResourceIdMap = urlToResourceIdMap;
83 return this;
84 }
85
86 public SingleInstanceEngineProvider useV8IsolateProvider(long ptr)
87 {
88 this.v8IsolateProviderPtr = ptr;
89 return this;
90 }
91
92 public SingleInstanceEngineProvider setEngineCreatedCallback(Runnable callback )
93 {
94 this.engineCreatedCallback = callback;
95 return this;
96 }
97
98 public SingleInstanceEngineProvider setEngineDisposedCallback(Runnable callbac k)
99 {
100 this.engineDisposedCallback = callback;
101 return this;
102 }
103
104 private void createAdblock()
105 {
106 ConnectivityManager connectivityManager =
107 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVIC E);
108 IsAllowedConnectionCallback isAllowedConnectionCallback =
109 new IsAllowedConnectionCallbackImpl(connectivityManager);
110
111 Log.d(TAG, "Creating adblock engine ...");
112
113 AdblockEngine.Builder builder = AdblockEngine
114 .builder(
115 AdblockEngine.generateAppInfo(context, developmentBuild),
116 basePath)
117 .setIsAllowedConnectionCallback(isAllowedConnectionCallback)
118 .enableElementHiding(true);
119
120 if (v8IsolateProviderPtr != null)
121 {
122 builder.useV8IsolateProvider(v8IsolateProviderPtr);
123 }
124
125 // if preloaded subscriptions provided
126 if (preloadedPreferenceName != null)
127 {
128 SharedPreferences preloadedSubscriptionsPrefs = context.getSharedPreferenc es(
129 preloadedPreferenceName,
130 Context.MODE_PRIVATE);
131 builder.preloadSubscriptions(
132 context,
133 urlToResourceIdMap,
134 new AndroidWebRequestResourceWrapper.SharedPrefsStorage(preloadedSubscri ptionsPrefs));
135 }
136
137 engine = builder.build();
138
139 Log.d(TAG, "AdblockHelper engine created");
140
141 // sometimes we need to init AdblockEngine instance, eg. set user settings
142 if (engineCreatedCallback != null)
143 {
144 engineCreatedCallback.run();
145 }
146 }
147
148 @Override
149 public synchronized boolean retain(boolean asynchronous)
150 {
151 boolean firstInstance = false;
152
153 if (referenceCounter.getAndIncrement() == 0)
154 {
155 firstInstance = true;
156
157 if (!asynchronous)
158 {
159 createAdblock();
160 }
161 else
162 {
163 // latch is required for async (see `waitForReady()`)
164 engineCreated = new CountDownLatch(1);
165
166 new Thread(new Runnable()
167 {
168 @Override
169 public void run()
170 {
171 createAdblock();
172
173 // unlock waiting client thread
174 engineCreated.countDown();
175 }
176 }).start();
177 }
178 }
179 return firstInstance;
180 }
181
182 @Override
183 public void waitForReady()
184 {
185 if (engineCreated == null)
186 {
187 throw new IllegalStateException("Usage exception: call retain(true) first" );
188 }
189
190 try
191 {
192 Log.d(TAG, "Waiting for ready in " + Thread.currentThread());
193 engineCreated.await();
194 Log.d(TAG, "Ready");
195 }
196 catch (InterruptedException e)
197 {
198 Log.w(TAG, "Interrupted", e);
199 }
200 }
201
202 @Override
203 public AdblockEngine getEngine()
204 {
205 return engine;
206 }
207
208 @Override
209 public synchronized boolean release()
210 {
211 boolean lastInstance = false;
212
213 if (referenceCounter.decrementAndGet() == 0)
214 {
215 lastInstance = true;
216
217 if (engineCreated != null)
218 {
219 // retained asynchronously
220 waitForReady();
221 disposeAdblock();
222
223 // to unlock waiting client in waitForReady()
224 engineCreated.countDown();
225 engineCreated = null;
226 }
227 else
228 {
229 disposeAdblock();
230 }
231 }
232 return lastInstance;
233 }
234
235 private void disposeAdblock()
236 {
237 Log.w(TAG, "Disposing adblock engine");
238
239 engine.dispose();
240 engine = null;
241
242 // sometimes we need to deinit something after AdblockEngine instance dispos ed
243 // eg. release user settings
244 if (engineDisposedCallback != null)
245 {
246 engineDisposedCallback.run();
247 }
248 }
249
250 @Override
251 public int getCounter()
252 {
253 return referenceCounter.get();
254 }
255 }
OLDNEW

Powered by Google App Engine
This is Rietveld