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
This commit is contained in:
Pavel Grafov
2021-03-18 22:46:08 +00:00
parent 097d262fda
commit 735a216da3
2 changed files with 33 additions and 2 deletions

View File

@@ -17,6 +17,7 @@
package com.android.settings.vpn2; package com.android.settings.vpn2;
import android.app.Dialog; import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@@ -55,6 +56,7 @@ public class AppDialogFragment extends InstrumentedDialogFragment implements App
private UserManager mUserManager; private UserManager mUserManager;
private final IConnectivityManager mService = IConnectivityManager.Stub.asInterface( private final IConnectivityManager mService = IConnectivityManager.Stub.asInterface(
ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
private DevicePolicyManager mDevicePolicyManager;
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
@@ -97,7 +99,11 @@ public class AppDialogFragment extends InstrumentedDialogFragment implements App
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mPackageInfo = getArguments().getParcelable(ARG_PACKAGE);
mUserManager = UserManager.get(getContext()); mUserManager = UserManager.get(getContext());
mDevicePolicyManager = getContext()
.createContextAsUser(UserHandle.of(getUserId()), /* flags= */ 0)
.getSystemService(DevicePolicyManager.class);
} }
@Override @Override
@@ -106,7 +112,6 @@ public class AppDialogFragment extends InstrumentedDialogFragment implements App
final String label = args.getString(ARG_LABEL); final String label = args.getString(ARG_LABEL);
boolean managing = args.getBoolean(ARG_MANAGING); boolean managing = args.getBoolean(ARG_MANAGING);
boolean connected = args.getBoolean(ARG_CONNECTED); boolean connected = args.getBoolean(ARG_CONNECTED);
mPackageInfo = args.getParcelable(ARG_PACKAGE);
if (managing) { if (managing) {
return new AppDialog(getActivity(), this, mPackageInfo, label); return new AppDialog(getActivity(), this, mPackageInfo, label);
@@ -178,7 +183,10 @@ public class AppDialogFragment extends InstrumentedDialogFragment implements App
private boolean isUiRestricted() { private boolean isUiRestricted() {
final UserHandle userHandle = UserHandle.of(getUserId()); 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() { private int getUserId() {

View File

@@ -16,6 +16,7 @@
package com.android.settings.vpn2; package com.android.settings.vpn2;
import android.app.admin.DevicePolicyManager;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@@ -26,6 +27,8 @@ import androidx.preference.Preference;
import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig; 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 * {@link androidx.preference.Preference} containing information about a VPN
@@ -43,6 +46,7 @@ public class AppPreference extends ManageablePreference {
super.setUserId(userId); super.setUserId(userId);
mPackageName = packageName; mPackageName = packageName;
disableIfConfiguredByAdmin();
// Fetch icon and VPN label // Fetch icon and VPN label
String label = packageName; String label = packageName;
@@ -74,6 +78,25 @@ public class AppPreference extends ManageablePreference {
setIcon(icon); 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() { public PackageInfo getPackageInfo() {
try { try {
PackageManager pm = getUserContext().getPackageManager(); PackageManager pm = getUserContext().getPackageManager();