| 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 |