Add UltraPrivacy. https://redmine.stoutner.com/issues/310
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / helpers / DomainsDatabaseHelper.java
1 /*
2  * Copyright © 2017-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.ContentValues;
23 import android.content.Context;
24 import android.content.SharedPreferences;
25 import android.database.Cursor;
26 import android.database.sqlite.SQLiteDatabase;
27 import android.database.sqlite.SQLiteOpenHelper;
28 import android.preference.PreferenceManager;
29
30 public class DomainsDatabaseHelper extends SQLiteOpenHelper {
31     private static final int SCHEMA_VERSION = 8;
32     private static final String DOMAINS_DATABASE = "domains.db";
33     private static final String DOMAINS_TABLE = "domains";
34
35     public static final String _ID = "_id";
36     public static final String DOMAIN_NAME = "domainname";
37     public static final String ENABLE_JAVASCRIPT = "enablejavascript";
38     public static final String ENABLE_FIRST_PARTY_COOKIES = "enablefirstpartycookies";
39     public static final String ENABLE_THIRD_PARTY_COOKIES = "enablethirdpartycookies";
40     public static final String ENABLE_DOM_STORAGE = "enabledomstorage";
41     public static final String ENABLE_FORM_DATA = "enableformdata";  // Form data can be removed once the minimum API >= 26.
42     public static final String ENABLE_EASYLIST = "enableeasylist";
43     public static final String ENABLE_EASYPRIVACY = "enableeasyprivacy";
44     public static final String ENABLE_FANBOYS_ANNOYANCE_LIST = "enablefanboysannoyancelist";
45     public static final String ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST = "enablefanboyssocialblockinglist";
46     public static final String ENABLE_ULTRAPRIVACY = "enableultraprivacy";
47     public static final String BLOCK_ALL_THIRD_PARTY_REQUESTS = "blockallthirdpartyrequests";
48     public static final String USER_AGENT = "useragent";
49     public static final String FONT_SIZE = "fontsize";
50     public static final String SWIPE_TO_REFRESH = "swipetorefresh";
51     public static final String NIGHT_MODE = "nightmode";
52     public static final String DISPLAY_IMAGES = "displayimages";
53     public static final String PINNED_SSL_CERTIFICATE = "pinnedsslcertificate";
54     public static final String SSL_ISSUED_TO_COMMON_NAME = "sslissuedtocommonname";
55     public static final String SSL_ISSUED_TO_ORGANIZATION = "sslissuedtoorganization";
56     public static final String SSL_ISSUED_TO_ORGANIZATIONAL_UNIT = "sslissuedtoorganizationalunit";
57     public static final String SSL_ISSUED_BY_COMMON_NAME = "sslissuedbycommonname";
58     public static final String SSL_ISSUED_BY_ORGANIZATION = "sslissuedbyorganization";
59     public static final String SSL_ISSUED_BY_ORGANIZATIONAL_UNIT = "sslissuedbyorganizationalunit";
60     public static final String SSL_START_DATE = "sslstartdate";
61     public static final String SSL_END_DATE = "sslenddate";
62
63     // Swipe to refresh constants.
64     public static final int SWIPE_TO_REFRESH_SYSTEM_DEFAULT = 0;
65     public static final int SWIPE_TO_REFRESH_ENABLED = 1;
66     public static final int SWIPE_TO_REFRESH_DISABLED = 2;
67
68     // Night mode constants.
69     public static final int NIGHT_MODE_SYSTEM_DEFAULT = 0;
70     public static final int NIGHT_MODE_ENABLED = 1;
71     public static final int NIGHT_MODE_DISABLED = 2;
72
73     // Display webpage images constants.
74     public static final int DISPLAY_WEBPAGE_IMAGES_SYSTEM_DEFAULT = 0;
75     public static final int DISPLAY_WEBPAGE_IMAGES_ENABLED = 1;
76     public static final int DISPLAY_WEBPAGE_IMAGES_DISABLED = 2;
77
78     private Context appContext;
79
80     // Initialize the database.  The lint warnings for the unused parameters are suppressed.
81     public DomainsDatabaseHelper(Context context, @SuppressWarnings("UnusedParameters") String name, SQLiteDatabase.CursorFactory cursorFactory, @SuppressWarnings("UnusedParameters") int version) {
82         super(context, DOMAINS_DATABASE, cursorFactory, SCHEMA_VERSION);
83
84         // Store a handle for the context.
85         appContext = context;
86     }
87
88     @Override
89     public void onCreate(SQLiteDatabase domainsDatabase) {
90         // Setup the SQL string to create the `domains` table.
91         String CREATE_DOMAINS_TABLE = "CREATE TABLE " + DOMAINS_TABLE + " (" +
92                 _ID + " INTEGER PRIMARY KEY, " +
93                 DOMAIN_NAME + " TEXT, " +
94                 ENABLE_JAVASCRIPT + " BOOLEAN, " +
95                 ENABLE_FIRST_PARTY_COOKIES + " BOOLEAN, " +
96                 ENABLE_THIRD_PARTY_COOKIES + " BOOLEAN, " +
97                 ENABLE_DOM_STORAGE + " BOOLEAN, " +
98                 ENABLE_FORM_DATA + " BOOLEAN, " +
99                 ENABLE_EASYLIST + " BOOLEAN, " +
100                 ENABLE_EASYPRIVACY + " BOOLEAN, " +
101                 ENABLE_FANBOYS_ANNOYANCE_LIST + " BOOLEAN, " +
102                 ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST + " BOOLEAN, " +
103                 ENABLE_ULTRAPRIVACY + " BOOLEAN, " +
104                 BLOCK_ALL_THIRD_PARTY_REQUESTS + " BOOLEAN, " +
105                 USER_AGENT + " TEXT, " +
106                 FONT_SIZE + " INTEGER, " +
107                 SWIPE_TO_REFRESH + " INTEGER, " +
108                 NIGHT_MODE + " INTEGER, " +
109                 DISPLAY_IMAGES + " INTEGER, " +
110                 PINNED_SSL_CERTIFICATE + " BOOLEAN, " +
111                 SSL_ISSUED_TO_COMMON_NAME + " TEXT, " +
112                 SSL_ISSUED_TO_ORGANIZATION + " TEXT, " +
113                 SSL_ISSUED_TO_ORGANIZATIONAL_UNIT + " TEXT, " +
114                 SSL_ISSUED_BY_COMMON_NAME + " TEXT, " +
115                 SSL_ISSUED_BY_ORGANIZATION + " TEXT, " +
116                 SSL_ISSUED_BY_ORGANIZATIONAL_UNIT + " TEXT, " +
117                 SSL_START_DATE + " INTEGER, " +
118                 SSL_END_DATE + " INTEGER);";
119
120         // Make it so.
121         domainsDatabase.execSQL(CREATE_DOMAINS_TABLE);
122     }
123
124     @Override
125     public void onUpgrade(SQLiteDatabase domainsDatabase, int oldVersion, int newVersion) {
126         // Upgrade the database table.
127         switch (oldVersion) {
128             // Upgrade from schema version 1.
129             case 1:
130                 // Add the display images column.
131                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + DISPLAY_IMAGES + " INTEGER");
132
133             // Upgrade from schema version 2.
134             case 2:
135                 //  Add the SSL certificate columns.
136                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + PINNED_SSL_CERTIFICATE + " BOOLEAN");
137                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + SSL_ISSUED_TO_COMMON_NAME + " TEXT");
138                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + SSL_ISSUED_TO_ORGANIZATION + " TEXT");
139                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + SSL_ISSUED_TO_ORGANIZATIONAL_UNIT + " TEXT");
140                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + SSL_ISSUED_BY_COMMON_NAME + " TEXT");
141                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + SSL_ISSUED_BY_ORGANIZATION + " TEXT");
142                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + SSL_ISSUED_BY_ORGANIZATIONAL_UNIT + " TEXT");
143                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + SSL_START_DATE + " INTEGER");
144                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + SSL_END_DATE + " INTEGER");
145
146             // Upgrade from schema version 3.
147             case 3:
148                 // Add the Night Mode column.
149                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + NIGHT_MODE + " INTEGER");
150
151             // Upgrade from schema version 4.
152             case 4:
153                 // Add the block lists columns.
154                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + ENABLE_EASYLIST + " BOOLEAN");
155                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + ENABLE_EASYPRIVACY + " BOOLEAN");
156                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + ENABLE_FANBOYS_ANNOYANCE_LIST + " BOOLEAN");
157                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST + " BOOLEAN");
158
159                 // Get a handle for the shared preference.
160                 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(appContext);
161
162                 // Get the default block list settings.
163                 boolean easyListEnabled = sharedPreferences.getBoolean("easylist", true);
164                 boolean easyPrivacyEnabled = sharedPreferences.getBoolean("easyprivacy", true);
165                 boolean fanboyAnnoyanceListEnabled = sharedPreferences.getBoolean("fanboy_annoyance_list", true);
166                 boolean fanboySocialBlockingListEnabled = sharedPreferences.getBoolean("fanboy_social_blocking_list", true);
167
168                 // Set EasyList for existing rows according to the current system-wide default.
169                 if (easyListEnabled) {
170                     domainsDatabase.execSQL("UPDATE " + DOMAINS_TABLE + " SET " + ENABLE_EASYLIST + " = " + 1);
171                 } else {
172                     domainsDatabase.execSQL("UPDATE " + DOMAINS_TABLE + " SET " + ENABLE_EASYLIST + " = " + 0);
173                 }
174
175                 // Set EasyPrivacy for existing rows according to the current system-wide default.
176                 if (easyPrivacyEnabled) {
177                     domainsDatabase.execSQL("UPDATE " + DOMAINS_TABLE + " SET " + ENABLE_EASYPRIVACY + " = " + 1);
178                 } else {
179                     domainsDatabase.execSQL("UPDATE " + DOMAINS_TABLE + " SET " + ENABLE_EASYPRIVACY + " = " + 0);
180                 }
181
182                 // Set Fanboy's Annoyance List for existing rows according to the current system-wide default.
183                 if (fanboyAnnoyanceListEnabled) {
184                     domainsDatabase.execSQL("UPDATE " + DOMAINS_TABLE + " SET " + ENABLE_FANBOYS_ANNOYANCE_LIST + " = " + 1);
185                 } else {
186                     domainsDatabase.execSQL("UPDATE " + DOMAINS_TABLE + " SET " + ENABLE_FANBOYS_ANNOYANCE_LIST + " = " + 0);
187                 }
188
189                 // Set Fanboy's Social Blocking List for existing rows according to the current system-wide default.
190                 if (fanboySocialBlockingListEnabled) {
191                     domainsDatabase.execSQL("UPDATE " + DOMAINS_TABLE + " SET " + ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST + " = " + 1);
192                 } else {
193                     domainsDatabase.execSQL("UPDATE " + DOMAINS_TABLE + " SET " + ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST + " = " + 0);
194                 }
195
196             // Upgrade from schema version 5.
197             case 5:
198                 // Add the swipe to refresh column.
199                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + SWIPE_TO_REFRESH + " INTEGER");
200
201             // Upgrade from schema version 6.
202             case 6:
203                 // Add the block all third-party requests column.
204                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + BLOCK_ALL_THIRD_PARTY_REQUESTS + " BOOLEAN");
205
206             // Upgrade from schema version 7.
207             case 7:
208                 // Add the UltraPrivacy column.
209                 domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + ENABLE_ULTRAPRIVACY + " BOOLEAN");
210
211                 // Enable it for all existing rows.
212                 domainsDatabase.execSQL("UPDATE " + DOMAINS_TABLE + " SET " + ENABLE_ULTRAPRIVACY + " = " + 1);
213         }
214     }
215
216     public Cursor getDomainNameCursorOrderedByDomain() {
217         // Get a readable database handle.
218         SQLiteDatabase domainsDatabase = this.getReadableDatabase();
219
220         // Get everything in `DOMAINS_TABLE` ordered by `DOMAIN_NAME`.
221         String GET_CURSOR_ORDERED_BY_DOMAIN = "SELECT " + _ID + ", " + DOMAIN_NAME +
222                 " FROM " + DOMAINS_TABLE +
223                 " ORDER BY " + DOMAIN_NAME + " ASC";
224
225         // Return the results as a `Cursor`.  The second argument is `null` because there are no `selectionArgs`.  The cursor can't be closed because it is needed in the calling activity.
226         return domainsDatabase.rawQuery(GET_CURSOR_ORDERED_BY_DOMAIN, null);
227     }
228
229     public Cursor getDomainNameCursorOrderedByDomainExcept(int databaseId) {
230         // Get a readable database handle.
231         SQLiteDatabase domainsDatabase = this.getReadableDatabase();
232
233         // Prepare the SQL statement to select all rows except that with `databaseId`.
234         String GET_CURSOR_ORDERED_BY_DOMAIN_EXCEPT = "SELECT " + _ID + ", " + DOMAIN_NAME +
235                 " FROM " + DOMAINS_TABLE +
236                 " WHERE " + _ID + " IS NOT " + databaseId +
237                 " ORDER BY " + DOMAIN_NAME + " ASC";
238
239         // Return the results as a `Cursor`.  The second argument is `null` because there are no `selectionArgs`.  The cursor can't be closed because it is needed in the calling activity.
240         return domainsDatabase.rawQuery(GET_CURSOR_ORDERED_BY_DOMAIN_EXCEPT, null);
241     }
242
243     public Cursor getCursorForId(int databaseId) {
244         // Get a readable database handle.
245         SQLiteDatabase domainsDatabase = this.getReadableDatabase();
246
247         // Prepare the SQL statement to get the `Cursor` for `databaseId`.
248         String GET_CURSOR_FOR_ID = "SELECT * FROM " + DOMAINS_TABLE +
249                 " WHERE " + _ID + " = " + databaseId;
250
251         // Return the results as a `Cursor`.  The second argument is `null` because there are no `selectionArgs`.  The cursor can't be closed because it is needed in the calling activity.
252         return domainsDatabase.rawQuery(GET_CURSOR_FOR_ID, null);
253     }
254
255     public Cursor getCursorForDomainName(String domainName) {
256         // Get a readable database handle.
257         SQLiteDatabase domainsDatabase = this.getReadableDatabase();
258
259         // Return a cursor for the requested domain name.
260         return domainsDatabase.query(DOMAINS_TABLE, null, DOMAIN_NAME + " = " + "\"" + domainName + "\"", null, null, null, null);
261
262     }
263
264     public int addDomain(String domainName) {
265         // Store the domain data in a `ContentValues`.
266         ContentValues domainContentValues = new ContentValues();
267
268         // Get a handle for the shared preference.
269         SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(appContext);
270
271         // Get the default settings.
272         boolean javaScriptEnabled = sharedPreferences.getBoolean("javascript_enabled", false);
273         boolean firstPartyCookiesEnabled = sharedPreferences.getBoolean("first_party_cookies_enabled", false);
274         boolean thirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies_enabled", false);
275         boolean domStorageEnabled = sharedPreferences.getBoolean("dom_storage_enabled", false);
276         boolean saveFormDataEnabled = sharedPreferences.getBoolean("save_form_data_enabled", false);  // Form data can be removed once the minimum API >= 26.
277         boolean easyListEnabled = sharedPreferences.getBoolean("easylist", true);
278         boolean easyPrivacyEnabled = sharedPreferences.getBoolean("easyprivacy", true);
279         boolean fanboyAnnoyanceListEnabled = sharedPreferences.getBoolean("fanboy_annoyance_list", true);
280         boolean fanboySocialBlockingListEnabled = sharedPreferences.getBoolean("fanboy_social_blocking_list", true);
281         boolean ultraPrivacyEnabled = sharedPreferences.getBoolean("ultraprivacy", true);
282         boolean blockAllThirdPartyRequests = sharedPreferences.getBoolean("block_all_third_party_requests", false);
283
284         // Create entries for the database fields.  The ID is created automatically.  The pinned SSL certificate information is not created unless added by the user.
285         domainContentValues.put(DOMAIN_NAME, domainName);
286         domainContentValues.put(ENABLE_JAVASCRIPT, javaScriptEnabled);
287         domainContentValues.put(ENABLE_FIRST_PARTY_COOKIES, firstPartyCookiesEnabled);
288         domainContentValues.put(ENABLE_THIRD_PARTY_COOKIES, thirdPartyCookiesEnabled);
289         domainContentValues.put(ENABLE_DOM_STORAGE, domStorageEnabled);
290         domainContentValues.put(ENABLE_FORM_DATA, saveFormDataEnabled);  // Form data can be removed once the minimum API >= 26.
291         domainContentValues.put(ENABLE_EASYLIST, easyListEnabled);
292         domainContentValues.put(ENABLE_EASYPRIVACY, easyPrivacyEnabled);
293         domainContentValues.put(ENABLE_FANBOYS_ANNOYANCE_LIST, fanboyAnnoyanceListEnabled);
294         domainContentValues.put(ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST, fanboySocialBlockingListEnabled);
295         domainContentValues.put(ENABLE_ULTRAPRIVACY, ultraPrivacyEnabled);
296         domainContentValues.put(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests);
297         domainContentValues.put(USER_AGENT, "System default user agent");
298         domainContentValues.put(FONT_SIZE, 0);
299         domainContentValues.put(SWIPE_TO_REFRESH, 0);
300         domainContentValues.put(NIGHT_MODE, 0);
301         domainContentValues.put(DISPLAY_IMAGES, 0);
302
303         // Get a writable database handle.
304         SQLiteDatabase domainsDatabase = this.getWritableDatabase();
305
306         // Insert a new row and store the resulting database ID.  The second argument is `null`, which makes it so that a completely null row cannot be created.
307         int newDomainDatabaseId  = (int) domainsDatabase.insert(DOMAINS_TABLE, null, domainContentValues);
308
309         // Close the database handle.
310         domainsDatabase.close();
311
312         // Return the new domain database ID.
313         return newDomainDatabaseId;
314     }
315
316     public void updateDomainExceptCertificate(int databaseId, String domainName, boolean javaScriptEnabled, boolean firstPartyCookiesEnabled, boolean thirdPartyCookiesEnabled, boolean domStorageEnabled,
317                                               boolean formDataEnabled, boolean easyListEnabled, boolean easyPrivacyEnabled, boolean fanboysAnnoyanceEnabled, boolean fanboysSocialBlockingEnabled,
318                                               boolean ultraPrivacyEnabled, boolean blockAllThirdPartyRequests, String userAgent, int fontSize, int swipeToRefresh, int nightMode, int displayImages,
319                                               boolean pinnedSslCertificate) {
320
321         // Store the domain data in a `ContentValues`.
322         ContentValues domainContentValues = new ContentValues();
323
324         // Add entries for each field in the database.
325         domainContentValues.put(DOMAIN_NAME, domainName);
326         domainContentValues.put(ENABLE_JAVASCRIPT, javaScriptEnabled);
327         domainContentValues.put(ENABLE_FIRST_PARTY_COOKIES, firstPartyCookiesEnabled);
328         domainContentValues.put(ENABLE_THIRD_PARTY_COOKIES, thirdPartyCookiesEnabled);
329         domainContentValues.put(ENABLE_DOM_STORAGE, domStorageEnabled);
330         domainContentValues.put(ENABLE_FORM_DATA, formDataEnabled);  // Form data can be removed once the minimum API >= 26.
331         domainContentValues.put(ENABLE_EASYLIST, easyListEnabled);
332         domainContentValues.put(ENABLE_EASYPRIVACY, easyPrivacyEnabled);
333         domainContentValues.put(ENABLE_FANBOYS_ANNOYANCE_LIST, fanboysAnnoyanceEnabled);
334         domainContentValues.put(ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST, fanboysSocialBlockingEnabled);
335         domainContentValues.put(ENABLE_ULTRAPRIVACY, ultraPrivacyEnabled);
336         domainContentValues.put(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests);
337         domainContentValues.put(USER_AGENT, userAgent);
338         domainContentValues.put(FONT_SIZE, fontSize);
339         domainContentValues.put(SWIPE_TO_REFRESH, swipeToRefresh);
340         domainContentValues.put(NIGHT_MODE, nightMode);
341         domainContentValues.put(DISPLAY_IMAGES, displayImages);
342         domainContentValues.put(PINNED_SSL_CERTIFICATE, pinnedSslCertificate);
343
344         // Get a writable database handle.
345         SQLiteDatabase domainsDatabase = this.getWritableDatabase();
346
347         // Update the row for `databaseId`.  The last argument is `null` because there are no `whereArgs`.
348         domainsDatabase.update(DOMAINS_TABLE, domainContentValues, _ID + " = " + databaseId, null);
349
350         // Close the database handle.
351         domainsDatabase.close();
352     }
353
354     public void updateDomainWithCertificate(int databaseId, String domainName, boolean javaScriptEnabled, boolean firstPartyCookiesEnabled, boolean thirdPartyCookiesEnabled, boolean domStorageEnabled,
355                                             boolean formDataEnabled, boolean easyListEnabled, boolean easyPrivacyEnabled, boolean fanboysAnnoyanceEnabled, boolean fanboysSocialBlockingEnabled,
356                                             boolean ultraPrivacyEnabled, boolean blockAllThirdPartyRequests, String userAgent, int fontSize, int swipeToRefresh, int nightMode, int displayImages,
357                                             boolean pinnedSslCertificate, String sslIssuedToCommonName, String sslIssuedToOrganization, String sslIssuedToOrganizationalUnit, String sslIssuedByCommonName,
358                                             String sslIssuedByOrganization, String sslIssuedByOrganizationalUnit, long sslStartDate, long sslEndDate) {
359
360         // Store the domain data in a `ContentValues`.
361         ContentValues domainContentValues = new ContentValues();
362
363         // Add entries for each field in the database.
364         domainContentValues.put(DOMAIN_NAME, domainName);
365         domainContentValues.put(ENABLE_JAVASCRIPT, javaScriptEnabled);
366         domainContentValues.put(ENABLE_FIRST_PARTY_COOKIES, firstPartyCookiesEnabled);
367         domainContentValues.put(ENABLE_THIRD_PARTY_COOKIES, thirdPartyCookiesEnabled);
368         domainContentValues.put(ENABLE_DOM_STORAGE, domStorageEnabled);
369         domainContentValues.put(ENABLE_FORM_DATA, formDataEnabled);  // Form data can be removed once the minimum API >= 26.
370         domainContentValues.put(ENABLE_EASYLIST, easyListEnabled);
371         domainContentValues.put(ENABLE_EASYPRIVACY, easyPrivacyEnabled);
372         domainContentValues.put(ENABLE_FANBOYS_ANNOYANCE_LIST, fanboysAnnoyanceEnabled);
373         domainContentValues.put(ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST, fanboysSocialBlockingEnabled);
374         domainContentValues.put(ENABLE_ULTRAPRIVACY, ultraPrivacyEnabled);
375         domainContentValues.put(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests);
376         domainContentValues.put(USER_AGENT, userAgent);
377         domainContentValues.put(FONT_SIZE, fontSize);
378         domainContentValues.put(SWIPE_TO_REFRESH, swipeToRefresh);
379         domainContentValues.put(NIGHT_MODE, nightMode);
380         domainContentValues.put(DISPLAY_IMAGES, displayImages);
381         domainContentValues.put(PINNED_SSL_CERTIFICATE, pinnedSslCertificate);
382         domainContentValues.put(SSL_ISSUED_TO_COMMON_NAME, sslIssuedToCommonName);
383         domainContentValues.put(SSL_ISSUED_TO_ORGANIZATION, sslIssuedToOrganization);
384         domainContentValues.put(SSL_ISSUED_TO_ORGANIZATIONAL_UNIT, sslIssuedToOrganizationalUnit);
385         domainContentValues.put(SSL_ISSUED_BY_COMMON_NAME, sslIssuedByCommonName);
386         domainContentValues.put(SSL_ISSUED_BY_ORGANIZATION, sslIssuedByOrganization);
387         domainContentValues.put(SSL_ISSUED_BY_ORGANIZATIONAL_UNIT, sslIssuedByOrganizationalUnit);
388         domainContentValues.put(SSL_START_DATE, sslStartDate);
389         domainContentValues.put(SSL_END_DATE, sslEndDate);
390
391         // Get a writable database handle.
392         SQLiteDatabase domainsDatabase = this.getWritableDatabase();
393
394         // Update the row for `databaseId`.  The last argument is `null` because there are no `whereArgs`.
395         domainsDatabase.update(DOMAINS_TABLE, domainContentValues, _ID + " = " + databaseId, null);
396
397         // Close the database handle.
398         domainsDatabase.close();
399     }
400
401     public void updateCertificate(int databaseId, String sslIssuedToCommonName, String sslIssuedToOrganization, String sslIssuedToOrganizationalUnit, String sslIssuedByCommonName,
402                                   String sslIssuedByOrganization, String sslIssuedByOrganizationalUnit, long sslStartDate, long sslEndDate) {
403         // Store the domain data in a `ContentValues`.
404         ContentValues domainContentValues = new ContentValues();
405
406         // Add entries for each field in the certificate.
407         domainContentValues.put(SSL_ISSUED_TO_COMMON_NAME, sslIssuedToCommonName);
408         domainContentValues.put(SSL_ISSUED_TO_ORGANIZATION, sslIssuedToOrganization);
409         domainContentValues.put(SSL_ISSUED_TO_ORGANIZATIONAL_UNIT, sslIssuedToOrganizationalUnit);
410         domainContentValues.put(SSL_ISSUED_BY_COMMON_NAME, sslIssuedByCommonName);
411         domainContentValues.put(SSL_ISSUED_BY_ORGANIZATION, sslIssuedByOrganization);
412         domainContentValues.put(SSL_ISSUED_BY_ORGANIZATIONAL_UNIT, sslIssuedByOrganizationalUnit);
413         domainContentValues.put(SSL_START_DATE, sslStartDate);
414         domainContentValues.put(SSL_END_DATE, sslEndDate);
415
416         // Get a writable database handle.
417         SQLiteDatabase domainsDatabase = this.getWritableDatabase();
418
419         // Update the row for `databaseId`.  The last argument is `null` because there are no `whereArgs`.
420         domainsDatabase.update(DOMAINS_TABLE, domainContentValues, _ID + " = " + databaseId, null);
421
422         // Close the database handle.
423         domainsDatabase.close();
424     }
425
426     public void deleteDomain(int databaseId) {
427         // Get a writable database handle.
428         SQLiteDatabase domainsDatabase = this.getWritableDatabase();
429
430         // Delete the row for `databaseId`.  The last argument is `null` because we don't need additional parameters.
431         domainsDatabase.delete(DOMAINS_TABLE, _ID + " = " + databaseId, null);
432
433         // Close the database handle.
434         domainsDatabase.close();
435     }
436 }