Loading core/api/current.txt +8 −9 Original line number Diff line number Diff line Loading @@ -8038,25 +8038,24 @@ package android.app.admin { field public static final int PACKAGE_POLICY_BLOCKLIST = 1; // 0x1 } public final class PolicyUpdateReason { ctor public PolicyUpdateReason(int); method public int getReasonCode(); field public static final int REASON_CONFLICTING_ADMIN_POLICY = 0; // 0x0 field public static final int REASON_UNKNOWN = -1; // 0xffffffff public final class PolicyUpdateResult { ctor public PolicyUpdateResult(int); method public int getResultCode(); field public static final int RESULT_FAILURE_CONFLICTING_ADMIN_POLICY = 1; // 0x1 field public static final int RESULT_FAILURE_UNKNOWN = -1; // 0xffffffff field public static final int RESULT_SUCCESS = 0; // 0x0 } public abstract class PolicyUpdatesReceiver extends android.content.BroadcastReceiver { ctor public PolicyUpdatesReceiver(); method public void onPolicyChanged(@NonNull android.content.Context, @NonNull String, @NonNull android.os.Bundle, @NonNull android.app.admin.TargetUser, @NonNull android.app.admin.PolicyUpdateReason); method public void onPolicySetResult(@NonNull android.content.Context, @NonNull String, @NonNull android.os.Bundle, @NonNull android.app.admin.TargetUser, int, @Nullable android.app.admin.PolicyUpdateReason); method public void onPolicyChanged(@NonNull android.content.Context, @NonNull String, @NonNull android.os.Bundle, @NonNull android.app.admin.TargetUser, @NonNull android.app.admin.PolicyUpdateResult); method public void onPolicySetResult(@NonNull android.content.Context, @NonNull String, @NonNull android.os.Bundle, @NonNull android.app.admin.TargetUser, @NonNull android.app.admin.PolicyUpdateResult); method public final void onReceive(android.content.Context, android.content.Intent); field public static final String ACTION_DEVICE_POLICY_CHANGED = "android.app.admin.action.DEVICE_POLICY_CHANGED"; field public static final String ACTION_DEVICE_POLICY_SET_RESULT = "android.app.admin.action.DEVICE_POLICY_SET_RESULT"; field public static final String EXTRA_INTENT_FILTER = "android.app.admin.extra.INTENT_FILTER"; field public static final String EXTRA_PACKAGE_NAME = "android.app.admin.extra.PACKAGE_NAME"; field public static final String EXTRA_PERMISSION_NAME = "android.app.admin.extra.PERMISSION_NAME"; field public static final int POLICY_SET_RESULT_FAILURE = -1; // 0xffffffff field public static final int POLICY_SET_RESULT_SUCCESS = 0; // 0x0 } public final class PreferentialNetworkServiceConfig implements android.os.Parcelable { core/java/android/app/admin/PolicyUpdateReason.java→core/java/android/app/admin/PolicyUpdateResult.java +82 −0 Original line number Diff line number Diff line Loading @@ -22,53 +22,61 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Class containing the reason a policy (set from {@link DevicePolicyManager}) hasn't been enforced * (passed in to {@link PolicyUpdatesReceiver#onPolicySetResult}) or has changed (passed in to * Class containing the reason for the policy (set from {@link DevicePolicyManager}) update (e.g. * success, failure reasons, etc.). This is passed in to * {@link PolicyUpdatesReceiver#onPolicySetResult}) and * {@link PolicyUpdatesReceiver#onPolicyChanged}). */ public final class PolicyUpdateReason { public final class PolicyUpdateResult { /** * Reason code to indicate that the policy has not been enforced or has changed for an unknown * Result code to indicate that the policy has not been enforced or has changed for an unknown * reason. */ public static final int REASON_UNKNOWN = -1; public static final int RESULT_FAILURE_UNKNOWN = -1; /** * Reason code to indicate that the policy has not been enforced or has changed because another * Result code to indicate that the policy has been changed to the desired value set by * the admin. */ public static final int RESULT_SUCCESS = 0; /** * Result code to indicate that the policy has not been enforced or has changed because another * admin has set a conflicting policy on the device. */ public static final int REASON_CONFLICTING_ADMIN_POLICY = 0; public static final int RESULT_FAILURE_CONFLICTING_ADMIN_POLICY = 1; /** * Reason codes for {@link #getReasonCode()}. * Reason codes for {@link #getResultCode()}. * * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "REASON_" }, value = { REASON_UNKNOWN, REASON_CONFLICTING_ADMIN_POLICY, @IntDef(flag = true, prefix = { "RESULT_" }, value = { RESULT_FAILURE_UNKNOWN, RESULT_SUCCESS, RESULT_FAILURE_CONFLICTING_ADMIN_POLICY }) public @interface ReasonCode {} public @interface ResultCode {} private final int mReasonCode; private final int mResultCode; /** * Constructor for {@code PolicyUpdateReason} that takes in a reason code describing why the * Constructor for {@code PolicyUpdateReason} that takes in a result code describing why the * policy has changed. * * @param reasonCode Describes why the policy has changed. * @param resultCode Describes why the policy has changed. */ public PolicyUpdateReason(@ReasonCode int reasonCode) { this.mReasonCode = reasonCode; public PolicyUpdateResult(@ResultCode int resultCode) { this.mResultCode = resultCode; } /** * Returns reason code for why a policy hasn't been applied or has changed. * Returns result code describing why the policy has changed. */ @ReasonCode public int getReasonCode() { return mReasonCode; @ResultCode public int getResultCode() { return mResultCode; } } core/java/android/app/admin/PolicyUpdatesReceiver.java +22 −72 Original line number Diff line number Diff line Loading @@ -17,9 +17,7 @@ package android.app.admin; import android.annotation.BroadcastBehavior; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -27,8 +25,6 @@ import android.content.Intent; import android.os.Bundle; import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** Loading @@ -49,31 +45,6 @@ import java.util.Objects; public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { private static String TAG = "PolicyUpdatesReceiver"; /** * Result code passed in to {@link #onPolicySetResult} to indicate that the policy has been * set successfully. */ public static final int POLICY_SET_RESULT_SUCCESS = 0; /** * Result code passed in to {@link #onPolicySetResult} to indicate that the policy has NOT been * set, a {@link PolicyUpdateReason} will be passed in to {@link #onPolicySetResult} to indicate * the reason. */ public static final int POLICY_SET_RESULT_FAILURE = -1; /** * Result codes passed in to {@link #onPolicySetResult}. * * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "POLICY_SET_RESULT_" }, value = { POLICY_SET_RESULT_SUCCESS, POLICY_SET_RESULT_FAILURE, }) public @interface ResultCode {} /** * Action for a broadcast sent to admins to communicate back the result of setting a policy in * {@link DevicePolicyManager}. Loading Loading @@ -152,14 +123,8 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { /** * @hide */ public static final String EXTRA_POLICY_SET_RESULT_KEY = "android.app.admin.extra.POLICY_SET_RESULT_KEY"; /** * @hide */ public static final String EXTRA_POLICY_UPDATE_REASON_KEY = "android.app.admin.extra.POLICY_UPDATE_REASON_KEY"; public static final String EXTRA_POLICY_UPDATE_RESULT_KEY = "android.app.admin.extra.POLICY_UPDATE_RESULT_KEY"; /** * @hide Loading @@ -180,7 +145,7 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { case ACTION_DEVICE_POLICY_SET_RESULT: Log.i(TAG, "Received ACTION_DEVICE_POLICY_SET_RESULT"); onPolicySetResult(context, getPolicyKey(intent), getPolicyExtraBundle(intent), getTargetUser(intent), getPolicyResult(intent), getFailureReason(intent)); getTargetUser(intent), getPolicyChangedReason(intent)); break; case ACTION_DEVICE_POLICY_CHANGED: Log.i(TAG, "Received ACTION_DEVICE_POLICY_CHANGED"); Loading @@ -202,17 +167,6 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { return intent.getStringExtra(EXTRA_POLICY_KEY); } /** * @hide */ @ResultCode static int getPolicyResult(Intent intent) { if (!intent.hasExtra(EXTRA_POLICY_SET_RESULT_KEY)) { throw new IllegalArgumentException("Result has to be provided."); } return intent.getIntExtra(EXTRA_POLICY_SET_RESULT_KEY, POLICY_SET_RESULT_FAILURE); } /** * @hide */ Loading @@ -222,25 +176,17 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { return bundle == null ? new Bundle() : bundle; } /** * @hide */ @Nullable static PolicyUpdateReason getFailureReason(Intent intent) { if (getPolicyResult(intent) != POLICY_SET_RESULT_FAILURE) { return null; } return getPolicyChangedReason(intent); } /** * @hide */ @NonNull static PolicyUpdateReason getPolicyChangedReason(Intent intent) { static PolicyUpdateResult getPolicyChangedReason(Intent intent) { if (!intent.hasExtra(EXTRA_POLICY_UPDATE_RESULT_KEY)) { throw new IllegalArgumentException("PolicyUpdateResult has to be provided."); } int reasonCode = intent.getIntExtra( EXTRA_POLICY_UPDATE_REASON_KEY, PolicyUpdateReason.REASON_UNKNOWN); return new PolicyUpdateReason(reasonCode); EXTRA_POLICY_UPDATE_RESULT_KEY, PolicyUpdateResult.RESULT_FAILURE_UNKNOWN); return new PolicyUpdateResult(reasonCode); } /** Loading Loading @@ -276,19 +222,18 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { * Each policy will document the required additional params if * needed. * @param targetUser The {@link TargetUser} which this policy relates to. * @param result Indicates whether the policy has been set successfully, * (see {@link PolicyUpdatesReceiver#POLICY_SET_RESULT_SUCCESS} and * {@link PolicyUpdatesReceiver#POLICY_SET_RESULT_FAILURE}). * @param reason Indicates the reason the policy failed to apply, {@code null} if the policy was * applied successfully. * @param policyUpdateResult Indicates whether the policy has been set successfully * ({@link PolicyUpdateResult#RESULT_SUCCESS}) or the reason it * failed to apply (e.g. * {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY}, * etc). */ public void onPolicySetResult( @NonNull Context context, @NonNull String policyKey, @NonNull Bundle additionalPolicyParams, @NonNull TargetUser targetUser, @ResultCode int result, @Nullable PolicyUpdateReason reason) {} @NonNull PolicyUpdateResult policyUpdateResult) {} // TODO(b/260847505): Add javadocs to explain which DPM APIs are supported // TODO(b/261430877): Add javadocs to explain when will this get triggered Loading @@ -310,12 +255,17 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { * Each policy will document the required additional params if * needed. * @param targetUser The {@link TargetUser} which this policy relates to. * @param reason Indicates the reason the policy value has changed. * @param policyUpdateResult Indicates the reason the policy value has changed * (e.g. {@link PolicyUpdateResult#RESULT_SUCCESS} if the policy has * changed to the value set by the admin, * {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY} * if the policy has changed because another admin has set a * conflicting policy, etc) */ public void onPolicyChanged( @NonNull Context context, @NonNull String policyKey, @NonNull Bundle additionalPolicyParams, @NonNull TargetUser targetUser, @NonNull PolicyUpdateReason reason) {} @NonNull PolicyUpdateResult policyUpdateResult) {} } services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +24 −28 Original line number Diff line number Diff line Loading @@ -16,12 +16,10 @@ package com.android.server.devicepolicy; import static android.app.admin.PolicyUpdateReason.REASON_CONFLICTING_ADMIN_POLICY; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_SET_RESULT_KEY; import static android.app.admin.PolicyUpdateResult.RESULT_FAILURE_CONFLICTING_ADMIN_POLICY; import static android.app.admin.PolicyUpdateResult.RESULT_SUCCESS; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_TARGET_USER_ID; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_UPDATE_REASON_KEY; import static android.app.admin.PolicyUpdatesReceiver.POLICY_SET_RESULT_FAILURE; import static android.app.admin.PolicyUpdatesReceiver.POLICY_SET_RESULT_SUCCESS; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_UPDATE_RESULT_KEY; import android.Manifest; import android.annotation.NonNull; Loading Loading @@ -144,9 +142,8 @@ final class DevicePolicyEngine { sendPolicyResultToAdmin( enforcingAdmin, policyDefinition, policyEnforced, // TODO: we're always sending this for now, should properly handle errors. REASON_CONFLICTING_ADMIN_POLICY, policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY, userId); updateDeviceAdminServiceOnPolicyAddLocked(enforcingAdmin); Loading Loading @@ -192,9 +189,8 @@ final class DevicePolicyEngine { sendPolicyResultToAdmin( enforcingAdmin, policyDefinition, policyEnforced, // TODO: we're always sending this for now, should properly handle errors. REASON_CONFLICTING_ADMIN_POLICY, policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY, userId); if (localPolicyState.getPoliciesSetByAdmins().isEmpty()) { Loading @@ -221,7 +217,7 @@ final class DevicePolicyEngine { // Send policy updates to admins who've set it locally sendPolicyChangedToAdmins( localPolicyState.getPoliciesSetByAdmins().keySet(), localPolicyState, enforcingAdmin, policyDefinition, // This policy change is only relevant to a single user, not the global Loading @@ -232,7 +228,7 @@ final class DevicePolicyEngine { if (hasGlobalPolicyLocked(policyDefinition)) { PolicyState<V> globalPolicyState = getGlobalPolicyStateLocked(policyDefinition); sendPolicyChangedToAdmins( globalPolicyState.getPoliciesSetByAdmins().keySet(), globalPolicyState, enforcingAdmin, policyDefinition, userId); Loading Loading @@ -264,13 +260,13 @@ final class DevicePolicyEngine { policyDefinition, enforcingAdmin, value); boolean policyEnforcedGlobally = Objects.equals( globalPolicyState.getCurrentResolvedPolicy(), value); boolean policyEnforced = policyEnforcedGlobally && policyEnforcedOnAllUsers; sendPolicyResultToAdmin( enforcingAdmin, policyDefinition, policyEnforcedGlobally && policyEnforcedOnAllUsers, // TODO: we're always sending this for now, should properly handle errors. REASON_CONFLICTING_ADMIN_POLICY, policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY, UserHandle.USER_ALL); updateDeviceAdminServiceOnPolicyAddLocked(enforcingAdmin); Loading Loading @@ -303,13 +299,13 @@ final class DevicePolicyEngine { policyDefinition, enforcingAdmin, /* value= */ null); // For a removePolicy to be enforced, it means no current policy exists boolean policyEnforcedGlobally = policyState.getCurrentResolvedPolicy() == null; boolean policyEnforced = policyEnforcedGlobally && policyEnforcedOnAllUsers; sendPolicyResultToAdmin( enforcingAdmin, policyDefinition, policyEnforcedGlobally && policyEnforcedOnAllUsers, // TODO: we're always sending this for now, should properly handle errors. REASON_CONFLICTING_ADMIN_POLICY, policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY, UserHandle.USER_ALL); if (policyState.getPoliciesSetByAdmins().isEmpty()) { Loading @@ -334,7 +330,7 @@ final class DevicePolicyEngine { UserHandle.USER_ALL); sendPolicyChangedToAdmins( policyState.getPoliciesSetByAdmins().keySet(), policyState, enforcingAdmin, policyDefinition, UserHandle.USER_ALL); Loading Loading @@ -374,7 +370,7 @@ final class DevicePolicyEngine { enforcePolicy( policyDefinition, localPolicyState.getCurrentResolvedPolicy(), userId); sendPolicyChangedToAdmins( localPolicyState.getPoliciesSetByAdmins().keySet(), localPolicyState, enforcingAdmin, policyDefinition, // Even though this is caused by a global policy change, admins who've set Loading Loading @@ -557,8 +553,7 @@ final class DevicePolicyEngine { } private <V> void sendPolicyResultToAdmin( EnforcingAdmin admin, PolicyDefinition<V> policyDefinition, boolean success, int reason, int userId) { EnforcingAdmin admin, PolicyDefinition<V> policyDefinition, int result, int userId) { Intent intent = new Intent(PolicyUpdatesReceiver.ACTION_DEVICE_POLICY_SET_RESULT); intent.setPackage(admin.getPackageName()); Loading @@ -578,12 +573,9 @@ final class DevicePolicyEngine { EXTRA_POLICY_TARGET_USER_ID, getTargetUser(admin.getUserId(), userId)); extras.putInt( EXTRA_POLICY_SET_RESULT_KEY, success ? POLICY_SET_RESULT_SUCCESS : POLICY_SET_RESULT_FAILURE); EXTRA_POLICY_UPDATE_RESULT_KEY, result); if (!success) { extras.putInt(EXTRA_POLICY_UPDATE_REASON_KEY, reason); } intent.putExtras(extras); maybeSendIntentToAdminReceivers(intent, UserHandle.of(admin.getUserId()), receivers); Loading @@ -591,17 +583,21 @@ final class DevicePolicyEngine { // TODO(b/261430877): Finalise the decision on which admins to send the updates to. private <V> void sendPolicyChangedToAdmins( Set<EnforcingAdmin> admins, PolicyState<V> policyState, EnforcingAdmin callingAdmin, PolicyDefinition<V> policyDefinition, int userId) { for (EnforcingAdmin admin: admins) { for (EnforcingAdmin admin: policyState.getPoliciesSetByAdmins().keySet()) { // We're sending a separate broadcast for the calling admin with the result. if (admin.equals(callingAdmin)) { continue; } int result = Objects.equals( policyState.getPoliciesSetByAdmins().get(admin), policyState.getCurrentResolvedPolicy()) ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY; maybeSendOnPolicyChanged( admin, policyDefinition, REASON_CONFLICTING_ADMIN_POLICY, userId); admin, policyDefinition, result, userId); } } Loading @@ -626,7 +622,7 @@ final class DevicePolicyEngine { extras.putInt( EXTRA_POLICY_TARGET_USER_ID, getTargetUser(admin.getUserId(), userId)); extras.putInt(EXTRA_POLICY_UPDATE_REASON_KEY, reason); extras.putInt(EXTRA_POLICY_UPDATE_RESULT_KEY, reason); intent.putExtras(extras); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); Loading Loading
core/api/current.txt +8 −9 Original line number Diff line number Diff line Loading @@ -8038,25 +8038,24 @@ package android.app.admin { field public static final int PACKAGE_POLICY_BLOCKLIST = 1; // 0x1 } public final class PolicyUpdateReason { ctor public PolicyUpdateReason(int); method public int getReasonCode(); field public static final int REASON_CONFLICTING_ADMIN_POLICY = 0; // 0x0 field public static final int REASON_UNKNOWN = -1; // 0xffffffff public final class PolicyUpdateResult { ctor public PolicyUpdateResult(int); method public int getResultCode(); field public static final int RESULT_FAILURE_CONFLICTING_ADMIN_POLICY = 1; // 0x1 field public static final int RESULT_FAILURE_UNKNOWN = -1; // 0xffffffff field public static final int RESULT_SUCCESS = 0; // 0x0 } public abstract class PolicyUpdatesReceiver extends android.content.BroadcastReceiver { ctor public PolicyUpdatesReceiver(); method public void onPolicyChanged(@NonNull android.content.Context, @NonNull String, @NonNull android.os.Bundle, @NonNull android.app.admin.TargetUser, @NonNull android.app.admin.PolicyUpdateReason); method public void onPolicySetResult(@NonNull android.content.Context, @NonNull String, @NonNull android.os.Bundle, @NonNull android.app.admin.TargetUser, int, @Nullable android.app.admin.PolicyUpdateReason); method public void onPolicyChanged(@NonNull android.content.Context, @NonNull String, @NonNull android.os.Bundle, @NonNull android.app.admin.TargetUser, @NonNull android.app.admin.PolicyUpdateResult); method public void onPolicySetResult(@NonNull android.content.Context, @NonNull String, @NonNull android.os.Bundle, @NonNull android.app.admin.TargetUser, @NonNull android.app.admin.PolicyUpdateResult); method public final void onReceive(android.content.Context, android.content.Intent); field public static final String ACTION_DEVICE_POLICY_CHANGED = "android.app.admin.action.DEVICE_POLICY_CHANGED"; field public static final String ACTION_DEVICE_POLICY_SET_RESULT = "android.app.admin.action.DEVICE_POLICY_SET_RESULT"; field public static final String EXTRA_INTENT_FILTER = "android.app.admin.extra.INTENT_FILTER"; field public static final String EXTRA_PACKAGE_NAME = "android.app.admin.extra.PACKAGE_NAME"; field public static final String EXTRA_PERMISSION_NAME = "android.app.admin.extra.PERMISSION_NAME"; field public static final int POLICY_SET_RESULT_FAILURE = -1; // 0xffffffff field public static final int POLICY_SET_RESULT_SUCCESS = 0; // 0x0 } public final class PreferentialNetworkServiceConfig implements android.os.Parcelable {
core/java/android/app/admin/PolicyUpdateReason.java→core/java/android/app/admin/PolicyUpdateResult.java +82 −0 Original line number Diff line number Diff line Loading @@ -22,53 +22,61 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Class containing the reason a policy (set from {@link DevicePolicyManager}) hasn't been enforced * (passed in to {@link PolicyUpdatesReceiver#onPolicySetResult}) or has changed (passed in to * Class containing the reason for the policy (set from {@link DevicePolicyManager}) update (e.g. * success, failure reasons, etc.). This is passed in to * {@link PolicyUpdatesReceiver#onPolicySetResult}) and * {@link PolicyUpdatesReceiver#onPolicyChanged}). */ public final class PolicyUpdateReason { public final class PolicyUpdateResult { /** * Reason code to indicate that the policy has not been enforced or has changed for an unknown * Result code to indicate that the policy has not been enforced or has changed for an unknown * reason. */ public static final int REASON_UNKNOWN = -1; public static final int RESULT_FAILURE_UNKNOWN = -1; /** * Reason code to indicate that the policy has not been enforced or has changed because another * Result code to indicate that the policy has been changed to the desired value set by * the admin. */ public static final int RESULT_SUCCESS = 0; /** * Result code to indicate that the policy has not been enforced or has changed because another * admin has set a conflicting policy on the device. */ public static final int REASON_CONFLICTING_ADMIN_POLICY = 0; public static final int RESULT_FAILURE_CONFLICTING_ADMIN_POLICY = 1; /** * Reason codes for {@link #getReasonCode()}. * Reason codes for {@link #getResultCode()}. * * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "REASON_" }, value = { REASON_UNKNOWN, REASON_CONFLICTING_ADMIN_POLICY, @IntDef(flag = true, prefix = { "RESULT_" }, value = { RESULT_FAILURE_UNKNOWN, RESULT_SUCCESS, RESULT_FAILURE_CONFLICTING_ADMIN_POLICY }) public @interface ReasonCode {} public @interface ResultCode {} private final int mReasonCode; private final int mResultCode; /** * Constructor for {@code PolicyUpdateReason} that takes in a reason code describing why the * Constructor for {@code PolicyUpdateReason} that takes in a result code describing why the * policy has changed. * * @param reasonCode Describes why the policy has changed. * @param resultCode Describes why the policy has changed. */ public PolicyUpdateReason(@ReasonCode int reasonCode) { this.mReasonCode = reasonCode; public PolicyUpdateResult(@ResultCode int resultCode) { this.mResultCode = resultCode; } /** * Returns reason code for why a policy hasn't been applied or has changed. * Returns result code describing why the policy has changed. */ @ReasonCode public int getReasonCode() { return mReasonCode; @ResultCode public int getResultCode() { return mResultCode; } }
core/java/android/app/admin/PolicyUpdatesReceiver.java +22 −72 Original line number Diff line number Diff line Loading @@ -17,9 +17,7 @@ package android.app.admin; import android.annotation.BroadcastBehavior; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -27,8 +25,6 @@ import android.content.Intent; import android.os.Bundle; import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** Loading @@ -49,31 +45,6 @@ import java.util.Objects; public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { private static String TAG = "PolicyUpdatesReceiver"; /** * Result code passed in to {@link #onPolicySetResult} to indicate that the policy has been * set successfully. */ public static final int POLICY_SET_RESULT_SUCCESS = 0; /** * Result code passed in to {@link #onPolicySetResult} to indicate that the policy has NOT been * set, a {@link PolicyUpdateReason} will be passed in to {@link #onPolicySetResult} to indicate * the reason. */ public static final int POLICY_SET_RESULT_FAILURE = -1; /** * Result codes passed in to {@link #onPolicySetResult}. * * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "POLICY_SET_RESULT_" }, value = { POLICY_SET_RESULT_SUCCESS, POLICY_SET_RESULT_FAILURE, }) public @interface ResultCode {} /** * Action for a broadcast sent to admins to communicate back the result of setting a policy in * {@link DevicePolicyManager}. Loading Loading @@ -152,14 +123,8 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { /** * @hide */ public static final String EXTRA_POLICY_SET_RESULT_KEY = "android.app.admin.extra.POLICY_SET_RESULT_KEY"; /** * @hide */ public static final String EXTRA_POLICY_UPDATE_REASON_KEY = "android.app.admin.extra.POLICY_UPDATE_REASON_KEY"; public static final String EXTRA_POLICY_UPDATE_RESULT_KEY = "android.app.admin.extra.POLICY_UPDATE_RESULT_KEY"; /** * @hide Loading @@ -180,7 +145,7 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { case ACTION_DEVICE_POLICY_SET_RESULT: Log.i(TAG, "Received ACTION_DEVICE_POLICY_SET_RESULT"); onPolicySetResult(context, getPolicyKey(intent), getPolicyExtraBundle(intent), getTargetUser(intent), getPolicyResult(intent), getFailureReason(intent)); getTargetUser(intent), getPolicyChangedReason(intent)); break; case ACTION_DEVICE_POLICY_CHANGED: Log.i(TAG, "Received ACTION_DEVICE_POLICY_CHANGED"); Loading @@ -202,17 +167,6 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { return intent.getStringExtra(EXTRA_POLICY_KEY); } /** * @hide */ @ResultCode static int getPolicyResult(Intent intent) { if (!intent.hasExtra(EXTRA_POLICY_SET_RESULT_KEY)) { throw new IllegalArgumentException("Result has to be provided."); } return intent.getIntExtra(EXTRA_POLICY_SET_RESULT_KEY, POLICY_SET_RESULT_FAILURE); } /** * @hide */ Loading @@ -222,25 +176,17 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { return bundle == null ? new Bundle() : bundle; } /** * @hide */ @Nullable static PolicyUpdateReason getFailureReason(Intent intent) { if (getPolicyResult(intent) != POLICY_SET_RESULT_FAILURE) { return null; } return getPolicyChangedReason(intent); } /** * @hide */ @NonNull static PolicyUpdateReason getPolicyChangedReason(Intent intent) { static PolicyUpdateResult getPolicyChangedReason(Intent intent) { if (!intent.hasExtra(EXTRA_POLICY_UPDATE_RESULT_KEY)) { throw new IllegalArgumentException("PolicyUpdateResult has to be provided."); } int reasonCode = intent.getIntExtra( EXTRA_POLICY_UPDATE_REASON_KEY, PolicyUpdateReason.REASON_UNKNOWN); return new PolicyUpdateReason(reasonCode); EXTRA_POLICY_UPDATE_RESULT_KEY, PolicyUpdateResult.RESULT_FAILURE_UNKNOWN); return new PolicyUpdateResult(reasonCode); } /** Loading Loading @@ -276,19 +222,18 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { * Each policy will document the required additional params if * needed. * @param targetUser The {@link TargetUser} which this policy relates to. * @param result Indicates whether the policy has been set successfully, * (see {@link PolicyUpdatesReceiver#POLICY_SET_RESULT_SUCCESS} and * {@link PolicyUpdatesReceiver#POLICY_SET_RESULT_FAILURE}). * @param reason Indicates the reason the policy failed to apply, {@code null} if the policy was * applied successfully. * @param policyUpdateResult Indicates whether the policy has been set successfully * ({@link PolicyUpdateResult#RESULT_SUCCESS}) or the reason it * failed to apply (e.g. * {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY}, * etc). */ public void onPolicySetResult( @NonNull Context context, @NonNull String policyKey, @NonNull Bundle additionalPolicyParams, @NonNull TargetUser targetUser, @ResultCode int result, @Nullable PolicyUpdateReason reason) {} @NonNull PolicyUpdateResult policyUpdateResult) {} // TODO(b/260847505): Add javadocs to explain which DPM APIs are supported // TODO(b/261430877): Add javadocs to explain when will this get triggered Loading @@ -310,12 +255,17 @@ public abstract class PolicyUpdatesReceiver extends BroadcastReceiver { * Each policy will document the required additional params if * needed. * @param targetUser The {@link TargetUser} which this policy relates to. * @param reason Indicates the reason the policy value has changed. * @param policyUpdateResult Indicates the reason the policy value has changed * (e.g. {@link PolicyUpdateResult#RESULT_SUCCESS} if the policy has * changed to the value set by the admin, * {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY} * if the policy has changed because another admin has set a * conflicting policy, etc) */ public void onPolicyChanged( @NonNull Context context, @NonNull String policyKey, @NonNull Bundle additionalPolicyParams, @NonNull TargetUser targetUser, @NonNull PolicyUpdateReason reason) {} @NonNull PolicyUpdateResult policyUpdateResult) {} }
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +24 −28 Original line number Diff line number Diff line Loading @@ -16,12 +16,10 @@ package com.android.server.devicepolicy; import static android.app.admin.PolicyUpdateReason.REASON_CONFLICTING_ADMIN_POLICY; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_SET_RESULT_KEY; import static android.app.admin.PolicyUpdateResult.RESULT_FAILURE_CONFLICTING_ADMIN_POLICY; import static android.app.admin.PolicyUpdateResult.RESULT_SUCCESS; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_TARGET_USER_ID; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_UPDATE_REASON_KEY; import static android.app.admin.PolicyUpdatesReceiver.POLICY_SET_RESULT_FAILURE; import static android.app.admin.PolicyUpdatesReceiver.POLICY_SET_RESULT_SUCCESS; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_UPDATE_RESULT_KEY; import android.Manifest; import android.annotation.NonNull; Loading Loading @@ -144,9 +142,8 @@ final class DevicePolicyEngine { sendPolicyResultToAdmin( enforcingAdmin, policyDefinition, policyEnforced, // TODO: we're always sending this for now, should properly handle errors. REASON_CONFLICTING_ADMIN_POLICY, policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY, userId); updateDeviceAdminServiceOnPolicyAddLocked(enforcingAdmin); Loading Loading @@ -192,9 +189,8 @@ final class DevicePolicyEngine { sendPolicyResultToAdmin( enforcingAdmin, policyDefinition, policyEnforced, // TODO: we're always sending this for now, should properly handle errors. REASON_CONFLICTING_ADMIN_POLICY, policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY, userId); if (localPolicyState.getPoliciesSetByAdmins().isEmpty()) { Loading @@ -221,7 +217,7 @@ final class DevicePolicyEngine { // Send policy updates to admins who've set it locally sendPolicyChangedToAdmins( localPolicyState.getPoliciesSetByAdmins().keySet(), localPolicyState, enforcingAdmin, policyDefinition, // This policy change is only relevant to a single user, not the global Loading @@ -232,7 +228,7 @@ final class DevicePolicyEngine { if (hasGlobalPolicyLocked(policyDefinition)) { PolicyState<V> globalPolicyState = getGlobalPolicyStateLocked(policyDefinition); sendPolicyChangedToAdmins( globalPolicyState.getPoliciesSetByAdmins().keySet(), globalPolicyState, enforcingAdmin, policyDefinition, userId); Loading Loading @@ -264,13 +260,13 @@ final class DevicePolicyEngine { policyDefinition, enforcingAdmin, value); boolean policyEnforcedGlobally = Objects.equals( globalPolicyState.getCurrentResolvedPolicy(), value); boolean policyEnforced = policyEnforcedGlobally && policyEnforcedOnAllUsers; sendPolicyResultToAdmin( enforcingAdmin, policyDefinition, policyEnforcedGlobally && policyEnforcedOnAllUsers, // TODO: we're always sending this for now, should properly handle errors. REASON_CONFLICTING_ADMIN_POLICY, policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY, UserHandle.USER_ALL); updateDeviceAdminServiceOnPolicyAddLocked(enforcingAdmin); Loading Loading @@ -303,13 +299,13 @@ final class DevicePolicyEngine { policyDefinition, enforcingAdmin, /* value= */ null); // For a removePolicy to be enforced, it means no current policy exists boolean policyEnforcedGlobally = policyState.getCurrentResolvedPolicy() == null; boolean policyEnforced = policyEnforcedGlobally && policyEnforcedOnAllUsers; sendPolicyResultToAdmin( enforcingAdmin, policyDefinition, policyEnforcedGlobally && policyEnforcedOnAllUsers, // TODO: we're always sending this for now, should properly handle errors. REASON_CONFLICTING_ADMIN_POLICY, policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY, UserHandle.USER_ALL); if (policyState.getPoliciesSetByAdmins().isEmpty()) { Loading @@ -334,7 +330,7 @@ final class DevicePolicyEngine { UserHandle.USER_ALL); sendPolicyChangedToAdmins( policyState.getPoliciesSetByAdmins().keySet(), policyState, enforcingAdmin, policyDefinition, UserHandle.USER_ALL); Loading Loading @@ -374,7 +370,7 @@ final class DevicePolicyEngine { enforcePolicy( policyDefinition, localPolicyState.getCurrentResolvedPolicy(), userId); sendPolicyChangedToAdmins( localPolicyState.getPoliciesSetByAdmins().keySet(), localPolicyState, enforcingAdmin, policyDefinition, // Even though this is caused by a global policy change, admins who've set Loading Loading @@ -557,8 +553,7 @@ final class DevicePolicyEngine { } private <V> void sendPolicyResultToAdmin( EnforcingAdmin admin, PolicyDefinition<V> policyDefinition, boolean success, int reason, int userId) { EnforcingAdmin admin, PolicyDefinition<V> policyDefinition, int result, int userId) { Intent intent = new Intent(PolicyUpdatesReceiver.ACTION_DEVICE_POLICY_SET_RESULT); intent.setPackage(admin.getPackageName()); Loading @@ -578,12 +573,9 @@ final class DevicePolicyEngine { EXTRA_POLICY_TARGET_USER_ID, getTargetUser(admin.getUserId(), userId)); extras.putInt( EXTRA_POLICY_SET_RESULT_KEY, success ? POLICY_SET_RESULT_SUCCESS : POLICY_SET_RESULT_FAILURE); EXTRA_POLICY_UPDATE_RESULT_KEY, result); if (!success) { extras.putInt(EXTRA_POLICY_UPDATE_REASON_KEY, reason); } intent.putExtras(extras); maybeSendIntentToAdminReceivers(intent, UserHandle.of(admin.getUserId()), receivers); Loading @@ -591,17 +583,21 @@ final class DevicePolicyEngine { // TODO(b/261430877): Finalise the decision on which admins to send the updates to. private <V> void sendPolicyChangedToAdmins( Set<EnforcingAdmin> admins, PolicyState<V> policyState, EnforcingAdmin callingAdmin, PolicyDefinition<V> policyDefinition, int userId) { for (EnforcingAdmin admin: admins) { for (EnforcingAdmin admin: policyState.getPoliciesSetByAdmins().keySet()) { // We're sending a separate broadcast for the calling admin with the result. if (admin.equals(callingAdmin)) { continue; } int result = Objects.equals( policyState.getPoliciesSetByAdmins().get(admin), policyState.getCurrentResolvedPolicy()) ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY; maybeSendOnPolicyChanged( admin, policyDefinition, REASON_CONFLICTING_ADMIN_POLICY, userId); admin, policyDefinition, result, userId); } } Loading @@ -626,7 +622,7 @@ final class DevicePolicyEngine { extras.putInt( EXTRA_POLICY_TARGET_USER_ID, getTargetUser(admin.getUserId(), userId)); extras.putInt(EXTRA_POLICY_UPDATE_REASON_KEY, reason); extras.putInt(EXTRA_POLICY_UPDATE_RESULT_KEY, reason); intent.putExtras(extras); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); Loading