Merge "Allow device owner to configure profile network preference"

This commit is contained in:
Sooraj Sasindran
2022-05-02 07:13:21 +00:00
committed by Gerrit Code Review
2 changed files with 63 additions and 6 deletions

View File

@@ -108,6 +108,7 @@ import android.annotation.TargetApi;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.app.usage.NetworkStatsManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -10639,13 +10640,29 @@ public class ConnectivityService extends IConnectivityManager.Stub
mQosCallbackTracker.unregisterCallback(callback);
}
private boolean isNetworkPreferenceAllowedForProfile(@NonNull UserHandle profile) {
// UserManager.isManagedProfile returns true for all apps in managed user profiles.
// Enterprise device can be fully managed like device owner and such use case
// also should be supported. Calling app check for work profile and fully managed device
// is already done in DevicePolicyManager.
// This check is an extra caution to be sure device is fully managed or not.
final UserManager um = mContext.getSystemService(UserManager.class);
final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
if (um.isManagedProfile(profile.getIdentifier())) {
return true;
}
if (SdkLevel.isAtLeastT() && dpm.getDeviceOwner() != null) return true;
return false;
}
/**
* Request that a user profile is put by default on a network matching a given preference.
* Set a list of default network selection policies for a user profile or device owner.
*
* See the documentation for the individual preferences for a description of the supported
* behaviors.
*
* @param profile the user profile for whih the preference is being set.
* @param profile If the device owner is set, any profile is allowed.
Otherwise, the given profile can only be managed profile.
* @param preferences the list of profile network preferences for the
* provided profile.
* @param listener an optional listener to listen for completion of the operation.
@@ -10670,9 +10687,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
throw new IllegalArgumentException("Must explicitly specify a user handle ("
+ "UserHandle.CURRENT not supported)");
}
final UserManager um = mContext.getSystemService(UserManager.class);
if (!um.isManagedProfile(profile.getIdentifier())) {
throw new IllegalArgumentException("Profile must be a managed profile");
if (!isNetworkPreferenceAllowedForProfile(profile)) {
throw new IllegalArgumentException("Profile must be a managed profile "
+ "or the device owner must be set. ");
}
final List<ProfileNetworkPreferenceList.Preference> preferenceList =

View File

@@ -194,6 +194,7 @@ import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.app.usage.NetworkStatsManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -541,6 +542,7 @@ public class ConnectivityServiceTest {
@Mock NetworkPolicyManager mNetworkPolicyManager;
@Mock VpnProfileStore mVpnProfileStore;
@Mock SystemConfigManager mSystemConfigManager;
@Mock DevicePolicyManager mDevicePolicyManager;
@Mock Resources mResources;
@Mock ClatCoordinator mClatCoordinator;
@Mock PacProxyManager mPacProxyManager;
@@ -663,6 +665,7 @@ public class ConnectivityServiceTest {
if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
if (Context.ETHERNET_SERVICE.equals(name)) return mEthernetManager;
if (Context.NETWORK_POLICY_SERVICE.equals(name)) return mNetworkPolicyManager;
if (Context.DEVICE_POLICY_SERVICE.equals(name)) return mDevicePolicyManager;
if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager;
if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager;
if (Context.BATTERY_STATS_SERVICE.equals(name)) return mBatteryStatsManager;
@@ -691,6 +694,14 @@ public class ConnectivityServiceTest {
doReturn(value).when(mUserManager).isManagedProfile(eq(userHandle.getIdentifier()));
}
public void setDeviceOwner(@NonNull final UserHandle userHandle, String value) {
// This relies on all contexts for a given user returning the same UM mock
final DevicePolicyManager dpmMock = createContextAsUser(userHandle, 0 /* flags */)
.getSystemService(DevicePolicyManager.class);
doReturn(value).when(dpmMock).getDeviceOwner();
doReturn(value).when(mDevicePolicyManager).getDeviceOwner();
}
@Override
public ContentResolver getContentResolver() {
return mContentResolver;
@@ -14731,12 +14742,41 @@ public class ConnectivityServiceTest {
public void testProfileNetworkPrefWrongProfile() throws Exception {
final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID);
mServiceContext.setWorkProfile(testHandle, false);
assertThrows("Should not be able to set a user pref for a non-work profile",
mServiceContext.setDeviceOwner(testHandle, null);
assertThrows("Should not be able to set a user pref for a non-work profile "
+ "and non device owner",
IllegalArgumentException.class , () ->
mCm.setProfileNetworkPreference(testHandle,
PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null, null));
}
/**
* Make sure requests for per-profile default networking for a device owner is
* accepted on T and not accepted on S
*/
public void testProfileNetworkDeviceOwner() throws Exception {
final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID);
mServiceContext.setWorkProfile(testHandle, false);
mServiceContext.setDeviceOwner(testHandle, "deviceOwnerPackage");
ProfileNetworkPreference.Builder profileNetworkPreferenceBuilder =
new ProfileNetworkPreference.Builder();
profileNetworkPreferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
profileNetworkPreferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1);
final TestOnCompleteListener listener = new TestOnCompleteListener();
if (SdkLevel.isAtLeastT()) {
mCm.setProfileNetworkPreferences(testHandle,
List.of(profileNetworkPreferenceBuilder.build()),
r -> r.run(), listener);
} else {
// S should not allow setting preference on device owner
assertThrows("Should not be able to set a user pref for a non-work profile on S",
IllegalArgumentException.class , () ->
mCm.setProfileNetworkPreferences(testHandle,
List.of(profileNetworkPreferenceBuilder.build()),
r -> r.run(), listener));
}
}
@Test
public void testSubIdsClearedWithoutNetworkFactoryPermission() throws Exception {
mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED);