diff options
Diffstat (limited to 'core/java')
5 files changed, 312 insertions, 255 deletions
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java index fe8e4d7b1bb2..6f07dd7a24e8 100644 --- a/core/java/android/content/pm/ResolveInfo.java +++ b/core/java/android/content/pm/ResolveInfo.java @@ -19,6 +19,7 @@ package android.content.pm; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; +import android.content.Intent; import android.content.IntentFilter; import android.graphics.drawable.Drawable; import android.os.Build; @@ -183,6 +184,17 @@ public class ResolveInfo implements Parcelable { @SystemApi public boolean handleAllWebDataURI; + /** + * Whether the resolved {@link IntentFilter} declares {@link Intent#CATEGORY_BROWSABLE} and is + * thus allowed to automatically resolve an {@link Intent} as it's assumed the action is safe + * for the user. + * + * Note that the above doesn't apply when this is the only result is returned in the candidate + * set, as the system will not prompt before opening the result. It only applies when there are + * multiple candidates. + */ + private final boolean mAutoResolutionAllowed; + /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ComponentInfo getComponentInfo() { @@ -364,8 +376,26 @@ public class ResolveInfo implements Parcelable { && INTENT_FORWARDER_ACTIVITY.equals(activityInfo.targetActivity); } + /** + * @see #mAutoResolutionAllowed + * @hide + */ + public boolean isAutoResolutionAllowed() { + return mAutoResolutionAllowed; + } + public ResolveInfo() { targetUserId = UserHandle.USER_CURRENT; + + // It's safer to assume that an unaware caller that constructs a ResolveInfo doesn't + // accidentally mark a result as auto resolveable. + mAutoResolutionAllowed = false; + } + + /** @hide */ + public ResolveInfo(boolean autoResolutionAllowed) { + targetUserId = UserHandle.USER_CURRENT; + mAutoResolutionAllowed = autoResolutionAllowed; } public ResolveInfo(ResolveInfo orig) { @@ -386,6 +416,7 @@ public class ResolveInfo implements Parcelable { system = orig.system; targetUserId = orig.targetUserId; handleAllWebDataURI = orig.handleAllWebDataURI; + mAutoResolutionAllowed = orig.mAutoResolutionAllowed; isInstantAppAvailable = orig.isInstantAppAvailable; } @@ -450,6 +481,7 @@ public class ResolveInfo implements Parcelable { dest.writeInt(noResourceId ? 1 : 0); dest.writeInt(iconResourceId); dest.writeInt(handleAllWebDataURI ? 1 : 0); + dest.writeInt(mAutoResolutionAllowed ? 1 : 0); dest.writeInt(isInstantAppAvailable ? 1 : 0); } @@ -498,6 +530,7 @@ public class ResolveInfo implements Parcelable { noResourceId = source.readInt() != 0; iconResourceId = source.readInt(); handleAllWebDataURI = source.readInt() != 0; + mAutoResolutionAllowed = source.readInt() != 0; isInstantAppAvailable = source.readInt() != 0; } diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java b/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java index 7c335b1d26dd..62277ef671e3 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java @@ -43,9 +43,50 @@ import java.util.UUID; */ @SystemApi @DataClass(genAidl = true, genHiddenConstructor = true, genParcelable = true, genToString = true, - genEqualsHashCode = true) + genEqualsHashCode = true, genHiddenConstDefs = true) public final class DomainVerificationInfo implements Parcelable { + // Implementation note: the following states are OUTPUT only. Any value that is synonymous with + // a value in DomainVerificationState must be the EXACT same integer, so that state + // transformation does not have to occur when sending input into the system, assuming that the + // system only accepts those synonymous values. The public API values declared here are only + // used when exiting the system server to prepare this data object for consumption by the + // verification agent. These constants should only be referenced inside public API classes. + // The server must use DomainVerificationState. + + /** + * No response has been recorded by either the system or any verification agent. + */ + public static final int STATE_NO_RESPONSE = DomainVerificationState.STATE_NO_RESPONSE; + + /** + * The domain has been explicitly verified. + */ + public static final int STATE_SUCCESS = DomainVerificationState.STATE_SUCCESS; + + /** + * Indicates the host cannot be modified by the verification agent. + */ + public static final int STATE_UNMODIFIABLE = 2; + + /** + * Indicates the host can be modified by the verification agent and is not considered verified. + */ + public static final int STATE_MODIFIABLE_UNVERIFIED = 3; + + /** + * Indicates the host can be modified by the verification agent and is considered verified. + */ + public static final int STATE_MODIFIABLE_VERIFIED = 4; + + /** + * The first available custom response code. This and any greater integer, along with {@link + * #STATE_SUCCESS} are the only values settable by the verification agent. All custom values + * will be treated as if the domain is unverified. + */ + public static final int STATE_FIRST_VERIFIER_DEFINED = + DomainVerificationState.STATE_FIRST_VERIFIER_DEFINED; + /** * A domain verification ID for use in later API calls. This represents the snapshot of the * domains for a package on device, and will be invalidated whenever the package changes. @@ -74,16 +115,12 @@ public final class DomainVerificationInfo implements Parcelable { /** * Map of host names to their current state. State is an integer, which defaults to {@link - * DomainVerificationManager#STATE_NO_RESPONSE}. State can be modified by the domain - * verification agent (the intended consumer of this API), which can be equal to {@link - * DomainVerificationManager#STATE_SUCCESS} when verified, or equal to or greater than {@link - * DomainVerificationManager#STATE_FIRST_VERIFIER_DEFINED} for any unsuccessful response. + * #STATE_NO_RESPONSE}. State can be modified by the domain verification agent (the intended + * consumer of this API), which can be equal to {@link #STATE_SUCCESS} when verified, or equal + * to or greater than {@link #STATE_FIRST_VERIFIER_DEFINED} for any unsuccessful response. * <p> - * Any value non-inclusive between those 2 values are reserved for use by the system. The domain - * verification agent may be able to act on these reserved values, and this ability can be - * queried using {@link DomainVerificationManager#isStateModifiable(int)}. It is expected that - * the agent attempt to verify all domains that it can modify the state of, even if it does not - * understand the meaning of those values. + * Hosts which cannot be edited will be assigned {@link #STATE_UNMODIFIABLE}. It is expected + * that the agent attempt to verify all domains that it can modify the state of. */ @NonNull private final Map<String, Integer> mHostToStateMap; @@ -112,6 +149,39 @@ public final class DomainVerificationInfo implements Parcelable { //@formatter:off + /** @hide */ + @android.annotation.IntDef(prefix = "STATE_", value = { + STATE_NO_RESPONSE, + STATE_SUCCESS, + STATE_UNMODIFIABLE, + STATE_MODIFIABLE_UNVERIFIED, + STATE_MODIFIABLE_VERIFIED, + STATE_FIRST_VERIFIER_DEFINED + }) + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) + @DataClass.Generated.Member + public @interface State {} + + /** @hide */ + @DataClass.Generated.Member + public static String stateToString(@State int value) { + switch (value) { + case STATE_NO_RESPONSE: + return "STATE_NO_RESPONSE"; + case STATE_SUCCESS: + return "STATE_SUCCESS"; + case STATE_UNMODIFIABLE: + return "STATE_UNMODIFIABLE"; + case STATE_MODIFIABLE_UNVERIFIED: + return "STATE_MODIFIABLE_UNVERIFIED"; + case STATE_MODIFIABLE_VERIFIED: + return "STATE_MODIFIABLE_VERIFIED"; + case STATE_FIRST_VERIFIER_DEFINED: + return "STATE_FIRST_VERIFIER_DEFINED"; + default: return Integer.toHexString(value); + } + } + /** * Creates a new DomainVerificationInfo. * @@ -134,16 +204,12 @@ public final class DomainVerificationInfo implements Parcelable { * The package name that this data corresponds to. * @param hostToStateMap * Map of host names to their current state. State is an integer, which defaults to {@link - * DomainVerificationManager#STATE_NO_RESPONSE}. State can be modified by the domain - * verification agent (the intended consumer of this API), which can be equal to {@link - * DomainVerificationManager#STATE_SUCCESS} when verified, or equal to or greater than {@link - * DomainVerificationManager#STATE_FIRST_VERIFIER_DEFINED} for any unsuccessful response. + * #STATE_NO_RESPONSE}. State can be modified by the domain verification agent (the intended + * consumer of this API), which can be equal to {@link #STATE_SUCCESS} when verified, or equal + * to or greater than {@link #STATE_FIRST_VERIFIER_DEFINED} for any unsuccessful response. * <p> - * Any value non-inclusive between those 2 values are reserved for use by the system. The domain - * verification agent may be able to act on these reserved values, and this ability can be - * queried using {@link DomainVerificationManager#isStateModifiable(int)}. It is expected that - * the agent attempt to verify all domains that it can modify the state of, even if it does not - * understand the meaning of those values. + * Hosts which cannot be edited will be assigned {@link #STATE_UNMODIFIABLE}. It is expected + * that the agent attempt to verify all domains that it can modify the state of. * @hide */ @DataClass.Generated.Member @@ -195,16 +261,12 @@ public final class DomainVerificationInfo implements Parcelable { /** * Map of host names to their current state. State is an integer, which defaults to {@link - * DomainVerificationManager#STATE_NO_RESPONSE}. State can be modified by the domain - * verification agent (the intended consumer of this API), which can be equal to {@link - * DomainVerificationManager#STATE_SUCCESS} when verified, or equal to or greater than {@link - * DomainVerificationManager#STATE_FIRST_VERIFIER_DEFINED} for any unsuccessful response. + * #STATE_NO_RESPONSE}. State can be modified by the domain verification agent (the intended + * consumer of this API), which can be equal to {@link #STATE_SUCCESS} when verified, or equal + * to or greater than {@link #STATE_FIRST_VERIFIER_DEFINED} for any unsuccessful response. * <p> - * Any value non-inclusive between those 2 values are reserved for use by the system. The domain - * verification agent may be able to act on these reserved values, and this ability can be - * queried using {@link DomainVerificationManager#isStateModifiable(int)}. It is expected that - * the agent attempt to verify all domains that it can modify the state of, even if it does not - * understand the meaning of those values. + * Hosts which cannot be edited will be assigned {@link #STATE_UNMODIFIABLE}. It is expected + * that the agent attempt to verify all domains that it can modify the state of. */ @DataClass.Generated.Member public @NonNull Map<String,Integer> getHostToStateMap() { @@ -320,10 +382,10 @@ public final class DomainVerificationInfo implements Parcelable { }; @DataClass.Generated( - time = 1614721812023L, + time = 1615317187669L, codegenVersion = "1.0.22", sourceFile = "frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java", - inputSignatures = "private final @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForUUID.class) java.util.UUID mIdentifier\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.Integer> mHostToStateMap\nprivate void parcelHostToStateMap(android.os.Parcel,int)\nprivate java.util.Map<java.lang.String,java.lang.Integer> unparcelHostToStateMap(android.os.Parcel)\nclass DomainVerificationInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genAidl=true, genHiddenConstructor=true, genParcelable=true, genToString=true, genEqualsHashCode=true)") + inputSignatures = "public static final int STATE_NO_RESPONSE\npublic static final int STATE_SUCCESS\npublic static final int STATE_UNMODIFIABLE\npublic static final int STATE_MODIFIABLE_UNVERIFIED\npublic static final int STATE_MODIFIABLE_VERIFIED\npublic static final int STATE_FIRST_VERIFIER_DEFINED\nprivate final @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForUUID.class) java.util.UUID mIdentifier\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.Integer> mHostToStateMap\nprivate void parcelHostToStateMap(android.os.Parcel,int)\nprivate java.util.Map<java.lang.String,java.lang.Integer> unparcelHostToStateMap(android.os.Parcel)\nclass DomainVerificationInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genAidl=true, genHiddenConstructor=true, genParcelable=true, genToString=true, genEqualsHashCode=true, genHiddenConstDefs=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationManager.java b/core/java/android/content/pm/verify/domain/DomainVerificationManager.java index f7c81bcffda3..55e19f2727bf 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationManager.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationManager.java @@ -60,154 +60,97 @@ public final class DomainVerificationManager { "android.content.pm.verify.domain.extra.VERIFICATION_REQUEST"; /** - * No response has been recorded by either the system or any verification agent. + * Default return code for when a method has succeeded. * * @hide */ @SystemApi - public static final int STATE_NO_RESPONSE = DomainVerificationState.STATE_NO_RESPONSE; + public static final int STATUS_OK = 0; /** - * The verification agent has explicitly verified the domain at some point. + * The provided domain set ID was invalid, probably due to the package being updated between + * the initial request that provided the ID and the method call that used it. This usually + * means the work being processed by the verification agent is outdated and a new request + * should be scheduled, which should already be in progress as part of the + * {@link Intent#ACTION_DOMAINS_NEED_VERIFICATION} broadcast. * * @hide */ @SystemApi - public static final int STATE_SUCCESS = DomainVerificationState.STATE_SUCCESS; + public static final int ERROR_DOMAIN_SET_ID_INVALID = 1; /** - * The first available custom response code. This and any greater integer, along with {@link - * #STATE_SUCCESS} are the only values settable by the verification agent. All values will be - * treated as if the domain is unverified. + * The provided domain set ID was null. This is a developer error. * * @hide */ @SystemApi - public static final int STATE_FIRST_VERIFIER_DEFINED = - DomainVerificationState.STATE_FIRST_VERIFIER_DEFINED; + public static final int ERROR_DOMAIN_SET_ID_NULL = 2; /** + * The provided set of domains was null or empty. This is a developer error. + * * @hide */ - @NonNull - public static String stateToDebugString(@DomainVerificationState.State int state) { - switch (state) { - case DomainVerificationState.STATE_NO_RESPONSE: - return "none"; - case DomainVerificationState.STATE_SUCCESS: - return "verified"; - case DomainVerificationState.STATE_APPROVED: - return "approved"; - case DomainVerificationState.STATE_DENIED: - return "denied"; - case DomainVerificationState.STATE_MIGRATED: - return "migrated"; - case DomainVerificationState.STATE_RESTORED: - return "restored"; - case DomainVerificationState.STATE_LEGACY_FAILURE: - return "legacy_failure"; - case DomainVerificationState.STATE_SYS_CONFIG: - return "system_configured"; - default: - return String.valueOf(state); - } - } + @SystemApi + public static final int ERROR_DOMAIN_SET_NULL_OR_EMPTY = 3; /** - * Checks if a state considers the corresponding domain to be successfully verified. The domain - * verification agent may use this to determine whether or not to re-verify a domain. + * The provided set of domains contains a domain not declared by the target package. This + * usually means the work being processed by the verification agent is outdated and a new + * request should be scheduled, which should already be in progress as part of the + * {@link Intent#ACTION_DOMAINS_NEED_VERIFICATION} broadcast. * * @hide */ @SystemApi - public static boolean isStateVerified(@DomainVerificationState.State int state) { - switch (state) { - case DomainVerificationState.STATE_SUCCESS: - case DomainVerificationState.STATE_APPROVED: - case DomainVerificationState.STATE_MIGRATED: - case DomainVerificationState.STATE_RESTORED: - case DomainVerificationState.STATE_SYS_CONFIG: - return true; - case DomainVerificationState.STATE_NO_RESPONSE: - case DomainVerificationState.STATE_DENIED: - case DomainVerificationState.STATE_LEGACY_FAILURE: - default: - return false; - } - } + public static final int ERROR_UNKNOWN_DOMAIN = 4; /** - * Checks if a state is modifiable by the domain verification agent. This is useful as the - * platform may add new state codes in newer versions, and older verification agents can use - * this method to determine if a state can be changed without having to be aware of what the new - * state means. + * The system was unable to select the domain for approval. This indicates another application + * has been granted a higher approval, usually through domain verification, and the target + * package is unable to override it. * * @hide */ @SystemApi - public static boolean isStateModifiable(@DomainVerificationState.State int state) { - switch (state) { - case DomainVerificationState.STATE_NO_RESPONSE: - case DomainVerificationState.STATE_SUCCESS: - case DomainVerificationState.STATE_MIGRATED: - case DomainVerificationState.STATE_RESTORED: - case DomainVerificationState.STATE_LEGACY_FAILURE: - return true; - case DomainVerificationState.STATE_APPROVED: - case DomainVerificationState.STATE_DENIED: - case DomainVerificationState.STATE_SYS_CONFIG: - return false; - default: - return state >= DomainVerificationState.STATE_FIRST_VERIFIER_DEFINED; - } - } + public static final int ERROR_UNABLE_TO_APPROVE = 5; /** - * For determine re-verify policy. This is hidden from the domain verification agent so that no - * behavior is made based on the result. + * The provided state code is incorrect. The domain verification agent is only allowed to + * assign {@link DomainVerificationInfo#STATE_SUCCESS} or error codes equal to or greater than + * {@link DomainVerificationInfo#STATE_FIRST_VERIFIER_DEFINED}. * * @hide */ - public static boolean isStateDefault(@DomainVerificationState.State int state) { - switch (state) { - case DomainVerificationState.STATE_NO_RESPONSE: - case DomainVerificationState.STATE_MIGRATED: - case DomainVerificationState.STATE_RESTORED: - return true; - case DomainVerificationState.STATE_SUCCESS: - case DomainVerificationState.STATE_APPROVED: - case DomainVerificationState.STATE_DENIED: - case DomainVerificationState.STATE_LEGACY_FAILURE: - case DomainVerificationState.STATE_SYS_CONFIG: - default: - return false; - } - } + @SystemApi + public static final int ERROR_INVALID_STATE_CODE = 6; /** + * Used to communicate through {@link ServiceSpecificException}. Should not be exposed as API. + * * @hide */ - public static final int ERROR_INVALID_DOMAIN_SET = 1; - /** - * @hide - */ - public static final int ERROR_NAME_NOT_FOUND = 2; + public static final int INTERNAL_ERROR_NAME_NOT_FOUND = 1; /** * @hide */ @IntDef(prefix = {"ERROR_"}, value = { - ERROR_INVALID_DOMAIN_SET, - ERROR_NAME_NOT_FOUND, + ERROR_DOMAIN_SET_ID_INVALID, + ERROR_DOMAIN_SET_ID_NULL, + ERROR_DOMAIN_SET_NULL_OR_EMPTY, + ERROR_UNKNOWN_DOMAIN, + ERROR_UNABLE_TO_APPROVE, + ERROR_INVALID_STATE_CODE }) - private @interface Error { + public @interface Error { } private final Context mContext; private final IDomainVerificationManager mDomainVerificationManager; - /** * System service to access the domain verification APIs. * <p> @@ -289,27 +232,24 @@ public final class DomainVerificationManager { * @param domainSetId See {@link DomainVerificationInfo#getIdentifier()}. * @param domains List of host names to change the state of. * @param state See {@link DomainVerificationInfo#getHostToStateMap()}. - * @throws IllegalArgumentException If the ID is invalidated or the {@param domains} are - * invalid. This usually means the work being processed by the - * verification agent is outdated and a new request should be - * scheduled, if one has not already been done as part of the - * {@link Intent#ACTION_DOMAINS_NEED_VERIFICATION} broadcast. * @throws NameNotFoundException If the ID is known to be good, but the package is * unavailable. This may be because the package is installed on * a volume that is no longer mounted. This error is * unrecoverable until the package is available again, and * should not be re-tried except on a time scheduled basis. + * @return error code or {@link #STATUS_OK} if successful + * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) - public void setDomainVerificationStatus(@NonNull UUID domainSetId, @NonNull Set<String> domains, - @DomainVerificationState.State int state) throws NameNotFoundException { + public int setDomainVerificationStatus(@NonNull UUID domainSetId, @NonNull Set<String> domains, + int state) throws NameNotFoundException { try { - mDomainVerificationManager.setDomainVerificationStatus(domainSetId.toString(), + return mDomainVerificationManager.setDomainVerificationStatus(domainSetId.toString(), new DomainSet(domains), state); } catch (Exception e) { - Exception converted = rethrow(e, domainSetId); + Exception converted = rethrow(e, null); if (converted instanceof NameNotFoundException) { throw (NameNotFoundException) converted; } else if (converted instanceof RuntimeException) { @@ -338,7 +278,7 @@ public final class DomainVerificationManager { mDomainVerificationManager.setDomainVerificationLinkHandlingAllowed(packageName, allowed, mContext.getUserId()); } catch (Exception e) { - Exception converted = rethrow(e, packageName); + Exception converted = rethrow(e, null); if (converted instanceof NameNotFoundException) { throw (NameNotFoundException) converted; } else if (converted instanceof RuntimeException) { @@ -372,24 +312,24 @@ public final class DomainVerificationManager { * @param domainSetId See {@link DomainVerificationInfo#getIdentifier()}. * @param domains The domains to toggle the state of. * @param enabled Whether or not the app should automatically open the domains specified. - * @throws IllegalArgumentException If the ID is invalidated or the {@param domains} are - * invalid. * @throws NameNotFoundException If the ID is known to be good, but the package is * unavailable. This may be because the package is installed on * a volume that is no longer mounted. This error is * unrecoverable until the package is available again, and * should not be re-tried except on a time scheduled basis. + * @return error code or {@link #STATUS_OK} if successful + * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) - public void setDomainVerificationUserSelection(@NonNull UUID domainSetId, + public int setDomainVerificationUserSelection(@NonNull UUID domainSetId, @NonNull Set<String> domains, boolean enabled) throws NameNotFoundException { try { - mDomainVerificationManager.setDomainVerificationUserSelection(domainSetId.toString(), - new DomainSet(domains), enabled, mContext.getUserId()); + return mDomainVerificationManager.setDomainVerificationUserSelection( + domainSetId.toString(), new DomainSet(domains), enabled, mContext.getUserId()); } catch (Exception e) { - Exception converted = rethrow(e, domainSetId); + Exception converted = rethrow(e, null); if (converted instanceof NameNotFoundException) { throw (NameNotFoundException) converted; } else if (converted instanceof RuntimeException) { @@ -447,123 +387,22 @@ public final class DomainVerificationManager { } } - private Exception rethrow(Exception exception, @Nullable UUID domainSetId) { - return rethrow(exception, domainSetId, null); - } - private Exception rethrow(Exception exception, @Nullable String packageName) { - return rethrow(exception, null, packageName); - } - - private Exception rethrow(Exception exception, @Nullable UUID domainSetId, - @Nullable String packageName) { if (exception instanceof ServiceSpecificException) { - int packedErrorCode = ((ServiceSpecificException) exception).errorCode; + int serviceSpecificErrorCode = ((ServiceSpecificException) exception).errorCode; if (packageName == null) { packageName = exception.getMessage(); } - @Error int managerErrorCode = packedErrorCode & 0xFFFF; - switch (managerErrorCode) { - case ERROR_INVALID_DOMAIN_SET: - int errorSpecificCode = packedErrorCode >> 16; - return new IllegalArgumentException(InvalidDomainSetException.buildMessage( - domainSetId, packageName, errorSpecificCode)); - case ERROR_NAME_NOT_FOUND: - return new NameNotFoundException(packageName); - default: - return exception; + if (serviceSpecificErrorCode == INTERNAL_ERROR_NAME_NOT_FOUND) { + return new NameNotFoundException(packageName); } + + return exception; } else if (exception instanceof RemoteException) { return ((RemoteException) exception).rethrowFromSystemServer(); } else { return exception; } } - - /** - * Thrown if a {@link DomainVerificationInfo#getIdentifier()}} or an associated set of domains - * provided by the caller is no longer valid. This may be recoverable, and the caller should - * re-query the package name associated with the ID using - * {@link #getDomainVerificationInfo(String)} - * in order to check. If that also fails, then the package is no longer known to the device and - * thus all pending work for it should be dropped. - * - * @hide - */ - public static class InvalidDomainSetException extends IllegalArgumentException { - - public static final int REASON_ID_NULL = 1; - public static final int REASON_ID_INVALID = 2; - public static final int REASON_SET_NULL_OR_EMPTY = 3; - public static final int REASON_UNKNOWN_DOMAIN = 4; - public static final int REASON_UNABLE_TO_APPROVE = 5; - - /** - * @hide - */ - @IntDef({ - REASON_ID_NULL, - REASON_ID_INVALID, - REASON_SET_NULL_OR_EMPTY, - REASON_UNKNOWN_DOMAIN, - REASON_UNABLE_TO_APPROVE - }) - public @interface Reason { - } - - public static String buildMessage(@Nullable UUID domainSetId, @Nullable String packageName, - @Reason int reason) { - switch (reason) { - case REASON_ID_NULL: - return "Domain set ID cannot be null"; - case REASON_ID_INVALID: - return "Domain set ID " + domainSetId + " has been invalidated"; - case REASON_SET_NULL_OR_EMPTY: - return "Domain set cannot be null or empty"; - case REASON_UNKNOWN_DOMAIN: - return "Domain set contains value that was not declared by the target package " - + packageName; - case REASON_UNABLE_TO_APPROVE: - return "Domain set contains value that was owned by another package"; - default: - return "Unknown failure"; - } - } - - @Reason - private final int mReason; - - @Nullable - private final UUID mDomainSetId; - - @Nullable - private final String mPackageName; - - /** - * @hide - */ - public InvalidDomainSetException(@Nullable UUID domainSetId, @Nullable String packageName, - @Reason int reason) { - super(buildMessage(domainSetId, packageName, reason)); - mDomainSetId = domainSetId; - mPackageName = packageName; - mReason = reason; - } - - @Nullable - public UUID getDomainSetId() { - return mDomainSetId; - } - - @Nullable - public String getPackageName() { - return mPackageName; - } - - @Reason - public int getReason() { - return mReason; - } - } } diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationState.java b/core/java/android/content/pm/verify/domain/DomainVerificationState.java index 17593ef2aeb1..8e28042bf581 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationState.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationState.java @@ -17,15 +17,13 @@ package android.content.pm.verify.domain; import android.annotation.IntDef; +import android.annotation.NonNull; /** * @hide */ public interface DomainVerificationState { - /** - * @hide - */ @IntDef({ STATE_NO_RESPONSE, STATE_SUCCESS, @@ -42,12 +40,12 @@ public interface DomainVerificationState { // TODO(b/159952358): Document all the places that states need to be updated when one is added /** - * @see DomainVerificationManager#STATE_NO_RESPONSE + * @see DomainVerificationInfo#STATE_NO_RESPONSE */ int STATE_NO_RESPONSE = 0; /** - * @see DomainVerificationManager#STATE_SUCCESS + * @see DomainVerificationInfo#STATE_SUCCESS */ int STATE_SUCCESS = 1; @@ -94,7 +92,132 @@ public interface DomainVerificationState { int STATE_SYS_CONFIG = 7; /** - * @see DomainVerificationManager#STATE_FIRST_VERIFIER_DEFINED + * @see DomainVerificationInfo#STATE_FIRST_VERIFIER_DEFINED */ int STATE_FIRST_VERIFIER_DEFINED = 0b10000000000; + + @NonNull + static String stateToDebugString(@DomainVerificationState.State int state) { + switch (state) { + case DomainVerificationState.STATE_NO_RESPONSE: + return "none"; + case DomainVerificationState.STATE_SUCCESS: + return "verified"; + case DomainVerificationState.STATE_APPROVED: + return "approved"; + case DomainVerificationState.STATE_DENIED: + return "denied"; + case DomainVerificationState.STATE_MIGRATED: + return "migrated"; + case DomainVerificationState.STATE_RESTORED: + return "restored"; + case DomainVerificationState.STATE_LEGACY_FAILURE: + return "legacy_failure"; + case DomainVerificationState.STATE_SYS_CONFIG: + return "system_configured"; + default: + return String.valueOf(state); + } + } + + /** + * For determining re-verify policy. This is hidden from the domain verification agent so that + * no behavior is made based on the result. + */ + static boolean isDefault(@State int state) { + switch (state) { + case STATE_NO_RESPONSE: + case STATE_MIGRATED: + case STATE_RESTORED: + return true; + case STATE_SUCCESS: + case STATE_APPROVED: + case STATE_DENIED: + case STATE_LEGACY_FAILURE: + case STATE_SYS_CONFIG: + default: + return false; + } + } + + /** + * Checks if a state considers the corresponding domain to be successfully verified. The domain + * verification agent may use this to determine whether or not to re-verify a domain. + */ + static boolean isVerified(@DomainVerificationState.State int state) { + switch (state) { + case DomainVerificationState.STATE_SUCCESS: + case DomainVerificationState.STATE_APPROVED: + case DomainVerificationState.STATE_MIGRATED: + case DomainVerificationState.STATE_RESTORED: + case DomainVerificationState.STATE_SYS_CONFIG: + return true; + case DomainVerificationState.STATE_NO_RESPONSE: + case DomainVerificationState.STATE_DENIED: + case DomainVerificationState.STATE_LEGACY_FAILURE: + default: + return false; + } + } + + /** + * Checks if a state is modifiable by the domain verification agent. This is useful as the + * platform may add new state codes in newer versions, and older verification agents can use + * this method to determine if a state can be changed without having to be aware of what the new + * state means. + */ + static boolean isModifiable(@DomainVerificationState.State int state) { + switch (state) { + case DomainVerificationState.STATE_NO_RESPONSE: + case DomainVerificationState.STATE_SUCCESS: + case DomainVerificationState.STATE_MIGRATED: + case DomainVerificationState.STATE_RESTORED: + case DomainVerificationState.STATE_LEGACY_FAILURE: + return true; + case DomainVerificationState.STATE_APPROVED: + case DomainVerificationState.STATE_DENIED: + case DomainVerificationState.STATE_SYS_CONFIG: + return false; + default: + return state >= DomainVerificationState.STATE_FIRST_VERIFIER_DEFINED; + } + } + + /** + * Whether the state is migrated when updating a package. Generally this is only for states + * that maintain verification state or were set by an explicit user or developer action. + */ + static boolean shouldMigrate(@State int state) { + switch (state) { + case STATE_SUCCESS: + case STATE_MIGRATED: + case STATE_RESTORED: + case STATE_APPROVED: + case STATE_DENIED: + return true; + case STATE_NO_RESPONSE: + case STATE_LEGACY_FAILURE: + case STATE_SYS_CONFIG: + case STATE_FIRST_VERIFIER_DEFINED: + default: + return false; + } + } + + @DomainVerificationInfo.State + static int convertToInfoState(@State int internalState) { + if (internalState >= STATE_FIRST_VERIFIER_DEFINED) { + return internalState; + } else if (internalState == STATE_NO_RESPONSE) { + return DomainVerificationInfo.STATE_NO_RESPONSE; + } else if (internalState == STATE_SUCCESS) { + return DomainVerificationInfo.STATE_SUCCESS; + } else if (!isModifiable(internalState)) { + return DomainVerificationInfo.STATE_UNMODIFIABLE; + } else if (isVerified(internalState)) { + return DomainVerificationInfo.STATE_MODIFIABLE_VERIFIED; + } else { + return DomainVerificationInfo.STATE_MODIFIABLE_UNVERIFIED; + } + } } diff --git a/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl b/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl index 332b92544581..53205f3ea470 100644 --- a/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl +++ b/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl @@ -40,10 +40,10 @@ interface IDomainVerificationManager { @nullable List<DomainOwner> getOwnersForDomain(String domain, int userId); - void setDomainVerificationStatus(String domainSetId, in DomainSet domains, int state); + int setDomainVerificationStatus(String domainSetId, in DomainSet domains, int state); void setDomainVerificationLinkHandlingAllowed(String packageName, boolean allowed, int userId); - void setDomainVerificationUserSelection(String domainSetId, in DomainSet domains, + int setDomainVerificationUserSelection(String domainSetId, in DomainSet domains, boolean enabled, int userId); } |
