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

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

Issue 29361445: Issue 4399 - Add WebView inheritor with ad blocking (Closed)
Patch Set: added retaining in asynchronous mode Created Nov. 25, 2016, 7:08 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-2016 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
18 package org.adblockplus.libadblockplus.android.settings;
19
20 import android.content.Context;
21 import android.content.SharedPreferences;
22 import android.util.Log;
23
24 import org.adblockplus.libadblockplus.android.AdblockEngine;
25 import org.adblockplus.libadblockplus.android.Utils;
26
27 import java.util.concurrent.CountDownLatch;
28 import java.util.concurrent.atomic.AtomicInteger;
29
30 /**
31 * Adblock shared resources
32 * (singleton)
33 */
34 public class Adblock
35 {
36 private static final String TAG = Utils.getTag(Adblock.class);
37
38 /**
39 * Suggested preference name
40 */
41 public static final String PREFERENCE_NAME = "ADBLOCK";
42
43 // singleton
44 protected Adblock()
45 {
46 // prevents instantiation
47 }
48
49 private static Adblock _instance;
50
51 /**
52 * Use to get Adblock instance
53 * @return adblock instance
54 */
55 public static synchronized Adblock get()
56 {
57 if (_instance == null)
58 {
59 _instance = new Adblock();
60 }
61
62 return _instance;
63 }
64
65 private Context context;
66 private boolean developmentBuild;
67 private String preferenceName;
68
69 private AdblockEngine engine;
70
71 public AdblockEngine getEngine()
72 {
73 return engine;
74 }
75
76 private AdblockSettingsStorage storage;
77
78 public AdblockSettingsStorage getStorage()
79 {
80 return storage;
81 }
82
83 /**
84 * Init with context
85 * @param context application context
86 * @param developmentBuild debug or release?
87 * @param preferenceName Shared Preferences name
88 */
89 public void init(Context context, boolean developmentBuild, String preferenceN ame)
90 {
91 this.context = context.getApplicationContext();
92 this.developmentBuild = developmentBuild;
93 this.preferenceName = preferenceName;
94 }
95
96 private CountDownLatch engineCreated;
97
98 private void createAdblock()
99 {
100 Log.d(TAG, "Creating adblock engine ...");
101
102 // read and apply current settings
103 SharedPreferences prefs = context.getSharedPreferences(preferenceName, Conte xt.MODE_PRIVATE);
104 storage = new AdblockSettingsSharedPrefsStorage(prefs);
105
106 // latch is required for async (see `waitForReady()`)
107 engineCreated = new CountDownLatch(1);
108
109 engine = AdblockEngine.create(
110 context,
111 AdblockEngine.generateAppInfo(context, developmentBuild),
112 context.getCacheDir().getAbsolutePath(),
113 true); // `true` as we need element hiding
114 Log.d(TAG, "Adblock engine created");
115
116 AdblockSettings settings = storage.load();
117 if (settings != null)
118 {
119 Log.d(TAG, "Applying saved adblock settings to adblock engine");
120 // apply last saved settings to adblock engine
121
122 // all the settings except `enabled` and whitelisted domains are saved by adblock engine itself
123 engine.setEnabled(settings.isAdblockEnabled());
124 engine.setWhitelistedDomains(settings.getWhitelistedDomains());
125 }
126 else
127 {
128 Log.w(TAG, "No saved adblock settings");
129 }
130
131 // unlock waiting client thread
132 engineCreated.countDown();
133 }
134
135 /**
136 * Wait until everything is ready (used for `retain(true)`)
137 * Warning: locks current thread
138 */
139 public void waitForReady()
140 {
141 if (engineCreated == null)
142 {
143 throw new RuntimeException("Adblock Plus usage exception: call retain(...) first");
144 }
145
146 try
147 {
148 Log.d(TAG, "Waiting for ready ...");
149 engineCreated.await();
150 Log.d(TAG, "Ready");
151 }
152 catch (InterruptedException e)
153 {
154 Log.w(TAG, "Interrupted", e);
155 }
156 }
157
158 private void disposeAdblock()
159 {
160 Log.w(TAG, "Disposing adblock engine");
161
162 engine.dispose();
163 engine = null;
164
165 // to unlock waiting client in WaitForReady()
166 engineCreated.countDown();
167 engineCreated = null;
168
169 storage = null;
170 }
171
172 /*
173 Simple ARC management for AdblockEngine
174 Use `retain` and `release`
175 */
176
177 private AtomicInteger referenceCounter = new AtomicInteger(0);
178
179 /**
180 * Get registered clients count
181 * @return registered clients count
182 */
183 public int getCounter()
184 {
185 return referenceCounter.get();
186 }
187
188 /**
189 * Register Adblock engine client
190 * @param asynchronous If `true` engines will be created in background thread without locking of
191 * current thread. Use waitForReady() before getEngine() l ater.
192 * If `false` locks current thread.
193 */
194 public synchronized void retain(boolean asynchronous)
195 {
196 if (referenceCounter.getAndIncrement() == 0)
197 {
198 if (!asynchronous)
199 {
200 createAdblock();
201 }
202 else
203 {
204 new Thread(new Runnable()
205 {
206 @Override
207 public void run()
208 {
209 createAdblock();
210 }
211 }).start();
212 }
213 }
214 }
215
216 /**
217 * Unregister Adblock engine client
218 */
219 public synchronized void release()
220 {
221 if (referenceCounter.decrementAndGet() == 0)
222 {
223 waitForReady();
224 disposeAdblock();
225 }
226 }
227 }
OLDNEW

Powered by Google App Engine
This is Rietveld