OSDN Git Service

Private DNS: Add policy transparency
authorEran Messeri <eranm@google.com>
Fri, 9 Nov 2018 13:21:34 +0000 (13:21 +0000)
committerEran Messeri <eranm@google.com>
Fri, 9 Nov 2018 13:33:16 +0000 (13:33 +0000)
When the Private DNS setting is disabled via a user restriction, show
information to the user explaining that they cannot change this setting
due to IT admin policy.

Testing steps:
* Installed & configured TestDPC on the device.
* Made sure that the Private DNS setting is usable.
* Set the user restriction via TestDPC ("User Restrictions" -> "Disallow
config Private DNS").
* Navigated to Settings -> Network & Internet -> Advanced
* Observed that Private DNS is greyed out and the Restricted icon is
showing.
* Observed that when tapping either the icon or the greyed-out text I
get a dialog with policy information.

Implementation notes:
I have not utilized the existing RestrictedPreference as the Private DNS
mode preference extends CustomDialogPreferenceCompat.
I have also not utilized the RestrictedPreferenceHelper as it modifies
the summary shown for the preference. This preference has its own
summary (showing the current state of Private DNS configuration) which I
did not want to override.

Bug: 112982691
Test: Manual, see above.
Change-Id: I9b7496b5b2cbb26012d889369f2199239cd2e00f

src/com/android/settings/network/PrivateDnsModeDialogPreference.java
src/com/android/settings/network/PrivateDnsPreferenceController.java

index a4e7d2a..322fdc4 100644 (file)
@@ -22,12 +22,16 @@ import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_INET6;
 
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
 import android.content.ActivityNotFoundException;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.net.NetworkUtils;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.system.Os;
 import android.text.Editable;
@@ -43,6 +47,7 @@ import android.widget.TextView;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.AlertDialog;
+import androidx.preference.PreferenceViewHolder;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
@@ -50,6 +55,8 @@ import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.utils.AnnotationSpan;
 import com.android.settingslib.CustomDialogPreferenceCompat;
 import com.android.settingslib.HelpUtils;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -99,19 +106,23 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat
 
     public PrivateDnsModeDialogPreference(Context context) {
         super(context);
+        initialize();
     }
 
     public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
+        initialize();
     }
 
     public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
+        initialize();
     }
 
     public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        initialize();
     }
 
     private final AnnotationSpan.LinkInfo mUrlLinkInfo = new AnnotationSpan.LinkInfo(
@@ -129,6 +140,30 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat
         }
     });
 
+    private void initialize() {
+        // Add the "Restricted" icon resource so that if the preference is disabled by the
+        // admin, an information button will be shown.
+        setWidgetLayoutResource(R.layout.restricted_icon);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        if (isDisabledByAdmin()) {
+            // If the preference is disabled by the admin, set the inner item as enabled so
+            // it could act as a click target. The preference itself will have been disabled
+            // by the controller.
+            holder.itemView.setEnabled(true);
+        }
+
+        final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
+        if (restrictedIcon != null) {
+            // Show the "Restricted" icon if, and only if, the preference was disabled by
+            // the admin.
+            restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
+        }
+    }
+
     @Override
     protected void onBindDialogView(View view) {
         final Context context = getContext();
@@ -202,6 +237,28 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat
         updateDialogInfo();
     }
 
+    @Override
+    public void performClick() {
+        EnforcedAdmin enforcedAdmin = getEnforcedAdmin();
+
+        if (enforcedAdmin == null) {
+            // If the restriction is not restricted by admin, continue as usual.
+            super.performClick();
+        } else {
+            // Show a dialog explaining to the user why they cannot change the preference.
+            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(), enforcedAdmin);
+        }
+    }
+
+    private EnforcedAdmin getEnforcedAdmin() {
+        return RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+                getContext(), UserManager.DISALLOW_CONFIG_PRIVATE_DNS, UserHandle.myUserId());
+    }
+
+    private boolean isDisabledByAdmin() {
+        return getEnforcedAdmin() != null;
+    }
+
     private Button getSaveButton() {
         final AlertDialog dialog = (AlertDialog) getDialog();
         if (dialog == null) {
index 8b3bfa0..37adea7 100644 (file)
@@ -143,7 +143,6 @@ public class PrivateDnsPreferenceController extends BasePreferenceController
     @Override
     public void updateState(Preference preference) {
         super.updateState(preference);
-        //TODO(b/112982691): Add policy transparency explaining why this setting is disabled.
         preference.setEnabled(!isManagedByAdmin());
     }