Private DNS: Add policy transparency

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
This commit is contained in:
Eran Messeri
2018-11-09 13:21:34 +00:00
parent 793a6eac3b
commit 203856e444
2 changed files with 57 additions and 1 deletions

View 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) {