Loading api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -6377,6 +6377,7 @@ package android.app.admin { public class DevicePolicyManager { method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int); method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String); method public int addOverrideApn(android.content.ComponentName, android.telephony.data.ApnSetting); method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName); method public void addUserRestriction(android.content.ComponentName, java.lang.String); method public boolean bindDeviceAdminServiceAsUser(android.content.ComponentName, android.content.Intent, android.content.ServiceConnection, int, android.os.UserHandle); Loading Loading @@ -6423,6 +6424,7 @@ package android.app.admin { method public java.util.List<java.lang.String> getMeteredDataDisabled(android.content.ComponentName); method public int getOrganizationColor(android.content.ComponentName); method public java.lang.CharSequence getOrganizationName(android.content.ComponentName); method public java.util.List<android.telephony.data.ApnSetting> getOverrideApns(android.content.ComponentName); method public android.app.admin.DevicePolicyManager getParentProfileInstance(android.content.ComponentName); method public java.lang.String getPasswordBlacklistName(android.content.ComponentName); method public long getPasswordExpiration(android.content.ComponentName); Loading Loading @@ -6474,6 +6476,7 @@ package android.app.admin { method public boolean isManagedProfile(android.content.ComponentName); method public boolean isMasterVolumeMuted(android.content.ComponentName); method public boolean isNetworkLoggingEnabled(android.content.ComponentName); method public boolean isOverrideApnEnabled(android.content.ComponentName); method public boolean isPackageSuspended(android.content.ComponentName, java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; method public boolean isPrintingEnabled(); method public boolean isProfileOwnerApp(java.lang.String); Loading @@ -6489,6 +6492,7 @@ package android.app.admin { method public void removeActiveAdmin(android.content.ComponentName); method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String); method public boolean removeKeyPair(android.content.ComponentName, java.lang.String); method public boolean removeOverrideApn(android.content.ComponentName, int); method public boolean removeUser(android.content.ComponentName, android.os.UserHandle); method public boolean requestBugreport(android.content.ComponentName); method public boolean resetPassword(java.lang.String, int); Loading Loading @@ -6529,6 +6533,7 @@ package android.app.admin { method public void setNetworkLoggingEnabled(android.content.ComponentName, boolean); method public void setOrganizationColor(android.content.ComponentName, int); method public void setOrganizationName(android.content.ComponentName, java.lang.CharSequence); method public void setOverrideApnsEnabled(android.content.ComponentName, boolean); method public java.lang.String[] setPackagesSuspended(android.content.ComponentName, java.lang.String[], boolean); method public boolean setPasswordBlacklist(android.content.ComponentName, java.lang.String, java.util.List<java.lang.String>); method public void setPasswordExpirationTimeout(android.content.ComponentName, long); Loading Loading @@ -6573,6 +6578,7 @@ package android.app.admin { method public void transferOwnership(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle); method public void uninstallAllUserCaCerts(android.content.ComponentName); method public void uninstallCaCert(android.content.ComponentName, byte[]); method public boolean updateOverrideApn(android.content.ComponentName, int, android.telephony.data.ApnSetting); method public void wipeData(int); method public void wipeDataWithReason(int, java.lang.CharSequence); field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN"; core/java/android/app/admin/DevicePolicyManager.java +135 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.ParcelableKeyGenParameterSpec; import android.service.restrictions.RestrictionsReceiver; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.util.ArraySet; import android.util.Log; Loading Loading @@ -9298,4 +9299,138 @@ public class DevicePolicyManager { throw re.rethrowFromSystemServer(); } } /** * Called by device owner to add an override APN. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @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. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ public int addOverrideApn(@NonNull ComponentName admin, @NonNull ApnSetting apnSetting) { throwIfParentInstance("addOverrideApn"); if (mService != null) { try { return mService.addOverrideApn(admin, apnSetting); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return -1; } /** * Called by device owner to update an override APN. * * @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. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ public boolean updateOverrideApn(@NonNull ComponentName admin, int apnId, @NonNull ApnSetting apnSetting) { throwIfParentInstance("updateOverrideApn"); if (mService != null) { try { return mService.updateOverrideApn(admin, apnId, apnSetting); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return false; } /** * Called by device owner to remove an override APN. * * @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. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ public boolean removeOverrideApn(@NonNull ComponentName admin, int apnId) { throwIfParentInstance("removeOverrideApn"); if (mService != null) { try { return mService.removeOverrideApn(admin, apnId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return false; } /** * Called by device owner to get all override APNs inserted by device owner. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @return A list of override APNs inserted by device owner. * @throws SecurityException if {@code admin} is not a device owner. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ public List<ApnSetting> getOverrideApns(@NonNull ComponentName admin) { throwIfParentInstance("getOverrideApns"); if (mService != null) { try { return mService.getOverrideApns(admin); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return Collections.emptyList(); } /** * Called by device owner to set if override APNs should be enabled. * <p> Override APNs are separated from other APNs on the device, and can only be inserted or * modified by the device owner. When enabled, only override APNs are in use, any other APNs * are ignored. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @param enabled {@code true} if override APNs should be enabled, {@code false} otherwise * @throws SecurityException if {@code admin} is not a device owner. */ public void setOverrideApnsEnabled(@NonNull ComponentName admin, boolean enabled) { throwIfParentInstance("setOverrideApnEnabled"); if (mService != null) { try { mService.setOverrideApnsEnabled(admin, enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * Called by device owner to check if override APNs are currently enabled. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @return {@code true} if override APNs are currently enabled, {@code false} otherwise. * @throws SecurityException if {@code admin} is not a device owner. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ public boolean isOverrideApnEnabled(@NonNull ComponentName admin) { throwIfParentInstance("isOverrideApnEnabled"); if (mService != null) { try { return mService.isOverrideApnEnabled(admin); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return false; } } core/java/android/app/admin/IDevicePolicyManager.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.os.RemoteCallback; import android.os.UserHandle; import android.security.keymaster.KeymasterCertificateChain; import android.security.keystore.ParcelableKeyGenParameterSpec; import android.telephony.data.ApnSetting; import java.util.List; Loading Loading @@ -403,4 +404,11 @@ interface IDevicePolicyManager { List<String> setMeteredDataDisabled(in ComponentName admin, in List<String> packageNames); List<String> getMeteredDataDisabled(in ComponentName admin); int addOverrideApn(in ComponentName admin, in ApnSetting apnSetting); boolean updateOverrideApn(in ComponentName admin, int apnId, in ApnSetting apnSetting); boolean removeOverrideApn(in ComponentName admin, int apnId); List<ApnSetting> getOverrideApns(in ComponentName admin); void setOverrideApnsEnabled(in ComponentName admin, boolean enabled); boolean isOverrideApnEnabled(in ComponentName admin); } services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java +30 −0 Original line number Diff line number Diff line Loading @@ -22,11 +22,13 @@ import android.os.PersistableBundle; import android.os.UserHandle; import android.security.keymaster.KeymasterCertificateChain; import android.security.keystore.ParcelableKeyGenParameterSpec; import android.telephony.data.ApnSetting; import com.android.internal.R; import com.android.server.SystemService; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Loading Loading @@ -146,4 +148,32 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { public List<String> getMeteredDataDisabled(ComponentName admin) { return new ArrayList<>(); } @Override public int addOverrideApn(ComponentName admin, ApnSetting apnSetting) { return -1; } @Override public boolean updateOverrideApn(ComponentName admin, int apnId, ApnSetting apnSetting) { return false; } @Override public boolean removeOverrideApn(ComponentName admin, int apnId) { return false; } @Override public List<ApnSetting> getOverrideApns(ComponentName admin) { return Collections.emptyList(); } @Override public void setOverrideApnsEnabled(ComponentName admin, boolean enabled) {} @Override public boolean isOverrideApnEnabled(ComponentName admin) { return false; } } services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +207 −7 Original line number Diff line number Diff line Loading @@ -58,8 +58,15 @@ import static android.app.admin.DevicePolicyManager.WIPE_EUICC; import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE; import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA; import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_ENTRY_POINT_ADB; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; 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 com.android.internal.logging.nano.MetricsProto.MetricsEvent .PROVISIONING_ENTRY_POINT_ADB; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker .STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_TAG; import static org.xmlpull.v1.XmlPullParser.TEXT; Loading Loading @@ -99,6 +106,7 @@ import android.app.trust.TrustManager; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; Loading @@ -108,8 +116,8 @@ import android.content.pm.IPackageDataObserver; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; Loading @@ -118,6 +126,7 @@ import android.content.pm.StringParceledListSlice; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Color; import android.media.AudioManager; Loading Loading @@ -161,13 +170,14 @@ import android.security.IKeyChainAliasCallback; import android.security.IKeyChainService; import android.security.KeyChain; import android.security.KeyChain.KeyChainConnection; import android.security.KeyStore; import android.security.keymaster.KeymasterCertificateChain; import android.security.keystore.AttestationUtils; import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.ParcelableKeyGenParameterSpec; import android.security.KeyStore; import android.security.keystore.AttestationUtils; import android.service.persistentdata.PersistentDataBlockManager; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; Loading Loading @@ -217,7 +227,6 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.lang.IllegalStateException; import java.lang.reflect.Constructor; import java.nio.charset.StandardCharsets; import java.text.DateFormat; Loading @@ -228,8 +237,8 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; Loading Loading @@ -7283,6 +7292,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } private void clearOverrideApnUnchecked() { // Disable Override APNs and remove them from database. setOverrideApnsEnabledUnchecked(false); final List<ApnSetting> apns = getOverrideApnsUnchecked(); for (int i = 0; i < apns.size(); i ++) { removeOverrideApnUnchecked(apns.get(i).getId()); } } private void clearDeviceOwnerLocked(ActiveAdmin admin, int userId) { mDeviceAdminServiceController.stopServiceForOwner(userId, "clear-device-owner"); Loading @@ -7303,6 +7321,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { systemPolicyData.mLastNetworkLogsRetrievalTime = -1; saveSettingsLocked(UserHandle.USER_SYSTEM); clearUserPoliciesLocked(userId); clearOverrideApnUnchecked(); mOwners.clearDeviceOwner(); mOwners.writeDeviceOwner(); Loading Loading @@ -12509,4 +12528,185 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .getResources().getString(R.string.printing_disabled_by, appLabel); } } @Override public int addOverrideApn(@NonNull ComponentName who, @NonNull ApnSetting apnSetting) { if (!mHasFeature) { return -1; } Preconditions.checkNotNull(who, "ComponentName is null in addOverrideApn"); Preconditions.checkNotNull(apnSetting, "ApnSetting is null in addOverrideApn"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } int operatedId = -1; Uri resultUri; final long id = mInjector.binderClearCallingIdentity(); try { resultUri = mContext.getContentResolver().insert(DPC_URI, apnSetting.toContentValues()); } finally { mInjector.binderRestoreCallingIdentity(id); } if (resultUri != null) { try { operatedId = Integer.parseInt(resultUri.getLastPathSegment()); } catch (NumberFormatException e) { Slog.e(LOG_TAG, "Failed to parse inserted override APN id.", e); } } return operatedId; } @Override public boolean updateOverrideApn(@NonNull ComponentName who, int apnId, @NonNull ApnSetting apnSetting) { if (!mHasFeature) { return false; } Preconditions.checkNotNull(who, "ComponentName is null in updateOverrideApn"); Preconditions.checkNotNull(apnSetting, "ApnSetting is null in updateOverrideApn"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } if (apnId < 0) { return false; } final long id = mInjector.binderClearCallingIdentity(); try { return mContext.getContentResolver().update( Uri.withAppendedPath(DPC_URI, Integer.toString(apnId)), apnSetting.toContentValues(), null, null) > 0; } finally { mInjector.binderRestoreCallingIdentity(id); } } @Override public boolean removeOverrideApn(@NonNull ComponentName who, int apnId) { if (!mHasFeature) { return false; } Preconditions.checkNotNull(who, "ComponentName is null in removeOverrideApn"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } return removeOverrideApnUnchecked(apnId); } private boolean removeOverrideApnUnchecked(int apnId) { if(apnId < 0) { return false; } int numDeleted = 0; final long id = mInjector.binderClearCallingIdentity(); try { numDeleted = mContext.getContentResolver().delete( Uri.withAppendedPath(DPC_URI, Integer.toString(apnId)), null, null); } finally { mInjector.binderRestoreCallingIdentity(id); } return numDeleted > 0; } @Override public List<ApnSetting> getOverrideApns(@NonNull ComponentName who) { if (!mHasFeature) { return Collections.emptyList(); } Preconditions.checkNotNull(who, "ComponentName is null in getOverrideApns"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } return getOverrideApnsUnchecked(); } private List<ApnSetting> getOverrideApnsUnchecked() { final Cursor cursor; final long id = mInjector.binderClearCallingIdentity(); try { cursor = mContext.getContentResolver().query(DPC_URI, null, null, null, null); } finally { mInjector.binderRestoreCallingIdentity(id); } if (cursor == null) { return Collections.emptyList(); } try { List<ApnSetting> apnList = new ArrayList<ApnSetting>(); cursor.moveToPosition(-1); while (cursor.moveToNext()) { ApnSetting apn = ApnSetting.makeApnSetting(cursor); apnList.add(apn); } return apnList; } finally { cursor.close(); } } @Override public void setOverrideApnsEnabled(@NonNull ComponentName who, boolean enabled) { if (!mHasFeature) { return; } Preconditions.checkNotNull(who, "ComponentName is null in setOverrideApnEnabled"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } setOverrideApnsEnabledUnchecked(enabled); } private void setOverrideApnsEnabledUnchecked(boolean enabled) { ContentValues value = new ContentValues(); value.put(ENFORCE_KEY, enabled); final long id = mInjector.binderClearCallingIdentity(); try { mContext.getContentResolver().update( ENFORCE_MANAGED_URI, value, null, null); } finally { mInjector.binderRestoreCallingIdentity(id); } } @Override public boolean isOverrideApnEnabled(@NonNull ComponentName who) { if (!mHasFeature) { return false; } Preconditions.checkNotNull(who, "ComponentName is null in isOverrideApnEnabled"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } Cursor enforceCursor; final long id = mInjector.binderClearCallingIdentity(); try { enforceCursor = mContext.getContentResolver().query( ENFORCE_MANAGED_URI, null, null, null, null); } finally { mInjector.binderRestoreCallingIdentity(id); } if (enforceCursor == null) { return false; } try { if (enforceCursor.moveToFirst()) { return enforceCursor.getInt(enforceCursor.getColumnIndex(ENFORCE_KEY)) == 1; } } catch (IllegalArgumentException e) { Slog.e(LOG_TAG, "Cursor returned from ENFORCE_MANAGED_URI doesn't contain " + "correct info.", e); } finally { enforceCursor.close(); } return false; } } Loading
api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -6377,6 +6377,7 @@ package android.app.admin { public class DevicePolicyManager { method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int); method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String); method public int addOverrideApn(android.content.ComponentName, android.telephony.data.ApnSetting); method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName); method public void addUserRestriction(android.content.ComponentName, java.lang.String); method public boolean bindDeviceAdminServiceAsUser(android.content.ComponentName, android.content.Intent, android.content.ServiceConnection, int, android.os.UserHandle); Loading Loading @@ -6423,6 +6424,7 @@ package android.app.admin { method public java.util.List<java.lang.String> getMeteredDataDisabled(android.content.ComponentName); method public int getOrganizationColor(android.content.ComponentName); method public java.lang.CharSequence getOrganizationName(android.content.ComponentName); method public java.util.List<android.telephony.data.ApnSetting> getOverrideApns(android.content.ComponentName); method public android.app.admin.DevicePolicyManager getParentProfileInstance(android.content.ComponentName); method public java.lang.String getPasswordBlacklistName(android.content.ComponentName); method public long getPasswordExpiration(android.content.ComponentName); Loading Loading @@ -6474,6 +6476,7 @@ package android.app.admin { method public boolean isManagedProfile(android.content.ComponentName); method public boolean isMasterVolumeMuted(android.content.ComponentName); method public boolean isNetworkLoggingEnabled(android.content.ComponentName); method public boolean isOverrideApnEnabled(android.content.ComponentName); method public boolean isPackageSuspended(android.content.ComponentName, java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; method public boolean isPrintingEnabled(); method public boolean isProfileOwnerApp(java.lang.String); Loading @@ -6489,6 +6492,7 @@ package android.app.admin { method public void removeActiveAdmin(android.content.ComponentName); method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String); method public boolean removeKeyPair(android.content.ComponentName, java.lang.String); method public boolean removeOverrideApn(android.content.ComponentName, int); method public boolean removeUser(android.content.ComponentName, android.os.UserHandle); method public boolean requestBugreport(android.content.ComponentName); method public boolean resetPassword(java.lang.String, int); Loading Loading @@ -6529,6 +6533,7 @@ package android.app.admin { method public void setNetworkLoggingEnabled(android.content.ComponentName, boolean); method public void setOrganizationColor(android.content.ComponentName, int); method public void setOrganizationName(android.content.ComponentName, java.lang.CharSequence); method public void setOverrideApnsEnabled(android.content.ComponentName, boolean); method public java.lang.String[] setPackagesSuspended(android.content.ComponentName, java.lang.String[], boolean); method public boolean setPasswordBlacklist(android.content.ComponentName, java.lang.String, java.util.List<java.lang.String>); method public void setPasswordExpirationTimeout(android.content.ComponentName, long); Loading Loading @@ -6573,6 +6578,7 @@ package android.app.admin { method public void transferOwnership(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle); method public void uninstallAllUserCaCerts(android.content.ComponentName); method public void uninstallCaCert(android.content.ComponentName, byte[]); method public boolean updateOverrideApn(android.content.ComponentName, int, android.telephony.data.ApnSetting); method public void wipeData(int); method public void wipeDataWithReason(int, java.lang.CharSequence); field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
core/java/android/app/admin/DevicePolicyManager.java +135 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.ParcelableKeyGenParameterSpec; import android.service.restrictions.RestrictionsReceiver; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.util.ArraySet; import android.util.Log; Loading Loading @@ -9298,4 +9299,138 @@ public class DevicePolicyManager { throw re.rethrowFromSystemServer(); } } /** * Called by device owner to add an override APN. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @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. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ public int addOverrideApn(@NonNull ComponentName admin, @NonNull ApnSetting apnSetting) { throwIfParentInstance("addOverrideApn"); if (mService != null) { try { return mService.addOverrideApn(admin, apnSetting); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return -1; } /** * Called by device owner to update an override APN. * * @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. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ public boolean updateOverrideApn(@NonNull ComponentName admin, int apnId, @NonNull ApnSetting apnSetting) { throwIfParentInstance("updateOverrideApn"); if (mService != null) { try { return mService.updateOverrideApn(admin, apnId, apnSetting); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return false; } /** * Called by device owner to remove an override APN. * * @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. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ public boolean removeOverrideApn(@NonNull ComponentName admin, int apnId) { throwIfParentInstance("removeOverrideApn"); if (mService != null) { try { return mService.removeOverrideApn(admin, apnId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return false; } /** * Called by device owner to get all override APNs inserted by device owner. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @return A list of override APNs inserted by device owner. * @throws SecurityException if {@code admin} is not a device owner. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ public List<ApnSetting> getOverrideApns(@NonNull ComponentName admin) { throwIfParentInstance("getOverrideApns"); if (mService != null) { try { return mService.getOverrideApns(admin); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return Collections.emptyList(); } /** * Called by device owner to set if override APNs should be enabled. * <p> Override APNs are separated from other APNs on the device, and can only be inserted or * modified by the device owner. When enabled, only override APNs are in use, any other APNs * are ignored. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @param enabled {@code true} if override APNs should be enabled, {@code false} otherwise * @throws SecurityException if {@code admin} is not a device owner. */ public void setOverrideApnsEnabled(@NonNull ComponentName admin, boolean enabled) { throwIfParentInstance("setOverrideApnEnabled"); if (mService != null) { try { mService.setOverrideApnsEnabled(admin, enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * Called by device owner to check if override APNs are currently enabled. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @return {@code true} if override APNs are currently enabled, {@code false} otherwise. * @throws SecurityException if {@code admin} is not a device owner. * * @see #setOverrideApnsEnabled(ComponentName, boolean) */ public boolean isOverrideApnEnabled(@NonNull ComponentName admin) { throwIfParentInstance("isOverrideApnEnabled"); if (mService != null) { try { return mService.isOverrideApnEnabled(admin); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return false; } }
core/java/android/app/admin/IDevicePolicyManager.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.os.RemoteCallback; import android.os.UserHandle; import android.security.keymaster.KeymasterCertificateChain; import android.security.keystore.ParcelableKeyGenParameterSpec; import android.telephony.data.ApnSetting; import java.util.List; Loading Loading @@ -403,4 +404,11 @@ interface IDevicePolicyManager { List<String> setMeteredDataDisabled(in ComponentName admin, in List<String> packageNames); List<String> getMeteredDataDisabled(in ComponentName admin); int addOverrideApn(in ComponentName admin, in ApnSetting apnSetting); boolean updateOverrideApn(in ComponentName admin, int apnId, in ApnSetting apnSetting); boolean removeOverrideApn(in ComponentName admin, int apnId); List<ApnSetting> getOverrideApns(in ComponentName admin); void setOverrideApnsEnabled(in ComponentName admin, boolean enabled); boolean isOverrideApnEnabled(in ComponentName admin); }
services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java +30 −0 Original line number Diff line number Diff line Loading @@ -22,11 +22,13 @@ import android.os.PersistableBundle; import android.os.UserHandle; import android.security.keymaster.KeymasterCertificateChain; import android.security.keystore.ParcelableKeyGenParameterSpec; import android.telephony.data.ApnSetting; import com.android.internal.R; import com.android.server.SystemService; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Loading Loading @@ -146,4 +148,32 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { public List<String> getMeteredDataDisabled(ComponentName admin) { return new ArrayList<>(); } @Override public int addOverrideApn(ComponentName admin, ApnSetting apnSetting) { return -1; } @Override public boolean updateOverrideApn(ComponentName admin, int apnId, ApnSetting apnSetting) { return false; } @Override public boolean removeOverrideApn(ComponentName admin, int apnId) { return false; } @Override public List<ApnSetting> getOverrideApns(ComponentName admin) { return Collections.emptyList(); } @Override public void setOverrideApnsEnabled(ComponentName admin, boolean enabled) {} @Override public boolean isOverrideApnEnabled(ComponentName admin) { return false; } }
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +207 −7 Original line number Diff line number Diff line Loading @@ -58,8 +58,15 @@ import static android.app.admin.DevicePolicyManager.WIPE_EUICC; import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE; import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA; import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_ENTRY_POINT_ADB; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; 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 com.android.internal.logging.nano.MetricsProto.MetricsEvent .PROVISIONING_ENTRY_POINT_ADB; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker .STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_TAG; import static org.xmlpull.v1.XmlPullParser.TEXT; Loading Loading @@ -99,6 +106,7 @@ import android.app.trust.TrustManager; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; Loading @@ -108,8 +116,8 @@ import android.content.pm.IPackageDataObserver; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; Loading @@ -118,6 +126,7 @@ import android.content.pm.StringParceledListSlice; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Color; import android.media.AudioManager; Loading Loading @@ -161,13 +170,14 @@ import android.security.IKeyChainAliasCallback; import android.security.IKeyChainService; import android.security.KeyChain; import android.security.KeyChain.KeyChainConnection; import android.security.KeyStore; import android.security.keymaster.KeymasterCertificateChain; import android.security.keystore.AttestationUtils; import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.ParcelableKeyGenParameterSpec; import android.security.KeyStore; import android.security.keystore.AttestationUtils; import android.service.persistentdata.PersistentDataBlockManager; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; Loading Loading @@ -217,7 +227,6 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.lang.IllegalStateException; import java.lang.reflect.Constructor; import java.nio.charset.StandardCharsets; import java.text.DateFormat; Loading @@ -228,8 +237,8 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; Loading Loading @@ -7283,6 +7292,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } private void clearOverrideApnUnchecked() { // Disable Override APNs and remove them from database. setOverrideApnsEnabledUnchecked(false); final List<ApnSetting> apns = getOverrideApnsUnchecked(); for (int i = 0; i < apns.size(); i ++) { removeOverrideApnUnchecked(apns.get(i).getId()); } } private void clearDeviceOwnerLocked(ActiveAdmin admin, int userId) { mDeviceAdminServiceController.stopServiceForOwner(userId, "clear-device-owner"); Loading @@ -7303,6 +7321,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { systemPolicyData.mLastNetworkLogsRetrievalTime = -1; saveSettingsLocked(UserHandle.USER_SYSTEM); clearUserPoliciesLocked(userId); clearOverrideApnUnchecked(); mOwners.clearDeviceOwner(); mOwners.writeDeviceOwner(); Loading Loading @@ -12509,4 +12528,185 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .getResources().getString(R.string.printing_disabled_by, appLabel); } } @Override public int addOverrideApn(@NonNull ComponentName who, @NonNull ApnSetting apnSetting) { if (!mHasFeature) { return -1; } Preconditions.checkNotNull(who, "ComponentName is null in addOverrideApn"); Preconditions.checkNotNull(apnSetting, "ApnSetting is null in addOverrideApn"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } int operatedId = -1; Uri resultUri; final long id = mInjector.binderClearCallingIdentity(); try { resultUri = mContext.getContentResolver().insert(DPC_URI, apnSetting.toContentValues()); } finally { mInjector.binderRestoreCallingIdentity(id); } if (resultUri != null) { try { operatedId = Integer.parseInt(resultUri.getLastPathSegment()); } catch (NumberFormatException e) { Slog.e(LOG_TAG, "Failed to parse inserted override APN id.", e); } } return operatedId; } @Override public boolean updateOverrideApn(@NonNull ComponentName who, int apnId, @NonNull ApnSetting apnSetting) { if (!mHasFeature) { return false; } Preconditions.checkNotNull(who, "ComponentName is null in updateOverrideApn"); Preconditions.checkNotNull(apnSetting, "ApnSetting is null in updateOverrideApn"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } if (apnId < 0) { return false; } final long id = mInjector.binderClearCallingIdentity(); try { return mContext.getContentResolver().update( Uri.withAppendedPath(DPC_URI, Integer.toString(apnId)), apnSetting.toContentValues(), null, null) > 0; } finally { mInjector.binderRestoreCallingIdentity(id); } } @Override public boolean removeOverrideApn(@NonNull ComponentName who, int apnId) { if (!mHasFeature) { return false; } Preconditions.checkNotNull(who, "ComponentName is null in removeOverrideApn"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } return removeOverrideApnUnchecked(apnId); } private boolean removeOverrideApnUnchecked(int apnId) { if(apnId < 0) { return false; } int numDeleted = 0; final long id = mInjector.binderClearCallingIdentity(); try { numDeleted = mContext.getContentResolver().delete( Uri.withAppendedPath(DPC_URI, Integer.toString(apnId)), null, null); } finally { mInjector.binderRestoreCallingIdentity(id); } return numDeleted > 0; } @Override public List<ApnSetting> getOverrideApns(@NonNull ComponentName who) { if (!mHasFeature) { return Collections.emptyList(); } Preconditions.checkNotNull(who, "ComponentName is null in getOverrideApns"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } return getOverrideApnsUnchecked(); } private List<ApnSetting> getOverrideApnsUnchecked() { final Cursor cursor; final long id = mInjector.binderClearCallingIdentity(); try { cursor = mContext.getContentResolver().query(DPC_URI, null, null, null, null); } finally { mInjector.binderRestoreCallingIdentity(id); } if (cursor == null) { return Collections.emptyList(); } try { List<ApnSetting> apnList = new ArrayList<ApnSetting>(); cursor.moveToPosition(-1); while (cursor.moveToNext()) { ApnSetting apn = ApnSetting.makeApnSetting(cursor); apnList.add(apn); } return apnList; } finally { cursor.close(); } } @Override public void setOverrideApnsEnabled(@NonNull ComponentName who, boolean enabled) { if (!mHasFeature) { return; } Preconditions.checkNotNull(who, "ComponentName is null in setOverrideApnEnabled"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } setOverrideApnsEnabledUnchecked(enabled); } private void setOverrideApnsEnabledUnchecked(boolean enabled) { ContentValues value = new ContentValues(); value.put(ENFORCE_KEY, enabled); final long id = mInjector.binderClearCallingIdentity(); try { mContext.getContentResolver().update( ENFORCE_MANAGED_URI, value, null, null); } finally { mInjector.binderRestoreCallingIdentity(id); } } @Override public boolean isOverrideApnEnabled(@NonNull ComponentName who) { if (!mHasFeature) { return false; } Preconditions.checkNotNull(who, "ComponentName is null in isOverrideApnEnabled"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); } Cursor enforceCursor; final long id = mInjector.binderClearCallingIdentity(); try { enforceCursor = mContext.getContentResolver().query( ENFORCE_MANAGED_URI, null, null, null, null); } finally { mInjector.binderRestoreCallingIdentity(id); } if (enforceCursor == null) { return false; } try { if (enforceCursor.moveToFirst()) { return enforceCursor.getInt(enforceCursor.getColumnIndex(ENFORCE_KEY)) == 1; } } catch (IllegalArgumentException e) { Slog.e(LOG_TAG, "Cursor returned from ENFORCE_MANAGED_URI doesn't contain " + "correct info.", e); } finally { enforceCursor.close(); } return false; } }