Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 192e0870 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add APIs to manipulate Override APN."

parents 8b314b2b e3d9c099
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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";
+135 −0
Original line number Diff line number Diff line
@@ -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;

@@ -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;
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -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;

@@ -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);
}
+30 −0
Original line number Diff line number Diff line
@@ -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;

/**
@@ -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;
    }
}
+207 −7
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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");
@@ -7303,6 +7321,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        systemPolicyData.mLastNetworkLogsRetrievalTime = -1;
        saveSettingsLocked(UserHandle.USER_SYSTEM);
        clearUserPoliciesLocked(userId);
        clearOverrideApnUnchecked();
        mOwners.clearDeviceOwner();
        mOwners.writeDeviceOwner();
@@ -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