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

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

Merge "New device policy API: DeviceAdminReceiver.onUnsafeOperationStateChanged()" into sc-dev

parents 7a337fac 25887749
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -6896,6 +6896,7 @@ package android.app.admin {
    method public void onLockTaskModeEntering(@NonNull android.content.Context, @NonNull android.content.Intent, @NonNull String);
    method public void onLockTaskModeEntering(@NonNull android.content.Context, @NonNull android.content.Intent, @NonNull String);
    method public void onLockTaskModeExiting(@NonNull android.content.Context, @NonNull android.content.Intent);
    method public void onLockTaskModeExiting(@NonNull android.content.Context, @NonNull android.content.Intent);
    method public void onNetworkLogsAvailable(@NonNull android.content.Context, @NonNull android.content.Intent, long, @IntRange(from=1) int);
    method public void onNetworkLogsAvailable(@NonNull android.content.Context, @NonNull android.content.Intent, long, @IntRange(from=1) int);
    method public void onOperationSafetyStateChanged(@NonNull android.content.Context, int, boolean);
    method @Deprecated public void onPasswordChanged(@NonNull android.content.Context, @NonNull android.content.Intent);
    method @Deprecated public void onPasswordChanged(@NonNull android.content.Context, @NonNull android.content.Intent);
    method public void onPasswordChanged(@NonNull android.content.Context, @NonNull android.content.Intent, @NonNull android.os.UserHandle);
    method public void onPasswordChanged(@NonNull android.content.Context, @NonNull android.content.Intent, @NonNull android.os.UserHandle);
    method @Deprecated public void onPasswordExpiring(@NonNull android.content.Context, @NonNull android.content.Intent);
    method @Deprecated public void onPasswordExpiring(@NonNull android.content.Context, @NonNull android.content.Intent);
@@ -7072,6 +7073,7 @@ package android.app.admin {
    method public boolean isProfileOwnerApp(String);
    method public boolean isProfileOwnerApp(String);
    method public boolean isProvisioningAllowed(@NonNull String);
    method public boolean isProvisioningAllowed(@NonNull String);
    method public boolean isResetPasswordTokenActive(android.content.ComponentName);
    method public boolean isResetPasswordTokenActive(android.content.ComponentName);
    method public boolean isSafeOperation(int);
    method public boolean isSecurityLoggingEnabled(@Nullable android.content.ComponentName);
    method public boolean isSecurityLoggingEnabled(@Nullable android.content.ComponentName);
    method public boolean isUninstallBlocked(@Nullable android.content.ComponentName, String);
    method public boolean isUninstallBlocked(@Nullable android.content.ComponentName, String);
    method public boolean isUniqueDeviceAttestationSupported();
    method public boolean isUniqueDeviceAttestationSupported();
@@ -7300,6 +7302,7 @@ package android.app.admin {
    field public static final int LOCK_TASK_FEATURE_SYSTEM_INFO = 1; // 0x1
    field public static final int LOCK_TASK_FEATURE_SYSTEM_INFO = 1; // 0x1
    field public static final int MAKE_USER_EPHEMERAL = 2; // 0x2
    field public static final int MAKE_USER_EPHEMERAL = 2; // 0x2
    field public static final String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning";
    field public static final String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning";
    field public static final int OPERATION_SAFETY_REASON_DRIVING_DISTRACTION = 1; // 0x1
    field public static final int PASSWORD_COMPLEXITY_HIGH = 327680; // 0x50000
    field public static final int PASSWORD_COMPLEXITY_HIGH = 327680; // 0x50000
    field public static final int PASSWORD_COMPLEXITY_LOW = 65536; // 0x10000
    field public static final int PASSWORD_COMPLEXITY_LOW = 65536; // 0x10000
    field public static final int PASSWORD_COMPLEXITY_MEDIUM = 196608; // 0x30000
    field public static final int PASSWORD_COMPLEXITY_MEDIUM = 196608; // 0x30000
@@ -7336,7 +7339,6 @@ package android.app.admin {
    field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
    field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
    field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
    field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
    field public static final int SKIP_SETUP_WIZARD = 1; // 0x1
    field public static final int SKIP_SETUP_WIZARD = 1; // 0x1
    field public static final int UNSAFE_OPERATION_REASON_DRIVING_DISTRACTION = 1; // 0x1
    field public static final int WIPE_EUICC = 4; // 0x4
    field public static final int WIPE_EUICC = 4; // 0x4
    field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
    field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
    field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
    field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
@@ -7490,7 +7492,7 @@ package android.app.admin {
  public final class UnsafeStateException extends java.lang.IllegalStateException implements android.os.Parcelable {
  public final class UnsafeStateException extends java.lang.IllegalStateException implements android.os.Parcelable {
    method public int describeContents();
    method public int describeContents();
    method public int getReason();
    method @NonNull public java.util.List<java.lang.Integer> getReasons();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.UnsafeStateException> CREATOR;
    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.UnsafeStateException> CREATOR;
  }
  }
+2 −2
Original line number Original line Diff line number Diff line
@@ -391,11 +391,11 @@ package android.app.admin {
    method public java.util.List<java.lang.String> getOwnerInstalledCaCerts(@NonNull android.os.UserHandle);
    method public java.util.List<java.lang.String> getOwnerInstalledCaCerts(@NonNull android.os.UserHandle);
    method public boolean isCurrentInputMethodSetByOwner();
    method public boolean isCurrentInputMethodSetByOwner();
    method public boolean isFactoryResetProtectionPolicySupported();
    method public boolean isFactoryResetProtectionPolicySupported();
    method @NonNull public static String operationSafetyReasonToString(int);
    method @NonNull public static String operationToString(int);
    method @NonNull public static String operationToString(int);
    method @RequiresPermission("android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS") public void provisionFullyManagedDevice(@NonNull android.app.admin.FullyManagedDeviceProvisioningParams) throws android.app.admin.ProvisioningException;
    method @RequiresPermission("android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS") public void provisionFullyManagedDevice(@NonNull android.app.admin.FullyManagedDeviceProvisioningParams) throws android.app.admin.ProvisioningException;
    method @RequiresPermission("android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS") public void resetDefaultCrossProfileIntentFilters(int);
    method @RequiresPermission("android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS") public void resetDefaultCrossProfileIntentFilters(int);
    method @RequiresPermission("android.permission.MANAGE_DEVICE_ADMINS") public void setNextOperationSafety(int, int);
    method @RequiresPermission("android.permission.MANAGE_DEVICE_ADMINS") public void setNextOperationSafety(int, int);
    method @NonNull public static String unsafeOperationReasonToString(int);
    field public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED = "android.app.action.DATA_SHARING_RESTRICTION_APPLIED";
    field public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED = "android.app.action.DATA_SHARING_RESTRICTION_APPLIED";
    field public static final int CODE_ACCOUNTS_NOT_EMPTY = 6; // 0x6
    field public static final int CODE_ACCOUNTS_NOT_EMPTY = 6; // 0x6
    field public static final int CODE_CANNOT_ADD_MANAGED_PROFILE = 11; // 0xb
    field public static final int CODE_CANNOT_ADD_MANAGED_PROFILE = 11; // 0xb
@@ -425,6 +425,7 @@ package android.app.admin {
    field public static final int OPERATION_REMOVE_KEY_PAIR = 28; // 0x1c
    field public static final int OPERATION_REMOVE_KEY_PAIR = 28; // 0x1c
    field public static final int OPERATION_REMOVE_USER = 6; // 0x6
    field public static final int OPERATION_REMOVE_USER = 6; // 0x6
    field public static final int OPERATION_REQUEST_BUGREPORT = 29; // 0x1d
    field public static final int OPERATION_REQUEST_BUGREPORT = 29; // 0x1d
    field public static final int OPERATION_SAFETY_REASON_NONE = -1; // 0xffffffff
    field public static final int OPERATION_SET_ALWAYS_ON_VPN_PACKAGE = 30; // 0x1e
    field public static final int OPERATION_SET_ALWAYS_ON_VPN_PACKAGE = 30; // 0x1e
    field public static final int OPERATION_SET_APPLICATION_HIDDEN = 15; // 0xf
    field public static final int OPERATION_SET_APPLICATION_HIDDEN = 15; // 0xf
    field public static final int OPERATION_SET_APPLICATION_RESTRICTIONS = 16; // 0x10
    field public static final int OPERATION_SET_APPLICATION_RESTRICTIONS = 16; // 0x10
@@ -460,7 +461,6 @@ package android.app.admin {
    field public static final int PROVISIONING_RESULT_SETTING_PROFILE_OWNER_FAILED = 4; // 0x4
    field public static final int PROVISIONING_RESULT_SETTING_PROFILE_OWNER_FAILED = 4; // 0x4
    field public static final int PROVISIONING_RESULT_SET_DEVICE_OWNER_FAILED = 7; // 0x7
    field public static final int PROVISIONING_RESULT_SET_DEVICE_OWNER_FAILED = 7; // 0x7
    field public static final int PROVISIONING_RESULT_STARTING_PROFILE_FAILED = 5; // 0x5
    field public static final int PROVISIONING_RESULT_STARTING_PROFILE_FAILED = 5; // 0x5
    field public static final int UNSAFE_OPERATION_REASON_NONE = -1; // 0xffffffff
  }
  }


  public final class FullyManagedDeviceProvisioningParams implements android.os.Parcelable {
  public final class FullyManagedDeviceProvisioningParams implements android.os.Parcelable {
+85 −2
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package android.app.admin;
package android.app.admin;


import static android.app.admin.DevicePolicyManager.OperationSafetyReason;

import android.accounts.AccountManager;
import android.accounts.AccountManager;
import android.annotation.BroadcastBehavior;
import android.annotation.BroadcastBehavior;
import android.annotation.IntDef;
import android.annotation.IntDef;
@@ -35,6 +37,7 @@ import android.os.PersistableBundle;
import android.os.Process;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserHandle;
import android.security.KeyChain;
import android.security.KeyChain;
import android.util.Log;


import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
@@ -72,8 +75,8 @@ import java.lang.annotation.RetentionPolicy;
 * </div>
 * </div>
 */
 */
public class DeviceAdminReceiver extends BroadcastReceiver {
public class DeviceAdminReceiver extends BroadcastReceiver {
    private static String TAG = "DevicePolicy";
    private static final String TAG = "DevicePolicy";
    private static boolean localLOGV = false;
    private static final boolean LOCAL_LOGV = false;


    /**
    /**
     * This is the primary action that a device administrator must implement to be
     * This is the primary action that a device administrator must implement to be
@@ -509,6 +512,36 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
    public static final String EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE =
    public static final String EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE =
            "android.app.extra.TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE";
            "android.app.extra.TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE";


    /**
     * Broadcast action: notify the admin that the state of operations that can be unsafe because
     * of a given reason (specified by the {@link #EXTRA_OPERATION_SAFETY_REASON} {@code int} extra)
     * has changed (the new value is specified by the {@link #EXTRA_OPERATION_SAFETY_STATE}
     * {@code boolean} extra).
     *
     * @hide
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_OPERATION_SAFETY_STATE_CHANGED =
            "android.app.action.OPERATION_SAFETY_STATE_CHANGED";

    /**
     * An {@code int} extra specifying an {@link OperationSafetyReason}.
     *
     * @hide
     */
    public static final String EXTRA_OPERATION_SAFETY_REASON  =
            "android.app.extra.OPERATION_SAFETY_REASON";

    /**
     * An {@code boolean} extra specifying whether an operation will fail due to a
     * {@link OperationSafetyReason}. {@code true} means operations that rely on that reason are
     * safe, while {@code false} means they're unsafe.
     *
     * @hide
     */
    public static final String EXTRA_OPERATION_SAFETY_STATE  =
            "android.app.extra.OPERATION_SAFETY_STATE";

    private DevicePolicyManager mManager;
    private DevicePolicyManager mManager;
    private ComponentName mWho;
    private ComponentName mWho;


@@ -1017,6 +1050,51 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
            @NonNull UserHandle user) {
            @NonNull UserHandle user) {
    }
    }


    /**
     * Called to notify the state of operations that can be unsafe to execute has changed.
     *
     * <p><b>Note:/b> notice that the operation safety state might change between the time this
     * callback is received and the operation's method on {@link DevicePolicyManager} is called, so
     * calls to the latter could still throw a {@link UnsafeStateException} even when this method
     * is called with {@code isSafe} as {@code true}
     *
     * @param context the running context as per {@link #onReceive}
     * @param reason the reason an operation could be unsafe.
     * @param isSafe whether the operation is safe to be executed.
     */
    public void onOperationSafetyStateChanged(@NonNull Context context,
            @OperationSafetyReason int reason, boolean isSafe) {
        if (LOCAL_LOGV) {
            Log.v(TAG, String.format("onOperationSafetyStateChanged(): %s=%b",
                    DevicePolicyManager.operationSafetyReasonToString(reason), isSafe));
        }
    }

    private void onOperationSafetyStateChanged(Context context, Intent intent) {
        if (!hasRequiredExtra(intent, EXTRA_OPERATION_SAFETY_REASON)
                || !hasRequiredExtra(intent, EXTRA_OPERATION_SAFETY_STATE)) {
            return;
        }

        int reason = intent.getIntExtra(EXTRA_OPERATION_SAFETY_REASON,
                DevicePolicyManager.OPERATION_SAFETY_REASON_NONE);
        if (!DevicePolicyManager.isValidOperationSafetyReason(reason)) {
            Log.wtf(TAG, "Received invalid reason on " + intent.getAction() + ": " + reason);
            return;
        }
        boolean isSafe = intent.getBooleanExtra(EXTRA_OPERATION_SAFETY_STATE,
                /* defaultValue=*/ false);

        onOperationSafetyStateChanged(context, reason, isSafe);
    }

    private boolean hasRequiredExtra(Intent intent, String extra) {
        if (intent.hasExtra(extra)) return true;

        Log.wtf(TAG, "Missing '" + extra + "' on intent " +  intent);
        return false;
    }

    /**
    /**
     * Intercept standard device administrator broadcasts.  Implementations
     * Intercept standard device administrator broadcasts.  Implementations
     * should not override this method; it is better to implement the
     * should not override this method; it is better to implement the
@@ -1025,6 +1103,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
    @Override
    @Override
    public void onReceive(@NonNull Context context, @NonNull Intent intent) {
    public void onReceive(@NonNull Context context, @NonNull Intent intent) {
        String action = intent.getAction();
        String action = intent.getAction();
        if (LOCAL_LOGV) {
            Log.v(TAG, "onReceive(): received " + action + " on user " + context.getUserId());
        }


        if (ACTION_PASSWORD_CHANGED.equals(action)) {
        if (ACTION_PASSWORD_CHANGED.equals(action)) {
            onPasswordChanged(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
            onPasswordChanged(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
@@ -1092,6 +1173,8 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
        } else if (ACTION_AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE.equals(action)) {
        } else if (ACTION_AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE.equals(action)) {
            onTransferAffiliatedProfileOwnershipComplete(context,
            onTransferAffiliatedProfileOwnershipComplete(context,
                    intent.getParcelableExtra(Intent.EXTRA_USER));
                    intent.getParcelableExtra(Intent.EXTRA_USER));
        } else if (ACTION_OPERATION_SAFETY_STATE_CHANGED.equals(action)) {
            onOperationSafetyStateChanged(context, intent);
        }
        }
    }
    }
}
}
+38 −10
Original line number Original line Diff line number Diff line
@@ -2922,33 +2922,61 @@ public class DevicePolicyManager {
        return DebugUtils.constantToString(DevicePolicyManager.class, PREFIX_OPERATION, operation);
        return DebugUtils.constantToString(DevicePolicyManager.class, PREFIX_OPERATION, operation);
    }
    }
    private static final String PREFIX_UNSAFE_OPERATION_REASON = "UNSAFE_OPERATION_REASON_";
    private static final String PREFIX_OPERATION_SAFETY_REASON = "OPERATION_SAFETY_REASON_";
    /** @hide */
    /** @hide */
    @IntDef(prefix = PREFIX_UNSAFE_OPERATION_REASON, value = {
    @IntDef(prefix = PREFIX_OPERATION_SAFETY_REASON, value = {
            UNSAFE_OPERATION_REASON_NONE,
            OPERATION_SAFETY_REASON_NONE,
            UNSAFE_OPERATION_REASON_DRIVING_DISTRACTION
            OPERATION_SAFETY_REASON_DRIVING_DISTRACTION
    })
    })
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
    public static @interface UnsafeOperationReason {
    public static @interface OperationSafetyReason {
    }
    }
    /** @hide */
    /** @hide */
    @TestApi
    @TestApi
    public static final int UNSAFE_OPERATION_REASON_NONE = -1;
    public static final int OPERATION_SAFETY_REASON_NONE = -1;
    /**
    /**
     * Indicates that a {@link UnsafeStateException} was thrown because the operation would distract
     * Indicates that a {@link UnsafeStateException} was thrown because the operation would distract
     * the driver of the vehicle.
     * the driver of the vehicle.
     */
     */
    public static final int UNSAFE_OPERATION_REASON_DRIVING_DISTRACTION = 1;
    public static final int OPERATION_SAFETY_REASON_DRIVING_DISTRACTION = 1;
    /** @hide */
    /** @hide */
    @NonNull
    @NonNull
    @TestApi
    @TestApi
    public static String unsafeOperationReasonToString(@UnsafeOperationReason int reason) {
    public static String operationSafetyReasonToString(@OperationSafetyReason int reason) {
        return DebugUtils.constantToString(DevicePolicyManager.class,
        return DebugUtils.constantToString(DevicePolicyManager.class,
                PREFIX_UNSAFE_OPERATION_REASON, reason);
                PREFIX_OPERATION_SAFETY_REASON, reason);
    }
    /** @hide */
    public static boolean isValidOperationSafetyReason(@OperationSafetyReason int reason) {
        return reason == OPERATION_SAFETY_REASON_DRIVING_DISTRACTION;
    }
    /**
     * Checks if it's safe to run operations that can be affected by the given {@code reason}.
     *
     * <p><b>Note:/b> notice that the operation safety state might change between the time this
     * method returns and the operation's method is called, so calls to the latter could still throw
     * a {@link UnsafeStateException} even when this method returns {@code true}.
     *
     * @param reason currently, only supported reason is
     * {@link #OPERATION_SAFETY_REASON_DRIVING_DISTRACTION}.
     *
     * @return whether it's safe to run operations that can be affected by the given {@code reason}.
     */
    // TODO(b/173541467): should it throw SecurityException if caller is not admin?
    public boolean isSafeOperation(@OperationSafetyReason int reason) {
        if (mService == null) return false;
        try {
            return mService.isSafeOperation(reason);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    }
    /** @hide */
    /** @hide */
@@ -13157,7 +13185,7 @@ public class DevicePolicyManager {
    @TestApi
    @TestApi
    @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS)
    @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS)
    public void setNextOperationSafety(@DevicePolicyOperation int operation,
    public void setNextOperationSafety(@DevicePolicyOperation int operation,
            @UnsafeOperationReason int reason) {
            @OperationSafetyReason int reason) {
        if (mService != null) {
        if (mService != null) {
            try {
            try {
                mService.setNextOperationSafety(operation, reason);
                mService.setNextOperationSafety(operation, reason);
+11 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package android.app.admin;


import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
import android.app.admin.DevicePolicyManager.OperationSafetyReason;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.Intent;
import android.content.Intent;
import android.os.UserHandle;
import android.os.UserHandle;
@@ -255,4 +256,14 @@ public abstract class DevicePolicyManagerInternal {
     * {@link #supportsResetOp(int)} is true.
     * {@link #supportsResetOp(int)} is true.
     */
     */
    public abstract void resetOp(int op, String packageName, @UserIdInt int userId);
    public abstract void resetOp(int op, String packageName, @UserIdInt int userId);

    /**
     * Notifies the system that an unsafe operation reason has changed.
     *
     * @throws IllegalArgumentException if {@code checker} is not the same as set on
     *         {@code DevicePolicyManagerService}.
     */
    public abstract void notifyUnsafeOperationStateChanged(DevicePolicySafetyChecker checker,
            @OperationSafetyReason int reason, boolean isSafe);

}
}
Loading