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