diff --git a/api/current.txt b/api/current.txt
index 884a046d88e4d..5a9be90b67369 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23629,6 +23629,7 @@ package android.os {
field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
field public static final java.lang.String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
+ field public static final java.lang.String DISALLOW_NETWORK_RESET = "no_network_reset";
field public static final java.lang.String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam";
field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user";
diff --git a/api/system-current.txt b/api/system-current.txt
index 04acd18f50c43..b4315fe1ecb28 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25552,6 +25552,7 @@ package android.os {
field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
field public static final java.lang.String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
+ field public static final java.lang.String DISALLOW_NETWORK_RESET = "no_network_reset";
field public static final java.lang.String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam";
field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user";
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a81b83f002998..ef7e747273d32 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -199,6 +199,20 @@ public class UserManager {
*/
public static final String DISALLOW_CONFIG_TETHERING = "no_config_tethering";
+ /**
+ * Specifies if a user is disallowed from resetting network settings
+ * from Settings. This can only be set by device owners and profile owners on the primary user.
+ * The default value is false.
+ *
This restriction has no effect on secondary users and managed profiles since only the
+ * primary user can reset the network settings of the device.
+ *
+ * Key for user restrictions.
+ * Type: Boolean
+ * @see #setUserRestrictions(Bundle)
+ * @see #getUserRestrictions()
+ */
+ public static final String DISALLOW_NETWORK_RESET = "no_network_reset";
+
/**
* Specifies if a user is disallowed from factory resetting
* from Settings. This can only be set by device owners and profile owners on the primary user.
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index edca4b87842e7..e5441128c1bb0 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -4603,27 +4603,36 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public void factoryReset() {
enforceConnectivityInternalPermission();
+
+ if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
+ return;
+ }
+
final int userId = UserHandle.getCallingUserId();
// Turn airplane mode off
setAirplaneMode(false);
- // Untether
- for (String tether : getTetheredIfaces()) {
- untether(tether);
+ if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) {
+ // Untether
+ for (String tether : getTetheredIfaces()) {
+ untether(tether);
+ }
}
- // Turn VPN off
- VpnConfig vpnConfig = getVpnConfig(userId);
- if (vpnConfig != null) {
- if (vpnConfig.legacy) {
- prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId);
- } else {
- // Prevent this app (packagename = vpnConfig.user) from initiating VPN connections
- // in the future without user intervention.
- setVpnPackageAuthorization(vpnConfig.user, userId, false);
+ if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
+ // Turn VPN off
+ VpnConfig vpnConfig = getVpnConfig(userId);
+ if (vpnConfig != null) {
+ if (vpnConfig.legacy) {
+ prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId);
+ } else {
+ // Prevent this app (packagename = vpnConfig.user) from initiating VPN connections
+ // in the future without user intervention.
+ setVpnPackageAuthorization(vpnConfig.user, userId, false);
- prepareVpn(vpnConfig.user, VpnConfig.LEGACY_VPN, userId);
+ prepareVpn(vpnConfig.user, VpnConfig.LEGACY_VPN, userId);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 1a7956874a2e0..792d4ba08b390 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -253,6 +253,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
private final INetworkManagementService mNetworkManager;
private UsageStatsManagerInternal mUsageStats;
private final TrustedTime mTime;
+ private final UserManager mUserManager;
private IConnectivityManager mConnManager;
private INotificationManager mNotifManager;
@@ -336,6 +337,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
DeviceIdleController.SERVICE_NAME));
mTime = checkNotNull(time, "missing TrustedTime");
+ mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
HandlerThread thread = new HandlerThread(TAG);
thread.start();
@@ -1986,7 +1988,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
*/
void updateRulesForGlobalChangeLocked(boolean restrictedNetworksChanged) {
final PackageManager pm = mContext.getPackageManager();
- final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
// If we are in restrict power mode, we allow all important apps
// to have data access. Otherwise, we restrict data access to only
@@ -1996,7 +1997,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
: ActivityManager.PROCESS_STATE_TOP;
// update rules for all installed applications
- final List users = um.getUsers();
+ final List users = mUserManager.getUsers();
final List apps = pm.getInstalledApplications(
PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS);
@@ -2353,6 +2354,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
public void factoryReset(String subscriber) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+ if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
+ return;
+ }
+
// Turn mobile data limit off
NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
@@ -2368,9 +2373,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
// Turn restrict background data off
setRestrictBackground(false);
- // Remove app's "restrict background data" flag
- for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
- setUidPolicy(uid, POLICY_NONE);
+ if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) {
+ // Remove app's "restrict background data" flag
+ for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
+ setUidPolicy(uid, POLICY_NONE);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 15d1535a2eb14..08d386b4e6990 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -950,6 +950,7 @@ public class UserManagerService extends IUserManager.Stub {
writeBoolean(serializer, restrictions, UserManager.DISALLOW_DEBUGGING_FEATURES);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_VPN);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_TETHERING);
+ writeBoolean(serializer, restrictions, UserManager.DISALLOW_NETWORK_RESET);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_FACTORY_RESET);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_ADD_USER);
writeBoolean(serializer, restrictions, UserManager.ENSURE_VERIFY_APPS);
@@ -1078,6 +1079,7 @@ public class UserManagerService extends IUserManager.Stub {
readBoolean(parser, restrictions, UserManager.DISALLOW_DEBUGGING_FEATURES);
readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_VPN);
readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_TETHERING);
+ readBoolean(parser, restrictions, UserManager.DISALLOW_NETWORK_RESET);
readBoolean(parser, restrictions, UserManager.DISALLOW_FACTORY_RESET);
readBoolean(parser, restrictions, UserManager.DISALLOW_ADD_USER);
readBoolean(parser, restrictions, UserManager.ENSURE_VERIFY_APPS);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index d807b0b49364b..ff748f23a48b4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -202,6 +202,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
DEVICE_OWNER_USER_RESTRICTIONS = new HashSet();
DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_USB_FILE_TRANSFER);
DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_TETHERING);
+ DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_NETWORK_RESET);
DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_FACTORY_RESET);
DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_ADD_USER);
DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);