diff options
7 files changed, 183 insertions, 189 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 88f4eecbaaa4..8337cb61455e 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -7192,7 +7192,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 @NonNull public java.util.List<android.app.admin.PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs(); method public int getRequiredPasswordComplexity(); method public long getRequiredStrongAuthTimeout(@Nullable android.content.ComponentName); method public boolean getScreenCaptureDisabled(@Nullable android.content.ComponentName); @@ -7335,7 +7335,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 setPreferentialNetworkServiceConfigs(@NonNull java.util.List<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); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 550d1d811228..067c135ca3aa 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -16,6 +16,8 @@ package android.app.admin; +import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; + import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import android.Manifest.permission; @@ -10266,7 +10268,7 @@ public class DevicePolicyManager { } /** - * Sets whether preferential network service is enabled on the work profile. + * Sets whether preferential network service is enabled. * For example, an organization can have a deal/agreement with a carrier that all of * the work data from its employees’ devices will be sent via a network service dedicated * for enterprise use. @@ -10274,75 +10276,72 @@ public class DevicePolicyManager { * 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. + * By default, preferential network service is disabled on the work profile and + * fully managed devices, on supported carriers and devices. + * Admins can explicitly enable it with this API. * * <p> This method enables preferential network service with a default configuration. - * To fine-tune the configuration, use {@link #setPreferentialNetworkServiceConfig) instead. + * To fine-tune the configuration, use {@link #setPreferentialNetworkServiceConfigs) instead. + * <p> Before Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}: + * this method can be called by the profile owner of a managed profile. + * <p> Starting from Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}: + * This method can be called by the profile owner of a managed profile + * or device owner. * - * <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. + * @throws SecurityException if the caller is not the profile owner or device owner. **/ public void setPreferentialNetworkServiceEnabled(boolean enabled) { throwIfParentInstance("setPreferentialNetworkServiceEnabled"); - if (mService == null) { - return; - } - - try { - mService.setPreferentialNetworkServiceEnabled(enabled); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + PreferentialNetworkServiceConfig.Builder configBuilder = + new PreferentialNetworkServiceConfig.Builder(); + configBuilder.setEnabled(enabled); + if (enabled) { + configBuilder.setNetworkId(NET_ENTERPRISE_ID_1); } + setPreferentialNetworkServiceConfigs(List.of(configBuilder.build())); } /** * Indicates whether preferential network service is enabled. * - * <p>This method can be called by the profile owner of a managed profile. + * <p> Before Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}: + * This method can be called by the profile owner of a managed profile. + * <p> Starting from Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}: + * This method can be called by the profile owner of a managed profile + * or device owner. * * @return whether preferential network service is enabled. - * @throws SecurityException if the caller is not the profile owner. + * @throws SecurityException if the caller is not the profile owner or device owner. */ public boolean isPreferentialNetworkServiceEnabled() { throwIfParentInstance("isPreferentialNetworkServiceEnabled"); - if (mService == null) { - return false; - } - try { - return mService.isPreferentialNetworkServiceEnabled(myUserId()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return getPreferentialNetworkServiceConfigs().stream().anyMatch(c -> c.isEnabled()); } /** - * Sets preferential network configuration on the work profile. + * Sets preferential network configurations. * {@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. + * By default, preferential network service is disabled on the work profile and fully managed + * devices, on supported carriers and devices. Admins can explicitly enable it with this API. + * If admin wants to have multiple enterprise slices, + * it can be configured by passing list of {@link PreferentialNetworkServiceConfig} objects. * - * <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. + * @param preferentialNetworkServiceConfigs list of preferential network configurations. + * @throws SecurityException if the caller is not the profile owner or device owner. **/ - public void setPreferentialNetworkServiceConfig( - @NonNull PreferentialNetworkServiceConfig preferentialNetworkServiceConfig) { - throwIfParentInstance("setPreferentialNetworkServiceConfig"); + public void setPreferentialNetworkServiceConfigs( + @NonNull List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs) { + throwIfParentInstance("setPreferentialNetworkServiceConfigs"); if (mService == null) { return; } try { - mService.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfig); + mService.setPreferentialNetworkServiceConfigs(preferentialNetworkServiceConfigs); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -10352,18 +10351,16 @@ public class DevicePolicyManager { * 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. + * @throws SecurityException if the caller is not the profile owner or device owner. */ - public @NonNull PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig() { - throwIfParentInstance("getPreferentialNetworkServiceConfig"); + public @NonNull List<PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs() { + throwIfParentInstance("getPreferentialNetworkServiceConfigs"); if (mService == null) { - return PreferentialNetworkServiceConfig.DEFAULT; + return List.of(PreferentialNetworkServiceConfig.DEFAULT); } try { - return mService.getPreferentialNetworkServiceConfig(); + return mService.getPreferentialNetworkServiceConfigs(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -12807,13 +12804,18 @@ public class DevicePolicyManager { } /** - * Called by device owner to add an override APN. + * Called by device owner or profile owner to add an override APN. * * <p>This method may returns {@code -1} if {@code apnSetting} conflicts with an existing * override APN. Update the existing conflicted APN with * {@link #updateOverrideApn(ComponentName, int, ApnSetting)} instead of adding a new entry. * <p>Two override APNs are considered to conflict when all the following APIs return * the same values on both override APNs: + * <p> Before Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}: + * Only device owners can add APNs. + * <p> Starting from Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}: + * Device and profile owners can add enterprise APNs + * ({@link ApnSetting#TYPE_ENTERPRISE}), while only device owners can add other type of APNs. * <ul> * <li>{@link ApnSetting#getOperatorNumeric()}</li> * <li>{@link ApnSetting#getApnName()}</li> @@ -12832,7 +12834,8 @@ public class DevicePolicyManager { * @param apnSetting the override APN to insert * @return The {@code id} of inserted override APN. Or {@code -1} when failed to insert into * the database. - * @throws SecurityException if {@code admin} is not a device owner. + * @throws SecurityException If request is for enterprise APN {@code admin} is either device + * owner or profile owner and in all other types of APN if {@code admin} is not a device owner. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ @@ -12849,20 +12852,26 @@ public class DevicePolicyManager { } /** - * Called by device owner to update an override APN. + * Called by device owner or profile owner to update an override APN. * * <p>This method may returns {@code false} if there is no override APN with the given * {@code apnId}. * <p>This method may also returns {@code false} if {@code apnSetting} conflicts with an * existing override APN. Update the existing conflicted APN instead. * <p>See {@link #addOverrideApn} for the definition of conflict. + * <p> Before Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}: + * Only device owners can update APNs. + * <p> Starting from Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}: + * Device and profile owners can update enterprise APNs + * ({@link ApnSetting#TYPE_ENTERPRISE}), while only device owners can update other type of APNs. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @param apnId the {@code id} of the override APN to update * @param apnSetting the override APN to update * @return {@code true} if the required override APN is successfully updated, * {@code false} otherwise. - * @throws SecurityException if {@code admin} is not a device owner. + * @throws SecurityException If request is for enterprise APN {@code admin} is either device + * owner or profile owner and in all other types of APN if {@code admin} is not a device owner. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ @@ -12880,16 +12889,22 @@ public class DevicePolicyManager { } /** - * Called by device owner to remove an override APN. + * Called by device owner or profile owner to remove an override APN. * * <p>This method may returns {@code false} if there is no override APN with the given * {@code apnId}. + * <p> Before Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}: + * Only device owners can remove APNs. + * <p> Starting from Android version {@link android.os.Build.VERSION_CODES#TIRAMISU}: + * Device and profile owners can remove enterprise APNs + * ({@link ApnSetting#TYPE_ENTERPRISE}), while only device owners can remove other type of APNs. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @param apnId the {@code id} of the override APN to remove * @return {@code true} if the required override APN is successfully removed, {@code false} * otherwise. - * @throws SecurityException if {@code admin} is not a device owner. + * @throws SecurityException If request is for enterprise APN {@code admin} is either device + * owner or profile owner and in all other types of APN if {@code admin} is not a device owner. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 7ad8379762f5..765c8cbfc627 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -278,12 +278,9 @@ interface IDevicePolicyManager { void setSecondaryLockscreenEnabled(in ComponentName who, boolean enabled); boolean isSecondaryLockscreenEnabled(in UserHandle userHandle); - void setPreferentialNetworkServiceEnabled(in boolean enabled); - boolean isPreferentialNetworkServiceEnabled(int userHandle); - - void setPreferentialNetworkServiceConfig( - in PreferentialNetworkServiceConfig preferentialNetworkServiceConfig); - PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig(); + void setPreferentialNetworkServiceConfigs( + in List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs); + List<PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs(); void setLockTaskPackages(in ComponentName who, in String[] packages); String[] getLockTaskPackages(in ComponentName who); diff --git a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java index 2849139c606b..54170a2a187f 100644 --- a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java +++ b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java @@ -28,7 +28,7 @@ import java.util.Objects; /** * Network configuration to be set for the user profile - * {@see DevicePolicyManager#setPreferentialNetworkServiceConfig}. + * {@see DevicePolicyManager#setPreferentialNetworkServiceConfigs}. */ public final class PreferentialNetworkServiceConfig implements Parcelable { final boolean mIsEnabled; @@ -147,8 +147,6 @@ public final class PreferentialNetworkServiceConfig implements Parcelable { /** * @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 * */ @@ -286,8 +284,6 @@ public final class PreferentialNetworkServiceConfig implements Parcelable { /** * 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. diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java index 1c9d58458629..ef3b0bb2be65 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java @@ -295,8 +295,8 @@ class ActiveAdmin { public boolean mAdminCanGrantSensorsPermissions; public boolean mPreferentialNetworkServiceEnabled = DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT; - public PreferentialNetworkServiceConfig mPreferentialNetworkServiceConfig = - PreferentialNetworkServiceConfig.DEFAULT; + public List<PreferentialNetworkServiceConfig> mPreferentialNetworkServiceConfigs = + List.of(PreferentialNetworkServiceConfig.DEFAULT); private static final boolean USB_DATA_SIGNALING_ENABLED_DEFAULT = true; boolean mUsbDataSignalingEnabled = USB_DATA_SIGNALING_ENABLED_DEFAULT; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index a8617c063800..b0997c0b2935 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -110,13 +110,13 @@ 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; import static android.provider.Settings.Secure.USER_SETUP_COMPLETE; import static android.provider.Telephony.Carriers.DPC_URI; import static android.provider.Telephony.Carriers.ENFORCE_KEY; import static android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI; +import static android.provider.Telephony.Carriers.INVALID_APN_ID; import static android.security.keystore.AttestationUtils.USE_INDIVIDUAL_ATTESTATION; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_ENTRY_POINT_ADB; @@ -3314,14 +3314,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { updatePermissionPolicyCache(userId); updateAdminCanGrantSensorsPermissionCache(userId); - final PreferentialNetworkServiceConfig preferentialNetworkServiceConfig; + final List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs; synchronized (getLockObject()) { ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userId); - preferentialNetworkServiceConfig = owner != null - ? owner.mPreferentialNetworkServiceConfig - : PreferentialNetworkServiceConfig.DEFAULT; + preferentialNetworkServiceConfigs = owner != null + ? owner.mPreferentialNetworkServiceConfigs + : List.of(PreferentialNetworkServiceConfig.DEFAULT); } - updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfig); + updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfigs); startOwnerService(userId, "start-user"); } @@ -3338,7 +3338,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override void handleStopUser(int userId) { - updateNetworkPreferenceForUser(userId, PreferentialNetworkServiceConfig.DEFAULT); + updateNetworkPreferenceForUser(userId, List.of(PreferentialNetworkServiceConfig.DEFAULT)); stopOwnerService(userId, "stop-user"); } @@ -12002,87 +12002,50 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } @Override - public void setPreferentialNetworkServiceEnabled(boolean enabled) { + public void setPreferentialNetworkServiceConfigs( + List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs) { 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"); + Preconditions.checkCallAuthorization(isProfileOwner(caller) + || isDeviceOwner(caller), + "Caller is not profile owner or device owner;" + + " only profile owner or device owner may control the preferential" + + " network service"); synchronized (getLockObject()) { final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked( caller.getUserId()); - if (requiredAdmin != null - && requiredAdmin.mPreferentialNetworkServiceEnabled != enabled) { - requiredAdmin.mPreferentialNetworkServiceEnabled = enabled; + if (!requiredAdmin.mPreferentialNetworkServiceConfigs.equals( + preferentialNetworkServiceConfigs)) { + requiredAdmin.mPreferentialNetworkServiceConfigs = + new ArrayList<>(preferentialNetworkServiceConfigs); saveSettingsLocked(caller.getUserId()); } } - updateNetworkPreferenceForUser(caller.getUserId(), enabled); + updateNetworkPreferenceForUser(caller.getUserId(), preferentialNetworkServiceConfigs); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_PREFERENTIAL_NETWORK_SERVICE_ENABLED) - .setBoolean(enabled) + .setBoolean(preferentialNetworkServiceConfigs + .stream().anyMatch(c -> c.isEnabled())) .write(); } @Override - public boolean isPreferentialNetworkServiceEnabled(int userHandle) { + public List<PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs() { if (!mHasFeature) { - return false; - } - - final CallerIdentity caller = getCallerIdentity(); - Preconditions.checkCallAuthorization(isProfileOwner(caller), - "Caller is not profile owner"); - synchronized (getLockObject()) { - final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(userHandle); - if (requiredAdmin != null) { - return requiredAdmin.mPreferentialNetworkServiceEnabled; - } else { - return false; - } + return List.of(PreferentialNetworkServiceConfig.DEFAULT); } - } - @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"); + Preconditions.checkCallAuthorization(isProfileOwner(caller) + || isDeviceOwner(caller), + "Caller is not profile owner or device owner;" + + " only profile owner or device owner may retrieve the preferential" + + " network service configurations"); synchronized (getLockObject()) { final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(caller.getUserId()); - return requiredAdmin.mPreferentialNetworkServiceConfig; + return requiredAdmin.mPreferentialNetworkServiceConfigs; } } @@ -16081,7 +16044,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(who, "ComponentName is null"); Objects.requireNonNull(apnSetting, "ApnSetting is null in addOverrideApn"); final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization(isDeviceOwner(caller)); + if (apnSetting.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) { + Preconditions.checkCallAuthorization(isDeviceOwner(caller) + || isProfileOwner(caller)); + } else { + Preconditions.checkCallAuthorization(isDeviceOwner(caller)); + } TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); if (tm != null) { @@ -16089,7 +16057,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { () -> tm.addDevicePolicyOverrideApn(mContext, apnSetting)); } else { Slogf.w(LOG_TAG, "TelephonyManager is null when trying to add override apn"); - return Telephony.Carriers.INVALID_APN_ID; + return INVALID_APN_ID; } } @@ -16102,7 +16070,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(who, "ComponentName is null"); Objects.requireNonNull(apnSetting, "ApnSetting is null in updateOverrideApn"); final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization(isDeviceOwner(caller)); + ApnSetting apn = getApnSetting(apnId); + if (apn != null && apn.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE + && apnSetting.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) { + Preconditions.checkCallAuthorization(isDeviceOwner(caller) + || isProfileOwner(caller)); + } else { + Preconditions.checkCallAuthorization(isDeviceOwner(caller)); + } if (apnId < 0) { return false; @@ -16124,7 +16099,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } Objects.requireNonNull(who, "ComponentName is null"); final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization(isDeviceOwner(caller)); + ApnSetting apn = getApnSetting(apnId); + if (apn != null && apn.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) { + Preconditions.checkCallAuthorization(isDeviceOwner(caller) + || isProfileOwner(caller)); + } else { + Preconditions.checkCallAuthorization(isDeviceOwner(caller)); + } return removeOverrideApnUnchecked(apnId); } @@ -16138,6 +16119,27 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return numDeleted > 0; } + private ApnSetting getApnSetting(int apnId) { + if (apnId < 0) { + return null; + } + ApnSetting apnSetting = null; + Cursor cursor = mInjector.binderWithCleanCallingIdentity( + () -> mContext.getContentResolver().query( + Uri.withAppendedPath(DPC_URI, Integer.toString(apnId)), null, null, null, + Telephony.Carriers.DEFAULT_SORT_ORDER)); + if (cursor != null) { + while (cursor.moveToNext()) { + apnSetting = ApnSetting.makeApnSetting(cursor); + if (apnSetting != null) { + break; + } + } + cursor.close(); + } + return apnSetting; + } + @Override public List<ApnSetting> getOverrideApns(@NonNull ComponentName who) { if (!mHasFeature || !mHasTelephonyFeature) { @@ -17824,54 +17826,38 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } private void updateNetworkPreferenceForUser(int userId, - boolean preferentialNetworkServiceEnabled) { + List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs) { if (!isManagedProfile(userId)) { return; } - ProfileNetworkPreference.Builder preferenceBuilder = - new ProfileNetworkPreference.Builder(); - if (preferentialNetworkServiceEnabled) { - preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE); - preferenceBuilder.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1); - } else { - preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); - } List<ProfileNetworkPreference> preferences = new ArrayList<>(); - preferences.add(preferenceBuilder.build()); - mInjector.binderWithCleanCallingIdentity(() -> - mInjector.getConnectivityManager().setProfileNetworkPreferences( - UserHandle.of(userId), preferences, - 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); + for (PreferentialNetworkServiceConfig preferentialNetworkServiceConfig : + preferentialNetworkServiceConfigs) { + 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_ENTERPRISE_NO_FALLBACK); + preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT); } - } 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()); + 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()); + + preferences.add(preferenceBuilder.build()); + } mInjector.binderWithCleanCallingIdentity(() -> mInjector.getConnectivityManager().setProfileNetworkPreferences( UserHandle.of(userId), preferences, diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 4ae855ff8b80..a67751d5b4bc 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -4137,8 +4137,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { @Test public void testSetPreferentialNetworkServiceConfig_noProfileOwner() throws Exception { assertExpectException(SecurityException.class, null, - () -> dpm.setPreferentialNetworkServiceConfig( - PreferentialNetworkServiceConfig.DEFAULT)); + () -> dpm.setPreferentialNetworkServiceConfigs( + List.of(PreferentialNetworkServiceConfig.DEFAULT))); } @Test @@ -4178,10 +4178,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { addManagedProfile(admin1, managedProfileAdminUid, admin1); mContext.binder.callingUid = managedProfileAdminUid; - dpm.setPreferentialNetworkServiceConfig(PreferentialNetworkServiceConfig.DEFAULT); + dpm.setPreferentialNetworkServiceConfigs( + List.of(PreferentialNetworkServiceConfig.DEFAULT)); assertThat(dpm.isPreferentialNetworkServiceEnabled()).isFalse(); - assertThat(dpm.getPreferentialNetworkServiceConfig() - .isEnabled()).isFalse(); + assertThat(dpm.getPreferentialNetworkServiceConfigs().get(0).isEnabled()).isFalse(); ProfileNetworkPreference preferenceDetails = new ProfileNetworkPreference.Builder() @@ -4207,8 +4207,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { addManagedProfile(admin1, managedProfileAdminUid, admin1); mContext.binder.callingUid = managedProfileAdminUid; - dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled); - assertThat(dpm.getPreferentialNetworkServiceConfig() + dpm.setPreferentialNetworkServiceConfigs(List.of(preferentialNetworkServiceConfigEnabled)); + assertThat(dpm.getPreferentialNetworkServiceConfigs().get(0) .isEnabled()).isTrue(); ProfileNetworkPreference preferenceDetails = new ProfileNetworkPreference.Builder() @@ -4237,8 +4237,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { .setFallbackToDefaultConnectionAllowed(false) .setIncludedUids(new int[]{1, 2}) .build(); - dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled); - assertThat(dpm.getPreferentialNetworkServiceConfig() + dpm.setPreferentialNetworkServiceConfigs(List.of(preferentialNetworkServiceConfigEnabled)); + assertThat(dpm.getPreferentialNetworkServiceConfigs().get(0) .isEnabled()).isTrue(); List<Integer> includedList = new ArrayList<>(); includedList.add(1); @@ -4272,8 +4272,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { .setExcludedUids(new int[]{1, 2}) .build(); - dpm.setPreferentialNetworkServiceConfig(preferentialNetworkServiceConfigEnabled); - assertThat(dpm.getPreferentialNetworkServiceConfig() + dpm.setPreferentialNetworkServiceConfigs(List.of(preferentialNetworkServiceConfigEnabled)); + assertThat(dpm.getPreferentialNetworkServiceConfigs().get(0) .isEnabled()).isTrue(); List<Integer> excludedUids = new ArrayList<>(); excludedUids.add(1); |