Add device poliy manager support for profile network preference

Change-Id: If3f28dfdd731dddf2d2a7516d6479359a5454b83

Bug: 194332512
CTS-Coverage-Bug: 215722242
Test: unit test
Change-Id: Ibe680d47548e0f17979301ccbbac98a79c9031ac
This commit is contained in:
Sooraj Sasindran 2022-01-11 16:24:52 -08:00
parent f97b80ebd7
commit 14074e8a2c
8 changed files with 688 additions and 9 deletions

View File

@ -7185,6 +7185,7 @@ package android.app.admin {
method @Nullable public java.util.List<java.lang.String> getPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName);
method @Nullable public java.util.List<java.lang.String> getPermittedInputMethods(@NonNull android.content.ComponentName);
method public int getPersonalAppsSuspendedReasons(@NonNull android.content.ComponentName);
method @NonNull public android.app.admin.PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig();
method public int getRequiredPasswordComplexity();
method public long getRequiredStrongAuthTimeout(@Nullable android.content.ComponentName);
method public boolean getScreenCaptureDisabled(@Nullable android.content.ComponentName);
@ -7327,6 +7328,7 @@ package android.app.admin {
method public boolean setPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName, @Nullable java.util.List<java.lang.String>);
method public boolean setPermittedInputMethods(@NonNull android.content.ComponentName, java.util.List<java.lang.String>);
method public void setPersonalAppsSuspended(@NonNull android.content.ComponentName, boolean);
method public void setPreferentialNetworkServiceConfig(@NonNull android.app.admin.PreferentialNetworkServiceConfig);
method public void setPreferentialNetworkServiceEnabled(boolean);
method public void setProfileEnabled(@NonNull android.content.ComponentName);
method public void setProfileName(@NonNull android.content.ComponentName, String);
@ -7572,6 +7574,32 @@ package android.app.admin {
field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.NetworkEvent> CREATOR;
}
public final class PreferentialNetworkServiceConfig implements android.os.Parcelable {
method public int describeContents();
method @NonNull public int[] getExcludedUids();
method @NonNull public int[] getIncludedUids();
method public int getNetworkId();
method public boolean isEnabled();
method public boolean isFallbackToDefaultConnectionAllowed();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.PreferentialNetworkServiceConfig> CREATOR;
field public static final int PREFERENTIAL_NETWORK_ID_1 = 1; // 0x1
field public static final int PREFERENTIAL_NETWORK_ID_2 = 2; // 0x2
field public static final int PREFERENTIAL_NETWORK_ID_3 = 3; // 0x3
field public static final int PREFERENTIAL_NETWORK_ID_4 = 4; // 0x4
field public static final int PREFERENTIAL_NETWORK_ID_5 = 5; // 0x5
}
public static final class PreferentialNetworkServiceConfig.Builder {
ctor public PreferentialNetworkServiceConfig.Builder();
method @NonNull public android.app.admin.PreferentialNetworkServiceConfig build();
method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setEnabled(boolean);
method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setExcludedUids(@NonNull int[]);
method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setFallbackToDefaultConnectionAllowed(boolean);
method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setIncludedUids(@NonNull int[]);
method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setNetworkId(int);
}
public class SecurityLog {
ctor public SecurityLog();
field public static final int LEVEL_ERROR = 3; // 0x3

View File

@ -10177,6 +10177,9 @@ public class DevicePolicyManager {
* On fully-managed devices this method is unsupported because all traffic is considered
* work traffic.
*
* <p> This method enables preferential network service with a default configuration.
* To fine-tune the configuration, use {@link #setPreferentialNetworkServiceConfig) instead.
*
* <p>This method can only be called by the profile owner of a managed profile.
* @param enabled whether preferential network service should be enabled.
* @throws SecurityException if the caller is not the profile owner.
@ -10214,6 +10217,56 @@ public class DevicePolicyManager {
}
}
/**
* Sets preferential network configuration on the work profile.
* {@see PreferentialNetworkServiceConfig}
*
* An example of a supported preferential network service is the Enterprise
* slice on 5G networks.
*
* By default, preferential network service is disabled on the work profile on supported
* carriers and devices. Admins can explicitly enable it with this API.
* On fully-managed devices this method is unsupported because all traffic is considered
* work traffic.
*
* <p>This method can only be called by the profile owner of a managed profile.
* @param preferentialNetworkServiceConfig preferential network configuration.
* @throws SecurityException if the caller is not the profile owner.
**/
public void setPreferentialNetworkServiceConfig(
@NonNull PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) {
throwIfParentInstance("setPreferentialNetworkServiceConfig");
if (mService == null) {
return;
}
try {
mService.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfig);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Get preferential network configuration
* {@see PreferentialNetworkServiceConfig}
*
* <p>This method can be called by the profile owner of a managed profile.
*
* @return preferential network configuration.
* @throws SecurityException if the caller is not the profile owner.
*/
public @NonNull PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig() {
throwIfParentInstance("getPreferentialNetworkServiceConfig");
if (mService == null) {
return PreferentialNetworkServiceConfig.DEFAULT;
}
try {
return mService.getPreferentialNetworkServiceConfig();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* This method is mostly deprecated.
* Most of the settings that still have an effect have dedicated setter methods or user

View File

@ -21,6 +21,7 @@ import android.app.admin.NetworkEvent;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
import android.app.admin.ParcelableGranteeMap;
import android.app.admin.PreferentialNetworkServiceConfig;
import android.app.admin.StartInstallingUpdateCallback;
import android.app.admin.SystemUpdateInfo;
import android.app.admin.SystemUpdatePolicy;
@ -278,6 +279,10 @@ interface IDevicePolicyManager {
void setPreferentialNetworkServiceEnabled(in boolean enabled);
boolean isPreferentialNetworkServiceEnabled(int userHandle);
void setPreferentialNetworkServiceConfig(
in PreferentialNetworkServiceConfig preferentialNetworkServiceConfig);
PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig();
void setLockTaskPackages(in ComponentName who, in String[] packages);
String[] getLockTaskPackages(in ComponentName who);
boolean isLockTaskPermitted(in String pkg);

View File

@ -0,0 +1,20 @@
/*
**
** Copyright 2022, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package android.app.admin;
parcelable PreferentialNetworkServiceConfig;

View File

@ -0,0 +1,335 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.admin;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
* Network configuration to be set for the user profile
* {@see DevicePolicyManager#setPreferentialNetworkServiceConfig}.
*/
public final class PreferentialNetworkServiceConfig implements Parcelable {
final boolean mIsEnabled;
final int mNetworkId;
final boolean mAllowFallbackToDefaultConnection;
final int[] mIncludedUids;
final int[] mExcludedUids;
/** @hide */
public static final PreferentialNetworkServiceConfig DEFAULT =
(new PreferentialNetworkServiceConfig.Builder()).build();
/**
* Preferential network identifier 1.
*/
public static final int PREFERENTIAL_NETWORK_ID_1 = 1;
/**
* Preferential network identifier 2.
*/
public static final int PREFERENTIAL_NETWORK_ID_2 = 2;
/**
* Preferential network identifier 3.
*/
public static final int PREFERENTIAL_NETWORK_ID_3 = 3;
/**
* Preferential network identifier 4.
*/
public static final int PREFERENTIAL_NETWORK_ID_4 = 4;
/**
* Preferential network identifier 5.
*/
public static final int PREFERENTIAL_NETWORK_ID_5 = 5;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = { "PREFERENTIAL_NETWORK_ID_" }, value = {
PREFERENTIAL_NETWORK_ID_1,
PREFERENTIAL_NETWORK_ID_2,
PREFERENTIAL_NETWORK_ID_3,
PREFERENTIAL_NETWORK_ID_4,
PREFERENTIAL_NETWORK_ID_5,
})
public @interface PreferentialNetworkPreferenceId {
}
private PreferentialNetworkServiceConfig(boolean isEnabled,
boolean allowFallbackToDefaultConnection, int[] includedUids,
int[] excludedUids, @PreferentialNetworkPreferenceId int networkId) {
mIsEnabled = isEnabled;
mAllowFallbackToDefaultConnection = allowFallbackToDefaultConnection;
mIncludedUids = includedUids;
mExcludedUids = excludedUids;
mNetworkId = networkId;
}
private PreferentialNetworkServiceConfig(Parcel in) {
mIsEnabled = in.readBoolean();
mAllowFallbackToDefaultConnection = in.readBoolean();
mNetworkId = in.readInt();
mIncludedUids = in.createIntArray();
mExcludedUids = in.createIntArray();
}
/**
* Is the preferential network enabled.
* @return true if enabled else false
*/
public boolean isEnabled() {
return mIsEnabled;
}
/**
* is fallback to default network allowed. This boolean configures whether default connection
* (default internet or wifi) should be used or not if a preferential network service
* connection is not available.
* @return true if fallback is allowed, else false.
*/
public boolean isFallbackToDefaultConnectionAllowed() {
return mAllowFallbackToDefaultConnection;
}
/**
* Get the array of uids that are applicable for the profile preference.
*
* {@see #getExcludedUids()}
* Included UIDs and Excluded UIDs can't both be non-empty.
* if both are empty, it means this request applies to all uids in the user profile.
* if included is not empty, then only included UIDs are applied.
* if excluded is not empty, then it is all uids in the user profile except these UIDs.
* @return Array of uids applicable for the profile preference.
* Empty array would mean that this request applies to all uids in the profile.
*/
public @NonNull int[] getIncludedUids() {
return mIncludedUids;
}
/**
* Get the array of uids that are excluded for the profile preference.
*
* {@see #getIncludedUids()}
* Included UIDs and Excluded UIDs can't both be non-empty.
* if both are empty, it means this request applies to all uids in the user profile.
* if included is not empty, then only included UIDs are applied.
* if excluded is not empty, then it is all uids in the user profile except these UIDs.
* @return Array of uids that are excluded for the profile preference.
* Empty array would mean that this request applies to all uids in the profile.
*/
public @NonNull int[] getExcludedUids() {
return mExcludedUids;
}
/**
* @return preference enterprise identifier.
* valid values starts from
* {@link #PREFERENTIAL_NETWORK_ID_1} to {@link #PREFERENTIAL_NETWORK_ID_5}.
* preference identifier is applicable only if preference network service is enabled
*
*/
public @PreferentialNetworkPreferenceId int getNetworkId() {
return mNetworkId;
}
@Override
public String toString() {
return "PreferentialNetworkServiceConfig{"
+ "mIsEnabled=" + isEnabled()
+ "mAllowFallbackToDefaultConnection=" + isFallbackToDefaultConnectionAllowed()
+ "mIncludedUids=" + mIncludedUids.toString()
+ "mExcludedUids=" + mExcludedUids.toString()
+ "mNetworkId=" + mNetworkId
+ '}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final PreferentialNetworkServiceConfig that = (PreferentialNetworkServiceConfig) o;
return mIsEnabled == that.mIsEnabled
&& mAllowFallbackToDefaultConnection == that.mAllowFallbackToDefaultConnection
&& mNetworkId == that.mNetworkId
&& Objects.equals(mIncludedUids, that.mIncludedUids)
&& Objects.equals(mExcludedUids, that.mExcludedUids);
}
@Override
public int hashCode() {
return ((Objects.hashCode(mIsEnabled) * 17)
+ (Objects.hashCode(mAllowFallbackToDefaultConnection) * 19)
+ (Objects.hashCode(mIncludedUids) * 23)
+ (Objects.hashCode(mExcludedUids) * 29)
+ mNetworkId * 31);
}
/**
* Builder used to create {@link PreferentialNetworkServiceConfig} objects.
* Specify the preferred Network preference
*/
public static final class Builder {
boolean mIsEnabled = false;
int mNetworkId = 0;
boolean mAllowFallbackToDefaultConnection = true;
int[] mIncludedUids = new int[0];
int[] mExcludedUids = new int[0];
/**
* Constructs an empty Builder with preferential network disabled by default.
*/
public Builder() {}
/**
* Set the preferential network service enabled state.
* Default value is false.
* @param isEnabled the desired network preference to use, true to enable else false
* @return The builder to facilitate chaining.
*/
@NonNull
public PreferentialNetworkServiceConfig.Builder setEnabled(boolean isEnabled) {
mIsEnabled = isEnabled;
return this;
}
/**
* Set whether the default connection should be used as fallback.
* This boolean configures whether the default connection (default internet or wifi)
* should be used if a preferential network service connection is not available.
* Default value is true
* @param allowFallbackToDefaultConnection true if fallback is allowed else false
* @return The builder to facilitate chaining.
*/
@NonNull
@SuppressLint("MissingGetterMatchingBuilder")
public PreferentialNetworkServiceConfig.Builder setFallbackToDefaultConnectionAllowed(
boolean allowFallbackToDefaultConnection) {
mAllowFallbackToDefaultConnection = allowFallbackToDefaultConnection;
return this;
}
/**
* Set the array of uids whose network access will go through this preferential
* network service.
* {@see #setExcludedUids(int[])}
* Included UIDs and Excluded UIDs can't both be non-empty.
* if both are empty, it means this request applies to all uids in the user profile.
* if included is not empty, then only included UIDs are applied.
* if excluded is not empty, then it is all uids in the user profile except these UIDs.
* @param uids array of included uids
* @return The builder to facilitate chaining.
*/
@NonNull
public PreferentialNetworkServiceConfig.Builder setIncludedUids(
@NonNull int[] uids) {
Objects.requireNonNull(uids);
mIncludedUids = uids;
return this;
}
/**
* Set the array of uids who are not allowed through this preferential
* network service.
* {@see #setIncludedUids(int[])}
* Included UIDs and Excluded UIDs can't both be non-empty.
* if both are empty, it means this request applies to all uids in the user profile.
* if included is not empty, then only included UIDs are applied.
* if excluded is not empty, then it is all uids in the user profile except these UIDs.
* @param uids array of excluded uids
* @return The builder to facilitate chaining.
*/
@NonNull
public PreferentialNetworkServiceConfig.Builder setExcludedUids(
@NonNull int[] uids) {
Objects.requireNonNull(uids);
mExcludedUids = uids;
return this;
}
/**
* Returns an instance of {@link PreferentialNetworkServiceConfig} created from the
* fields set on this builder.
*/
@NonNull
public PreferentialNetworkServiceConfig build() {
if (mIncludedUids.length > 0 && mExcludedUids.length > 0) {
throw new IllegalStateException("Both includedUids and excludedUids "
+ "cannot be nonempty");
}
return new PreferentialNetworkServiceConfig(mIsEnabled,
mAllowFallbackToDefaultConnection, mIncludedUids, mExcludedUids, mNetworkId);
}
/**
* Set the preferential network identifier.
* Valid values starts from {@link #PREFERENTIAL_NETWORK_ID_1} to
* {@link #PREFERENTIAL_NETWORK_ID_5}.
* preference identifier is applicable only if preferential network service is enabled.
* @param preferenceId preference Id
* @return The builder to facilitate chaining.
*/
@NonNull
public PreferentialNetworkServiceConfig.Builder setNetworkId(
@PreferentialNetworkPreferenceId int preferenceId) {
if ((preferenceId < PREFERENTIAL_NETWORK_ID_1)
|| (preferenceId > PREFERENTIAL_NETWORK_ID_5)) {
throw new IllegalArgumentException("Invalid preference identifier");
}
mNetworkId = preferenceId;
return this;
}
}
@Override
public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
dest.writeBoolean(mIsEnabled);
dest.writeBoolean(mAllowFallbackToDefaultConnection);
dest.writeInt(mNetworkId);
dest.writeIntArray(mIncludedUids);
dest.writeIntArray(mExcludedUids);
}
@Override
public int describeContents() {
return 0;
}
@NonNull
public static final Creator<PreferentialNetworkServiceConfig> CREATOR =
new Creator<PreferentialNetworkServiceConfig>() {
@Override
public PreferentialNetworkServiceConfig[] newArray(int size) {
return new PreferentialNetworkServiceConfig[size];
}
@Override
public PreferentialNetworkServiceConfig createFromParcel(
@NonNull android.os.Parcel in) {
return new PreferentialNetworkServiceConfig(in);
}
};
}

View File

@ -32,6 +32,7 @@ import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManager;
import android.app.admin.FactoryResetProtectionPolicy;
import android.app.admin.PasswordPolicy;
import android.app.admin.PreferentialNetworkServiceConfig;
import android.graphics.Color;
import android.os.Bundle;
import android.os.PersistableBundle;
@ -294,6 +295,8 @@ class ActiveAdmin {
public boolean mAdminCanGrantSensorsPermissions;
public boolean mPreferentialNetworkServiceEnabled =
DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT;
public PreferentialNetworkServiceConfig mPreferentialNetworkServiceConfig =
PreferentialNetworkServiceConfig.DEFAULT;
private static final boolean USB_DATA_SIGNALING_ENABLED_DEFAULT = true;
boolean mUsbDataSignalingEnabled = USB_DATA_SIGNALING_ENABLED_DEFAULT;

View File

@ -109,6 +109,7 @@ import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
@ -180,6 +181,7 @@ import android.app.admin.NetworkEvent;
import android.app.admin.ParcelableGranteeMap;
import android.app.admin.PasswordMetrics;
import android.app.admin.PasswordPolicy;
import android.app.admin.PreferentialNetworkServiceConfig;
import android.app.admin.SecurityLog;
import android.app.admin.SecurityLog.SecurityEvent;
import android.app.admin.StartInstallingUpdateCallback;
@ -3278,14 +3280,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
updatePermissionPolicyCache(userId);
updateAdminCanGrantSensorsPermissionCache(userId);
final boolean preferentialNetworkServiceEnabled;
final PreferentialNetworkServiceConfig preferentialNetworkServiceConfig;
synchronized (getLockObject()) {
ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userId);
preferentialNetworkServiceEnabled = owner != null
? owner.mPreferentialNetworkServiceEnabled
: DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT;
preferentialNetworkServiceConfig = owner != null
? owner.mPreferentialNetworkServiceConfig
: PreferentialNetworkServiceConfig.DEFAULT;
}
updateNetworkPreferenceForUser(userId, preferentialNetworkServiceEnabled);
updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfig);
startOwnerService(userId, "start-user");
}
@ -3302,7 +3304,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
void handleStopUser(int userId) {
updateNetworkPreferenceForUser(userId, false);
updateNetworkPreferenceForUser(userId, PreferentialNetworkServiceConfig.DEFAULT);
stopOwnerService(userId, "stop-user");
}
@ -11846,7 +11848,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(isProfileOwner(caller),
"Caller is not profile owner;"
+ " only profile owner may control the preferntial network service");
+ " only profile owner may control the preferential network service");
synchronized (getLockObject()) {
final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(
caller.getUserId());
@ -11882,6 +11884,47 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
@Override
public void setPreferentialNetworkServiceConfig(
PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) {
if (!mHasFeature) {
return;
}
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(isProfileOwner(caller),
"Caller is not profile owner;"
+ " only profile owner may control the preferential network service");
synchronized (getLockObject()) {
final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(
caller.getUserId());
if (!requiredAdmin.mPreferentialNetworkServiceConfig.equals(
preferentialNetworkServiceConfig)) {
requiredAdmin.mPreferentialNetworkServiceConfig = preferentialNetworkServiceConfig;
saveSettingsLocked(caller.getUserId());
}
}
updateNetworkPreferenceForUser(caller.getUserId(), preferentialNetworkServiceConfig);
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_PREFERENTIAL_NETWORK_SERVICE_ENABLED)
.setBoolean(preferentialNetworkServiceConfig.isEnabled())
.write();
}
@Override
public PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig() {
if (!mHasFeature) {
return PreferentialNetworkServiceConfig.DEFAULT;
}
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(isProfileOwner(caller),
"Caller is not profile owner");
synchronized (getLockObject()) {
final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(caller.getUserId());
return requiredAdmin.mPreferentialNetworkServiceConfig;
}
}
@Override
public void setLockTaskPackages(ComponentName who, String[] packages)
throws SecurityException {
@ -17538,8 +17581,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (!isManagedProfile(userId)) {
return;
}
int networkPreference = preferentialNetworkServiceEnabled
? PROFILE_NETWORK_PREFERENCE_ENTERPRISE : PROFILE_NETWORK_PREFERENCE_DEFAULT;
ProfileNetworkPreference.Builder preferenceBuilder =
new ProfileNetworkPreference.Builder();
if (preferentialNetworkServiceEnabled) {
@ -17556,6 +17597,40 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
null /* executor */, null /* listener */));
}
private void updateNetworkPreferenceForUser(int userId,
PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) {
if (!isManagedProfile(userId)) {
return;
}
ProfileNetworkPreference.Builder preferenceBuilder =
new ProfileNetworkPreference.Builder();
if (preferentialNetworkServiceConfig.isEnabled()) {
if (preferentialNetworkServiceConfig.isFallbackToDefaultConnectionAllowed()) {
preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
} else {
preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
}
} else {
preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT);
}
List<Integer> allowedUids = Arrays.stream(
preferentialNetworkServiceConfig.getIncludedUids()).boxed().collect(
Collectors.toList());
List<Integer> excludedUids = Arrays.stream(
preferentialNetworkServiceConfig.getExcludedUids()).boxed().collect(
Collectors.toList());
preferenceBuilder.setIncludedUids(allowedUids);
preferenceBuilder.setExcludedUids(excludedUids);
preferenceBuilder.setPreferenceEnterpriseId(
preferentialNetworkServiceConfig.getNetworkId());
List<ProfileNetworkPreference> preferences = new ArrayList<>();
preferences.add(preferenceBuilder.build());
mInjector.binderWithCleanCallingIdentity(() ->
mInjector.getConnectivityManager().setProfileNetworkPreferences(
UserHandle.of(userId), preferences,
null /* executor */, null /* listener */));
}
@Override
public boolean canAdminGrantSensorsPermissionsForUser(int userId) {
if (!mHasFeature) {

View File

@ -39,6 +39,7 @@ import static android.app.admin.PasswordMetrics.computeForPasswordOrPin;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
import static android.net.InetAddresses.parseNumericAddress;
import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
@ -90,6 +91,7 @@ import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DevicePolicyManagerLiteInternal;
import android.app.admin.FactoryResetProtectionPolicy;
import android.app.admin.PasswordMetrics;
import android.app.admin.PreferentialNetworkServiceConfig;
import android.app.admin.SystemUpdatePolicy;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@ -4119,6 +4121,164 @@ public class DevicePolicyManagerTest extends DpmTestBase {
null, null);
}
@Test
public void testSetPreferentialNetworkServiceConfig_noProfileOwner() throws Exception {
assertExpectException(SecurityException.class, null,
() -> dpm.setPreferentialNetworkServiceConfig(
PreferentialNetworkServiceConfig.DEFAULT));
}
@Test
public void testIsPreferentialNetworkServiceEnabled_noProfileOwner() throws Exception {
assertExpectException(SecurityException.class, null,
() -> dpm.isPreferentialNetworkServiceEnabled());
}
@Test
public void testSetPreferentialNetworkServiceConfig_invalidConfig() throws Exception {
final int managedProfileUserId = 15;
final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
addManagedProfile(admin1, managedProfileAdminUid, admin1);
mContext.binder.callingUid = managedProfileAdminUid;
PreferentialNetworkServiceConfig.Builder preferentialNetworkServiceConfigBuilder =
new PreferentialNetworkServiceConfig.Builder();
assertExpectException(NullPointerException.class, null,
() -> preferentialNetworkServiceConfigBuilder.setIncludedUids(null));
assertExpectException(NullPointerException.class, null,
() -> preferentialNetworkServiceConfigBuilder.setExcludedUids(null));
assertExpectException(IllegalArgumentException.class, null,
() -> preferentialNetworkServiceConfigBuilder.setNetworkId(6));
int[] includedUids = new int[]{1, 2};
int[] excludedUids = new int[]{3, 4};
preferentialNetworkServiceConfigBuilder.setIncludedUids(includedUids);
preferentialNetworkServiceConfigBuilder.setExcludedUids(excludedUids);
assertExpectException(IllegalStateException.class, null,
() -> preferentialNetworkServiceConfigBuilder.build());
}
@Test
public void testSetPreferentialNetworkServiceConfig_defaultPreference() throws Exception {
final int managedProfileUserId = 15;
final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
addManagedProfile(admin1, managedProfileAdminUid, admin1);
mContext.binder.callingUid = managedProfileAdminUid;
dpm.setPreferentialNetworkServiceConfig(PreferentialNetworkServiceConfig.DEFAULT);
assertThat(dpm.isPreferentialNetworkServiceEnabled()).isFalse();
assertThat(dpm.getPreferentialNetworkServiceConfig()
.isEnabled()).isFalse();
ProfileNetworkPreference preferenceDetails =
new ProfileNetworkPreference.Builder()
.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT)
.build();
List<ProfileNetworkPreference> preferences = new ArrayList<>();
preferences.add(preferenceDetails);
verify(getServices().connectivityManager, times(1))
.setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
null, null);
}
@Test
public void testSetPreferentialNetworkServiceConfig_enterprisePreference() throws Exception {
PreferentialNetworkServiceConfig preferentialNetworkServiceConfigEnabled =
(new PreferentialNetworkServiceConfig.Builder())
.setEnabled(true)
.setNetworkId(NET_ENTERPRISE_ID_1)
.build();
final int managedProfileUserId = 15;
final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
addManagedProfile(admin1, managedProfileAdminUid, admin1);
mContext.binder.callingUid = managedProfileAdminUid;
dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled);
assertThat(dpm.getPreferentialNetworkServiceConfig()
.isEnabled()).isTrue();
ProfileNetworkPreference preferenceDetails =
new ProfileNetworkPreference.Builder()
.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE)
.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1)
.build();
List<ProfileNetworkPreference> preferences = new ArrayList<>();
preferences.add(preferenceDetails);
verify(getServices().connectivityManager, times(1))
.setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
null, null);
}
@Test
public void testSetPreferentialNetworkServiceConfig_enterprisePreferenceIncludedUids()
throws Exception {
final int managedProfileUserId = 15;
final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
addManagedProfile(admin1, managedProfileAdminUid, admin1);
mContext.binder.callingUid = managedProfileAdminUid;
PreferentialNetworkServiceConfig preferentialNetworkServiceConfigEnabled =
(new PreferentialNetworkServiceConfig.Builder())
.setEnabled(true)
.setNetworkId(NET_ENTERPRISE_ID_1)
.setFallbackToDefaultConnectionAllowed(false)
.setIncludedUids(new int[]{1, 2})
.build();
dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled);
assertThat(dpm.getPreferentialNetworkServiceConfig()
.isEnabled()).isTrue();
List<Integer> includedList = new ArrayList<>();
includedList.add(1);
includedList.add(2);
ProfileNetworkPreference preferenceDetails =
new ProfileNetworkPreference.Builder()
.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK)
.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1)
.setIncludedUids(includedList)
.build();
List<ProfileNetworkPreference> preferences = new ArrayList<>();
preferences.add(preferenceDetails);
verify(getServices().connectivityManager, times(1))
.setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
null, null);
}
@Test
public void testSetPreferentialNetworkServiceConfig_enterprisePreferenceExcludedUids()
throws Exception {
final int managedProfileUserId = 15;
final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
addManagedProfile(admin1, managedProfileAdminUid, admin1);
mContext.binder.callingUid = managedProfileAdminUid;
PreferentialNetworkServiceConfig preferentialNetworkServiceConfigEnabled =
(new PreferentialNetworkServiceConfig.Builder())
.setEnabled(true)
.setNetworkId(NET_ENTERPRISE_ID_1)
.setFallbackToDefaultConnectionAllowed(false)
.setExcludedUids(new int[]{1, 2})
.build();
dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled);
assertThat(dpm.getPreferentialNetworkServiceConfig()
.isEnabled()).isTrue();
List<Integer> excludedUids = new ArrayList<>();
excludedUids.add(1);
excludedUids.add(2);
ProfileNetworkPreference preferenceDetails =
new ProfileNetworkPreference.Builder()
.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK)
.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1)
.setExcludedUids(excludedUids)
.build();
List<ProfileNetworkPreference> preferences = new ArrayList<>();
preferences.clear();
preferences.add(preferenceDetails);
verify(getServices().connectivityManager, times(1))
.setProfileNetworkPreferences(UserHandle.of(managedProfileUserId), preferences,
null, null);
}
@Test
public void testSetSystemSettingFailWithNonWhitelistedSettings() throws Exception {
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;