Block trackers listed at privacytests.org. https://redmine.stoutner.com/issues/863
authorSoren Stoutner <soren@stoutner.com>
Fri, 15 Jul 2022 22:19:00 +0000 (15:19 -0700)
committerSoren Stoutner <soren@stoutner.com>
Fri, 15 Jul 2022 22:19:00 +0000 (15:19 -0700)
21 files changed:
app/build.gradle
app/src/main/assets/blocklists/ultraprivacy.txt
app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/SslCertificateErrorDialog.kt
app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java
app/src/main/java/com/stoutner/privacybrowser/helpers/BookmarksDatabaseHelper.kt
app/src/main/java/com/stoutner/privacybrowser/helpers/CheckPinnedMismatchHelper.kt
app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.kt
app/src/main/java/com/stoutner/privacybrowser/helpers/ImportExportDatabaseHelper.kt
app/src/main/java/com/stoutner/privacybrowser/helpers/ProxyHelper.kt
app/src/main/java/com/stoutner/privacybrowser/helpers/SanitizeUrlHelper.kt [new file with mode: 0644]
app/src/main/res/values-de/strings.xml
app/src/main/res/values-es/strings.xml
app/src/main/res/values-fr/strings.xml
app/src/main/res/values-it/strings.xml
app/src/main/res/values-pt-rBR/strings.xml
app/src/main/res/values-ru/strings.xml
app/src/main/res/values-tr/strings.xml
app/src/main/res/values/strings.xml
app/src/main/res/xml/preferences.xml
build.gradle

index 1abaa0e30c71e55e5a550a913af9a0f0f5dd94ef..2ab5953ca9aeb871f7f84744ba31c828028aaf54 100644 (file)
@@ -23,7 +23,7 @@ plugins {
 }
 
 android {
-    compileSdk 31
+    compileSdk 32
 
     defaultConfig {
         minSdk 23
@@ -70,10 +70,10 @@ dependencies {
     // Include the following AndroidX libraries.
     implementation 'androidx.arch.core:core-common:2.1.0'
     implementation 'androidx.arch.core:core-runtime:2.1.0'
-    implementation 'androidx.appcompat:appcompat:1.4.1'
+    implementation 'androidx.appcompat:appcompat:1.4.2'
     implementation 'androidx.cardview:cardview:1.0.0'
     implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
-    implementation 'androidx.core:core-ktx:1.7.0'
+    implementation 'androidx.core:core-ktx:1.8.0'
     implementation 'androidx.drawerlayout:drawerlayout:1.1.1'
     implementation 'androidx.preference:preference-ktx:1.2.0'
     implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
@@ -81,8 +81,8 @@ dependencies {
     implementation 'androidx.webkit:webkit:1.4.0'
 
     // Include the Kotlin standard library.  This should be the same version number listed in project build.gradle.
-    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21'
+    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10'
 
     // Include the Google material library.
-    implementation 'com.google.android.material:material:1.6.0'
+    implementation 'com.google.android.material:material:1.6.1'
 }
\ No newline at end of file
index 77d9c6d29cb38ead718f436ada93829c1c7b7690..3bbd70c0132af49c3a60b8ce27e47210d68eb6e3 100644 (file)
@@ -1,12 +1,14 @@
 [Adblock Plus 2.0]
 ! Version: 2
 ! Title: UltraPrivacy
-! Last modified: 22 May 2019 18:11 UTC
+! Last modified: 2 June 2022 17:37 UTC
 ! Expires: 90 days (update frequency)
-! Homepage: https://www.stoutner.com/privacy-browser/blocklists/ultraprivacy/
+! Homepage: https://www.stoutner.com/privacy-browser-android/blocklists/ultraprivacy/
 ! Licence: GPLv3+ http://www.gnu.org/licenses/gpl-3.0.html
 !
-! I can't imagine that anything that includes `analytics` is good for your privacy.  https://redmine.stoutner.com/issues/312.
+! I can't imagine that anything that includes `analytics` is good for your privacy.  <https://redmine.stoutner.com/issues/312>
 analytics
-! Block Google Tag Services.  https://redmine.stoutner.com/issues/449
+! Block Google Tag Services.  <https://redmine.stoutner.com/issues/449>
 googletagservices
+! There shall be no connecting to Facebook on the backend.  <https://redmine.stoutner.com/issues/858>
+connect.facebook
\ No newline at end of file
index 9bea7991873988a291707cced7e440ccb7c40fbf..13d81cb9f5eb103e3e839de96804f2e408c4bb47 100644 (file)
@@ -118,7 +118,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 import androidx.viewpager.widget.ViewPager;
 import androidx.webkit.WebSettingsCompat;
 import androidx.webkit.WebViewFeature;
-import kotlin.Pair;
 
 import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.floatingactionbutton.FloatingActionButton;
@@ -153,6 +152,7 @@ import com.stoutner.privacybrowser.helpers.BlocklistHelper;
 import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
 import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper;
 import com.stoutner.privacybrowser.helpers.ProxyHelper;
+import com.stoutner.privacybrowser.helpers.SanitizeUrlHelper;
 import com.stoutner.privacybrowser.views.NestedScrollWebView;
 
 import java.io.ByteArrayInputStream;
@@ -183,6 +183,8 @@ import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
+import kotlin.Pair;
+
 public class MainWebViewActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener,
         EditBookmarkFolderDialog.EditBookmarkFolderListener, FontSizeDialog.UpdateFontSizeListener, NavigationView.OnNavigationItemSelectedListener, OpenDialog.OpenListener,
         PinnedMismatchDialog.PinnedMismatchListener, PopulateBlocklists.PopulateBlocklistsListener, SaveDialog.SaveListener, UrlHistoryDialog.NavigateHistoryListener,
@@ -273,13 +275,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     private int defaultProgressViewStartOffset;
     private int defaultProgressViewEndOffset;
 
-    // The URL sanitizers are set in `applyAppSettings()` and used in `sanitizeUrl()`.
-    private boolean sanitizeGoogleAnalytics;
-    private boolean sanitizeFacebookClickIds;
-    private boolean sanitizeTwitterAmpRedirects;
+    // Declare the helpers.
+    private BookmarksDatabaseHelper bookmarksDatabaseHelper;
+    private DomainsDatabaseHelper domainsDatabaseHelper;
+    private ProxyHelper proxyHelper;
+    private SanitizeUrlHelper sanitizeUrlHelper;
 
     // Declare the class variables
-    private BookmarksDatabaseHelper bookmarksDatabaseHelper;
     private boolean bottomAppBar;
     private boolean displayingFullScreenVideo;
     private boolean downloadWithExternalApp;
@@ -289,9 +291,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     private boolean inFullScreenBrowsingMode;
     private boolean loadingNewIntent;
     private BroadcastReceiver orbotStatusBroadcastReceiver;
-    private ProxyHelper proxyHelper;
     private boolean reapplyAppSettingsOnRestart;
     private boolean reapplyDomainSettingsOnRestart;
+    private boolean sanitizeAmpRedirects;
+    private boolean sanitizeTrackingQueries;
     private boolean scrollAppBar;
     private boolean waitingForProxy;
     private String webViewDefaultUserAgent;
@@ -600,8 +603,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         // Store up to 100 tabs in memory.
         webViewPager.setOffscreenPageLimit(100);
 
-        // Instantiate the proxy helper.
+        // Instantiate the helpers.
+        bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this);
+        domainsDatabaseHelper = new DomainsDatabaseHelper(this);
         proxyHelper = new ProxyHelper();
+        sanitizeUrlHelper = new SanitizeUrlHelper();
 
         // Initialize the app.
         initializeApp();
@@ -1952,9 +1958,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 Uri currentUri = Uri.parse(currentWebView.getUrl());
                 String currentDomain = currentUri.getHost();
 
-                // Initialize the database handler.
-                DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this);
-
                 // Create the domain and store the database ID.
                 int newDomainDatabaseId = domainsDatabaseHelper.addDomain(currentDomain);
 
@@ -3382,9 +3385,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         drawerLayout.setDrawerTitle(GravityCompat.START, getString(R.string.navigation_drawer));
         drawerLayout.setDrawerTitle(GravityCompat.END, getString(R.string.bookmarks));
 
-        // Initialize the bookmarks database helper.
-        bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this);
-
         // Initialize `currentBookmarksFolder`.  `""` is the home folder in the database.
         currentBookmarksFolder = "";
 
@@ -3519,9 +3519,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
         // Store the values from the shared preferences in variables.
         incognitoModeEnabled = sharedPreferences.getBoolean("incognito_mode", false);
-        sanitizeGoogleAnalytics = sharedPreferences.getBoolean("google_analytics", true);
-        sanitizeFacebookClickIds = sharedPreferences.getBoolean("facebook_click_ids", true);
-        sanitizeTwitterAmpRedirects = sharedPreferences.getBoolean("twitter_amp_redirects", true);
+        sanitizeTrackingQueries = sharedPreferences.getBoolean(getString(R.string.tracking_queries_key), true);
+        sanitizeAmpRedirects = sharedPreferences.getBoolean(getString(R.string.amp_redirects_key), true);
         proxyMode = sharedPreferences.getString("proxy", getString(R.string.proxy_default_value));
         fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false);
         downloadWithExternalApp = sharedPreferences.getBoolean(getString(R.string.download_with_external_app_key), false);
@@ -3737,10 +3736,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 }
             }
 
-            // Initialize the database handler.
-            DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this);
-
-            // Get a full cursor from `domainsDatabaseHelper`.
+            // Get a full domain name cursor.
             Cursor domainNameCursor = domainsDatabaseHelper.getDomainNameCursorOrderedByDomain();
 
             // Initialize `domainSettingsSet`.
@@ -4498,49 +4494,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     private String sanitizeUrl(String url) {
-        // Sanitize Google Analytics.
-        if (sanitizeGoogleAnalytics) {
-            // Remove `?utm_`.
-            if (url.contains("?utm_")) {
-                url = url.substring(0, url.indexOf("?utm_"));
-            }
+        // Sanitize tracking queries.
+        if (sanitizeTrackingQueries)
+            url = sanitizeUrlHelper.sanitizeTrackingQueries(url);
 
-            // Remove `&utm_`.
-            if (url.contains("&utm_")) {
-                url = url.substring(0, url.indexOf("&utm_"));
-            }
-        }
-
-        // Sanitize Facebook Click IDs.
-        if (sanitizeFacebookClickIds) {
-            // Remove `?fbclid=`.
-            if (url.contains("?fbclid=")) {
-                url = url.substring(0, url.indexOf("?fbclid="));
-            }
-
-            // Remove `&fbclid=`.
-            if (url.contains("&fbclid=")) {
-                url = url.substring(0, url.indexOf("&fbclid="));
-            }
-
-            // Remove `?fbadid=`.
-            if (url.contains("?fbadid=")) {
-                url = url.substring(0, url.indexOf("?fbadid="));
-            }
-
-            // Remove `&fbadid=`.
-            if (url.contains("&fbadid=")) {
-                url = url.substring(0, url.indexOf("&fbadid="));
-            }
-        }
-
-        // Sanitize Twitter AMP redirects.
-        if (sanitizeTwitterAmpRedirects) {
-            // Remove `?amp=1`.
-            if (url.contains("?amp=1")) {
-                url = url.substring(0, url.indexOf("?amp=1"));
-            }
-        }
+        // Sanitize AMP redirects.
+        if (sanitizeAmpRedirects)
+            url = sanitizeUrlHelper.sanitizeAmpRedirects(url);
 
         // Return the sanitized URL.
         return url;
index d146de5300c77c364ce7695e148d18e087561f54..04ff898238c530754451f356c6d06bd4c767d92d 100644 (file)
@@ -322,6 +322,7 @@ class SslCertificateErrorDialog : DialogFragment() {
         private val activityWeakReference: WeakReference<Activity> = WeakReference(activity)
         private val alertDialogWeakReference: WeakReference<AlertDialog> = WeakReference(alertDialog)
 
+        @Deprecated("Deprecated in Java")
         override fun doInBackground(vararg domainName: String): SpannableStringBuilder {
             // Get handles for the activity and the alert dialog.
             val activity = activityWeakReference.get()
@@ -372,6 +373,7 @@ class SslCertificateErrorDialog : DialogFragment() {
         }
 
         // `onPostExecute()` operates on the UI thread.
+        @Deprecated("Deprecated in Java")
         override fun onPostExecute(ipAddresses: SpannableStringBuilder) {
             // Get handles for the activity and the alert dialog.
             val activity = activityWeakReference.get()
index e17f82728b6968eb9a4f4ba063ebfb31ed2ea5aa..bf864c114dbd9779fdc21b9ade87802bce8d572e 100644 (file)
@@ -75,9 +75,8 @@ public class SettingsFragment extends PreferenceFragmentCompat {
     private Preference ultraListPreference;
     private Preference ultraPrivacyPreference;
     private Preference blockAllThirdPartyRequestsPreference;
-    private Preference googleAnalyticsPreference;
-    private Preference facebookClickIdsPreference;
-    private Preference twitterAmpRedirectsPreference;
+    private Preference trackingQueriesPreference;
+    private Preference ampRedirectsPreference;
     private Preference searchPreference;
     private Preference searchCustomURLPreference;
     private Preference proxyPreference;
@@ -142,9 +141,8 @@ public class SettingsFragment extends PreferenceFragmentCompat {
         ultraListPreference = findPreference("ultralist");
         ultraPrivacyPreference = findPreference("ultraprivacy");
         blockAllThirdPartyRequestsPreference = findPreference("block_all_third_party_requests");
-        googleAnalyticsPreference = findPreference("google_analytics");
-        facebookClickIdsPreference = findPreference("facebook_click_ids");
-        twitterAmpRedirectsPreference = findPreference("twitter_amp_redirects");
+        trackingQueriesPreference = findPreference(getString(R.string.tracking_queries_key));
+        ampRedirectsPreference = findPreference(getString(R.string.amp_redirects_key));
         searchPreference = findPreference("search");
         searchCustomURLPreference = findPreference("search_custom_url");
         proxyPreference = findPreference("proxy");
@@ -186,9 +184,8 @@ public class SettingsFragment extends PreferenceFragmentCompat {
         assert ultraListPreference != null;
         assert ultraPrivacyPreference != null;
         assert blockAllThirdPartyRequestsPreference != null;
-        assert googleAnalyticsPreference != null;
-        assert facebookClickIdsPreference != null;
-        assert twitterAmpRedirectsPreference != null;
+        assert trackingQueriesPreference != null;
+        assert ampRedirectsPreference != null;
         assert searchPreference != null;
         assert searchCustomURLPreference != null;
         assert proxyPreference != null;
@@ -516,25 +513,18 @@ public class SettingsFragment extends PreferenceFragmentCompat {
             blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled);
         }
 
-        // Set the Google Analytics icon.
-        if (sharedPreferences.getBoolean("google_analytics", true)) {
-            googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled);
+        // Set the Tracking Queries icon.
+        if (sharedPreferences.getBoolean(getString(R.string.tracking_queries_key), true)) {
+            trackingQueriesPreference.setIcon(R.drawable.modify_url_enabled);
         } else {
-            googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled);
+            trackingQueriesPreference.setIcon(R.drawable.modify_url_disabled);
         }
 
-        // Set the Facebook Click IDs icon.
-        if (sharedPreferences.getBoolean("facebook_click_ids", true)) {
-            facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled);
+        // Set the AMP Redirects icon.
+        if (sharedPreferences.getBoolean(getString(R.string.amp_redirects_key), true)) {
+            ampRedirectsPreference.setIcon(R.drawable.modify_url_enabled);
         } else {
-            facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled);
-        }
-
-        // Set the Twitter AMP redirects icon.
-        if (sharedPreferences.getBoolean("twitter_amp_redirects", true)) {
-            twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled);
-        } else {
-            twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled);
+            ampRedirectsPreference.setIcon(R.drawable.modify_url_disabled);
         }
 
         // Set the search custom URL icon.
@@ -952,30 +942,21 @@ public class SettingsFragment extends PreferenceFragmentCompat {
                     }
                     break;
 
-                case "google_analytics":
-                    // Update the icon.
-                    if (sharedPreferences.getBoolean("google_analytics", true)) {
-                        googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled);
-                    } else {
-                        googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled);
-                    }
-                    break;
-
-                case "facebook_click_ids":
+                case "tracking_queries":
                     // Update the icon.
-                    if (sharedPreferences.getBoolean("facebook_click_ids", true)) {
-                        facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled);
+                    if (sharedPreferences.getBoolean(context.getString(R.string.tracking_queries_key), true)) {
+                        trackingQueriesPreference.setIcon(R.drawable.modify_url_enabled);
                     } else {
-                        facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled);
+                        trackingQueriesPreference.setIcon(R.drawable.modify_url_disabled);
                     }
                     break;
 
-                case "twitter_amp_redirects":
+                case "amp_redirects":
                     // Update the icon.
-                    if (sharedPreferences.getBoolean("twitter_amp_redirects", true)) {
-                        twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled);
+                    if (sharedPreferences.getBoolean(context.getString(R.string.amp_redirects_key), true)) {
+                        ampRedirectsPreference.setIcon(R.drawable.modify_url_enabled);
                     } else {
-                        twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled);
+                        ampRedirectsPreference.setIcon(R.drawable.modify_url_disabled);
                     }
                     break;
 
index 135827ec64e48b835dc929cbf91a8d498a170904..fac7001ad6fa2fb1952c8d3ad47c5008912f393d 100644 (file)
@@ -46,14 +46,14 @@ class BookmarksDatabaseHelper(context: Context) : SQLiteOpenHelper(context, BOOK
         const val FAVORITE_ICON = "favoriteicon"
 
         // Define the public table creation constant.
-        const val CREATE_BOOKMARKS_TABLE = "CREATE TABLE " + BOOKMARKS_TABLE + " (" +
-                ID + " INTEGER PRIMARY KEY, " +
-                BOOKMARK_NAME + " TEXT, " +
-                BOOKMARK_URL + " TEXT, " +
-                PARENT_FOLDER + " TEXT, " +
-                DISPLAY_ORDER + " INTEGER, " +
-                IS_FOLDER + " BOOLEAN, " +
-                FAVORITE_ICON + " BLOB)"
+        const val CREATE_BOOKMARKS_TABLE = "CREATE TABLE $BOOKMARKS_TABLE (" +
+                "$ID INTEGER PRIMARY KEY, " +
+                "$BOOKMARK_NAME TEXT, " +
+                "$BOOKMARK_URL TEXT, " +
+                "$PARENT_FOLDER TEXT, " +
+                "$DISPLAY_ORDER INTEGER, " +
+                "$IS_FOLDER BOOLEAN, " +
+                "$FAVORITE_ICON BLOB)"
     }
 
     override fun onCreate(bookmarksDatabase: SQLiteDatabase) {
index 8fa8369fc365e0ae192d60655e6c8a948c662888..b67a7f3f46e4506468b713b195d1712e34b70d1a 100644 (file)
@@ -16,6 +16,7 @@
  * You should have received a copy of the GNU General Public License
  * along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>.
  */
+
 package com.stoutner.privacybrowser.helpers
 
 import android.app.Activity
index 53a3cbe4569c84e22202de8494ccef8b7fd06051..9d58eef07fd1fe0a46047756337f905e34c9f066 100644 (file)
@@ -80,37 +80,37 @@ class DomainsDatabaseHelper(private val appContext: Context) : SQLiteOpenHelper(
         const val IP_ADDRESSES = "ip_addresses"
 
         // The table creation constant.
-        const val CREATE_DOMAINS_TABLE = "CREATE TABLE " + DOMAINS_TABLE + " (" +
-                ID + " INTEGER PRIMARY KEY, " +
-                DOMAIN_NAME + " TEXT, " +
-                ENABLE_JAVASCRIPT + " BOOLEAN, " +
-                COOKIES + " BOOLEAN, " +
-                ENABLE_DOM_STORAGE + " BOOLEAN, " +
-                ENABLE_FORM_DATA + " BOOLEAN, " +
-                ENABLE_EASYLIST + " BOOLEAN, " +
-                ENABLE_EASYPRIVACY + " BOOLEAN, " +
-                ENABLE_FANBOYS_ANNOYANCE_LIST + " BOOLEAN, " +
-                ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST + " BOOLEAN, " +
-                ULTRALIST + " BOOLEAN, " +
-                ENABLE_ULTRAPRIVACY + " BOOLEAN, " +
-                BLOCK_ALL_THIRD_PARTY_REQUESTS + " BOOLEAN, " +
-                USER_AGENT + " TEXT, " +
-                FONT_SIZE + " INTEGER, " +
-                SWIPE_TO_REFRESH + " INTEGER, " +
-                WEBVIEW_THEME + " INTEGER, " +
-                WIDE_VIEWPORT + " INTEGER, " +
-                DISPLAY_IMAGES + " INTEGER, " +
-                PINNED_SSL_CERTIFICATE + " BOOLEAN, " +
-                SSL_ISSUED_TO_COMMON_NAME + " TEXT, " +
-                SSL_ISSUED_TO_ORGANIZATION + " TEXT, " +
-                SSL_ISSUED_TO_ORGANIZATIONAL_UNIT + " TEXT, " +
-                SSL_ISSUED_BY_COMMON_NAME + " TEXT, " +
-                SSL_ISSUED_BY_ORGANIZATION + " TEXT, " +
-                SSL_ISSUED_BY_ORGANIZATIONAL_UNIT + " TEXT, " +
-                SSL_START_DATE + " INTEGER, " +
-                SSL_END_DATE + " INTEGER, " +
-                PINNED_IP_ADDRESSES + " BOOLEAN, " +
-                IP_ADDRESSES + " TEXT)"
+        const val CREATE_DOMAINS_TABLE = "CREATE TABLE $DOMAINS_TABLE (" +
+                "$ID INTEGER PRIMARY KEY, " +
+                "$DOMAIN_NAME TEXT, " +
+                "$ENABLE_JAVASCRIPT BOOLEAN, " +
+                "$COOKIES BOOLEAN, " +
+                "$ENABLE_DOM_STORAGE BOOLEAN, " +
+                "$ENABLE_FORM_DATA BOOLEAN, " +
+                "$ENABLE_EASYLIST BOOLEAN, " +
+                "$ENABLE_EASYPRIVACY BOOLEAN, " +
+                "$ENABLE_FANBOYS_ANNOYANCE_LIST BOOLEAN, " +
+                "$ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST BOOLEAN, " +
+                "$ULTRALIST BOOLEAN, " +
+                "$ENABLE_ULTRAPRIVACY BOOLEAN, " +
+                "$BLOCK_ALL_THIRD_PARTY_REQUESTS BOOLEAN, " +
+                "$USER_AGENT TEXT, " +
+                "$FONT_SIZE INTEGER, " +
+                "$SWIPE_TO_REFRESH INTEGER, " +
+                "$WEBVIEW_THEME INTEGER, " +
+                "$WIDE_VIEWPORT INTEGER, " +
+                "$DISPLAY_IMAGES INTEGER, " +
+                "$PINNED_SSL_CERTIFICATE BOOLEAN, " +
+                "$SSL_ISSUED_TO_COMMON_NAME TEXT, " +
+                "$SSL_ISSUED_TO_ORGANIZATION TEXT, " +
+                "$SSL_ISSUED_TO_ORGANIZATIONAL_UNIT TEXT, " +
+                "$SSL_ISSUED_BY_COMMON_NAME TEXT, " +
+                "$SSL_ISSUED_BY_ORGANIZATION TEXT, " +
+                "$SSL_ISSUED_BY_ORGANIZATIONAL_UNIT TEXT, " +
+                "$SSL_START_DATE INTEGER, " +
+                "$SSL_END_DATE INTEGER, " +
+                "$PINNED_IP_ADDRESSES BOOLEAN, " +
+                "$IP_ADDRESSES TEXT)"
     }
 
     override fun onCreate(domainsDatabase: SQLiteDatabase) {
index 1e2ea1583da731bd7efe0e87a8fdd24ff1e64eaf..415fd92bae463388180c9d59eb4b8169bec88fba 100644 (file)
@@ -35,7 +35,7 @@ import java.io.InputStream
 import java.io.OutputStream
 
 // Define the private class constants.
-private const val SCHEMA_VERSION = 14
+private const val SCHEMA_VERSION = 15
 private const val PREFERENCES_TABLE = "preferences"
 
 // Define the private preferences constants.
@@ -55,9 +55,8 @@ private const val FANBOYS_SOCIAL_BLOCKING_LIST = "fanboys_social_blocking_list"
 private const val ULTRALIST = "ultralist"
 private const val ULTRAPRIVACY = "ultraprivacy"
 private const val BLOCK_ALL_THIRD_PARTY_REQUESTS = "block_all_third_party_requests"
-private const val GOOGLE_ANALYTICS = "google_analytics"
-private const val FACEBOOK_CLICK_IDS = "facebook_click_ids"
-private const val TWITTER_AMP_REDIRECTS = "twitter_amp_redirects"
+private const val TRACKING_QUERIES = "tracking_queries"
+private const val AMP_REDIRECTS = "amp_redirects"
 private const val SEARCH = "search"
 private const val SEARCH_CUSTOM_URL = "search_custom_url"
 private const val PROXY = "proxy"
@@ -137,7 +136,7 @@ class ImportExportDatabaseHelper {
 
             // Upgrade from schema version 2, first used in Privacy Browser 2.14, to schema version 3, first used in Privacy Browser 2.15.
             if (importDatabaseVersion < 3) {
-                // Once the SQLite version is >= 3.25.0 (API >= 30) `ALTER TABLE RENAME COLUMN` can be used.  <https://www.sqlite.org/lang_altertable.html> <https://www.sqlite.org/changes.html>
+                // Once the SQLite version is >= 3.25.0 (Android API >= 30) `ALTER TABLE RENAME COLUMN` can be used.  <https://www.sqlite.org/lang_altertable.html> <https://www.sqlite.org/changes.html>
                 // <https://developer.android.com/reference/android/database/sqlite/package-summary>
                 // In the meantime, a new column must be created with the new name.  There is no need to delete the old column on the temporary import database.
 
@@ -201,42 +200,35 @@ class ImportExportDatabaseHelper {
 
             // Upgrade from schema version 6, first used in Privacy Browser 3.0, to schema version 7, first used in Privacy Browser 3.1.
             if (importDatabaseVersion < 7) {
+                // Previously this upgrade added `facebook_click_ids` to the Preferences table.  But that is now removed in schema version 15.
+
                 // Add the wide viewport column to the domains table.
                 importDatabase.execSQL("ALTER TABLE ${DomainsDatabaseHelper.DOMAINS_TABLE} ADD COLUMN ${DomainsDatabaseHelper.WIDE_VIEWPORT} INTEGER")
 
-                // Add the Google Analytics, Facebook Click IDs, Twitter AMP redirects, and wide viewport columns to the preferences table.
-                importDatabase.execSQL("ALTER TABLE $PREFERENCES_TABLE ADD COLUMN $GOOGLE_ANALYTICS BOOLEAN")
-                importDatabase.execSQL("ALTER TABLE $PREFERENCES_TABLE ADD COLUMN $FACEBOOK_CLICK_IDS BOOLEAN")
-                importDatabase.execSQL("ALTER TABLE $PREFERENCES_TABLE ADD COLUMN $TWITTER_AMP_REDIRECTS BOOLEAN")
+                // Add the Google Analytics, Twitter AMP redirects, and wide viewport columns to the preferences table.
+                importDatabase.execSQL("ALTER TABLE $PREFERENCES_TABLE ADD COLUMN google_analytics BOOLEAN")
+                importDatabase.execSQL("ALTER TABLE $PREFERENCES_TABLE ADD COLUMN twitter_amp_redirects BOOLEAN")
                 importDatabase.execSQL("ALTER TABLE $PREFERENCES_TABLE ADD COLUMN $WIDE_VIEWPORT BOOLEAN")
 
                 // Get the current preference values.
-                val googleAnalytics = sharedPreferences.getBoolean(GOOGLE_ANALYTICS, true)
-                val facebookClickIds = sharedPreferences.getBoolean(FACEBOOK_CLICK_IDS, true)
-                val twitterAmpRedirects = sharedPreferences.getBoolean(TWITTER_AMP_REDIRECTS, true)
+                val trackingQueries = sharedPreferences.getBoolean(TRACKING_QUERIES, true)
+                val ampRedirects = sharedPreferences.getBoolean(AMP_REDIRECTS, true)
                 val wideViewport = sharedPreferences.getBoolean(WIDE_VIEWPORT, true)
 
-                // Populate the preferences with the current Google Analytics value.
+                // Populate the preferences with the current Tracking Queries value.  Google Analytics was renamed Tracking Queries in schema version 15.
                 // This can switch to using the variables directly once the API >= 30.  <https://www.sqlite.org/datatype3.html#boolean_datatype>
                 // <https://developer.android.com/reference/android/database/sqlite/package-summary>
-                if (googleAnalytics) {
-                    importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET $GOOGLE_ANALYTICS = 1")
-                } else {
-                    importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET $GOOGLE_ANALYTICS = 0")
-                }
-
-                // Populate the preferences with the current Facebook Click IDs value.
-                if (facebookClickIds) {
-                    importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET $FACEBOOK_CLICK_IDS = 1")
+                if (trackingQueries) {
+                    importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET google_analytics = 1")
                 } else {
-                    importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET $FACEBOOK_CLICK_IDS = 0")
+                    importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET google_analytics = 0")
                 }
 
-                // Populate the preferences table with the current Twitter AMP redirects value.
-                if (twitterAmpRedirects) {
-                    importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET $TWITTER_AMP_REDIRECTS = 1")
+                // Populate the preferences table with the current AMP Redirects value.  Twitter AMP Redirects was renamed AMP Redirects in schema version 15.
+                if (ampRedirects) {
+                    importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET twitter_amp_redirects = 1")
                 } else {
-                    importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET $TWITTER_AMP_REDIRECTS = 0")
+                    importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET twitter_amp_redirects = 0")
                 }
 
                 // Populate the preferences table with the current wide viewport value.
@@ -362,7 +354,7 @@ class ImportExportDatabaseHelper {
             if (importDatabaseVersion < 14) {
                 // `enabledthirdpartycookies` was removed from the domains table.  `do_not_track` and `third_party_cookies` were removed from the preferences table.
 
-                // Once the SQLite version is >= 3.25.0 `ALTER TABLE RENAME COLUMN` can be used.  <https://www.sqlite.org/lang_altertable.html> <https://www.sqlite.org/changes.html>
+                // Once the SQLite version is >= 3.25.0 (Android API >= 30) `ALTER TABLE RENAME COLUMN` can be used.  <https://www.sqlite.org/lang_altertable.html> <https://www.sqlite.org/changes.html>
                 // <https://developer.android.com/reference/android/database/sqlite/package-summary>
                 // In the meantime, a new column must be created with the new name.  There is no need to delete the old column on the temporary import database.
 
@@ -399,6 +391,23 @@ class ImportExportDatabaseHelper {
                 }
             }
 
+            // Upgrade from schema version 14, first used in Privacy Browser 3.8, to schema version 15, first used in Privacy Browser 3.11.
+            if (importDatabaseVersion < 15) {
+                // `facebook_click_ids` was removed from the preferences table.
+
+                // Once the SQLite version is >= 3.25.0 (Android API >= 30) `ALTER TABLE RENAME COLUMN` can be used.  <https://www.sqlite.org/lang_altertable.html> <https://www.sqlite.org/changes.html>
+                // <https://developer.android.com/reference/android/database/sqlite/package-summary>
+                // In the meantime, a new column must be created with the new name.  There is no need to delete the old column on the temporary import database.
+
+                // Create the new URL modification columns.
+                importDatabase.execSQL("ALTER TABLE $PREFERENCES_TABLE ADD COLUMN $TRACKING_QUERIES BOOLEAN")
+                importDatabase.execSQL("ALTER TABLE $PREFERENCES_TABLE ADD COLUMN $AMP_REDIRECTS BOOLEAN")
+
+                // Copy the data from the old columns to the new ones.
+                importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET $TRACKING_QUERIES = google_analytics")
+                importDatabase.execSQL("UPDATE $PREFERENCES_TABLE SET $AMP_REDIRECTS = twitter_amp_redirects")
+            }
+
             // Get a cursor for the bookmarks table.
             val importBookmarksCursor = importDatabase.rawQuery("SELECT * FROM ${BookmarksDatabaseHelper.BOOKMARKS_TABLE}", null)
 
@@ -528,9 +537,8 @@ class ImportExportDatabaseHelper {
                 .putBoolean(ULTRALIST, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndexOrThrow(ULTRALIST)) == 1)
                 .putBoolean(ULTRAPRIVACY, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndexOrThrow(ULTRAPRIVACY)) == 1)
                 .putBoolean(BLOCK_ALL_THIRD_PARTY_REQUESTS, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndexOrThrow(BLOCK_ALL_THIRD_PARTY_REQUESTS)) == 1)
-                .putBoolean(GOOGLE_ANALYTICS, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndexOrThrow(GOOGLE_ANALYTICS)) == 1)
-                .putBoolean(FACEBOOK_CLICK_IDS, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndexOrThrow(FACEBOOK_CLICK_IDS)) == 1)
-                .putBoolean(TWITTER_AMP_REDIRECTS, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndexOrThrow(TWITTER_AMP_REDIRECTS)) == 1)
+                .putBoolean(TRACKING_QUERIES, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndexOrThrow(TRACKING_QUERIES)) == 1)
+                .putBoolean(AMP_REDIRECTS, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndexOrThrow(AMP_REDIRECTS)) == 1)
                 .putString(SEARCH, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndexOrThrow(SEARCH)))
                 .putString(SEARCH_CUSTOM_URL, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndexOrThrow(SEARCH_CUSTOM_URL)))
                 .putString(PROXY, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndexOrThrow(PROXY)))
@@ -685,50 +693,49 @@ class ImportExportDatabaseHelper {
 
 
             // Prepare the preferences table SQL creation string.
-            val createPreferencesTable = "CREATE TABLE " + PREFERENCES_TABLE + " (" +
-                    ID + " INTEGER PRIMARY KEY, " +
-                    JAVASCRIPT + " BOOLEAN, " +
-                    COOKIES + " BOOLEAN, " +
-                    DOM_STORAGE + " BOOLEAN, " +
-                    SAVE_FORM_DATA + " BOOLEAN, " +
-                    USER_AGENT + " TEXT, " +
-                    CUSTOM_USER_AGENT + " TEXT, " +
-                    INCOGNITO_MODE + " BOOLEAN, " +
-                    ALLOW_SCREENSHOTS + " BOOLEAN, " +
-                    EASYLIST + " BOOLEAN, " +
-                    EASYPRIVACY + " BOOLEAN, " +
-                    FANBOYS_ANNOYANCE_LIST + " BOOLEAN, " +
-                    FANBOYS_SOCIAL_BLOCKING_LIST + " BOOLEAN, " +
-                    ULTRALIST + " BOOLEAN, " +
-                    ULTRAPRIVACY + " BOOLEAN, " +
-                    BLOCK_ALL_THIRD_PARTY_REQUESTS + " BOOLEAN, " +
-                    GOOGLE_ANALYTICS + " BOOLEAN, " +
-                    FACEBOOK_CLICK_IDS + " BOOLEAN, " +
-                    TWITTER_AMP_REDIRECTS + " BOOLEAN, " +
-                    SEARCH + " TEXT, " +
-                    SEARCH_CUSTOM_URL + " TEXT, " +
-                    PROXY + " TEXT, " +
-                    PROXY_CUSTOM_URL + " TEXT, " +
-                    FULL_SCREEN_BROWSING_MODE + " BOOLEAN, " +
-                    HIDE_APP_BAR + " BOOLEAN, " +
-                    CLEAR_EVERYTHING + " BOOLEAN, " +
-                    CLEAR_COOKIES + " BOOLEAN, " +
-                    CLEAR_DOM_STORAGE + " BOOLEAN, " +
-                    CLEAR_FORM_DATA + " BOOLEAN, " +
-                    CLEAR_LOGCAT + " BOOLEAN, " +
-                    CLEAR_CACHE + " BOOLEAN, " +
-                    HOMEPAGE + " TEXT, " +
-                    FONT_SIZE + " TEXT, " +
-                    OPEN_INTENTS_IN_NEW_TAB + " BOOLEAN, " +
-                    SWIPE_TO_REFRESH + " BOOLEAN, " +
-                    DOWNLOAD_WITH_EXTERNAL_APP + " BOOLEAN, " +
-                    SCROLL_APP_BAR + " BOOLEAN, " +
-                    BOTTOM_APP_BAR + " BOOLEAN, " +
-                    DISPLAY_ADDITIONAL_APP_BAR_ICONS + " BOOLEAN, " +
-                    APP_THEME + " TEXT, " +
-                    WEBVIEW_THEME + " TEXT, " +
-                    WIDE_VIEWPORT + " BOOLEAN, " +
-                    DISPLAY_WEBPAGE_IMAGES + " BOOLEAN)"
+            val createPreferencesTable = "CREATE TABLE $PREFERENCES_TABLE (" +
+                    "$ID INTEGER PRIMARY KEY, " +
+                    "$JAVASCRIPT BOOLEAN, " +
+                    "$COOKIES BOOLEAN, " +
+                    "$DOM_STORAGE BOOLEAN, " +
+                    "$SAVE_FORM_DATA BOOLEAN, " +
+                    "$USER_AGENT TEXT, " +
+                    "$CUSTOM_USER_AGENT TEXT, " +
+                    "$INCOGNITO_MODE BOOLEAN, " +
+                    "$ALLOW_SCREENSHOTS BOOLEAN, " +
+                    "$EASYLIST BOOLEAN, " +
+                    "$EASYPRIVACY BOOLEAN, " +
+                    "$FANBOYS_ANNOYANCE_LIST BOOLEAN, " +
+                    "$FANBOYS_SOCIAL_BLOCKING_LIST BOOLEAN, " +
+                    "$ULTRALIST BOOLEAN, " +
+                    "$ULTRAPRIVACY BOOLEAN, " +
+                    "$BLOCK_ALL_THIRD_PARTY_REQUESTS BOOLEAN, " +
+                    "$TRACKING_QUERIES BOOLEAN, " +
+                    "$AMP_REDIRECTS BOOLEAN, " +
+                    "$SEARCH TEXT, " +
+                    "$SEARCH_CUSTOM_URL TEXT, " +
+                    "$PROXY TEXT, " +
+                    "$PROXY_CUSTOM_URL TEXT, " +
+                    "$FULL_SCREEN_BROWSING_MODE BOOLEAN, " +
+                    "$HIDE_APP_BAR BOOLEAN, " +
+                    "$CLEAR_EVERYTHING BOOLEAN, " +
+                    "$CLEAR_COOKIES BOOLEAN, " +
+                    "$CLEAR_DOM_STORAGE BOOLEAN, " +
+                    "$CLEAR_FORM_DATA BOOLEAN, " +
+                    "$CLEAR_LOGCAT BOOLEAN, " +
+                    "$CLEAR_CACHE BOOLEAN, " +
+                    "$HOMEPAGE TEXT, " +
+                    "$FONT_SIZE TEXT, " +
+                    "$OPEN_INTENTS_IN_NEW_TAB BOOLEAN, " +
+                    "$SWIPE_TO_REFRESH BOOLEAN, " +
+                    "$DOWNLOAD_WITH_EXTERNAL_APP BOOLEAN, " +
+                    "$SCROLL_APP_BAR BOOLEAN, " +
+                    "$BOTTOM_APP_BAR BOOLEAN, " +
+                    "$DISPLAY_ADDITIONAL_APP_BAR_ICONS BOOLEAN, " +
+                    "$APP_THEME TEXT, " +
+                    "$WEBVIEW_THEME TEXT, " +
+                    "$WIDE_VIEWPORT BOOLEAN, " +
+                    "$DISPLAY_WEBPAGE_IMAGES BOOLEAN)"
 
             // Create the temporary export database preferences table.
             temporaryExportDatabase.execSQL(createPreferencesTable)
@@ -755,9 +762,8 @@ class ImportExportDatabaseHelper {
             preferencesContentValues.put(ULTRALIST, sharedPreferences.getBoolean(ULTRALIST, true))
             preferencesContentValues.put(ULTRAPRIVACY, sharedPreferences.getBoolean(ULTRAPRIVACY, true))
             preferencesContentValues.put(BLOCK_ALL_THIRD_PARTY_REQUESTS, sharedPreferences.getBoolean(BLOCK_ALL_THIRD_PARTY_REQUESTS, false))
-            preferencesContentValues.put(GOOGLE_ANALYTICS, sharedPreferences.getBoolean(GOOGLE_ANALYTICS, true))
-            preferencesContentValues.put(FACEBOOK_CLICK_IDS, sharedPreferences.getBoolean(FACEBOOK_CLICK_IDS, true))
-            preferencesContentValues.put(TWITTER_AMP_REDIRECTS, sharedPreferences.getBoolean(TWITTER_AMP_REDIRECTS, true))
+            preferencesContentValues.put(TRACKING_QUERIES, sharedPreferences.getBoolean(TRACKING_QUERIES, true))
+            preferencesContentValues.put(AMP_REDIRECTS, sharedPreferences.getBoolean(AMP_REDIRECTS, true))
             preferencesContentValues.put(SEARCH, sharedPreferences.getString(SEARCH, context.getString(R.string.search_default_value)))
             preferencesContentValues.put(SEARCH_CUSTOM_URL, sharedPreferences.getString(SEARCH_CUSTOM_URL, context.getString(R.string.search_custom_url_default_value)))
             preferencesContentValues.put(PROXY, sharedPreferences.getString(PROXY, context.getString(R.string.proxy_default_value)))
index c0cad0377acc93a791408321f04217944891a2a4..58057b780407edf9dfbcb9303b7574ed2c45b7ec 100644 (file)
@@ -42,7 +42,7 @@ import java.net.SocketAddress
 
 class ProxyHelper {
     companion object {
-        // Define the public companion object constants.  These can be moved to public class constants once the entire project has migrated to Kotlin.
+        // Define the public static companion object constants.
         const val NONE = "None"
         const val TOR = "Tor"
         const val I2P = "I2P"
diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/SanitizeUrlHelper.kt b/app/src/main/java/com/stoutner/privacybrowser/helpers/SanitizeUrlHelper.kt
new file mode 100644 (file)
index 0000000..7e4ad98
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright ©2022 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+ *
+ * Privacy Browser Android is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser Android is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.helpers
+
+private val trackingQueriesList = listOf(
+    "__hsfp=",             // HubSpot.
+    "__hssc=",             // HubSpot.
+    "__hstc=",             // HubSpot.
+    "__s=",                // Drip.com.
+    "_hsenc=",             // HubSpot.
+    "_openstat=",          // Yandex.
+    "dclid=",              // DoubleClick ID.
+    "fbadid=",             // FaceBook Ad ID.
+    "fbclid=",             // FaceBook Click ID.
+    "gclid=",              // Google Click ID.
+    "hsCtaTracking=",      // HubSpot.
+    "igshid=",             // Instagram.
+    "mc_eid=",             // MailChimp Email ID.
+    "?mkt_tok=",           // Adobe Marketo.
+    "ml_subscriber=",      // MailerLite.
+    "ml_subscriber_hash=", // MailerLite.
+    "msclkid=",            // Microsoft Click ID.
+    "oly_anon_id=",        // Omeda Anonymous ID.
+    "oly_enc_id=",         // Omeda ID.
+    "rb_clickid=",         // Unknown tracker.
+    "s_cid=",              // Adobe Site Catalyst.
+    "utm_",                // Google Analytics.
+    "vero_conv=",          // Vero.
+    "vero_id=",            // Vero ID.
+    "wickedid=",           // Wicked Reports ID.
+    "yclid="               // Yandex Click ID.
+)
+
+class SanitizeUrlHelper {
+    fun sanitizeTrackingQueries(inputUrl: String): String {
+        // Make a copy of the input URL so that it can be modified.
+        var url = inputUrl
+
+        // Remove each tracking query from the URL.
+        trackingQueriesList.forEach {
+            if (url.contains("?$it")) {  // Check for an initial query
+                // Remove the first query and anything after it.
+                url = url.substring(0, url.indexOf("?$it"))
+            }
+            else if (url.contains("&$it")) {  // Check for a subsequent query.
+                // Remove the query and anything after it.
+                url = url.substring(0, url.indexOf("&$it"))
+            }
+        }
+
+        // Return the sanitized URL.
+        return url
+    }
+
+    fun sanitizeAmpRedirects(inputUrl: String): String {
+        // Make a copy of the input URL so that it can be modified.
+        var url = inputUrl
+
+        // Remove Twitter `amp=1`.
+        if (url.contains("?amp"))
+            url = url.substring(0, url.indexOf("?amp"))
+        else if (url.contains("&amp"))
+            url = url.substring(0, url.indexOf("&amp"))
+
+        // Return the sanitized URL.
+        return url
+    }
+}
\ No newline at end of file
index 5fc5ca69042dffdac697be54aecd7b5a23f42286..62d72549fd702567a6fa4400d404881ee1dbed18 100644 (file)
         <string name="block_all_third_party_requests">Alle Zugriffe auf Dritt-Anbieter-Inhalte blockieren</string>
         <string name="block_all_third_party_requests_summary">Alle Zugriffe auf Dritt-Anbieter-Inhalte zu blockieren verbessert die Privatsphäre, kann jedoch Webseiten verunstalten.</string>
     <string name="url_modification">URL-Bereinigung</string>
-        <string name="google_analytics">Google Analytics</string>
-        <string name="google_analytics_summary">Entfernt “?utm_” und “&amp;utm_” sowie alles danach aus URLs.</string>
-        <string name="facebook_click_ids">Facebook Click-IDs</string>
-        <string name="facebook_click_ids_summary">Entfernt “?fbclid=”, “&amp;fbclid=”, “?fbadid=” und “&amp;fbadid=” sowie alles danach aus URLs.</string>
-        <string name="twitter_amp_redirects">Twitter AMP-Umleitungen</string>
-        <string name="twitter_amp_redirects_summary">Entfernt “?amp=1” sowie alles danach URLs.</string>
     <string name="search">Suche</string>
         <string-array name="search_entries">
             <item>Mojeek</item>
index 5044c8bb8ee65f3330e49fd01ab01ba3eef5901d..c5584a85deedfd4bfdcdcc982f451f5c7e608f94 100644 (file)
         <string name="block_all_third_party_requests">Bloquear todas las solicitudes de terceras partes</string>
         <string name="block_all_third_party_requests_summary">Bloquear todas las solicitudes de terceras  partes aumenta la privacidad, pero rompe muchas páginas web.</string>
     <string name="url_modification">Modificación de URL</string>
-        <string name="google_analytics">Google Analytics</string>
-        <string name="google_analytics_summary">Eliminar “?utm_”, “&amp;utm_” y cualquier cosa tras ello de las URLs.</string>
-        <string name="facebook_click_ids">IDs de clics en Facebook</string>
-        <string name="facebook_click_ids_summary">Eliminar “?fbclid=”, “&amp;fbclid=”, “?fbadid=”, “&amp;fbadid=” y cualquier cosa tras ello de las URLs.</string>
-        <string name="twitter_amp_redirects">Redirecciones de Twitter AMP</string>
-        <string name="twitter_amp_redirects_summary">Eliminar “?amp=1” y cualquier cosa después de esto de las URLs.</string>
     <string name="search">Búsqueda</string>
         <string-array name="search_entries">
             <item>Mojeek</item>
index 362c5e1d52e301128337cddb17a56b70b73ceaae..913c5946bcb8d5320bab75f3c578897d05dd32b6 100644 (file)
         <string name="add_to_home_screen">Ajouter à l\'écran d\'accueil</string>
         <string name="view_source">Voir Source</string>
     <string name="share">Partager</string>
+        <string name="share_message">Partager le message</string>
         <string name="share_url">Partager URL</string>
         <string name="open_with_app">Ouvrir avec une application</string>
         <string name="open_with_browser">Ouvrir dans le navigateur</string>
         <string name="block_all_third_party_requests">Bloquer toutes les requêtes tierces</string>
         <string name="block_all_third_party_requests_summary">Le blocage de toutes les requêtes tierces augmente la vie privée, mais détruit de nombreux sites Web.</string>
     <string name="url_modification">Modifications d\'URL</string>
-        <string name="google_analytics">Google Analytics</string>
-        <string name="google_analytics_summary">Supprime “?utm_” et “&amp;utm_” et tout ce qui suit après ces URLs.</string>
-        <string name="facebook_click_ids">Facebook Click IDs</string>
-        <string name="facebook_click_ids_summary">Supprime “?fbclid=”, “&amp;fbclid=”, “?fbadid=” et “&amp;fbadid=” et tout ce qui suit après ces URLs.</string>
-        <string name="twitter_amp_redirects">Twitter AMP</string>
-        <string name="twitter_amp_redirects_summary">Supprime “?amp=1” et tout ce qui suit après cette URL.</string>
     <string name="search">Moteur de Recherche</string>
         <string-array name="search_entries">
             <item>Mojeek</item>
index c0e8cce4e35c7ab437c0adca6ae942ae384191e1..56d7aba390aac05c0dcf10fdaafeaa8582b4bed5 100644 (file)
             <string name="api">API</string>
             <string name="security_patch">Patch si sicurezza:</string>
             <string name="build">Build:</string>
+            <string name="kernel">Kernel:</string>
             <string name="webview_provider">Provider di WebView:</string>
             <string name="webview_version">Versione di WebView:</string>
             <string name="orbot">Orbot:</string>
         <string name="block_all_third_party_requests">Blocca tutte le richieste di Terze Parti</string>
         <string name="block_all_third_party_requests_summary">Il blocco di tutte le richieste di Terze Parti aumenta privacy, ma impedisce la visualizzazione di molti siti web.</string>
     <string name="url_modification">Modifica delle URL</string>
-        <string name="google_analytics">Google Analytics</string>
-        <string name="google_analytics_summary">Rimuovi “?utm_” e “&amp;utm_” e tutto quello che segue dalle URL.</string>
-        <string name="facebook_click_ids">Facebook Click ID</string>
-        <string name="facebook_click_ids_summary">Rimuovi “?fbclid=”, “&amp;fbclid=”, “?fbadid=”, e “&amp;fbadid=” e tutto quello che segue dalle URL.</string>
-        <string name="twitter_amp_redirects">Reindirizzamenti Twitter AMP</string>
-        <string name="twitter_amp_redirects_summary">Rimuovi “?amp=1”  e tutto quello che segue dalle URL.</string>
     <string name="search">Ricerca</string>
         <string-array name="search_entries">
             <item>Mojeek</item>
index 8646ae84b19fae558e93aa6b9084911a6e17fb9d..8e62c196e221f5c283e08b4a06e5f822091950ed 100644 (file)
             <string name="api">API</string>
             <string name="security_patch">Patch de segurança:</string>
             <string name="build">Build:</string>
+            <string name="kernel">Kernel:</string>
             <string name="webview_provider">Fornecedor WebView:</string>
             <string name="webview_version">Versão do WebView:</string>
             <string name="orbot">Orbot:</string>
         <string name="block_all_third_party_requests">Bloquear todas as solicitações de terceiros</string>
         <string name="block_all_third_party_requests_summary">Bloquear todas as solicitações de terceiros aumenta a privacidade, mas quebra muitos sites.</string>
     <string name="url_modification">Modificação de URL</string>
-        <string name="google_analytics">Google Analytics</string>
-        <string name="google_analytics_summary">Remova utm_ e amp; utm_ e qualquer coisa depois deles dos URLs.</string>
-        <string name="facebook_click_ids">IDs de clique do Facebook</string>
-        <string name="facebook_click_ids_summary">Remover â€œ?fbclid=†, â€œ&amp;fbclid=†, â€œ?fbadid=†, e â€œ&amp;fbadid=† e qualquer coisa depois deles a partir de URLs.</string>
-        <string name="twitter_amp_redirects">Redirecionamentos de AMP do Twitter</string>
-        <string name="twitter_amp_redirects_summary">Remover â€œ?amp=1† e qualquer coisa depois de URLs.</string>
     <string name="search">Search</string>
         <string-array name="search_entries">
             <item>Mojeek</item>
index 4ec273664db389889f4c40817312c74161a41cb3..c08cba292e0de7b8bedb2261c798777932768355 100644 (file)
             <string name="api">API</string>
             <string name="security_patch">Патч безопасности:</string>
             <string name="build">Сборка:</string>
+            <string name="kernel">Ядро:</string>
             <string name="webview_provider">Провайдер WebView:</string>
             <string name="webview_version">Версия WebView:</string>
             <string name="orbot">Orbot:</string>
         <string name="block_all_third_party_requests">Блокировать все сторонние запросы</string>
         <string name="block_all_third_party_requests_summary">Блокировка всех сторонних запросов повышает конфиденциальность, но ломает многие веб-сайты.</string>
     <string name="url_modification">Модификация URL</string>
-        <string name="google_analytics">Google Analytics</string>
-        <string name="google_analytics_summary">Удалять из URL “?utm_” и “&amp;utm_” и все что будет после.</string>
-        <string name="facebook_click_ids">Идентификаторы кликов в Facebook</string>
-        <string name="facebook_click_ids_summary">Удалять из URL “?fbclid=”, “&amp;fbclid=”, “?fbadid=”, и “&amp;fbadid=” и все что будет после.</string>
-        <string name="twitter_amp_redirects">AMP-перенаправления в Twitter</string>
-        <string name="twitter_amp_redirects_summary">Удалять из URL “?amp=1” и все что будет после.</string>
     <string name="search">Поиск</string>
         <string-array name="search_entries">
             <item>Mojeek</item>
index 3e663f77ec2ab808f920bf526ee7ee7bd39e73cb..5c3bc78d72a9cacad6fd97b4b3fd73c38361dec1 100644 (file)
         <string name="block_all_third_party_requests">Tüm üçüncü taraf istekleri engelle</string>
         <string name="block_all_third_party_requests_summary">Tüm üçüncü taraf istekleri engellemek gizliliği arttırır, fakat çoğu web sitesinin çökmesine sebep olur.</string>
     <string name="url_modification">URL Modifikasyonu</string>
-        <string name="google_analytics">Google Analytics</string>
-        <string name="google_analytics_summary">URL\'lerde “?utm_” ve “&amp;utm_” ve onlardan sonra gelen her şey kaldırıldı.</string>
-        <string name="facebook_click_ids">Facebook Tık ID\'leri</string>
-        <string name="facebook_click_ids_summary">URL\'lerde “?fbclid=”, “&amp;fbclid=”, “?fbadid=”, ve “&amp;fbadid=” ve onlardan sonra gelen her şey kaldırıldı.</string>
-        <string name="twitter_amp_redirects">Twitter AMP yönlendirmeleri</string>
-        <string name="twitter_amp_redirects_summary">URL\'den sonra gelen “?amp=1” ve diğer şeyleri kaldırır.</string>
     <string name="search">Arama</string>
         <string-array name="search_entries">
             <item>Mojeek</item>
index d34133c658c4e972df12ee74869878faf54e1292..4162936a4981154c1786bfa68e73545da7aea559 100644 (file)
         <string name="block_all_third_party_requests">Block all third-party requests</string>
         <string name="block_all_third_party_requests_summary">Blocking all third-party requests increases privacy, but it breaks many websites.</string>
     <string name="url_modification">URL Modification</string>
-        <string name="google_analytics">Google Analytics</string>
-        <string name="google_analytics_summary">Remove “?utm_” and “&amp;utm_” and anything after them from URLs.</string>
-        <string name="facebook_click_ids">Facebook Click IDs</string>
-        <string name="facebook_click_ids_summary">Remove “?fbclid=”, “&amp;fbclid=”, “?fbadid=”, and “&amp;fbadid=” and anything after them from URLs.</string>
-        <string name="twitter_amp_redirects">Twitter AMP redirects</string>
-        <string name="twitter_amp_redirects_summary">Remove “?amp=1” and anything after it from URLs.</string>
+        <string name="tracking_queries">Tracking queries</string>
+        <string name="tracking_queries_summary">Remove known tracking queries from URLs.</string>
+        <string name="amp_redirects">AMP redirects</string>
+        <string name="amp_redirects_summary">Remove known AMP (Accelerated Mobil Pages) redirect queries from URLs.</string>
     <string name="search">Search</string>
         <string-array name="search_entries">
             <item>Mojeek</item>
 
     <!-- Non-translatable preference keys. -->
     <string name="allow_screenshots_key" translatable="false">allow_screenshots</string>
+    <string name="amp_redirects_key" translatable="false">amp_redirects</string>
     <string name="bottom_app_bar_key" translatable="false">bottom_app_bar</string>
     <string name="cookies_key" translatable="false">cookies</string>
     <string name="clear_logcat_key" translatable="false">clear_logcat</string>
     <string name="display_additional_app_bar_icons_key" translatable="false">display_additional_app_bar_icons</string>
     <string name="proxy_custom_url_key" translatable="false">proxy_custom_url</string>
     <string name="scroll_app_bar_key" translatable="false">scroll_app_bar</string>
+    <string name="tracking_queries_key" translatable="false">tracking_queries</string>
 
     <!-- Non-translatable preference default values. -->
     <string name="app_theme_default_value" translatable="false">System default</string>
index 1bdbd183b285f270667321dc0ffd82986a8e116f..5d1abb9b943d2c398290b1eef16f1e9fb24a857a 100644 (file)
         android:title="@string/url_modification" >
 
         <SwitchPreference
-            android:key="google_analytics"
-            android:title="@string/google_analytics"
-            android:summary="@string/google_analytics_summary"
+            android:key="tracking_queries"
+            android:title="@string/tracking_queries"
+            android:summary="@string/tracking_queries_summary"
             android:defaultValue="true" />
 
         <SwitchPreference
-            android:key="facebook_click_ids"
-            android:title="@string/facebook_click_ids"
-            android:summary="@string/facebook_click_ids_summary"
-            android:defaultValue="true" />
-
-        <SwitchPreference
-            android:key="twitter_amp_redirects"
-            android:title="@string/twitter_amp_redirects"
-            android:summary="@string/twitter_amp_redirects_summary"
+            android:key="amp_redirects"
+            android:title="@string/amp_redirects"
+            android:summary="@string/amp_redirects_summary"
             android:defaultValue="true" />
     </PreferenceCategory>
 
index 09ebadaa21e60e335f2702696d9f2ac7f4da0aa2..68c5ada8f4290a0f65f7c99f4b2589b169492afb 100644 (file)
@@ -27,7 +27,7 @@ buildscript {
 
     dependencies {
         classpath 'com.android.tools.build:gradle:7.2.1'
-        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files