Prevent disconnecting admin-configured VPN First, if the VPN is configured by an admin, the preference is disabled and tapping on it will results in a policy disclouser dialog. In addition restriction checks in the dialog also check if the VPN is admin-configured. Bug: 179975048 Test: Manual, setting VPN in profile and primary user and via DPM API. Test: make RunSettingsRoboTests -j Merged-In: Id59d2ac2782e83601bc3093d3a092faea36ff5d9 Change-Id: Id59d2ac2782e83601bc3093d3a092faea36ff5d9
diff --git a/src/com/android/settings/vpn2/AppDialogFragment.java b/src/com/android/settings/vpn2/AppDialogFragment.java index ea9e546..60c6596 100644 --- a/src/com/android/settings/vpn2/AppDialogFragment.java +++ b/src/com/android/settings/vpn2/AppDialogFragment.java
@@ -17,6 +17,7 @@ package com.android.settings.vpn2; import android.app.Dialog; +import android.app.admin.DevicePolicyManager; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.DialogInterface; @@ -55,6 +56,7 @@ private UserManager mUserManager; private final IConnectivityManager mService = IConnectivityManager.Stub.asInterface( ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); + private DevicePolicyManager mDevicePolicyManager; @Override public int getMetricsCategory() { @@ -97,7 +99,11 @@ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mPackageInfo = getArguments().getParcelable(ARG_PACKAGE); mUserManager = UserManager.get(getContext()); + mDevicePolicyManager = getContext() + .createContextAsUser(UserHandle.of(getUserId()), /* flags= */ 0) + .getSystemService(DevicePolicyManager.class); } @Override @@ -106,7 +112,6 @@ final String label = args.getString(ARG_LABEL); boolean managing = args.getBoolean(ARG_MANAGING); boolean connected = args.getBoolean(ARG_CONNECTED); - mPackageInfo = args.getParcelable(ARG_PACKAGE); if (managing) { return new AppDialog(getActivity(), this, mPackageInfo, label); @@ -178,7 +183,10 @@ private boolean isUiRestricted() { final UserHandle userHandle = UserHandle.of(getUserId()); - return mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, userHandle); + if (mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, userHandle)) { + return true; + } + return mPackageInfo.packageName.equals(mDevicePolicyManager.getAlwaysOnVpnPackage()); } private int getUserId() {
diff --git a/src/com/android/settings/vpn2/AppPreference.java b/src/com/android/settings/vpn2/AppPreference.java index 6b64250..8ee2f5f 100644 --- a/src/com/android/settings/vpn2/AppPreference.java +++ b/src/com/android/settings/vpn2/AppPreference.java
@@ -16,6 +16,7 @@ package com.android.settings.vpn2; +import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -26,6 +27,8 @@ import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; /** * {@link androidx.preference.Preference} containing information about a VPN @@ -43,6 +46,7 @@ super.setUserId(userId); mPackageName = packageName; + disableIfConfiguredByAdmin(); // Fetch icon and VPN label String label = packageName; @@ -74,6 +78,25 @@ setIcon(icon); } + /** + * Disable this preference if VPN is set as always on by a profile or device owner. + * NB: it should be called after super.setUserId() otherwise admin information can be lost. + */ + private void disableIfConfiguredByAdmin() { + if (isDisabledByAdmin()) { + // Already disabled due to user restriction. + return; + } + final DevicePolicyManager dpm = getContext() + .createContextAsUser(UserHandle.of(getUserId()), /* flags= */ 0) + .getSystemService(DevicePolicyManager.class); + if (mPackageName.equals(dpm.getAlwaysOnVpnPackage())) { + final EnforcedAdmin admin = RestrictedLockUtils.getProfileOrDeviceOwner( + getContext(), UserHandle.of(mUserId)); + setDisabledByAdmin(admin); + } + } + public PackageInfo getPackageInfo() { try { PackageManager pm = getUserContext().getPackageManager();