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