summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/content/pm/ResolveInfo.java33
-rw-r--r--core/java/android/content/pm/verify/domain/DomainVerificationInfo.java122
-rw-r--r--core/java/android/content/pm/verify/domain/DomainVerificationManager.java273
-rw-r--r--core/java/android/content/pm/verify/domain/DomainVerificationState.java135
-rw-r--r--core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl4
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);
}