From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tad <tad@spotco.us>
Date: Thu, 21 Oct 2021 21:09:38 -0400
Subject: [PATCH] Add more 'Private DNS' options

This adds thirteen DNS providers as available presets.

Credit: CalyxOS
- Chirayu Desai <chirayudesai1@gmail.com>
  https://review.calyxos.org/c/CalyxOS/platform_packages_apps_Settings/+/458
- Pavel Shirshov <pshirshov@eml.cc>
  https://review.calyxos.org/c/CalyxOS/platform_packages_apps_Settings/+/5357

Signed-off-by: Tad <tad@spotco.us>
Change-Id: I423ad5a3c360a687a226e61df3f75b5550f851c0
---
 res/layout/private_dns_mode_dialog.xml        | 91 +++++++++++++++++++
 res/values/cm_strings.xml                     | 15 +++
 .../PrivateDnsModeDialogPreference.java       | 65 +++++++++++++
 .../PrivateDnsPreferenceController.java       | 65 +++++++++++++
 4 files changed, 236 insertions(+)

diff --git a/res/layout/private_dns_mode_dialog.xml b/res/layout/private_dns_mode_dialog.xml
index 652bc63ae3..6106900318 100644
--- a/res/layout/private_dns_mode_dialog.xml
+++ b/res/layout/private_dns_mode_dialog.xml
@@ -33,6 +33,97 @@
             android:layout_height="wrap_content"
             android:layout_margin="8dp"/>
 
+        <RadioButton
+            android:id="@id/private_dns_mode_adguard"
+            android:text="@string/private_dns_mode_adguard"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_appliedprivacy"
+            android:text="@string/private_dns_mode_appliedprivacy"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_cira"
+            android:text="@string/private_dns_mode_cira"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_cleanbrowsing"
+            android:text="@string/private_dns_mode_cleanbrowsing"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_cloudflare"
+            android:text="@string/private_dns_mode_cloudflare"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_cznic"
+            android:text="@string/private_dns_mode_cznic"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_google"
+            android:text="@string/private_dns_mode_google"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_mullvad"
+            android:text="@string/private_dns_mode_mullvad"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_quadnine"
+            android:text="@string/private_dns_mode_quadnine"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_restena"
+            android:text="@string/private_dns_mode_restena"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_switch"
+            android:text="@string/private_dns_mode_switch"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_twnic"
+            android:text="@string/private_dns_mode_twnic"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
+        <RadioButton
+            android:id="@id/private_dns_mode_uncensoreddns"
+            android:text="@string/private_dns_mode_uncensoreddns"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="8dp"/>
+
         <RadioButton
             android:id="@+id/private_dns_mode_opportunistic"
             android:text="@string/private_dns_mode_opportunistic"
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml
index 1150011970..23e6f595d1 100644
--- a/res/values/cm_strings.xml
+++ b/res/values/cm_strings.xml
@@ -342,6 +342,21 @@
     <string name="unlock_scramble_pin_layout_title">Scramble layout</string>
     <string name="unlock_scramble_pin_layout_summary">Scramble PIN layout when unlocking device</string>
 
+    <!-- Private DNS -->
+    <string name="private_dns_mode_adguard" translatable="false">AdGuard (CY)</string>
+    <string name="private_dns_mode_appliedprivacy" translatable="false">AppliedPrivacy (AT)</string>
+    <string name="private_dns_mode_cira" translatable="false">CIRA (CA)</string>
+    <string name="private_dns_mode_cleanbrowsing" translatable="false">CleanBrowsing (US)</string>
+    <string name="private_dns_mode_cloudflare" translatable="false">Cloudflare (US)</string>
+    <string name="private_dns_mode_cznic" translatable="false">CZ.NIC (CZ)</string>
+    <string name="private_dns_mode_google" translatable="false">Google (US)</string>
+    <string name="private_dns_mode_mullvad" translatable="false">Mullvad (SE)</string>
+    <string name="private_dns_mode_quadnine" translatable="false">Quad9 (CH)</string>
+    <string name="private_dns_mode_restena" translatable="false">Restena (LU)</string>
+    <string name="private_dns_mode_switch" translatable="false">SWITCH (CH)</string>
+    <string name="private_dns_mode_twnic" translatable="false">TW.NIC (TW)</string>
+    <string name="private_dns_mode_uncensoreddns" translatable="false">UncensoredDNS (DK)</string>
+
     <!-- Proximity wake -->
     <string name="proximity_wake_title">Prevent accidental wake-up</string>
     <string name="proximity_wake_summary">Check the proximity sensor prior to waking up screen</string>
diff --git a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
index 290ffd599e..a37b535660 100644
--- a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
+++ b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
@@ -17,6 +17,19 @@ package com.android.settings.network;
 
 import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE_FALLBACK;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_ADGUARD;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_APPLIEDPRIVACY;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_CIRA;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_CLEANBROWSING;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_CLOUDFLARE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_CZNIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_GOOGLE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_MULLVAD;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_QUADNINE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_RESTENA;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_SWITCH;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_TWNIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_UNCENSOREDDNS;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 import static android.system.OsConstants.AF_INET;
@@ -68,6 +81,19 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreference imple
     static {
         PRIVATE_DNS_MAP = new HashMap<>();
         PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_OFF, R.id.private_dns_mode_off);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_ADGUARD, R.id.private_dns_mode_adguard);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_APPLIEDPRIVACY, R.id.private_dns_mode_appliedprivacy);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_CIRA, R.id.private_dns_mode_cira);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_CLEANBROWSING, R.id.private_dns_mode_cleanbrowsing);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_CLOUDFLARE, R.id.private_dns_mode_cloudflare);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_CZNIC, R.id.private_dns_mode_cznic);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_GOOGLE, R.id.private_dns_mode_google);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_MULLVAD, R.id.private_dns_mode_mullvad);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_QUADNINE, R.id.private_dns_mode_quadnine);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_RESTENA, R.id.private_dns_mode_restena);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_SWITCH, R.id.private_dns_mode_switch);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_TWNIC, R.id.private_dns_mode_twnic);
+        PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_UNCENSOREDDNS, R.id.private_dns_mode_uncensoreddns);
         PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_OPPORTUNISTIC, R.id.private_dns_mode_opportunistic);
         PRIVATE_DNS_MAP.put(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, R.id.private_dns_mode_provider);
     }
@@ -180,6 +206,45 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreference imple
             case R.id.private_dns_mode_off:
                 mMode = PRIVATE_DNS_MODE_OFF;
                 break;
+            case R.id.private_dns_mode_adguard:
+                mMode = PRIVATE_DNS_MODE_ADGUARD;
+                break;
+            case R.id.private_dns_mode_appliedprivacy:
+                mMode = PRIVATE_DNS_MODE_APPLIEDPRIVACY;
+                break;
+            case R.id.private_dns_mode_cira:
+                mMode = PRIVATE_DNS_MODE_CIRA;
+                break;
+            case R.id.private_dns_mode_cleanbrowsing:
+                mMode = PRIVATE_DNS_MODE_CLEANBROWSING;
+                break;
+            case R.id.private_dns_mode_cloudflare:
+                mMode = PRIVATE_DNS_MODE_CLOUDFLARE;
+                break;
+            case R.id.private_dns_mode_cznic:
+                mMode = PRIVATE_DNS_MODE_CZNIC;
+                break;
+            case R.id.private_dns_mode_google:
+                mMode = PRIVATE_DNS_MODE_GOOGLE;
+                break;
+            case R.id.private_dns_mode_mullvad:
+                mMode = PRIVATE_DNS_MODE_MULLVAD;
+                break;
+            case R.id.private_dns_mode_quadnine:
+                mMode = PRIVATE_DNS_MODE_QUADNINE;
+                break;
+            case R.id.private_dns_mode_restena:
+                mMode = PRIVATE_DNS_MODE_RESTENA;
+                break;
+            case R.id.private_dns_mode_switch:
+                mMode = PRIVATE_DNS_MODE_SWITCH;
+                break;
+            case R.id.private_dns_mode_twnic:
+                mMode = PRIVATE_DNS_MODE_TWNIC;
+                break;
+            case R.id.private_dns_mode_uncensoreddns:
+                mMode = PRIVATE_DNS_MODE_UNCENSOREDDNS;
+                break;
             case R.id.private_dns_mode_opportunistic:
                 mMode = PRIVATE_DNS_MODE_OPPORTUNISTIC;
                 break;
diff --git a/src/com/android/settings/network/PrivateDnsPreferenceController.java b/src/com/android/settings/network/PrivateDnsPreferenceController.java
index 6f38569673..d24f9563f5 100644
--- a/src/com/android/settings/network/PrivateDnsPreferenceController.java
+++ b/src/com/android/settings/network/PrivateDnsPreferenceController.java
@@ -17,6 +17,19 @@
 package com.android.settings.network;
 
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_ADGUARD;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_APPLIEDPRIVACY;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_CIRA;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_CLEANBROWSING;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_CLOUDFLARE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_CZNIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_GOOGLE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_MULLVAD;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_QUADNINE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_RESTENA;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_SWITCH;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_TWNIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_UNCENSOREDDNS;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE;
@@ -118,6 +131,58 @@ public class PrivateDnsPreferenceController extends BasePreferenceController
         switch (mode) {
             case PRIVATE_DNS_MODE_OFF:
                 return res.getString(R.string.private_dns_mode_off);
+            case PRIVATE_DNS_MODE_ADGUARD:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_adguard)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_APPLIEDPRIVACY:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_appliedprivacy)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_CIRA:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_cira)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_CLEANBROWSING:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_cleanbrowsing)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_CLOUDFLARE:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_cloudflare)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_CZNIC:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_cznic)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_GOOGLE:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_google)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_MULLVAD:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_mullvad)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_QUADNINE:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_quadnine)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_RESTENA:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_restena)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_SWITCH:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_switch)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_TWNIC:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_twnic)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
+            case PRIVATE_DNS_MODE_UNCENSOREDDNS:
+                return dnsesResolved
+                        ? res.getString(R.string.private_dns_mode_uncensoreddns)
+                        : res.getString(R.string.private_dns_mode_provider_failure);
             case PRIVATE_DNS_MODE_OPPORTUNISTIC:
                 // TODO (b/79122154) : create a string specifically for this, instead of
                 // hijacking a string from notifications. This is necessary at this time
