Left: | ||
Right: |
OLD | NEW |
---|---|
(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 package org.adblockplus.libadblockplus.android; | |
18 | |
19 import android.content.Context; | |
20 import android.content.SharedPreferences; | |
21 import android.util.Log; | |
22 | |
23 import org.adblockplus.libadblockplus.HeaderEntry; | |
24 import org.adblockplus.libadblockplus.ServerResponse; | |
25 import org.adblockplus.libadblockplus.WebRequest; | |
26 | |
27 import java.io.BufferedReader; | |
28 import java.io.IOException; | |
29 import java.io.InputStream; | |
30 import java.io.InputStreamReader; | |
31 import java.util.Collections; | |
32 import java.util.HashSet; | |
33 import java.util.List; | |
34 import java.util.Map; | |
35 import java.util.Set; | |
36 | |
37 /** | |
38 * WebRequest wrapper to return request response from android resources for sele cted URLs | |
39 */ | |
40 public class AndroidWebRequestResourceWrapper extends WebRequest | |
41 { | |
42 private static final String TAG = Utils.getTag(AndroidWebRequestResourceWrappe r.class); | |
43 | |
44 public static final String EASYLIST = | |
45 "https://easylist-downloads.adblockplus.org/easylist.txt"; | |
46 public static final String EASYLIST_INDONESIAN = | |
47 "https://easylist-downloads.adblockplus.org/abpindo+easylist.txt"; | |
48 public static final String EASYLIST_BULGARIAN = | |
49 "https://easylist-downloads.adblockplus.org/bulgarian_list+easylist.txt"; | |
50 public static final String EASYLIST_CHINESE = | |
51 "https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt"; | |
52 public static final String EASYLIST_CZECH_SLOVAK = | |
53 "https://easylist-downloads.adblockplus.org/easylistczechslovak+easylist.txt "; | |
54 public static final String EASYLIST_DUTCH = | |
55 "https://easylist-downloads.adblockplus.org/easylistdutch+easylist.txt"; | |
56 public static final String EASYLIST_GERMAN = | |
57 "https://easylist-downloads.adblockplus.org/easylistgermany+easylist.txt"; | |
58 public static final String EASYLIST_ISRAELI = | |
59 "https://easylist-downloads.adblockplus.org/israellist+easylist.txt"; | |
60 public static final String EASYLIST_ITALIAN = | |
61 "https://easylist-downloads.adblockplus.org/easylistitaly+easylist.txt"; | |
62 public static final String EASYLIST_LITHUANIAN = | |
63 "https://easylist-downloads.adblockplus.org/easylistlithuania+easylist.txt"; | |
64 public static final String EASYLIST_LATVIAN = | |
65 "https://easylist-downloads.adblockplus.org/latvianlist+easylist.txt"; | |
66 public static final String EASYLIST_ARABIAN_FRENCH = | |
67 "https://easylist-downloads.adblockplus.org/liste_ar+liste_fr+easylist.txt"; | |
68 public static final String EASYLIST_FRENCH = | |
69 "https://easylist-downloads.adblockplus.org/liste_fr+easylist.txt"; | |
70 public static final String EASYLIST_ROMANIAN = | |
71 "https://easylist-downloads.adblockplus.org/rolist+easylist.txt"; | |
72 public static final String EASYLIST_RUSSIAN = | |
73 "https://easylist-downloads.adblockplus.org/ruadlist+easylist.txt"; | |
74 public static final String ACCEPTABLE_ADS = | |
75 "https://easylist-downloads.adblockplus.org/exceptionrules.txt"; | |
76 | |
77 private Context context; | |
78 private WebRequest request; | |
79 private Map<String, Integer> URLtoResouceIdMap; | |
80 private Storage storage; | |
81 private Listener listener; | |
82 | |
83 /** | |
84 * Constructor | |
85 * @param context android context | |
86 * @param request wrapped request to perform the request if it's not preloaded subscription requested | |
87 * @param URLtoResourceIdMap map URL -> android resource id for preloaded subs criptions | |
88 * See AndroidWebRequestResourceWrapper.EASYLIST_... constants | |
89 * @param storage Storage impl to remember served interceptions | |
90 */ | |
91 public AndroidWebRequestResourceWrapper(Context context, WebRequest request, | |
92 Map<String, Integer> URLtoResourceIdMa p, | |
anton
2017/03/20 08:28:46
using map allows to pass multiple mappings and des
| |
93 Storage storage) | |
94 { | |
95 this.context = context; | |
96 this.request = request; | |
97 this.URLtoResouceIdMap = Collections.synchronizedMap(URLtoResourceIdMap); | |
98 this.storage = storage; | |
99 } | |
100 | |
101 public Listener getListener() | |
102 { | |
103 return listener; | |
104 } | |
105 | |
106 public void setListener(Listener listener) | |
107 { | |
108 this.listener = listener; | |
109 } | |
110 | |
111 @Override | |
112 public ServerResponse httpGET(String url, List<HeaderEntry> headers) | |
113 { | |
114 // since parameters may vary we need to ignore them | |
115 String urlWithoutParams = url.substring(0, url.indexOf("?")); | |
116 Integer resourceId = URLtoResouceIdMap.get(urlWithoutParams); | |
117 | |
118 if (resourceId != null) | |
119 { | |
120 if (!storage.contains(urlWithoutParams)) | |
121 { | |
122 Log.w(TAG, "Intercepting request for " + url + " with resource #" + reso urceId.intValue()); | |
123 ServerResponse response = buildResourceContentResponse(resourceId); | |
124 storage.put(urlWithoutParams); | |
125 | |
126 if (listener != null) | |
127 { | |
128 listener.onIntercepted(url, resourceId); | |
129 } | |
130 | |
131 return response; | |
132 } | |
133 else | |
134 { | |
135 Log.d(TAG, "Skip intercepting"); | |
136 } | |
137 } | |
138 | |
139 // delegate to wrapper request | |
140 return request.httpGET(url, headers); | |
141 } | |
142 | |
143 protected String readResourceContent(int resourceId) throws IOException | |
144 { | |
145 Log.d(TAG, "Reading from resource ..."); | |
146 | |
147 InputStream is = null; | |
148 | |
149 try | |
150 { | |
151 is = context.getResources().openRawResource(resourceId); | |
152 BufferedReader br = new BufferedReader(new InputStreamReader(is)); | |
153 StringBuilder sb = new StringBuilder(); | |
154 String line; | |
155 boolean firstLine = true; | |
156 while ((line = br.readLine()) != null) | |
157 { | |
158 if (firstLine) | |
159 { | |
160 firstLine = false; | |
161 } | |
162 else | |
163 { | |
164 sb.append("\r\n"); | |
165 } | |
166 sb.append(line); | |
167 } | |
168 | |
169 Log.d(TAG, "Resource read (" + sb.length() + " bytes)"); | |
170 return sb.toString(); | |
171 } | |
172 finally | |
173 { | |
174 if (is != null) | |
175 { | |
176 is.close(); | |
177 } | |
178 } | |
179 } | |
180 | |
181 protected ServerResponse buildResourceContentResponse(int resourceId) | |
182 { | |
183 ServerResponse response = new ServerResponse(); | |
184 try | |
185 { | |
186 response.setResponse(readResourceContent(resourceId)); | |
187 response.setResponseStatus(200); | |
188 response.setStatus(ServerResponse.NsStatus.OK); | |
189 } | |
190 catch (IOException e) | |
191 { | |
192 Log.e(TAG, "Error injecting response", e); | |
193 response.setStatus(ServerResponse.NsStatus.ERROR_FAILURE); | |
194 } | |
195 | |
196 return response; | |
197 } | |
198 | |
199 @Override | |
200 public void dispose() | |
201 { | |
202 request.dispose(); | |
203 super.dispose(); | |
204 } | |
205 | |
206 /** | |
207 * Listener for events | |
208 */ | |
209 public interface Listener | |
anton
2017/03/20 08:28:45
listener is introduced for the only purpose - we n
| |
210 { | |
211 void onIntercepted(String url, int resourceId); | |
212 } | |
213 | |
214 /** | |
215 * Interface to remember intercepted subscription requests | |
216 */ | |
217 public interface Storage | |
218 { | |
219 void put(String url); | |
220 boolean contains(String url); | |
221 } | |
222 | |
223 /** | |
224 * Storage impl in Shared Preferences | |
225 */ | |
226 public static class SharedPrefsStorage implements Storage | |
anton
2017/03/20 08:28:46
The only iml for now. Since we use SharedPrefsStor
| |
227 { | |
228 private static final String URLS = "urls"; | |
229 | |
230 private SharedPreferences prefs; | |
231 private Set<String> urls; | |
232 | |
233 public SharedPrefsStorage(SharedPreferences prefs) | |
234 { | |
235 this.prefs = prefs; | |
236 this.urls = prefs.getStringSet(URLS, new HashSet<String>()); | |
237 } | |
238 | |
239 @Override | |
240 public synchronized void put(String url) | |
241 { | |
242 urls.add(url); | |
243 | |
244 prefs | |
245 .edit() | |
246 .putStringSet(URLS, urls) | |
247 .commit(); | |
248 } | |
249 | |
250 @Override | |
251 public synchronized boolean contains(String url) | |
252 { | |
253 return urls.contains(url); | |
254 } | |
255 } | |
256 } | |
OLD | NEW |