Add UltraPrivacy. https://redmine.stoutner.com/issues/310
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / helpers / BlockListHelper.java
1 /*
2  * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
5  *
6  * Privacy Browser is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Browser is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacybrowser.helpers;
21
22 import android.content.res.AssetManager;
23
24 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
25
26 import java.io.BufferedReader;
27 import java.io.IOException;
28 import java.io.InputStreamReader;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.regex.Pattern;
32
33 public class BlockListHelper {
34     public ArrayList<List<String[]>> parseBlockList(AssetManager assets, String blockListName) {
35         // Initialize the header list.
36         List<String[]> headers = new ArrayList<>();  // 0.
37
38         // Initialize the whitelists.
39         List<String[]> mainWhiteList = new ArrayList<>();  // 1.
40         List<String[]> finalWhiteList = new ArrayList<>();  // 2.
41         List<String[]> domainWhiteList = new ArrayList<>();  // 3.
42         List<String[]> domainInitialWhiteList = new ArrayList<>();  // 4.
43         List<String[]> domainFinalWhiteList = new ArrayList<>();  // 5.
44         List<String[]> thirdPartyWhiteList = new ArrayList<>();  // 6.
45         List<String[]> thirdPartyDomainWhiteList = new ArrayList<>();  // 7.
46         List<String[]> thirdPartyDomainInitialWhiteList = new ArrayList<>();  // 8.
47
48         // Initialize the blacklists
49         List<String[]> mainBlackList = new ArrayList<>();  // 9.
50         List<String[]> initialBlackList = new ArrayList<>();  // 10.
51         List<String[]> finalBlackList = new ArrayList<>();  // 11.
52         List<String[]> domainBlackList = new ArrayList<>();  // 12.
53         List<String[]> domainInitialBlackList = new ArrayList<>();  // 13.
54         List<String[]> domainFinalBlackList = new ArrayList<>();  // 14.
55         List<String[]> domainRegularExpressionBlackList = new ArrayList<>();  // 15.
56         List<String[]> thirdPartyBlackList = new ArrayList<>();  // 16.
57         List<String[]> thirdPartyInitialBlackList = new ArrayList<>();  // 17.
58         List<String[]> thirdPartyDomainBlackList = new ArrayList<>();  // 18.
59         List<String[]> thirdPartyDomainInitialBlackList = new ArrayList<>();  // 19.
60         List<String[]> regularExpressionBlackList = new ArrayList<>();  // 20.
61         List<String[]> thirdPartyRegularExpressionBlackList = new ArrayList<>();  // 21.
62         List<String[]> thirdPartyDomainRegularExpressionBlackList = new ArrayList<>();  // 22.
63
64
65         // Populate the block lists.  The `try` is required by `InputStreamReader`.
66         try {
67             // Load the block list into a `BufferedReader`.
68             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(assets.open(blockListName)));
69
70             // Create a string for storing the block list entries.
71             String blockListEntry;
72
73             // Parse the block list.
74             while ((blockListEntry = bufferedReader.readLine()) != null) {
75                 // Store the original block list entry.
76                 String originalBlockListEntry = blockListEntry;
77
78                 // Remove any `^` from the block list entry.  Privacy Browser does not process them in the interest of efficiency.
79                 blockListEntry = blockListEntry.replace("^", "");
80
81                 //noinspection StatementWithEmptyBody
82                 if (blockListEntry.contains("##") || blockListEntry.contains("#?#") || blockListEntry.contains("#@#") || blockListEntry.startsWith("[")) {
83                     // Entries that contain `##`, `#?#`, and `#@#` are for hiding elements in the main page's HTML.  Entries that start with `[` describe the AdBlock compatibility level.
84                     // Do nothing.  Privacy Browser does not currently use these entries.
85
86                     //Log.i("BlockLists", "Not added: " + blockListEntry);
87                 } else //noinspection StatementWithEmptyBody
88                     if (blockListEntry.contains("$csp=script-src")) {  // Ignore entries that contain `$csp=script-src`.
89                     // Do nothing.  It is uncertain what this directive is even supposed to mean, and it is blocking entire websites like androidcentral.com.  https://redmine.stoutner.com/issues/306.
90
91                     //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
92                 } else if (blockListEntry.startsWith("!")) {  //  Comment entries.
93                     if (blockListEntry.startsWith("! Version:")) {
94                         // Get the list version number.
95                         String[] listVersion = {blockListEntry.substring(11)};
96
97                         // Store the list version in the headers list.
98                         headers.add(listVersion);
99                     }
100
101                     if (blockListEntry.startsWith("! Title:")) {
102                         // Get the list title.
103                         String[] listTitle = {blockListEntry.substring(9)};
104
105                         // Store the list title in the headers list.
106                         headers.add(listTitle);
107                     }
108
109                     //Log.i("BlockLists", "Not added: " + blockListEntry);
110                 } else if (blockListEntry.startsWith("@@")) {  // Entries that begin with `@@` are whitelists.
111                     // Remove the `@@`
112                     blockListEntry = blockListEntry.substring(2);
113
114                     // Strip out any initial `||`.  Privacy Browser doesn't differentiate items that only match against the end of the domain name.
115                     if (blockListEntry.startsWith("||")) {
116                         blockListEntry = blockListEntry.substring(2);
117                     }
118
119                     if (blockListEntry.contains("$")) {  // Filter entries.
120                         //noinspection StatementWithEmptyBody
121                         if (blockListEntry.contains("~third-party")) {  // Ignore entries that contain `~third-party`.
122                             // Do nothing.
123
124                             //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
125                         } else if (blockListEntry.contains("third-party")) {  // Third-party white list entries.
126                             if (blockListEntry.contains("domain=")) {  // Third-party domain white list entries.
127                                 // Parse the entry.
128                                 String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
129                                 String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
130                                 String domains = filters.substring(filters.indexOf("domain=") + 7);
131
132                                 //noinspection StatementWithEmptyBody
133                                 if (domains.contains("~")) {  // It is uncertain what a `~` domain means inside an `@@` entry.
134                                     // Do Nothing
135
136                                     //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
137                                 } else if (blockListEntry.startsWith("|")) {  // Third-party domain initial white list entries.
138                                     // Strip out the initial `|`.
139                                     entry = entry.substring(1);
140
141                                     //noinspection StatementWithEmptyBody
142                                     if (entry.equals("http://") || entry.equals("https://")) {  // Ignore generic entries.
143                                         // Do nothing.  These entries are designed for filter options that Privacy Browser does not use.
144
145                                         //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
146                                     } else {  // Process third-party domain initial white list entries.
147                                         // Process each domain.
148                                         do {
149                                             // Create a string to keep track of the current domain.
150                                             String domain;
151
152                                             if (domains.contains("|")) {  // There is more than one domain in the list.
153                                                 // Get the first domain from the list.
154                                                 domain = domains.substring(0, domains.indexOf("|"));
155
156                                                 // Remove the first domain from the list.
157                                                 domains = domains.substring(domains.indexOf("|") + 1);
158                                             } else {  // There is only one domain in the list.
159                                                 domain = domains;
160                                             }
161
162                                             if (entry.contains("*")) {  // Process a third-party domain initial white list double entry.
163                                                 // Get the index of the wildcard.
164                                                 int wildcardIndex = entry.indexOf("*");
165
166                                                 // Split the entry into components.
167                                                 String firstEntry = entry.substring(0, wildcardIndex);
168                                                 String secondEntry = entry.substring(wildcardIndex + 1);
169
170                                                 // Create an entry string array.
171                                                 String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
172
173                                                 // Add the entry to the white list.
174                                                 thirdPartyDomainInitialWhiteList.add(domainDoubleEntry);
175
176                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party domain initial white list added: " + domain + " , " + firstEntry + " , " + secondEntry +
177                                                 //        "  -  " + originalBlockListEntry);
178                                             } else {  // Process a third-party domain initial white list single entry.
179                                                 // Create a domain entry string array.
180                                                 String[] domainEntry = {domain, entry, originalBlockListEntry};
181
182                                                 // Add the entry to the third party domain initial white list.
183                                                 thirdPartyDomainInitialWhiteList.add(domainEntry);
184
185                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party domain initial white list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
186                                             }
187                                         } while (domains.contains("|"));
188                                     }
189                                 } else {  // Third-party domain entries.
190                                     // Process each domain.
191                                     do {
192                                         // Create a string to keep track of the current domain.
193                                         String domain;
194
195                                         if (domains.contains("|")) {  // three is more than one domain in the list.
196                                             // Get the first domain from the list.
197                                             domain = domains.substring(0, domains.indexOf("|"));
198
199                                             // Remove the first domain from the list.
200                                             domains = domains.substring(domains.indexOf("|") + 1);
201                                         } else {  // There is only one domain in the list.
202                                             domain = domains;
203                                         }
204
205                                         // Remove any trailing `*` from the entry.
206                                         if (entry.endsWith("*")) {
207                                             entry = entry.substring(0, entry.length() - 1);
208                                         }
209
210                                         if (entry.contains("*")) {  // Process a third-party domain double entry.
211                                             // Get the index of the wildcard.
212                                             int wildcardIndex = entry.indexOf("*");
213
214                                             // Split the entry into components.
215                                             String firstEntry = entry.substring(0, wildcardIndex);
216                                             String secondEntry = entry.substring(wildcardIndex + 1);
217
218                                             // Create an entry string array.
219                                             String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
220
221                                             // Add the entry to the white list.
222                                             thirdPartyDomainWhiteList.add(domainDoubleEntry);
223
224                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain white list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
225                                             //        originalBlockListEntry);
226                                         } else {  // Process a third-party domain single entry.
227                                             // Create an entry string array.
228                                             String[] domainEntry = {domain, entry, originalBlockListEntry};
229
230                                             // Add the entry to the white list.
231                                             thirdPartyDomainWhiteList.add(domainEntry);
232
233                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain white list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
234                                         }
235                                     } while (domains.contains("|"));
236                                 }
237                             } else {  // Process third-party white list entries.
238                                 // Parse the entry
239                                 String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
240
241                                 if (entry.contains("*")) {  // There are two or more entries.
242                                     // Get the index of the wildcard.
243                                     int wildcardIndex = entry.indexOf("*");
244
245                                     // Split the entry into components.
246                                     String firstEntry = entry.substring(0, wildcardIndex);
247                                     String secondEntry = entry.substring(wildcardIndex + 1);
248
249                                     if (secondEntry.contains("*")) {  // There are three or more entries.
250                                         // Get the index of the wildcard.
251                                         int secondWildcardIndex = secondEntry.indexOf("*");
252
253                                         // Split the entry into components.
254                                         String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
255                                         String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
256
257                                         if (thirdEntry.contains("*")) {  // There are four or more entries.
258                                             // Get the index of the wildcard.
259                                             int thirdWildcardIndex = thirdEntry.indexOf("*");
260
261                                             // Split the entry into components.
262                                             String realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex);
263                                             String fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1);
264
265                                             if (fourthEntry.contains("*")) {  // Process a third-party white list quintuple entry.
266                                                 // Get the index of the wildcard.
267                                                 int fourthWildcardIndex = fourthEntry.indexOf("*");
268
269                                                 // Split the entry into components.
270                                                 String realFourthEntry = fourthEntry.substring(0, fourthWildcardIndex);
271                                                 String fifthEntry = fourthEntry.substring(fourthWildcardIndex + 1);
272
273                                                 // Create an entry string array.
274                                                 String[] quintupleEntry = {firstEntry, realSecondEntry, realThirdEntry, realFourthEntry, fifthEntry, originalBlockListEntry};
275
276                                                 // Add the entry to the white list.
277                                                 thirdPartyWhiteList.add(quintupleEntry);
278
279                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party white list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
280                                                 //        realFourthEntry + " , " + fifthEntry + "  -  " + originalBlockListEntry);
281                                             } else {  // Process a third-party white list quadruple entry.
282                                                 // Create an entry string array.
283                                                 String[] quadrupleEntry = {firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalBlockListEntry};
284
285                                                 // Add the entry to the white list.
286                                                 thirdPartyWhiteList.add(quadrupleEntry);
287
288                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party white list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
289                                                 //        fourthEntry + "  -  " + originalBlockListEntry);
290                                             }
291                                         } else {  // Process a third-party white list triple entry.
292                                             // Create an entry string array.
293                                             String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
294
295                                             // Add the entry to the white list.
296                                             thirdPartyWhiteList.add(tripleEntry);
297
298                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party white list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " +
299                                             //        originalBlockListEntry);
300                                         }
301                                     } else {  // Process a third-party white list double entry.
302                                         // Create an entry string array.
303                                         String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
304
305                                         // Add the entry to the white list.
306                                         thirdPartyWhiteList.add(doubleEntry);
307
308                                         //Log.i("BlockLists", headers.get(1)[0] + " third-party white list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
309                                     }
310                                 } else {  // Process a third-party white list single entry.
311                                     // Create an entry string array.
312                                     String[] singleEntry = {entry, originalBlockListEntry};
313
314                                     // Add the entry to the white list.
315                                     thirdPartyWhiteList.add(singleEntry);
316
317                                     //Log.i("BlockLists", headers.get(1)[0] + " third-party domain white list added: " + entry + "  -  " + originalBlockListEntry);
318                                 }
319                             }
320                         } else if (blockListEntry.contains("domain=")) {  // Process domain white list entries.
321                             // Parse the entry
322                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
323                             String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
324                             String domains = filters.substring(filters.indexOf("domain=") + 7);
325
326                             if (entry.startsWith("|")) {  // Initial domain white list entries.
327                                 // Strip the initial `|`.
328                                 entry = entry.substring(1);
329
330                                 //noinspection StatementWithEmptyBody
331                                 if (entry.equals("http://") || entry.equals("https://")) {  // Ignore generic entries.
332                                     // Do nothing.  These entries are designed for filter options that Privacy Browser does not use.
333
334                                     //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
335                                 } else {  // Initial domain white list entry.
336                                     // Process each domain.
337                                     do {
338                                         // Create a string to keep track of the current domain.
339                                         String domain;
340
341                                         if (domains.contains("|")) {  // There is more than one domain in the list.
342                                             // Get the first domain from the list.
343                                             domain = domains.substring(0, domains.indexOf("|"));
344
345                                             // Remove the first domain from the list.
346                                             domains = domains.substring(domains.indexOf("|") + 1);
347                                         } else {  // There is only one domain in the list.
348                                             domain = domains;
349                                         }
350
351                                         if (entry.contains("*")) {  // There are two or more entries.
352                                             // Get the index of the wildcard.
353                                             int wildcardIndex = entry.indexOf("*");
354
355                                             // Split the entry into components.
356                                             String firstEntry = entry.substring(0, wildcardIndex);
357                                             String secondEntry = entry.substring(wildcardIndex + 1);
358
359                                             if (secondEntry.contains("*")) {  // Process a domain initial triple entry.
360                                                 // Get the index of the wildcard.
361                                                 int secondWildcardIndex = secondEntry.indexOf("*");
362
363                                                 // Split the entry into components.
364                                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
365                                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
366
367                                                 // Create an entry string array.
368                                                 String[] domainTripleEntry = {domain, firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
369
370                                                 // Add the entry to the white list.
371                                                 domainInitialWhiteList.add(domainTripleEntry);
372
373                                                 //Log.i("BlockLists", headers.get(1)[0] + " domain initial white list entry added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
374                                                 //        thirdEntry + "  -  " + originalBlockListEntry);
375                                             } else {  // Process a domain initial double entry.
376                                                 // Create an entry string array.
377                                                 String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
378
379                                                 // Add the entry to the white list.
380                                                 domainInitialWhiteList.add(domainDoubleEntry);
381
382                                                 //Log.i("BlockLists", headers.get(1)[0] + " domain initial white list entry added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
383                                                 //        originalBlockListEntry);
384                                             }
385                                         } else {  // Process a domain initial single entry.
386                                             // Create an entry string array.
387                                             String[] domainEntry = {domain, entry, originalBlockListEntry};
388
389                                             // Add the entry to the white list.
390                                             domainInitialWhiteList.add(domainEntry);
391
392                                             //Log.i("BlockLists", headers.get(1)[0] + " domain initial white list entry added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
393                                         }
394                                     } while (domains.contains("|"));
395                                 }
396                             } else if (entry.endsWith("|")) {  // Final domain white list entries.
397                                 // Strip the `|` from the end of the entry.
398                                 entry = entry.substring(0, entry.length() - 1);
399
400                                 // Process each domain.
401                                 do {
402                                     // Create a string to keep track of the current domain.
403                                     String domain;
404
405                                     if (domains.contains("|")) {  // There is more than one domain in the list.
406                                         // Get the first domain from the list.
407                                         domain = domains.substring(0, domains.indexOf("|"));
408
409                                         // Remove the first domain from the list.
410                                         domains = domains.substring(domains.indexOf("|") + 1);
411                                     } else {  // There is only one domain in the list.
412                                         domain = domains;
413                                     }
414
415                                     if (entry.contains("*")) {  // Process a domain final white list double entry.
416                                         // Get the index of the wildcard.
417                                         int wildcardIndex = entry.indexOf("*");
418
419                                         // Split the entry into components.
420                                         String firstEntry = entry.substring(0, wildcardIndex);
421                                         String secondEntry = entry.substring(wildcardIndex + 1);
422
423                                         // Create an entry string array.
424                                         String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
425
426                                         // Add the entry to the white list.
427                                         domainFinalWhiteList.add(domainDoubleEntry);
428
429                                         //Log.i("BlockLists", headers.get(1)[0] + " domain final white list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
430                                         //        originalBlockListEntry);
431                                     } else {  // Process a domain final white list single entry.
432                                         // create an entry string array.
433                                         String[] domainEntry = {domain, entry, originalBlockListEntry};
434
435                                         // Add the entry to the white list.
436                                         domainFinalWhiteList.add(domainEntry);
437
438                                         //Log.i("BlockLists", headers.get(1)[0] + " domain final white list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
439                                     }
440                                 } while (domains.contains("|"));
441
442                             } else {  // Standard domain white list entries with filters.
443                                 //noinspection StatementWithEmptyBody
444                                 if (domains.contains("~")) {  // It is uncertain what a `~` domain means inside an `@@` entry.
445                                     // Do Nothing
446
447                                     //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
448                                 } else {
449                                     // Process each domain.
450                                     do {
451                                         // Create a string to keep track of the current domain.
452                                         String domain;
453
454                                         if (domains.contains("|")) {  // There is more than one domain in the list.
455                                             // Get the first domain from the list.
456                                             domain = domains.substring(0, domains.indexOf("|"));
457
458                                             // Remove the first domain from the list.
459                                             domains = domains.substring(domains.indexOf("|") + 1);
460                                         } else {  // There is only one domain in the list.
461                                             domain = domains;
462                                         }
463
464                                         if (entry.contains("*")) {  // There are two or more entries.
465                                             // Get the index of the wildcard.
466                                             int wildcardIndex = entry.indexOf("*");
467
468                                             // Split the entry into components.
469                                             String firstEntry = entry.substring(0, wildcardIndex);
470                                             String secondEntry = entry.substring(wildcardIndex + 1);
471
472                                             if (secondEntry.contains("*")) {  // There are three or more entries.
473                                                 // Get the index of the wildcard.
474                                                 int secondWildcardIndex = secondEntry.indexOf("*");
475
476                                                 // Split the entry into components.
477                                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
478                                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
479
480                                                 if (thirdEntry.contains("*")) {  // Process a domain white list quadruple entry.
481                                                     // Get the index of the wildcard.
482                                                     int thirdWildcardIndex = thirdEntry.indexOf("*");
483
484                                                     // Split the entry into components.
485                                                     String realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex);
486                                                     String fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1);
487
488                                                     // Create an entry string array.
489                                                     String[] domainQuadrupleEntry = {domain, firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalBlockListEntry};
490
491                                                     // Add the entry to the white list.
492                                                     domainWhiteList.add(domainQuadrupleEntry);
493
494                                                     //Log.i("BlockLists", headers.get(1)[0] + " domain white list added : " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
495                                                     //        realThirdEntry + " , " + fourthEntry + "  -  " + originalBlockListEntry);
496                                                 } else {  // Process a domain white list triple entry.
497                                                     // Create an entry string array.
498                                                     String[] domainTripleEntry = {domain, firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
499
500                                                     // Add the entry to the white list.
501                                                     domainWhiteList.add(domainTripleEntry);
502
503                                                     //Log.i("BlockLists", headers.get(1)[0] + " domain white list added : " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
504                                                     //        thirdEntry + "  -  " + originalBlockListEntry);
505                                                 }
506                                             } else {  // Process a domain white list double entry.
507                                                 // Create an entry string array.
508                                                 String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
509
510                                                 // Add the entry to the white list.
511                                                 domainWhiteList.add(domainDoubleEntry);
512
513                                                 //Log.i("BlockLists", headers.get(1)[0] + " domain white list added : " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
514                                                 //        originalBlockListEntry);
515                                             }
516                                         } else {  // Process a domain white list single entry.
517                                             // Create an entry string array.
518                                             String[] domainEntry = {domain, entry, originalBlockListEntry};
519
520                                             // Add the entry to the white list.
521                                             domainWhiteList.add(domainEntry);
522
523                                             //Log.i("BlockLists", headers.get(1)[0] + " domain white list added : " + domain + " , " + entry + "  -  " + originalBlockListEntry);
524                                         }
525                                     } while (domains.contains("|"));
526                                 }
527                             }
528                         }  // Ignore all other filter entries.
529                     } else if (blockListEntry.endsWith("|")) {  // Final white list entries.
530                         // Remove the final `|` from the entry.
531                         String entry = blockListEntry.substring(0, blockListEntry.length() - 1);
532
533                         if (entry.contains("*")) {  // Process a final white list double entry
534                             // Get the index of the wildcard.
535                             int wildcardIndex = entry.indexOf("*");
536
537                             // split the entry into components.
538                             String firstEntry = entry.substring(0, wildcardIndex);
539                             String secondEntry = entry.substring(wildcardIndex + 1);
540
541                             // Create an entry string array.
542                             String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
543
544                             // Add the entry to the white list.
545                             finalWhiteList.add(doubleEntry);
546
547                             //Log.i("BlockLists", headers.get(1)[0] + " final white list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
548                         } else {  // Process a final white list single entry.
549                             // Create an entry string array.
550                             String[] singleEntry = {entry, originalBlockListEntry};
551
552                             // Add the entry to the white list.
553                             finalWhiteList.add(singleEntry);
554
555                             //Log.i("BlockLists", headers.get(1)[0] + " final white list added: " + entry + "  -  " + originalBlockListEntry);
556                         }
557                     } else {  // Main white list entries.
558                         if (blockListEntry.contains("*")) {  // There are two or more entries.
559                             // Get the index of the wildcard.
560                             int wildcardIndex = blockListEntry.indexOf("*");
561
562                             // Split the entry into components.
563                             String firstEntry = blockListEntry.substring(0, wildcardIndex);
564                             String secondEntry = blockListEntry.substring(wildcardIndex + 1);
565
566                             if (secondEntry.contains("*")) {  // Process a main white list triple entry.
567                                 // Get the index of the wildcard.
568                                 int secondWildcardIndex = secondEntry.indexOf("*");
569
570                                 // Split the entry into components.
571                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
572                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
573
574                                 // Create an entry string array.
575                                 String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
576
577                                 // Add the entry to the white list.
578                                 mainWhiteList.add(tripleEntry);
579
580                                 //Log.i("BlockLists", headers.get(1)[0] + " main white list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalBlockListEntry);
581                             } else {  // Process a main white list double entry.
582                                 // Create an entry string array.
583                                 String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
584
585                                 // Add the entry to the white list.
586                                 mainWhiteList.add(doubleEntry);
587
588                                 //Log.i("BlockLists", headers.get(1)[0] + " main white list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
589                             }
590                         } else {  // Process a main white list single entry.
591                             // Create an entry string array.
592                             String[] singleEntry = {blockListEntry, originalBlockListEntry};
593
594                             // Add the entry to the white list.
595                             mainWhiteList.add(singleEntry);
596
597                             //Log.i("BlockLists", headers.get(1)[0] + " main white list added: " + blockListEntry + "  -  " + originalBlockListEntry);
598                         }
599                     }
600                 } else if (blockListEntry.endsWith("|")) {  // Final black list entries.
601                     // Strip out the final "|"
602                     String entry = blockListEntry.substring(0, blockListEntry.length() - 1);
603
604                     // Strip out any initial `||`.  They are redundant in this case because the block list entry is being matched against the end of the URL.
605                     if (entry.startsWith("||")) {
606                         entry = entry.substring(2);
607                     }
608
609                     if (entry.contains("*")) {  // Process a final black list double entry.
610                         // Get the index of the wildcard.
611                         int wildcardIndex = entry.indexOf("*");
612
613                         // Split the entry into components.
614                         String firstEntry = entry.substring(0, wildcardIndex);
615                         String secondEntry = entry.substring(wildcardIndex + 1);
616
617                         // Create an entry string array.
618                         String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
619
620                         // Add the entry to the black list.
621                         finalBlackList.add(doubleEntry);
622
623                         //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
624                     } else {  // Process a final black list single entry.
625                         // create an entry string array.
626                         String[] singleEntry = {entry, originalBlockListEntry};
627
628                         // Add the entry to the black list.
629                         finalBlackList.add(singleEntry);
630
631                         //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + entry + "  -  " + originalBlockListEntry);
632                     }
633                 } else if (blockListEntry.contains("$")) {  // Entries with filter options.
634                     // Strip out any initial `||`.  These will be treated like any other entry.
635                     if (blockListEntry.startsWith("||")) {
636                         blockListEntry = blockListEntry.substring(2);
637                     }
638
639                     if (blockListEntry.contains("third-party")) {  // Third-party entries.
640                         //noinspection StatementWithEmptyBody
641                         if (blockListEntry.contains("~third-party")) {  // Third-party filter white list entries.
642                             // Do not process these white list entries.  They are designed to combine with block filters that Privacy Browser doesn't use, like `subdocument` and `xmlhttprequest`.
643
644                             //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
645                         } else if (blockListEntry.contains("domain=")) {  // Third-party domain entries.
646                             if (blockListEntry.startsWith("|")) {  // Third-party domain initial entries.
647                                 // Strip the initial `|`.
648                                 blockListEntry = blockListEntry.substring(1);
649
650                                 // Parse the entry
651                                 String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
652                                 String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
653                                 String domains = filters.substring(filters.indexOf("domain=") + 7);
654
655                                 //noinspection StatementWithEmptyBody
656                                 if (entry.equals("http:") || entry.equals("https:") || entry.equals("http://") || entry.equals("https://")) {  // Ignore generic entries.
657                                     // Do nothing.  These entries will almost entirely disable the website.
658                                     // Often the original entry blocks filter options like `$script`, which Privacy Browser does not differentiate.
659
660                                     //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
661                                 } else {  // Third-party domain initial entries.
662                                     // Process each domain.
663                                     do {
664                                         // Create a string to keep track of the current domain.
665                                         String domain;
666
667                                         if (domains.contains("|")) {  // There is more than one domain in the list.
668                                             // Get the first domain from the list.
669                                             domain = domains.substring(0, domains.indexOf("|"));
670
671                                             // Remove the first domain from the list.
672                                             domains = domains.substring(domains.indexOf("|") + 1);
673                                         } else {  // There is only one domain in the list.
674                                             domain = domains;
675                                         }
676
677                                         if (entry.contains("*")) {  // Three are two or more entries.
678                                             // Get the index of the wildcard.
679                                             int wildcardIndex = entry.indexOf("*");
680
681                                             // Split the entry into components.
682                                             String firstEntry = entry.substring(0, wildcardIndex);
683                                             String secondEntry = entry.substring(wildcardIndex + 1);
684
685                                             if (secondEntry.contains("*")) {  // Process a third-party domain initial black list triple entry.
686                                                 // Get the index of the wildcard.
687                                                 int secondWildcardIndex = secondEntry.indexOf("*");
688
689                                                 // Split the entry into components.
690                                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
691                                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
692
693                                                 // Create an entry string array.
694                                                 String[] tripleDomainEntry = {domain, firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
695
696                                                 // Add the entry to the black list.
697                                                 thirdPartyDomainInitialBlackList.add(tripleDomainEntry);
698
699                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party domain initial black list added: " + domain + " , " + firstEntry + " , " + realSecondEntry +
700                                                 //        " , " + thirdEntry + "  -  " + originalBlockListEntry);
701                                             } else {  // Process a third-party domain initial black list double entry.
702                                                 // Create an entry string array.
703                                                 String[] doubleDomainEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
704
705                                                 // Add the entry to the black list.
706                                                 thirdPartyDomainInitialBlackList.add(doubleDomainEntry);
707
708                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party domain initial black list added: " + domain + " , " + firstEntry + " , " + secondEntry +
709                                                 //        "  -  " + originalBlockListEntry);
710                                             }
711                                         } else {  // Process a third-party domain initial black list single entry.
712                                             // Create an entry string array.
713                                             String[] singleEntry = {domain, entry, originalBlockListEntry};
714
715                                             // Add the entry to the black list.
716                                             thirdPartyDomainInitialBlackList.add(singleEntry);
717
718                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain initial black list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
719                                         }
720                                     } while (domains.contains("|"));
721                                 }
722                             } else if (blockListEntry.contains("\\")) {  // Process a third-party domain black list regular expression.
723                                 // Parse the entry.  At least one regular expression in this entry contains `$`, so the parser uses `/$`.
724                                 String entry = blockListEntry.substring(0, blockListEntry.indexOf("/$") + 1);
725                                 String filters = blockListEntry.substring(blockListEntry.indexOf("/$") + 2);
726                                 String domains = filters.substring(filters.indexOf("domain=") + 7);
727
728                                 // Process each domain.
729                                 do {
730                                     // Create a string to keep track of the current domain.
731                                     String domain;
732
733                                     if (domains.contains("|")) {  // There is more than one domain in the list.
734                                         // Get the first domain from the list.
735                                         domain = domains.substring(0, domains.indexOf("|"));
736
737                                         // Remove the first domain from the list.
738                                         domains = domains.substring(domains.indexOf("|") + 1);
739                                     } else {  // There is only one domain in the list.
740                                         domain = domains;
741                                     }
742
743                                     // Create an entry string array.
744                                     String[] domainEntry = {domain, entry, originalBlockListEntry};
745
746                                     // Add the entry to the black list.
747                                     thirdPartyDomainRegularExpressionBlackList.add(domainEntry);
748
749                                     //Log.i("BlockLists", headers.get(1)[0] + " third-party domain regular expression black list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
750                                 } while (domains.contains("|"));
751                             } else {  // Third-party domain entries.
752                                 // Parse the entry
753                                 String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
754                                 String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
755                                 String domains = filters.substring(filters.indexOf("domain=") + 7);
756
757                                 // Strip any trailing "*" from the entry.
758                                 if (entry.endsWith("*")) {
759                                     entry = entry.substring(0, entry.length() - 1);
760                                 }
761
762                                 // Track if any third-party white list filters are applied.
763                                 boolean whiteListDomain = false;
764
765                                 // Process each domain.
766                                 do {
767                                     // Create a string to keep track of the current domain.
768                                     String domain;
769
770                                     if (domains.contains("|")) {  // There is more than one domain in the list.
771                                         // Get the first domain from the list.
772                                         domain = domains.substring(0, domains.indexOf("|"));
773
774                                         // Remove the first domain from the list.
775                                         domains = domains.substring(domains.indexOf("|") + 1);
776                                     } else {  // The is only one domain in the list.
777                                         domain = domains;
778                                     }
779
780                                     // Differentiate between block list domains and white list domains.
781                                     if (domain.startsWith("~")) {  // White list third-party domain entry.
782                                         // Strip the initial `~`.
783                                         domain = domain.substring(1);
784
785                                         // Set the white list domain flag.
786                                         whiteListDomain = true;
787
788                                         if (entry.contains("*")) {  // Process a third-party domain white list double entry.
789                                             // Get the index of the wildcard.
790                                             int wildcardIndex = entry.indexOf("*");
791
792                                             // Split the entry into components.
793                                             String firstEntry = entry.substring(0, wildcardIndex);
794                                             String secondEntry = entry.substring(wildcardIndex + 1);
795
796                                             // Create an entry string array.
797                                             String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
798
799                                             // Add the entry to the white list.
800                                             thirdPartyDomainWhiteList.add(domainDoubleEntry);
801
802                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain white list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
803                                             //        originalBlockListEntry);
804                                         } else {  // Process a third-party domain white list single entry.
805                                             // Create an entry string array.
806                                             String[] domainEntry = {domain, entry, originalBlockListEntry};
807
808                                             // Add the entry to the white list.
809                                             thirdPartyDomainWhiteList.add(domainEntry);
810
811                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain white list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
812                                         }
813                                     } else {  // Third-party domain black list entries.
814                                         if (entry.contains("*")) {  // Process a third-party domain black list double entry.
815                                             // Get the index of the wildcard.
816                                             int wildcardIndex = entry.indexOf("*");
817
818                                             // Split the entry into components.
819                                             String firstEntry = entry.substring(0, wildcardIndex);
820                                             String secondEntry = entry.substring(wildcardIndex + 1);
821
822                                             // Create an entry string array.
823                                             String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
824
825                                             // Add the entry to the black list
826                                             thirdPartyDomainBlackList.add(domainDoubleEntry);
827
828                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain black list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
829                                             //        originalBlockListEntry);
830                                         } else {  // Process a third-party domain black list single entry.
831                                             // Create an entry string array.
832                                             String[] domainEntry = {domain, entry, originalBlockListEntry};
833
834                                             // Add the entry to the black list.
835                                             thirdPartyDomainBlackList.add(domainEntry);
836
837                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain block list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
838                                         }
839                                     }
840                                 } while (domains.contains("|"));
841
842                                 // Add a third-party black list entry if a white list domain was processed.
843                                 if (whiteListDomain) {
844                                     if (entry.contains("*")) {  // Process a third-party black list double entry.
845                                         // Get the index of the wildcard.
846                                         int wildcardIndex = entry.indexOf("*");
847
848                                         // Split the entry into components.
849                                         String firstEntry = entry.substring(0, wildcardIndex);
850                                         String secondEntry = entry.substring(wildcardIndex + 1);
851
852                                         // Create an entry string array.
853                                         String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
854
855                                         // Add the entry to the black list.
856                                         thirdPartyBlackList.add(doubleEntry);
857
858                                         //Log.i("BlockLists", headers.get(1)[0] + " third-party black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
859                                     } else {  // Process a third-party black list single entry.
860                                         // Create an entry string array.
861                                         String[] singleEntry = {entry, originalBlockListEntry};
862
863                                         // Add an entry to the black list.
864                                         thirdPartyBlackList.add(singleEntry);
865
866                                         //Log.i("BlockLists", headers.get(1)[0] + " third-party black list added: " + entry + "  -  " + originalBlockListEntry);
867                                     }
868                                 }
869                             }
870                         } else if (blockListEntry.startsWith("|")) {  // Third-party initial black list entries.
871                             // Strip the initial `|`.
872                             blockListEntry = blockListEntry.substring(1);
873
874                             // Get the entry.
875                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
876
877                             if (entry.contains("*")) {  // Process a third-party initial black list double entry.
878                                 // Get the index of the wildcard.
879                                 int wildcardIndex = entry.indexOf("*");
880
881                                 // Split the entry into components.
882                                 String firstEntry = entry.substring(0, wildcardIndex);
883                                 String secondEntry = entry.substring(wildcardIndex + 1);
884
885                                 // Create an entry string array.
886                                 String[] thirdPartyDoubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
887
888                                 // Add the entry to the black list.
889                                 thirdPartyInitialBlackList.add(thirdPartyDoubleEntry);
890
891                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party initial black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
892                             } else {  // Process a third-party initial black list single entry.
893                                 // Create an entry string array.
894                                 String[] singleEntry = {entry, originalBlockListEntry};
895
896                                 // Add the entry to the black list.
897                                 thirdPartyInitialBlackList.add(singleEntry);
898
899                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party initial black list added: " + entry + "  -  " + originalBlockListEntry);
900                             }
901                         } else if (blockListEntry.contains("\\")) {  // Process a regular expression black list entry.
902                             // Prepare a string to hold the entry.
903                             String entry;
904
905                             // Get the entry.
906                             if (blockListEntry.contains("$/$")) {  // The first `$` is part of the regular expression.
907                                 entry = blockListEntry.substring(0, blockListEntry.indexOf("$/$") + 2);
908                             } else {  // The only `$` indicates the filter options.
909                                 entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
910                             }
911
912                             // Create an entry string array.
913                             String[] singleEntry = {entry, originalBlockListEntry};
914
915                             // Add the entry to the black list.
916                             thirdPartyRegularExpressionBlackList.add(singleEntry);
917
918                             //Log.i("BlockLists", headers.get(1)[0] + " third-party regular expression black list added: " + entry + "  -  " + originalBlockListEntry);
919                         } else if (blockListEntry.contains("*")) {  // Third-party and regular expression black list entries.
920                             // Get the entry.
921                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
922
923                             if (entry.endsWith("*")) {  // Process a third-party black list single entry.
924                                 // Strip the final `*`.
925                                 entry = entry.substring(0, entry.length() - 1);
926
927                                 // Create an entry string array.
928                                 String[] singleEntry = {entry, originalBlockListEntry};
929
930                                 // Add the entry to the black list.
931                                 thirdPartyBlackList.add(singleEntry);
932
933                                 //Log.i("BlockLists", headers.get(1)[0] + " third party black list added: " + entry + "  -  " + originalBlockListEntry);
934                             } else {  // There are two or more entries.
935                                 // Get the index of the wildcard.
936                                 int wildcardIndex = entry.indexOf("*");
937
938                                 // Split the entry into components.
939                                 String firstEntry = entry.substring(0, wildcardIndex);
940                                 String secondEntry = entry.substring(wildcardIndex + 1);
941
942                                 if (secondEntry.contains("*")) {  // There are three or more entries.
943                                     // Get the index of the wildcard.
944                                     int secondWildcardIndex = secondEntry.indexOf("*");
945
946                                     // Split the entry into components.
947                                     String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
948                                     String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
949
950                                     if (thirdEntry.contains("*")) {  // Process a third-party black list quadruple entry.
951                                         // Get the index of the wildcard.
952                                         int thirdWildcardIndex = thirdEntry.indexOf("*");
953
954                                         // Split the entry into components.
955                                         String realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex);
956                                         String fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1);
957
958                                         // Create an entry string array.
959                                         String[] quadrupleEntry = {firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalBlockListEntry};
960
961                                         // Add the entry to the black list.
962                                         thirdPartyBlackList.add(quadrupleEntry);
963
964                                         //Log.i("BlockLists", headers.get(1)[0] + " third-party black list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
965                                         //        fourthEntry + "  -  " + originalBlockListEntry);
966                                     } else {  // Process a third-party black list triple entry.
967                                         // Create an entry string array.
968                                         String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
969
970                                         // Add the entry to the black list.
971                                         thirdPartyBlackList.add(tripleEntry);
972
973                                         //Log.i("BlockLists", headers.get(1)[0] + " third-party black list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " +
974                                         //        originalBlockListEntry);
975                                     }
976                                 } else {  // Process a third-party black list double entry.
977                                     // Create an entry string array.
978                                     String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
979
980                                     // Add the entry to the black list.
981                                     thirdPartyBlackList.add(doubleEntry);
982
983                                     //Log.i("BlockLists", headers.get(1)[0] + " third-party black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
984                                 }
985                             }
986                         } else {  // Process a third party black list single entry.
987                             // Get the entry.
988                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
989
990                             // Create an entry string array.
991                             String[] singleEntry = {entry, originalBlockListEntry};
992
993                             // Add the entry to the black list.
994                             thirdPartyBlackList.add(singleEntry);
995
996                             //Log.i("BlockLists", headers.get(1)[0] + " third party black list added: " + entry + "  -  " + originalBlockListEntry);
997                         }
998                     } else if (blockListEntry.substring(blockListEntry.indexOf("$")).contains("domain=")) {  // Domain entries.
999                         if (blockListEntry.contains("~")) {  // Domain white list entries.
1000                             // Separate the filters.
1001                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
1002                             String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
1003                             String domains = filters.substring(filters.indexOf("domain=") + 7);
1004
1005                             // Strip any final `*` from the entry.  They are redundant.
1006                             if (entry.endsWith("*")) {
1007                                 entry = entry.substring(0, entry.length() - 1);
1008                             }
1009
1010                             // Process each domain.
1011                             do {
1012                                 // Create a string to keep track of the current domain.
1013                                 String domain;
1014
1015                                 if (domains.contains("|")) {  // There is more than one domain in the list.
1016                                     // Get the first domain from the list.
1017                                     domain = domains.substring(0, domains.indexOf("|"));
1018
1019                                     // Remove the first domain from the list.
1020                                     domains = domains.substring(domains.indexOf("|") + 1);
1021                                 } else {  // There is only one domain in the list.
1022                                     domain = domains;
1023                                 }
1024
1025                                 // Strip the initial `~`.
1026                                 domain = domain.substring(1);
1027
1028                                 if (entry.contains("*")) {  // There are two or more entries.
1029                                     // Get the index of the wildcard.
1030                                     int wildcardIndex = entry.indexOf("*");
1031
1032                                     // Split the entry into components.
1033                                     String firstEntry = entry.substring(0, wildcardIndex);
1034                                     String secondEntry = entry.substring(wildcardIndex + 1);
1035
1036                                     if (secondEntry.contains("*")) {  // Process a domain white list triple entry.
1037                                         // Get the index of the wildcard.
1038                                         int secondWildcardIndex = secondEntry.indexOf("*");
1039
1040                                         // Split the entry into components.
1041                                         String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1042                                         String thirdEntry = secondEntry.substring((secondWildcardIndex + 1));
1043
1044                                         // Create an entry string array.
1045                                         String[] domainTripleEntry = {domain, firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1046
1047                                         // Add the entry to the white list.
1048                                         domainWhiteList.add(domainTripleEntry);
1049
1050                                         //Log.i("BlockLists", headers.get(1)[0] + " domain white list added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry +
1051                                         //        "  -  " + originalBlockListEntry);
1052                                     } else {  // Process a domain white list double entry.
1053                                         // Create an entry string array.
1054                                         String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
1055
1056                                         // Add the entry to the white list.
1057                                         domainWhiteList.add(domainDoubleEntry);
1058
1059                                         //Log.i("BlockLists", headers.get(1)[0] + " domain white list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1060                                     }
1061                                 } else {  // Process a domain white list single entry.
1062                                     // Create an entry string array.
1063                                     String[] domainEntry = {domain, entry, originalBlockListEntry};
1064
1065                                     // Add the entry to the white list.
1066                                     domainWhiteList.add(domainEntry);
1067
1068                                     //Log.i("BlockLists", headers.get(1)[0] + " domain white list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
1069                                 }
1070                             } while (domains.contains("|"));
1071                         } else {  // Domain black list entries.
1072                             // Separate the filters.
1073                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
1074                             String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
1075                             String domains = filters.substring(filters.indexOf("domain=") + 7);
1076
1077                             // Only process the item if the entry is not null.  For example, some lines begin with `$websocket`, which create a null entry.
1078                             if (!entry.equals("")) {
1079                                 // Process each domain.
1080                                 do {
1081                                     // Create a string to keep track of the current domain.
1082                                     String domain;
1083
1084                                     if (domains.contains("|")) {  // There is more than one domain in the list.
1085                                         // Get the first domain from the list.
1086                                         domain = domains.substring(0, domains.indexOf("|"));
1087
1088                                         // Remove the first domain from the list.
1089                                         domains = domains.substring(domains.indexOf("|") + 1);
1090                                     } else {  // There is only one domain in the list.
1091                                         domain = domains;
1092                                     }
1093
1094                                     if (entry.startsWith("|")) {  // Domain initial black list entries.
1095                                         // Remove the initial `|`;
1096                                         String entryBase = entry.substring(1);
1097
1098                                         //noinspection StatementWithEmptyBody
1099                                         if (entryBase.equals("http://") || entryBase.equals("https://")) {
1100                                             // Do nothing.  These entries will entirely block the website.
1101                                             // Often the original entry blocks `$script` but Privacy Browser does not currently differentiate between scripts and other entries.
1102
1103                                             //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
1104                                         } else {  // Process a domain initial black list entry
1105                                             // Create an entry string array.
1106                                             String[] domainEntry = {domain, entryBase, originalBlockListEntry};
1107
1108                                             // Add the entry to the black list.
1109                                             domainInitialBlackList.add(domainEntry);
1110
1111                                             //Log.i("BlockLists", headers.get(1)[0] + " domain initial black list added: " + domain + " , " + entryBase + "  -  " + originalBlockListEntry);
1112                                         }
1113                                     } else if (entry.endsWith("|")) {  // Domain final black list entries.
1114                                         // Remove the final `|`.
1115                                         String entryBase = entry.substring(0, entry.length() - 1);
1116
1117                                         if (entryBase.contains("*")) {  // Process a domain final black list double entry.
1118                                             // Get the index of the wildcard.
1119                                             int wildcardIndex = entry.indexOf("*");
1120
1121                                             // Split the entry into components.
1122                                             String firstEntry = entryBase.substring(0, wildcardIndex);
1123                                             String secondEntry = entryBase.substring(wildcardIndex + 1);
1124
1125                                             // Create an entry string array.
1126                                             String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
1127
1128                                             // Add the entry to the black list.
1129                                             domainFinalBlackList.add(domainDoubleEntry);
1130
1131                                             //Log.i("BlockLists", headers.get(1)[0] + " domain final black list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
1132                                             //        originalBlockListEntry);
1133                                         } else {  // Process a domain final black list single entry.
1134                                             // Create an entry string array.
1135                                             String[] domainEntry = {domain, entryBase, originalBlockListEntry};
1136
1137                                             // Add the entry to the black list.
1138                                             domainFinalBlackList.add(domainEntry);
1139
1140                                             //Log.i("BlockLists", headers.get(1)[0] + " domain final black list added: " + domain + " , " + entryBase + "  -  " + originalBlockListEntry);
1141                                         }
1142                                     } else if (entry.contains("\\")) {  // Process a domain regular expression black list entry.
1143                                         // Create an entry string array.
1144                                         String[] domainEntry = {domain, entry, originalBlockListEntry};
1145
1146                                         // Add the entry to the black list.
1147                                         domainRegularExpressionBlackList.add(domainEntry);
1148
1149                                         //Log.i("BlockLists", headers.get(1)[0] + " domain regular expression black list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
1150                                     } else if (entry.contains("*")) {  // There are two or more entries.
1151                                         // Get the index of the wildcard.
1152                                         int wildcardIndex = entry.indexOf("*");
1153
1154                                         // Split the entry into components.
1155                                         String firstEntry = entry.substring(0, wildcardIndex);
1156                                         String secondEntry = entry.substring(wildcardIndex + 1);
1157
1158                                         if (secondEntry.contains("*")) {  // Process a domain black list triple entry.
1159                                             // Get the index of the wildcard.
1160                                             int secondWildcardIndex = secondEntry.indexOf("*");
1161
1162                                             // Split the entry into components.
1163                                             String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1164                                             String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
1165
1166                                             // Create an entry string array.
1167                                             String[] domainTripleEntry = {domain, firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1168
1169                                             // Add the entry to the black list.
1170                                             domainBlackList.add(domainTripleEntry);
1171
1172                                             //Log.i("BlockLists", headers.get(1)[0] + " domain black list added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry +
1173                                             //        "  -  " + originalBlockListEntry);
1174                                         } else {  // Process a domain black list double entry.
1175                                             // Create an entry string array.
1176                                             String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
1177
1178                                             // Add the entry to the black list.
1179                                             domainBlackList.add(domainDoubleEntry);
1180
1181                                             //Log.i("BlockLists", headers.get(1)[0] + " domain black list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
1182                                             //        originalBlockListEntry);
1183                                         }
1184                                     } else {  // Process a domain black list single entry.
1185                                         // Create an entry string array.
1186                                         String[] domainEntry = {domain, entry, originalBlockListEntry};
1187
1188                                         // Add the entry to the black list.
1189                                         domainBlackList.add(domainEntry);
1190
1191                                         //Log.i("BlockLists", headers.get(1)[0] + " domain black list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
1192                                     }
1193                                 } while (domains.contains("|"));
1194                             }
1195                         }
1196                     } else if (blockListEntry.contains("~")) {  // White list entries.  Privacy Browser does not differentiate against these filter options, so they are just generally white listed.
1197                         // Remove the filter options.
1198                         blockListEntry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
1199
1200                         // Strip any trailing `*`.
1201                         if (blockListEntry.endsWith("*")) {
1202                             blockListEntry = blockListEntry.substring(0, blockListEntry.length() - 1);
1203                         }
1204
1205                         if (blockListEntry.contains("*")) {  // Process a white list double entry.
1206                             // Get the index of the wildcard.
1207                             int wildcardIndex = blockListEntry.indexOf("*");
1208
1209                             // Split the entry into components.
1210                             String firstEntry = blockListEntry.substring(0, wildcardIndex);
1211                             String secondEntry = blockListEntry.substring(wildcardIndex + 1);
1212
1213                             // Create an entry string array.
1214                             String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1215
1216                             // Add the entry to the white list.
1217                             mainWhiteList.add(doubleEntry);
1218
1219                             //Log.i("BlockLists", headers.get(1)[0] + " main white list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1220                         } else {  // Process a white list single entry.
1221                             // Create an entry string array.
1222                             String[] singleEntry = {blockListEntry, originalBlockListEntry};
1223
1224                             // Add the entry to the white list.
1225                             mainWhiteList.add(singleEntry);
1226
1227                             //Log.i("BlockLists", headers.get(1)[0] + " main white list added: " + blockListEntry + "  -  + " + originalBlockListEntry);
1228                         }
1229                     } else if (blockListEntry.contains("\\")) {  // Process a regular expression black list entry.
1230                         // Remove the filter options.
1231                         blockListEntry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
1232
1233                         // Create an entry string array.
1234                         String[] singleEntry = {blockListEntry, originalBlockListEntry};
1235
1236                         // Add the entry to the black list.
1237                         regularExpressionBlackList.add(singleEntry);
1238
1239                         //Log.i("BlockLists", headers.get(1)[0] + " regular expression black list added: " + blockListEntry + "  -  " + originalBlockListEntry);
1240                     } else {  // Black list entries.
1241                         // Remove the filter options.
1242                         if (!blockListEntry.contains("$file")) {  // EasyPrivacy contains an entry with `$file` that does not have filter options.
1243                             blockListEntry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
1244                         }
1245
1246                         // Strip any trailing `*`.  These are redundant.
1247                         if (blockListEntry.endsWith("*")) {
1248                             blockListEntry = blockListEntry.substring(0, blockListEntry.length() - 1);
1249                         }
1250
1251                         if (blockListEntry.startsWith("|")) {  // Initial black list entries.
1252                             // Strip the initial `|`.
1253                             String entry = blockListEntry.substring(1);
1254
1255                             if (entry.contains("*")) {  // Process an initial black list double entry.
1256                                 // Get the index of the wildcard.
1257                                 int wildcardIndex = entry.indexOf("*");
1258
1259                                 // Split the entry into components.
1260                                 String firstEntry = entry.substring(0, wildcardIndex);
1261                                 String secondEntry = entry.substring(wildcardIndex + 1);
1262
1263                                 // Create an entry string array.
1264                                 String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1265
1266                                 // Add the entry to the black list.
1267                                 initialBlackList.add(doubleEntry);
1268
1269                                 //Log.i("BlockLists", headers.get(1)[0] + " initial black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1270                             } else {  // Process an initial black list single entry.
1271                                 // Create an entry string array.
1272                                 String[] singleEntry = {entry, originalBlockListEntry};
1273
1274                                 // Add the entry to the black list.
1275                                 initialBlackList.add(singleEntry);
1276
1277                                 //Log.i("BlockLists", headers.get(1)[0] + " initial black list added: " + entry + "  -  " + originalBlockListEntry);
1278                             }
1279                         } else if (blockListEntry.endsWith("|")) {  // Final black list entries.
1280                             // Ignore entries with `object` filters.  They can block entire websites and don't have any meaning in the context of Privacy Browser.
1281                             if (!originalBlockListEntry.contains("$object")) {
1282                                 // Strip the final `|`.
1283                                 String entry = blockListEntry.substring(0, blockListEntry.length() - 1);
1284
1285                                 if (entry.contains("*")) {  // There are two or more entries.
1286                                     // Get the index of the wildcard.
1287                                     int wildcardIndex = entry.indexOf("*");
1288
1289                                     // Split the entry into components.
1290                                     String firstEntry = entry.substring(0, wildcardIndex);
1291                                     String secondEntry = entry.substring(wildcardIndex + 1);
1292
1293                                     if (secondEntry.contains("*")) {  // Process a final black list triple entry.
1294                                         // Get the index of the wildcard.
1295                                         int secondWildcardIndex = secondEntry.indexOf("*");
1296
1297                                         // Split the entry into components.
1298                                         String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1299                                         String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
1300
1301                                         // Create an entry string array.
1302                                         String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1303
1304                                         // Add the entry to the black list.
1305                                         finalBlackList.add(tripleEntry);
1306
1307                                         //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " +
1308                                         //        originalBlockListEntry);
1309                                     } else {  // Process a final black list double entry.
1310                                         // Create an entry string array.
1311                                         String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1312
1313                                         // Add the entry to the black list.
1314                                         finalBlackList.add(doubleEntry);
1315
1316                                         //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1317                                     }
1318                                 } else {  // Process a final black list single entry.
1319                                     // Create an entry sting array.
1320                                     String[] singleEntry = {entry, originalBlockListEntry};
1321
1322                                     // Add the entry to the black list.
1323                                     finalBlackList.add(singleEntry);
1324
1325                                     //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + entry + "  -  " + originalBlockListEntry);
1326                                 }
1327                             }
1328                         } else if (blockListEntry.contains("*")) {  // There are two or more entries.
1329                             // Get the index of the wildcard.
1330                             int wildcardIndex = blockListEntry.indexOf("*");
1331
1332                             // Split the entry into components.
1333                             String firstEntry = blockListEntry.substring(0, wildcardIndex);
1334                             String secondEntry = blockListEntry.substring(wildcardIndex + 1);
1335
1336                             if (secondEntry.contains("*")) {  // Process a main black list triple entry.
1337                                 // Get the index of the wildcard.
1338                                 int secondWildcardIndex = secondEntry.indexOf("*");
1339
1340                                 // Split the entry into components.
1341                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1342                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
1343
1344                                 // Create an entry string array.
1345                                 String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1346
1347                                 // Add the entry to the black list.
1348                                 mainBlackList.add(tripleEntry);
1349
1350                                 //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalBlockListEntry);
1351                             } else {  // Process a main black list double entry.
1352                                 // Create an entry string array.
1353                                 String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1354
1355                                 // Add the entry to the black list.
1356                                 mainBlackList.add(doubleEntry);
1357
1358                                 //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1359                             }
1360                         } else {  // Process a main black list single entry.
1361                             // Create an entry string array.
1362                             String[] singleEntry = {blockListEntry, originalBlockListEntry};
1363
1364                             // Add the entry to the black list.
1365                             mainBlackList.add(singleEntry);
1366
1367                             //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + blockListEntry + "  -  " + originalBlockListEntry);
1368                         }
1369                     }
1370                 } else {  // Main black list entries
1371                     // Strip out any initial `||`.  These will be treated like any other entry.
1372                     if (blockListEntry.startsWith("||")) {
1373                         blockListEntry = blockListEntry.substring(2);
1374                     }
1375
1376                     // Strip out any initial `*`.
1377                     if (blockListEntry.startsWith("*")) {
1378                         blockListEntry = blockListEntry.substring(1);
1379                     }
1380
1381                     // Strip out any trailing `*`.
1382                     if (blockListEntry.endsWith("*")) {
1383                         blockListEntry = blockListEntry.substring(0, blockListEntry.length() - 1);
1384                     }
1385
1386                     if (blockListEntry.startsWith("|")) {  // Initial black list entries.
1387                         // Strip the initial `|`.
1388                         String entry = blockListEntry.substring(1);
1389
1390                         if (entry.contains("*")) {  // Process an initial black list double entry.
1391                             // Get the index of the wildcard.
1392                             int wildcardIndex = entry.indexOf("*");
1393
1394                             // Split the entry into components.
1395                             String firstEntry = entry.substring(0, wildcardIndex);
1396                             String secondEntry = entry.substring(wildcardIndex + 1);
1397
1398                             // Create an entry string array.
1399                             String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1400
1401                             // Add the entry to the black list.
1402                             initialBlackList.add(doubleEntry);
1403
1404                             //Log.i("BlockLists", headers.get(1)[0] + " initial black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1405                         } else {  // Process an initial black list single entry.
1406                             // Create an entry string array.
1407                             String[] singleEntry = {entry, originalBlockListEntry};
1408
1409                             // Add the entry to the black list.
1410                             initialBlackList.add(singleEntry);
1411
1412                             //Log.i("BlockLists", headers.get(1)[0] + " initial black list added: " + entry + "  -  " + originalBlockListEntry);
1413                         }
1414                     } else if (blockListEntry.endsWith("|")) {  // Final black list entries.
1415                         // Strip the final `|`.
1416                         String entry = blockListEntry.substring(0, blockListEntry.length() - 1);
1417
1418                         if (entry.contains("*")) {  // There are two or more entries.
1419                             // Get the index of the wildcard.
1420                             int wildcardIndex = entry.indexOf("*");
1421
1422                             // Split the entry into components.
1423                             String firstEntry = entry.substring(0, wildcardIndex);
1424                             String secondEntry = entry.substring(wildcardIndex + 1);
1425
1426                             if (secondEntry.contains("*")) {  // Process a final black list triple entry.
1427                                 // Get the index of the wildcard.
1428                                 int secondWildcardIndex = secondEntry.indexOf("*");
1429
1430                                 // Split the entry into components.
1431                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1432                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
1433
1434                                 // Create an entry string array.
1435                                 String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1436
1437                                 // Add the entry to the black list.
1438                                 finalBlackList.add(tripleEntry);
1439
1440                                 //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " +
1441                                 //        originalBlockListEntry);
1442                             } else {  // Process a final black list double entry.
1443                                 // Create an entry string array.
1444                                 String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1445
1446                                 // Add the entry to the black list.
1447                                 finalBlackList.add(doubleEntry);
1448
1449                                 //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1450                             }
1451                         } else {  // Process a final black list single entry.
1452                             // Create an entry string array.
1453                             String[] singleEntry = {entry, originalBlockListEntry};
1454
1455                             // Add the entry to the black list.
1456                             finalBlackList.add(singleEntry);
1457
1458                             //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + entry + "  -  " + originalBlockListEntry);
1459                         }
1460                     } else {  // Main black list entries.
1461                         if (blockListEntry.contains("*")) {  // There are two or more entries.
1462                             // Get the index of the wildcard.
1463                             int wildcardIndex = blockListEntry.indexOf("*");
1464
1465                             // Split the entry into components.
1466                             String firstEntry = blockListEntry.substring(0, wildcardIndex);
1467                             String secondEntry = blockListEntry.substring(wildcardIndex + 1);
1468
1469                             if (secondEntry.contains("*")) {  // There are three or more entries.
1470                                 // Get the index of the wildcard.
1471                                 int secondWildcardIndex = secondEntry.indexOf("*");
1472
1473                                 // Split the entry into components.
1474                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1475                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
1476
1477                                 if (thirdEntry.contains("*")) {  // There are four or more entries.
1478                                     // Get the index of the wildcard.
1479                                     int thirdWildcardIndex = thirdEntry.indexOf("*");
1480
1481                                     // Split the entry into components.
1482                                     String realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex);
1483                                     String fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1);
1484
1485                                     if (fourthEntry.contains("*")) {  // Process a main black list quintuple entry.
1486                                         // Get the index of the wildcard.
1487                                         int fourthWildcardIndex = fourthEntry.indexOf("*");
1488
1489                                         // Split the entry into components.
1490                                         String realFourthEntry = fourthEntry.substring(0, fourthWildcardIndex);
1491                                         String fifthEntry = fourthEntry.substring(fourthWildcardIndex + 1);
1492
1493                                         // Create an entry string array.
1494                                         String[] quintupleEntry = {firstEntry, realSecondEntry, realThirdEntry, realFourthEntry, fifthEntry, originalBlockListEntry};
1495
1496                                         // Add the entry to the black list.
1497                                         mainBlackList.add(quintupleEntry);
1498
1499                                         //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
1500                                         //        realFourthEntry + " , " + fifthEntry + "  -  " + originalBlockListEntry);
1501                                     } else {  // Process a main black list quadruple entry.
1502                                         // Create an entry string array.
1503                                         String[] quadrupleEntry = {firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalBlockListEntry};
1504
1505                                         // Add the entry to the black list.
1506                                         mainBlackList.add(quadrupleEntry);
1507
1508                                         //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
1509                                         //        fourthEntry + "  -  " + originalBlockListEntry);
1510                                     }
1511                                 } else {  // Process a main black list triple entry.
1512                                     // Create an entry string array.
1513                                     String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1514
1515                                     // Add the entry to the black list.
1516                                     mainBlackList.add(tripleEntry);
1517
1518                                     //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalBlockListEntry);
1519                                 }
1520                             } else {  // Process a main black list double entry.
1521                                 // Create an entry string array.
1522                                 String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1523
1524                                 // Add the entry to the black list.
1525                                 mainBlackList.add(doubleEntry);
1526
1527                                 //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1528                             }
1529                         } else {  // Process a main black list single entry.
1530                             // Create an entry string array.
1531                             String[] singleEntry = {blockListEntry, originalBlockListEntry};
1532
1533                             // Add the entry to the black list.
1534                             mainBlackList.add(singleEntry);
1535
1536                             //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + blockListEntry + "  -  " + originalBlockListEntry);
1537                         }
1538                     }
1539                 }
1540             }
1541             // Close `bufferedReader`.
1542             bufferedReader.close();
1543         } catch (IOException e) {
1544             // The asset exists, so the `IOException` will never be thrown.
1545         }
1546
1547         // Initialize the combined list.
1548         ArrayList<List<String[]>> combinedLists = new ArrayList<>();
1549
1550         // Add the headers (0).
1551         combinedLists.add(headers);  // 0.
1552
1553         // Add the white lists (1-8).
1554         combinedLists.add(mainWhiteList);  // 1.
1555         combinedLists.add(finalWhiteList);  // 2.
1556         combinedLists.add(domainWhiteList);  // 3.
1557         combinedLists.add(domainInitialWhiteList);  // 4.
1558         combinedLists.add(domainFinalWhiteList); // 5.
1559         combinedLists.add(thirdPartyWhiteList);  // 6.
1560         combinedLists.add(thirdPartyDomainWhiteList);  // 7.
1561         combinedLists.add(thirdPartyDomainInitialWhiteList);  // 8.
1562
1563         // Add the black lists (9-22).
1564         combinedLists.add(mainBlackList);  // 9.
1565         combinedLists.add(initialBlackList);  // 10.
1566         combinedLists.add(finalBlackList);  // 11.
1567         combinedLists.add(domainBlackList);  //  12.
1568         combinedLists.add(domainInitialBlackList);  // 13.
1569         combinedLists.add(domainFinalBlackList);  // 14.
1570         combinedLists.add(domainRegularExpressionBlackList);  // 15.
1571         combinedLists.add(thirdPartyBlackList);  // 16.
1572         combinedLists.add(thirdPartyInitialBlackList);  // 17.
1573         combinedLists.add(thirdPartyDomainBlackList);  // 18.
1574         combinedLists.add(thirdPartyDomainInitialBlackList);  // 19.
1575         combinedLists.add(thirdPartyRegularExpressionBlackList);  // 20.
1576         combinedLists.add(thirdPartyDomainRegularExpressionBlackList);  // 21.
1577         combinedLists.add(regularExpressionBlackList);  // 22.
1578
1579         return combinedLists;
1580     }
1581
1582     public boolean isBlocked(String currentDomain, String resourceUrl, boolean isThirdPartyRequest, ArrayList<List<String[]>> blockList) {
1583         // Get the block list name.
1584         String BLOCK_LIST_NAME_STRING = blockList.get(0).get(1)[0];
1585
1586         // Assert that currentDomain != null only if this is a third party request.  Apparently, lint can't tell that this isn't redundant.
1587         //noinspection RedundantIfStatement
1588         if (isThirdPartyRequest) {
1589             assert currentDomain != null;
1590         }
1591
1592         // Process the white lists.
1593         // Main white list.
1594         for (String[] whiteListEntry : blockList.get(MainWebViewActivity.MAIN_WHITELIST)) {
1595             switch (whiteListEntry.length) {
1596                 case 2:  // There is one entry.
1597                     if (resourceUrl.contains(whiteListEntry[0])) {
1598                         // Store the entry in the resource request log.
1599                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1600                                 String.valueOf(MainWebViewActivity.MAIN_WHITELIST), whiteListEntry[0], whiteListEntry[1]};
1601
1602                         // Not blocked.
1603                         return false;
1604                     }
1605                     break;
1606
1607                 case 3:  // There are two entries.
1608                     if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1])) {
1609                         // Store the entry in the resource request log.
1610                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1611                                 String.valueOf(MainWebViewActivity.MAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1],
1612                                 whiteListEntry[2]};
1613
1614                         // Not blocked.
1615                         return false;
1616                     }
1617                     break;
1618
1619                 case 4:  // There are three entries.
1620                     if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1621                         // Store the entry in the resource request log.
1622                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1623                                 String.valueOf(MainWebViewActivity.MAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1624
1625                         // Not blocked.
1626                         return false;
1627                     }
1628                     break;
1629             }
1630         }
1631
1632         // Final white list.
1633         for (String[] whiteListEntry : blockList.get(MainWebViewActivity.FINAL_WHITELIST)) {
1634             if (whiteListEntry.length == 2) {  // There is one entry.
1635                 if (resourceUrl.contains(whiteListEntry[0])) {
1636                     // Store the entry in the resource request log.
1637                     MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1638                             String.valueOf(MainWebViewActivity.FINAL_WHITELIST), whiteListEntry[0], whiteListEntry[1]};
1639
1640                     // Not blocked.
1641                     return false;
1642                 }
1643             } else {  // There are two entries.
1644                 if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1])) {
1645                     // Store the entry in the resource request log.
1646                     MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1647                             String.valueOf(MainWebViewActivity.FINAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1648
1649                     // Not blocked.
1650                     return false;
1651                 }
1652             }
1653         }
1654
1655         // Only check the domain lists if the current domain is not null (like `about:blank`).
1656         if (currentDomain != null) {
1657             // Domain white list.
1658             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.DOMAIN_WHITELIST)) {
1659                 switch (whiteListEntry.length) {
1660                     case 3:  // There is one entry.
1661                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1])) {
1662                             // Store the entry in the resource request log.
1663                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1664                                     String.valueOf(MainWebViewActivity.DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1665
1666                             // Not blocked.
1667                             return false;
1668                         }
1669                         break;
1670
1671                     case 4:  // There are two entries.
1672                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1673                             // Store the entry in the resource request log.
1674                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1675                                     String.valueOf(MainWebViewActivity.DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1676
1677                             // Not blocked.
1678                             return false;
1679                         }
1680                         break;
1681
1682                     case 5:  // There are three entries.
1683                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2]) && resourceUrl.contains(whiteListEntry[3])) {
1684                             // Store the entry in the resource request log.
1685                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1686                                     String.valueOf(MainWebViewActivity.DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2] + "\n" + whiteListEntry[3],
1687                                     whiteListEntry[4]};
1688
1689                             // Not blocked.
1690                             return false;
1691                         }
1692                         break;
1693
1694                     case 6:  // There are four entries.
1695                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2]) && resourceUrl.contains(whiteListEntry[3]) &&
1696                                 resourceUrl.contains(whiteListEntry[4])) {
1697                             // Store the entry in the resource request log.
1698                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1699                                     String.valueOf(MainWebViewActivity.DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2] + "\n" + whiteListEntry[3] + "\n" +
1700                                     whiteListEntry[4], whiteListEntry[5]};
1701
1702                             // Not blocked.
1703                             return false;
1704                         }
1705                         break;
1706                 }
1707             }
1708
1709             // Domain initial white list.
1710             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.DOMAIN_INITIAL_WHITELIST)) {
1711                 switch (whiteListEntry.length) {
1712                     case 3:  // There is one entry.
1713                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.startsWith(whiteListEntry[1])) {
1714                             // Store the entry in the resource request log.
1715                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1716                                     String.valueOf(MainWebViewActivity.DOMAIN_INITIAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1717
1718                             // Not blocked.
1719                             return false;
1720                         }
1721                         break;
1722
1723                     case 4:  // There are two entries.
1724                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.startsWith(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1725                             // Store the entry in the resource request log.
1726                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1727                                     String.valueOf(MainWebViewActivity.DOMAIN_INITIAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1728
1729                             // Not blocked.
1730                             return false;
1731                         }
1732                         break;
1733
1734                     case 5:  // There are three entries.
1735                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.startsWith(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2]) && resourceUrl.startsWith(whiteListEntry[3])) {
1736                             // Store the entry in the resource request log.
1737                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1738                                     String.valueOf(MainWebViewActivity.DOMAIN_INITIAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2] + "\n" + whiteListEntry[3],
1739                                     whiteListEntry[4]};
1740
1741                             // Not blocked.
1742                             return false;
1743                         }
1744                         break;
1745                 }
1746             }
1747
1748             // Domain final white list.
1749             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.DOMAIN_FINAL_WHITELIST)) {
1750                 switch (whiteListEntry.length) {
1751                     case 3:  // There is one entry;
1752                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.endsWith(whiteListEntry[1])) {
1753                             // Store the entry in the resource request log.
1754                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1755                                     String.valueOf(MainWebViewActivity.DOMAIN_FINAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1756
1757                             // Not blocked.
1758                             return false;
1759                         }
1760                         break;
1761
1762                     case 4:  // There are two entries;
1763                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.endsWith(whiteListEntry[2])) {
1764                             // Store the entry in the resource request log.
1765                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1766                                     String.valueOf(MainWebViewActivity.DOMAIN_FINAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1767
1768
1769                             // Not blocked.
1770                             return false;
1771                         }
1772                         break;
1773                 }
1774             }
1775         }
1776
1777         // Only check the third-party white lists if this is a third-party request.
1778         if (isThirdPartyRequest) {
1779             // Third-party white list.
1780             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_WHITELIST)) {
1781                 switch (whiteListEntry.length) {
1782                     case 2:  // There is one entry
1783                         if (resourceUrl.contains(whiteListEntry[0])) {
1784                             // Store the entry in the resource request log.
1785                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1786                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_WHITELIST), whiteListEntry[0], whiteListEntry[1]};
1787
1788                             // Not blocked.
1789                             return false;
1790                         }
1791                         break;
1792
1793                     case 3:  // There are two entries.
1794                         if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1])) {
1795                             // Store the entry in the resource request log.
1796                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1797                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1798
1799                             // Not blocked.
1800                             return false;
1801                         }
1802                         break;
1803
1804                     case 4:  // There are three entries.
1805                         if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1806                             // Store the entry in the resource request log.
1807                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1808                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1809
1810                             // Not blocked.
1811                             return false;
1812                         }
1813                         break;
1814
1815                     case 5:  // There are four entries.
1816                         if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2]) && resourceUrl.contains(whiteListEntry[3])) {
1817                             // Store the entry in the resource request log.
1818                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1819                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2] + "\n" + whiteListEntry[3],
1820                                     whiteListEntry[4]};
1821                             // Not blocked.
1822                             return false;
1823                         }
1824                         break;
1825
1826                     case 6:  // There are five entries.
1827                         if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2]) && resourceUrl.contains(whiteListEntry[3]) &&
1828                                 resourceUrl.contains(whiteListEntry[4])) {
1829                             // Store the entry in the resource request log.
1830                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1831                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2] + "\n" + whiteListEntry[3] + "\n" +
1832                                     whiteListEntry[4], whiteListEntry[5]};
1833
1834                             // Not blocked.
1835                             return false;
1836                         }
1837                         break;
1838                 }
1839             }
1840
1841             // Third-party domain white list.
1842             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_DOMAIN_WHITELIST)) {
1843                 if (whiteListEntry.length == 3) {  // There is one entry.
1844                     if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1])) {
1845                         // Store the entry in the resource request log.
1846                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1847                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1848
1849                         // Not blocked.
1850                         return false;
1851                     }
1852                 } else {  // There are two entries.
1853                     if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1854                         // Store the entry in the resource request log.
1855                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1856                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1857
1858                         // Not blocked.
1859                         return false;
1860                     }
1861                 }
1862             }
1863
1864             // Third-party domain initial white list.
1865             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_DOMAIN_INITIAL_WHITELIST)) {
1866                 if (whiteListEntry.length == 3) {  // There is one entry.
1867                     if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.startsWith(whiteListEntry[1])) {
1868                         // Store the entry in the resource request log.
1869                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1870                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_DOMAIN_INITIAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1871
1872                         // Not blocked.
1873                         return false;
1874                     }
1875                 } else {  // There are two entries.
1876                     if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.startsWith(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1877                         // Store the entry in the resource request log.
1878                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1879                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1880
1881                         // Not blocked.
1882                         return false;
1883                     }
1884                 }
1885             }
1886         }
1887
1888         // Process the black lists.
1889         // Main black list.
1890         for (String[] blackListEntry : blockList.get(MainWebViewActivity.MAIN_BLACKLIST)) {
1891             switch (blackListEntry.length) {
1892                 case 2:  // There is one entry.
1893                     if (resourceUrl.contains(blackListEntry[0])) {
1894                         // Store the entry in the resource request log.
1895                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1896                                 String.valueOf(MainWebViewActivity.MAIN_BLACKLIST), blackListEntry[0], blackListEntry[1]});
1897
1898                         // Blocked.
1899                         return true;
1900                     }
1901                     break;
1902
1903                 case 3:  // There are two entries.
1904                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1])) {
1905                         // Store the entry in the resource request log.
1906                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1907                                 String.valueOf(MainWebViewActivity.MAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
1908
1909                         // Blocked.
1910                         return true;
1911                     }
1912                     break;
1913
1914                 case 4:  // There are three entries.
1915                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2])) {
1916                         // Store the entry in the resource request log.
1917                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1918                                 String.valueOf(MainWebViewActivity.MAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2], blackListEntry[3]});
1919
1920                         // Blocked.
1921                         return true;
1922                     }
1923                     break;
1924
1925                 case 5:  // There are four entries.
1926                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2]) && resourceUrl.contains(blackListEntry[3])) {
1927                         // Store the entry in the resource request log.
1928                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1929                                 String.valueOf(MainWebViewActivity.MAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2] + "\n" + blackListEntry[3], blackListEntry[4]});
1930
1931                         // Blocked.
1932                         return true;
1933                     }
1934                     break;
1935
1936                 case 6:  // There are five entries.
1937                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2]) && resourceUrl.contains(blackListEntry[3]) &&
1938                             resourceUrl.contains(blackListEntry[4])) {
1939                         // Store the entry in the resource request log.
1940                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1941                                 String.valueOf(MainWebViewActivity.MAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2] + "\n" + blackListEntry[3] + "\n" +
1942                                 blackListEntry[4], blackListEntry[5]});
1943
1944                         // Blocked.
1945                         return true;
1946                     }
1947                     break;
1948             }
1949         }
1950
1951         // Initial black list.
1952         for (String[] blackListEntry : blockList.get(MainWebViewActivity.INITIAL_BLACKLIST)) {
1953             if (blackListEntry.length == 2) {  // There is one entry.
1954                 if (resourceUrl.startsWith(blackListEntry[0])) {
1955                     // Store the entry in the resource request log.
1956                     MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1957                             String.valueOf(MainWebViewActivity.INITIAL_BLACKLIST), blackListEntry[0], blackListEntry[1]});
1958
1959                     // Blocked.
1960                     return true;
1961                 }
1962             } else {  // There are two entries
1963                 if (resourceUrl.startsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1])) {
1964                     // Store the entry in the resource request log.
1965                     MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1966                             String.valueOf(MainWebViewActivity.INITIAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
1967
1968                     // Blocked.
1969                     return true;
1970                 }
1971             }
1972         }
1973
1974         // Final black list.
1975         for (String[] blackListEntry : blockList.get(MainWebViewActivity.FINAL_BLACKLIST)) {
1976             switch (blackListEntry.length) {
1977                 case 2:  // There is one entry.
1978                     if (resourceUrl.endsWith(blackListEntry[0])) {
1979                         // Store the entry in the resource request log.
1980                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1981                                 String.valueOf(MainWebViewActivity.FINAL_BLACKLIST), blackListEntry[0], blackListEntry[1]});
1982
1983                         // Blocked.
1984                         return true;
1985                     }
1986                     break;
1987
1988                 case 3:  // There are two entries.
1989                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.endsWith(blackListEntry[1])) {
1990                         // Store the entry in the resource request log.
1991                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1992                                 String.valueOf(MainWebViewActivity.FINAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
1993
1994                         // Blocked.
1995                         return true;
1996                     }
1997                     break;
1998
1999                 case 4:  // There are three entries.
2000                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.endsWith(blackListEntry[2])) {
2001                         // Store the entry in the resource request log.
2002                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2003                                 String.valueOf(MainWebViewActivity.FINAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2], blackListEntry[3]});
2004
2005                         // Blocked.
2006                         return true;
2007                     }
2008                     break;
2009             }
2010         }
2011
2012         // Only check the domain lists if the current domain is not null (like `about:blank`).
2013         if (currentDomain != null) {
2014             // Domain black list.
2015             for (String[] blackListEntry : blockList.get(MainWebViewActivity.DOMAIN_BLACKLIST)) {
2016                 switch (blackListEntry.length) {
2017                     case 3:  // There is one entry.
2018                         if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1])) {
2019                             // Store the entry in the resource request log.
2020                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2021                                     String.valueOf(MainWebViewActivity.DOMAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
2022
2023                             // Blocked.
2024                             return true;
2025                         }
2026                         break;
2027
2028                     case 4:  // There are two entries.
2029                         if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2])) {
2030                             // Store the entry in the resource request log.
2031                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2032                                     String.valueOf(MainWebViewActivity.DOMAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2], blackListEntry[3]});
2033
2034                             // Blocked.
2035                             return true;
2036                         }
2037                         break;
2038
2039                     case 5:  // There are three entries.
2040                         if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2]) && resourceUrl.contains(blackListEntry[3])) {
2041                             // Store the entry in the resource request log.
2042                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2043                                     String.valueOf(MainWebViewActivity.DOMAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2] + "\n" + blackListEntry[3],
2044                                     blackListEntry[4]});
2045
2046                             // Blocked.
2047                             return true;
2048                         }
2049                         break;
2050                 }
2051             }
2052
2053             // Domain initial black list.
2054             for (String[] blackListEntry : blockList.get(MainWebViewActivity.DOMAIN_INITIAL_BLACKLIST)) {
2055                 // Store the entry in the resource request log.
2056                 if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.startsWith(blackListEntry[1])) {
2057                     MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2058                             String.valueOf(MainWebViewActivity.DOMAIN_INITIAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1],
2059                             blackListEntry[2]});
2060
2061                     // Blocked.
2062                     return true;
2063                 }
2064             }
2065
2066             // Domain final black list.
2067             for (String[] blackListEntry : blockList.get(MainWebViewActivity.DOMAIN_FINAL_BLACKLIST)) {
2068                 switch (blackListEntry.length) {
2069                     case 3:  // There is one entry.
2070                         if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.endsWith(blackListEntry[1])) {
2071                             // Store the entry in the resource request log.
2072                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2073                                     String.valueOf(MainWebViewActivity.DOMAIN_FINAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
2074
2075                             // Blocked.
2076                             return true;
2077                         }
2078                         break;
2079
2080                     case 4:  // There are two entries.
2081                         if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.endsWith(blackListEntry[2])) {
2082                             // Store the entry in the resource request log.
2083                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2084                                     String.valueOf(MainWebViewActivity.DOMAIN_FINAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2], blackListEntry[3]});
2085
2086                             // Blocked.
2087                             return true;
2088                         }
2089                         break;
2090                 }
2091             }
2092
2093             // Domain regular expression black list.
2094             for (String[] blackListEntry : blockList.get(MainWebViewActivity.DOMAIN_REGULAR_EXPRESSION_BLACKLIST)) {
2095                 if (currentDomain.endsWith(blackListEntry[0]) && Pattern.matches(blackListEntry[1], resourceUrl)) {
2096                     // Store the entry in the resource request log.
2097                     MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2098                             String.valueOf(MainWebViewActivity.DOMAIN_REGULAR_EXPRESSION_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
2099
2100                     // Blocked.
2101                     return true;
2102                 }
2103             }
2104         }
2105
2106         // Only check the third-party black lists if this is a third-party request.
2107         if (isThirdPartyRequest) {
2108             // Third-party black list.
2109             for (String[] blackListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_BLACKLIST)) {
2110                 switch (blackListEntry.length) {
2111                     case 2:  // There is one entry.
2112                         if (resourceUrl.contains(blackListEntry[0])) {
2113                             // Store the entry in the resource request log.
2114                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2115                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_BLACKLIST), blackListEntry[0], blackListEntry[1]});
2116
2117                             // Blocked.
2118                             return true;
2119                         }
2120                         break;
2121
2122                     case 3:  // There are two entries.
2123                         if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1])) {
2124                             // Store the entry in the resource request log.
2125                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2126                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
2127
2128                             // Blocked.
2129                             return true;
2130                         }
2131                         break;
2132
2133                     case 4:  // There are three entries.
2134                         if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2])) {
2135                             // Store the entry in the resource request log.
2136                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2137                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2], blackListEntry[3]});
2138
2139                             // Blocked.
2140                             return true;
2141                         }
2142                         break;
2143
2144                     case 5:  // There are four entries.
2145                         if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2]) && resourceUrl.contains(blackListEntry[3])) {
2146                             // Store the entry in the resource request log.
2147                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2148                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2] + "\n" + blackListEntry[3],
2149                                     blackListEntry[4]});
2150
2151                             // Blocked.
2152                             return true;
2153                         }
2154                         break;
2155                 }
2156             }
2157
2158             // Third-party initial black list.
2159             for (String[] blackListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_INITIAL_BLACKLIST)) {
2160                 if (blackListEntry.length == 2) {  // There is one entry.
2161                     if (resourceUrl.startsWith(blackListEntry[0])) {
2162                         // Store the entry in the resource request log.
2163                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2164                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_INITIAL_BLACKLIST), blackListEntry[0], blackListEntry[1]});
2165
2166                         // Blocked.
2167                         return true;
2168                     }
2169                 } else {  // There are two entries.
2170                     if (resourceUrl.startsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1])) {
2171                         // Store the entry in the resource request log.
2172                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2173                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_INITIAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
2174