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