diff --git a/core/api/current.txt b/core/api/current.txt index 8ef2230b32e66..a9303a7fa1a86 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -12948,6 +12948,27 @@ package android.content.pm { } +package android.content.pm.verify.domain { + + public final class DomainVerificationManager { + method @Nullable public android.content.pm.verify.domain.DomainVerificationUserState getDomainVerificationUserState(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + } + + public final class DomainVerificationUserState implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public java.util.Map getHostToStateMap(); + method @NonNull public String getPackageName(); + method @NonNull public android.os.UserHandle getUser(); + method @NonNull public boolean isLinkHandlingAllowed(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int DOMAIN_STATE_NONE = 0; // 0x0 + field public static final int DOMAIN_STATE_SELECTED = 1; // 0x1 + field public static final int DOMAIN_STATE_VERIFIED = 2; // 0x2 + } + +} + package android.content.res { public class AssetFileDescriptor implements java.io.Closeable android.os.Parcelable { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 8f067c237bbe0..f01724316c5fd 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -2789,13 +2789,12 @@ package android.content.pm.verify.domain { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } - public interface DomainVerificationManager { + public final class DomainVerificationManager { method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION}) public android.content.pm.verify.domain.DomainVerificationInfo getDomainVerificationInfo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; - method @Nullable @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) public android.content.pm.verify.domain.DomainVerificationUserSelection getDomainVerificationUserSelection(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) public java.util.List getOwnersForDomain(@NonNull String); - method @NonNull @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) public java.util.List getValidVerificationPackageNames(); method public static boolean isStateModifiable(int); method public static boolean isStateVerified(int); + method @NonNull @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) public java.util.List queryValidVerificationPackageNames(); method @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) public void setDomainVerificationLinkHandlingAllowed(@NonNull String, boolean) throws android.content.pm.PackageManager.NameNotFoundException; method @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) public void setDomainVerificationStatus(@NonNull java.util.UUID, @NonNull java.util.Set, int) throws android.content.pm.PackageManager.NameNotFoundException; method @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) public void setDomainVerificationUserSelection(@NonNull java.util.UUID, @NonNull java.util.Set, boolean) throws android.content.pm.PackageManager.NameNotFoundException; @@ -2812,18 +2811,8 @@ package android.content.pm.verify.domain { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } - public final class DomainVerificationUserSelection implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public java.util.Map getHostToStateMap(); + public final class DomainVerificationUserState implements android.os.Parcelable { method @NonNull public java.util.UUID getIdentifier(); - method @NonNull public String getPackageName(); - method @NonNull public android.os.UserHandle getUser(); - method @NonNull public boolean isLinkHandlingAllowed(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator CREATOR; - field public static final int DOMAIN_STATE_NONE = 0; // 0x0 - field public static final int DOMAIN_STATE_SELECTED = 1; // 0x1 - field public static final int DOMAIN_STATE_VERIFIED = 2; // 0x2 } } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index e16e40b6d5725..43c14a99b2212 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -71,7 +71,6 @@ import android.content.pm.LauncherApps; import android.content.pm.PackageManager; import android.content.pm.ShortcutManager; import android.content.pm.verify.domain.DomainVerificationManager; -import android.content.pm.verify.domain.DomainVerificationManagerImpl; import android.content.pm.verify.domain.IDomainVerificationManager; import android.content.res.Resources; import android.content.rollback.RollbackManagerFrameworkInitializer; @@ -1422,7 +1421,6 @@ public final class SystemServiceRegistry { } }); - // TODO(b/159952358): Only register this service for the domain verification agent? registerService(Context.DOMAIN_VERIFICATION_SERVICE, DomainVerificationManager.class, new CachedServiceFetcher() { @Override @@ -1432,7 +1430,7 @@ public final class SystemServiceRegistry { Context.DOMAIN_VERIFICATION_SERVICE); IDomainVerificationManager service = IDomainVerificationManager.Stub.asInterface(binder); - return new DomainVerificationManagerImpl(context, service); + return new DomainVerificationManager(context, service); } }); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 7b62f3b2f1a2b..d79b66c1cf56f 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -7017,7 +7017,7 @@ public abstract class PackageManager { * domain to an application, use * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, boolean)}, * passing in all of the domains returned inside - * {@link DomainVerificationManager#getDomainVerificationUserSelection(String)}. + * {@link DomainVerificationManager#getDomainVerificationUserState(String)}. * * @hide */ diff --git a/core/java/android/content/pm/verify/domain/DomainOwner.java b/core/java/android/content/pm/verify/domain/DomainOwner.java index b050f5da79286..5bf2c0983a9a8 100644 --- a/core/java/android/content/pm/verify/domain/DomainOwner.java +++ b/core/java/android/content/pm/verify/domain/DomainOwner.java @@ -66,16 +66,7 @@ public final class DomainOwner implements Parcelable { * @param packageName * Package name of that owns the domain. * @param overrideable - * Whether or not this owner can be automatically overridden. If all owners for a domain are - * overrideable, then calling - * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, - * Set, boolean)} to enable the domain will disable all other owners. On the other hand, if any - * of the owners are non-overrideable, then - * {@link DomainVerificationManager#setDomainVerificationLinkHandlingAllowed(String, - * boolean)} must be called with false to disable all of the other owners before this domain can - * be taken by a new owner through - * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, - * Set, boolean)}. + * Whether or not this owner can be automatically overridden. */ @DataClass.Generated.Member public DomainOwner( @@ -98,16 +89,9 @@ public final class DomainOwner implements Parcelable { } /** - * Whether or not this owner can be automatically overridden. If all owners for a domain are - * overrideable, then calling - * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, - * Set, boolean)} to enable the domain will disable all other owners. On the other hand, if any - * of the owners are non-overrideable, then - * {@link DomainVerificationManager#setDomainVerificationLinkHandlingAllowed(String, - * boolean)} must be called with false to disable all of the other owners before this domain can - * be taken by a new owner through - * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, - * Set, boolean)}. + * Whether or not this owner can be automatically overridden. + * + * @see DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, boolean) */ @DataClass.Generated.Member public boolean isOverrideable() { @@ -205,7 +189,7 @@ public final class DomainOwner implements Parcelable { }; @DataClass.Generated( - time = 1614119379978L, + time = 1614721802044L, codegenVersion = "1.0.22", sourceFile = "frameworks/base/core/java/android/content/pm/verify/domain/DomainOwner.java", inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final boolean mOverrideable\nclass DomainOwner extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genEqualsHashCode=true, genAidl=true, genToString=true)") diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java b/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java index 809587524f586..7c335b1d26dda 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java @@ -94,7 +94,7 @@ public final class DomainVerificationInfo implements Parcelable { private Map unparcelHostToStateMap(Parcel in) { return DomainVerificationUtils.readHostMap(in, new ArrayMap<>(), - DomainVerificationUserSelection.class.getClassLoader()); + DomainVerificationUserState.class.getClassLoader()); } @@ -105,8 +105,7 @@ public final class DomainVerificationInfo implements Parcelable { // CHECKSTYLE:OFF Generated code // // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain - // /DomainVerificationInfo.java + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java // // To exclude the generated code from IntelliJ auto-formatting enable (one-time): // Settings > Editor > Code Style > Formatter Control @@ -321,7 +320,7 @@ public final class DomainVerificationInfo implements Parcelable { }; @DataClass.Generated( - time = 1613002530369L, + time = 1614721812023L, 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 mHostToStateMap\nprivate void parcelHostToStateMap(android.os.Parcel,int)\nprivate java.util.Map 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)") diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationManager.java b/core/java/android/content/pm/verify/domain/DomainVerificationManager.java index 11402afac8b68..f7c81bcffda3f 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationManager.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationManager.java @@ -25,6 +25,8 @@ import android.annotation.SystemService; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager.NameNotFoundException; +import android.os.RemoteException; +import android.os.ServiceSpecificException; import android.os.UserHandle; import java.util.List; @@ -32,55 +34,63 @@ import java.util.Set; import java.util.UUID; /** - * System service to access the domain verification APIs. + * System service to access domain verification APIs. * - * Allows the approved domain verification - * agent on the device (the sole holder of - * {@link android.Manifest.permission#DOMAIN_VERIFICATION_AGENT}) to update the approval status - * of domains declared by applications in their AndroidManifest.xml, to allow them to open those - * links inside the app when selected by the user. This is done through querying - * {@link #getDomainVerificationInfo(String)} and calling - * {@link #setDomainVerificationStatus(UUID, Set, int)}. - * - * Also allows the domain preference settings (holder of - * {@link android.Manifest.permission#UPDATE_DOMAIN_VERIFICATION_USER_SELECTION}) to update the - * preferences of the user, when they have chosen to explicitly allow an application to open links. - * This is done through querying {@link #getDomainVerificationUserSelection(String)} and calling - * {@link #setDomainVerificationUserSelection(UUID, Set, boolean)} and - * {@link #setDomainVerificationLinkHandlingAllowed(String, boolean)}. - * - * @hide + * Applications should use {@link #getDomainVerificationUserState(String)} if necessary to + * check if/how they are verified for a domain, which is required starting from platform + * {@link android.os.Build.VERSION_CODES#S} in order to open {@link Intent}s which declare + * {@link Intent#CATEGORY_BROWSABLE} or no category and also match against + * {@link Intent#CATEGORY_DEFAULT} {@link android.content.IntentFilter}s, either through an + * explicit declaration of {@link Intent#CATEGORY_DEFAULT} or through the use of + * {@link android.content.pm.PackageManager#MATCH_DEFAULT_ONLY}, which is usually added for the + * caller when using {@link Context#startActivity(Intent)} and similar. */ -@SystemApi @SystemService(Context.DOMAIN_VERIFICATION_SERVICE) -public interface DomainVerificationManager { +public final class DomainVerificationManager { /** - * Extra field name for a {@link DomainVerificationRequest} for the requested packages. - * Passed to an the domain verification agent that handles + * Extra field name for a {@link DomainVerificationRequest} for the requested packages. Passed + * to an the domain verification agent that handles * {@link Intent#ACTION_DOMAINS_NEED_VERIFICATION}. + * + * @hide */ - String EXTRA_VERIFICATION_REQUEST = + @SystemApi + public static final String EXTRA_VERIFICATION_REQUEST = "android.content.pm.verify.domain.extra.VERIFICATION_REQUEST"; /** * No response has been recorded by either the system or any verification agent. + * + * @hide */ - int STATE_NO_RESPONSE = DomainVerificationState.STATE_NO_RESPONSE; - - /** The verification agent has explicitly verified the domain at some point. */ - int STATE_SUCCESS = DomainVerificationState.STATE_SUCCESS; + @SystemApi + public static final int STATE_NO_RESPONSE = DomainVerificationState.STATE_NO_RESPONSE; /** - * 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 verification agent has explicitly verified the domain at some point. + * + * @hide */ - int STATE_FIRST_VERIFIER_DEFINED = DomainVerificationState.STATE_FIRST_VERIFIER_DEFINED; + @SystemApi + public static final int STATE_SUCCESS = DomainVerificationState.STATE_SUCCESS; - /** @hide */ + /** + * 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. + * + * @hide + */ + @SystemApi + public static final int STATE_FIRST_VERIFIER_DEFINED = + DomainVerificationState.STATE_FIRST_VERIFIER_DEFINED; + + /** + * @hide + */ @NonNull - static String stateToDebugString(@DomainVerificationState.State int state) { + public static String stateToDebugString(@DomainVerificationState.State int state) { switch (state) { case DomainVerificationState.STATE_NO_RESPONSE: return "none"; @@ -104,10 +114,13 @@ public interface DomainVerificationManager { } /** - * 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. + * 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. + * + * @hide */ - static boolean isStateVerified(@DomainVerificationState.State int state) { + @SystemApi + public static boolean isStateVerified(@DomainVerificationState.State int state) { switch (state) { case DomainVerificationState.STATE_SUCCESS: case DomainVerificationState.STATE_APPROVED: @@ -126,10 +139,13 @@ public interface DomainVerificationManager { /** * 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. + * this method to determine if a state can be changed without having to be aware of what the new + * state means. + * + * @hide */ - static boolean isStateModifiable(@DomainVerificationState.State int state) { + @SystemApi + public static boolean isStateModifiable(@DomainVerificationState.State int state) { switch (state) { case DomainVerificationState.STATE_NO_RESPONSE: case DomainVerificationState.STATE_SUCCESS: @@ -147,11 +163,12 @@ public interface DomainVerificationManager { } /** - * For determine re-verify policy. This is hidden from the domain verification agent so that - * no behavior is made based on the result. + * For determine re-verify policy. This is hidden from the domain verification agent so that no + * behavior is made based on the result. + * * @hide */ - static boolean isStateDefault(@DomainVerificationState.State int state) { + public static boolean isStateDefault(@DomainVerificationState.State int state) { switch (state) { case DomainVerificationState.STATE_NO_RESPONSE: case DomainVerificationState.STATE_MIGRATED: @@ -167,15 +184,73 @@ public interface DomainVerificationManager { } } + /** + * @hide + */ + public static final int ERROR_INVALID_DOMAIN_SET = 1; + /** + * @hide + */ + public static final int ERROR_NAME_NOT_FOUND = 2; + + /** + * @hide + */ + @IntDef(prefix = {"ERROR_"}, value = { + ERROR_INVALID_DOMAIN_SET, + ERROR_NAME_NOT_FOUND, + }) + private @interface Error { + } + + private final Context mContext; + + private final IDomainVerificationManager mDomainVerificationManager; + + + /** + * System service to access the domain verification APIs. + *

+ * Allows the approved domain verification agent on the device (the sole holder of {@link + * android.Manifest.permission#DOMAIN_VERIFICATION_AGENT}) to update the approval status of + * domains declared by applications in their AndroidManifest.xml, to allow them to open those + * links inside the app when selected by the user. This is done through querying {@link + * #getDomainVerificationInfo(String)} and calling {@link #setDomainVerificationStatus(UUID, + * Set, int)}. + *

+ * Also allows the domain preference settings (holder of + * {@link android.Manifest.permission#UPDATE_DOMAIN_VERIFICATION_USER_SELECTION}) + * to update the preferences of the user, when they have chosen to explicitly allow an + * application to open links. This is done through querying + * {@link #getDomainVerificationUserState(String)} and calling + * {@link #setDomainVerificationUserSelection(UUID, Set, boolean)} and + * {@link #setDomainVerificationLinkHandlingAllowed(String, boolean)}. + * + * @hide + */ + public DomainVerificationManager(Context context, + IDomainVerificationManager domainVerificationManager) { + mContext = context; + mDomainVerificationManager = domainVerificationManager; + } + /** * Used to iterate all {@link DomainVerificationInfo} values to do cleanup or retries. This is * usually a heavy workload and should be done infrequently. * * @return the current snapshot of package names with valid autoVerify URLs. + * @hide */ + @SystemApi @NonNull @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) - List getValidVerificationPackageNames(); + public List queryValidVerificationPackageNames() { + try { + return mDomainVerificationManager.queryValidVerificationPackageNames(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } /** * Retrieves the domain verification state for a given package. @@ -183,61 +258,106 @@ public interface DomainVerificationManager { * @return the data for the package, or null if it does not declare any autoVerify domains * @throws NameNotFoundException If the package is unavailable. This is an unrecoverable error * and should not be re-tried except on a time scheduled basis. + * @hide */ + @SystemApi @Nullable @RequiresPermission(anyOf = { android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION }) - DomainVerificationInfo getDomainVerificationInfo(@NonNull String packageName) - throws NameNotFoundException; + public DomainVerificationInfo getDomainVerificationInfo(@NonNull String packageName) + throws NameNotFoundException { + try { + return mDomainVerificationManager.getDomainVerificationInfo(packageName); + } catch (Exception e) { + Exception converted = rethrow(e, packageName); + if (converted instanceof NameNotFoundException) { + throw (NameNotFoundException) converted; + } else if (converted instanceof RuntimeException) { + throw (RuntimeException) converted; + } else { + throw new RuntimeException(converted); + } + } + } /** - * Change the verification status of the {@param domains} of the package associated with - * {@param domainSetId}. + * Change the verification status of the {@param domains} of the package associated with {@param + * domainSetId}. * * @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. + * 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. + * 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. + * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) - void setDomainVerificationStatus(@NonNull UUID domainSetId, @NonNull Set domains, - @DomainVerificationState.State int state) throws NameNotFoundException; + public void setDomainVerificationStatus(@NonNull UUID domainSetId, @NonNull Set domains, + @DomainVerificationState.State int state) throws NameNotFoundException { + try { + mDomainVerificationManager.setDomainVerificationStatus(domainSetId.toString(), + new DomainSet(domains), state); + } catch (Exception e) { + Exception converted = rethrow(e, domainSetId); + if (converted instanceof NameNotFoundException) { + throw (NameNotFoundException) converted; + } else if (converted instanceof RuntimeException) { + throw (RuntimeException) converted; + } else { + throw new RuntimeException(converted); + } + } + } /** - * TODO(b/178525735): This documentation is incorrect in the context of UX changes. - * Change whether the given {@param packageName} is allowed to automatically open verified - * HTTP/HTTPS domains. The final state is determined along with the verification status for the - * specific domain being opened and other system state. An app with this enabled is not - * guaranteed to be the sole link handler for its domains. + * Change whether the given packageName is allowed to handle BROWSABLE and DEFAULT category web + * (HTTP/HTTPS) {@link Intent} Activity open requests. The final state is determined along with + * the verification status for the specific domain being opened and other system state. An app + * with this enabled is not guaranteed to be the sole link handler for its domains. + *

+ * By default, all apps are allowed to open links. Users must disable them explicitly. * - * By default, all apps are allowed to open verified links. Users must disable them explicitly. + * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) - void setDomainVerificationLinkHandlingAllowed(@NonNull String packageName, boolean allowed) - throws NameNotFoundException; + public void setDomainVerificationLinkHandlingAllowed(@NonNull String packageName, + boolean allowed) throws NameNotFoundException { + try { + mDomainVerificationManager.setDomainVerificationLinkHandlingAllowed(packageName, + allowed, mContext.getUserId()); + } catch (Exception e) { + Exception converted = rethrow(e, packageName); + if (converted instanceof NameNotFoundException) { + throw (NameNotFoundException) converted; + } else if (converted instanceof RuntimeException) { + throw (RuntimeException) converted; + } else { + throw new RuntimeException(converted); + } + } + } /** * Update the recorded user selection for the given {@param domains} for the given {@param * domainSetId}. This state is recorded for the lifetime of a domain for a package on device, * and will never be reset by the system short of an app data clear. - * + *

* This state is stored per device user. If another user needs to be changed, the appropriate - * permissions must be acquired and - * {@link Context#createPackageContextAsUser(String, int, UserHandle)} should be used. - * + * permissions must be acquired and {@link Context#createContextAsUser(UserHandle, int)} should + * be used. + *

* Enabling an unverified domain will allow an application to open it, but this can only occur * if no other app on the device is approved for a higher approval level. This can queried * using {@link #getOwnersForDomain(String)}. @@ -255,33 +375,55 @@ public interface DomainVerificationManager { * @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. + * 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. + * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) - void setDomainVerificationUserSelection(@NonNull UUID domainSetId, - @NonNull Set domains, boolean enabled) throws NameNotFoundException; + public void setDomainVerificationUserSelection(@NonNull UUID domainSetId, + @NonNull Set domains, boolean enabled) throws NameNotFoundException { + try { + mDomainVerificationManager.setDomainVerificationUserSelection(domainSetId.toString(), + new DomainSet(domains), enabled, mContext.getUserId()); + } catch (Exception e) { + Exception converted = rethrow(e, domainSetId); + if (converted instanceof NameNotFoundException) { + throw (NameNotFoundException) converted; + } else if (converted instanceof RuntimeException) { + throw (RuntimeException) converted; + } else { + throw new RuntimeException(converted); + } + } + } /** * Retrieve the user selection data for the given {@param packageName} and the current user. - * It is the responsibility of the caller to ensure that the - * {@link DomainVerificationUserSelection#getIdentifier()} matches any prior API calls. - * - * This state is stored per device user. If another user needs to be accessed, the appropriate - * permissions must be acquired and - * {@link Context#createPackageContextAsUser(String, int, UserHandle)} should be used. * * @param packageName The app to query state for. - * @return the user selection verification data for the given package for the current user, - * or null if the package does not declare any HTTP/HTTPS domains. + * @return the user selection verification data for the given package for the current user, or + * null if the package does not declare any HTTP/HTTPS domains. */ @Nullable - @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) - DomainVerificationUserSelection getDomainVerificationUserSelection(@NonNull String packageName) - throws NameNotFoundException; + public DomainVerificationUserState getDomainVerificationUserState( + @NonNull String packageName) throws NameNotFoundException { + try { + return mDomainVerificationManager.getDomainVerificationUserState(packageName, + mContext.getUserId()); + } catch (Exception e) { + Exception converted = rethrow(e, packageName); + if (converted instanceof NameNotFoundException) { + throw (NameNotFoundException) converted; + } else if (converted instanceof RuntimeException) { + throw (RuntimeException) converted; + } else { + throw new RuntimeException(converted); + } + } + } /** * For the given domain, return all apps which are approved to open it in a @@ -291,21 +433,65 @@ public interface DomainVerificationManager { * * By default the list will be returned ordered from lowest to highest * priority. + * + * @hide */ + @SystemApi @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) - List getOwnersForDomain(@NonNull String domain); + public List getOwnersForDomain(@NonNull String domain) { + try { + return mDomainVerificationManager.getOwnersForDomain(domain, mContext.getUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + 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; + 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; + } + } 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. + * {@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 */ - class InvalidDomainSetException extends IllegalArgumentException { + public static class InvalidDomainSetException extends IllegalArgumentException { public static final int REASON_ID_NULL = 1; public static final int REASON_ID_INVALID = 2; @@ -313,7 +499,9 @@ public interface DomainVerificationManager { public static final int REASON_UNKNOWN_DOMAIN = 4; public static final int REASON_UNABLE_TO_APPROVE = 5; - /** @hide */ + /** + * @hide + */ @IntDef({ REASON_ID_NULL, REASON_ID_INVALID, @@ -352,7 +540,9 @@ public interface DomainVerificationManager { @Nullable private final String mPackageName; - /** @hide */ + /** + * @hide + */ public InvalidDomainSetException(@Nullable UUID domainSetId, @Nullable String packageName, @Reason int reason) { super(buildMessage(domainSetId, packageName, reason)); diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationManagerImpl.java b/core/java/android/content/pm/verify/domain/DomainVerificationManagerImpl.java deleted file mode 100644 index 8b9865c2b436a..0000000000000 --- a/core/java/android/content/pm/verify/domain/DomainVerificationManagerImpl.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.content.pm.verify.domain; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Context; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.RemoteException; -import android.os.ServiceSpecificException; - -import java.util.List; -import java.util.Set; -import java.util.UUID; - -/** - * @hide - */ -@SuppressWarnings("RedundantThrows") -public class DomainVerificationManagerImpl implements DomainVerificationManager { - - public static final int ERROR_INVALID_DOMAIN_SET = 1; - public static final int ERROR_NAME_NOT_FOUND = 2; - - @IntDef(prefix = { "ERROR_" }, value = { - ERROR_INVALID_DOMAIN_SET, - ERROR_NAME_NOT_FOUND, - }) - private @interface Error { - } - - private final Context mContext; - - private final IDomainVerificationManager mDomainVerificationManager; - - public DomainVerificationManagerImpl(Context context, - IDomainVerificationManager domainVerificationManager) { - mContext = context; - mDomainVerificationManager = domainVerificationManager; - } - - @NonNull - @Override - public List getValidVerificationPackageNames() { - try { - return mDomainVerificationManager.getValidVerificationPackageNames(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - @Nullable - @Override - public DomainVerificationInfo getDomainVerificationInfo(@NonNull String packageName) - throws NameNotFoundException { - try { - return mDomainVerificationManager.getDomainVerificationInfo(packageName); - } catch (Exception e) { - Exception converted = rethrow(e, packageName); - if (converted instanceof NameNotFoundException) { - throw (NameNotFoundException) converted; - } else if (converted instanceof RuntimeException) { - throw (RuntimeException) converted; - } else { - throw new RuntimeException(converted); - } - } - } - - @Override - public void setDomainVerificationStatus(@NonNull UUID domainSetId, @NonNull Set domains, - int state) throws IllegalArgumentException, NameNotFoundException { - try { - mDomainVerificationManager.setDomainVerificationStatus(domainSetId.toString(), - new DomainSet(domains), state); - } catch (Exception e) { - Exception converted = rethrow(e, domainSetId); - if (converted instanceof NameNotFoundException) { - throw (NameNotFoundException) converted; - } else if (converted instanceof RuntimeException) { - throw (RuntimeException) converted; - } else { - throw new RuntimeException(converted); - } - } - } - - @Override - public void setDomainVerificationLinkHandlingAllowed(@NonNull String packageName, - boolean allowed) throws NameNotFoundException { - try { - mDomainVerificationManager.setDomainVerificationLinkHandlingAllowed(packageName, - allowed, mContext.getUserId()); - } catch (Exception e) { - Exception converted = rethrow(e, packageName); - if (converted instanceof NameNotFoundException) { - throw (NameNotFoundException) converted; - } else if (converted instanceof RuntimeException) { - throw (RuntimeException) converted; - } else { - throw new RuntimeException(converted); - } - } - } - - @Override - public void setDomainVerificationUserSelection(@NonNull UUID domainSetId, - @NonNull Set domains, boolean enabled) - throws IllegalArgumentException, NameNotFoundException { - try { - mDomainVerificationManager.setDomainVerificationUserSelection(domainSetId.toString(), - new DomainSet(domains), enabled, mContext.getUserId()); - } catch (Exception e) { - Exception converted = rethrow(e, domainSetId); - if (converted instanceof NameNotFoundException) { - throw (NameNotFoundException) converted; - } else if (converted instanceof RuntimeException) { - throw (RuntimeException) converted; - } else { - throw new RuntimeException(converted); - } - } - } - - @Nullable - @Override - public DomainVerificationUserSelection getDomainVerificationUserSelection( - @NonNull String packageName) throws NameNotFoundException { - try { - return mDomainVerificationManager.getDomainVerificationUserSelection(packageName, - mContext.getUserId()); - } catch (Exception e) { - Exception converted = rethrow(e, packageName); - if (converted instanceof NameNotFoundException) { - throw (NameNotFoundException) converted; - } else if (converted instanceof RuntimeException) { - throw (RuntimeException) converted; - } else { - throw new RuntimeException(converted); - } - } - } - - @NonNull - @Override - public List getOwnersForDomain(@NonNull String domain) { - try { - return mDomainVerificationManager.getOwnersForDomain(domain, mContext.getUserId()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - 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; - 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; - } - } else if (exception instanceof RemoteException) { - return ((RemoteException) exception).rethrowFromSystemServer(); - } else { - return exception; - } - } -} diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.aidl b/core/java/android/content/pm/verify/domain/DomainVerificationUserState.aidl similarity index 93% rename from core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.aidl rename to core/java/android/content/pm/verify/domain/DomainVerificationUserState.aidl index ddb5ef85382a1..94690c1dae938 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.aidl +++ b/core/java/android/content/pm/verify/domain/DomainVerificationUserState.aidl @@ -16,4 +16,4 @@ package android.content.pm.verify.domain; -parcelable DomainVerificationUserSelection; +parcelable DomainVerificationUserState; diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java b/core/java/android/content/pm/verify/domain/DomainVerificationUserState.java similarity index 82% rename from core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java rename to core/java/android/content/pm/verify/domain/DomainVerificationUserState.java index d23f5f133841e..1e60abb300119 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationUserState.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.content.Context; +import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; @@ -29,39 +30,36 @@ import com.android.internal.util.DataClass; import com.android.internal.util.Parcelling; import java.util.Map; -import java.util.Set; import java.util.UUID; /** * Contains the user selection state for a package. This means all web HTTP(S) domains declared by a * package in its manifest, whether or not they were marked for auto verification. *

- * By default, all apps are allowed to automatically open links with domains that they've - * successfully verified against. This is reflected by {@link #isLinkHandlingAllowed()}. The user - * can decide to disable this, disallowing the application from opening all links. Note that the - * toggle affects all links and is not based on the verification state of the domains. + * Applications should use {@link #getHostToStateMap()} if necessary to + * check if/how they are verified for a domain, which is required starting from platform + * {@link android.os.Build.VERSION_CODES#S} in order to open {@link Intent}s which declare + * {@link Intent#CATEGORY_BROWSABLE} or no category and also match against + * {@link Intent#CATEGORY_DEFAULT} {@link android.content.IntentFilter}s, either through an + * explicit declaration of {@link Intent#CATEGORY_DEFAULT} or through the use of + * {@link android.content.pm.PackageManager#MATCH_DEFAULT_ONLY}, which is usually added for the + * caller when using {@link Context#startActivity(Intent)} and similar. + *

+ * By default, all apps are allowed to automatically open links for the above case for domains that + * they've successfully verified against. This is reflected by {@link #isLinkHandlingAllowed()}. + * The user can decide to disable this, disallowing the application from opening all links. Note + * that the toggle affects all links and is not based on the verification state of the + * domains. *

* Assuming the toggle is enabled, the user can also select additional unverified domains to grant * to the application to open, which is reflected in {@link #getHostToStateMap()}. But only a single * application can be approved for a domain unless the applications are both approved. If another * application is approved, the user will not be allowed to enable the domain. - *

- * These values can be changed through the - * {@link DomainVerificationManager#setDomainVerificationLinkHandlingAllowed(String, - * boolean)} and {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, - * boolean)} APIs. - *

- * Note that because state is per user, if a different user needs to be changed, one will need to - * use {@link Context#createContextAsUser(UserHandle, int)} and hold the {@link - * android.Manifest.permission#INTERACT_ACROSS_USERS} permission. - * - * @hide */ -@SystemApi @SuppressWarnings("DefaultAnnotationParam") @DataClass(genAidl = true, genHiddenConstructor = true, genParcelable = true, genToString = true, genEqualsHashCode = true, genHiddenConstDefs = true) -public final class DomainVerificationUserSelection implements Parcelable { +public final class DomainVerificationUserState implements Parcelable { /** * The domain is unverified and unselected, and the application is unable to open web links @@ -70,9 +68,8 @@ public final class DomainVerificationUserSelection implements Parcelable { public static final int DOMAIN_STATE_NONE = 0; /** - * The domain has been selected through the - * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, boolean)} - * API, under the assumption it has not been reset by the system. + * The domain has been selected by the user. This may be reset to {@link #DOMAIN_STATE_NONE} if + * another application is selected or verified for the same domain. */ public static final int DOMAIN_STATE_SELECTED = 1; @@ -119,7 +116,16 @@ public final class DomainVerificationUserSelection implements Parcelable { @NonNull private Map unparcelHostToStateMap(Parcel in) { return DomainVerificationUtils.readHostMap(in, new ArrayMap<>(), - DomainVerificationUserSelection.class.getClassLoader()); + DomainVerificationUserState.class.getClassLoader()); + } + + /** + * @see DomainVerificationInfo#getIdentifier + * @hide + */ + @SystemApi + public @NonNull UUID getIdentifier() { + return mIdentifier; } @@ -130,7 +136,7 @@ public final class DomainVerificationUserSelection implements Parcelable { // CHECKSTYLE:OFF Generated code // // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationUserState.java // // To exclude the generated code from IntelliJ auto-formatting enable (one-time): // Settings > Editor > Code Style > Formatter Control @@ -162,7 +168,7 @@ public final class DomainVerificationUserSelection implements Parcelable { } /** - * Creates a new DomainVerificationUserSelection. + * Creates a new DomainVerificationUserState. * * @param packageName * The package name that this data corresponds to. @@ -175,7 +181,7 @@ public final class DomainVerificationUserSelection implements Parcelable { * @hide */ @DataClass.Generated.Member - public DomainVerificationUserSelection( + public DomainVerificationUserState( @NonNull UUID identifier, @NonNull String packageName, @NonNull UserHandle user, @@ -200,14 +206,6 @@ public final class DomainVerificationUserSelection implements Parcelable { // onConstructed(); // You can define this method to get a callback } - /** - * @see DomainVerificationInfo#getIdentifier - */ - @DataClass.Generated.Member - public @NonNull UUID getIdentifier() { - return mIdentifier; - } - /** * The package name that this data corresponds to. */ @@ -246,7 +244,7 @@ public final class DomainVerificationUserSelection implements Parcelable { // You can override field toString logic by defining methods like: // String fieldNameToString() { ... } - return "DomainVerificationUserSelection { " + + return "DomainVerificationUserState { " + "identifier = " + mIdentifier + ", " + "packageName = " + mPackageName + ", " + "user = " + mUser + ", " + @@ -259,13 +257,13 @@ public final class DomainVerificationUserSelection implements Parcelable { @DataClass.Generated.Member public boolean equals(@Nullable Object o) { // You can override field equality logic by defining either of the methods like: - // boolean fieldNameEquals(DomainVerificationUserSelection other) { ... } + // boolean fieldNameEquals(DomainVerificationUserState other) { ... } // boolean fieldNameEquals(FieldType otherValue) { ... } if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; @SuppressWarnings("unchecked") - DomainVerificationUserSelection that = (DomainVerificationUserSelection) o; + DomainVerificationUserState that = (DomainVerificationUserState) o; //noinspection PointlessBooleanExpression return true && java.util.Objects.equals(mIdentifier, that.mIdentifier) @@ -323,7 +321,7 @@ public final class DomainVerificationUserSelection implements Parcelable { /** @hide */ @SuppressWarnings({"unchecked", "RedundantCast"}) @DataClass.Generated.Member - /* package-private */ DomainVerificationUserSelection(@NonNull Parcel in) { + /* package-private */ DomainVerificationUserState(@NonNull Parcel in) { // You can override field unparcelling by defining methods like: // static FieldType unparcelFieldName(Parcel in) { ... } @@ -354,24 +352,24 @@ public final class DomainVerificationUserSelection implements Parcelable { } @DataClass.Generated.Member - public static final @NonNull Parcelable.Creator CREATOR - = new Parcelable.Creator() { + public static final @NonNull Parcelable.Creator CREATOR + = new Parcelable.Creator() { @Override - public DomainVerificationUserSelection[] newArray(int size) { - return new DomainVerificationUserSelection[size]; + public DomainVerificationUserState[] newArray(int size) { + return new DomainVerificationUserState[size]; } @Override - public DomainVerificationUserSelection createFromParcel(@NonNull Parcel in) { - return new DomainVerificationUserSelection(in); + public DomainVerificationUserState createFromParcel(@NonNull Parcel in) { + return new DomainVerificationUserState(in); } }; @DataClass.Generated( - time = 1613683603297L, + time = 1614721840152L, codegenVersion = "1.0.22", - sourceFile = "frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java", - inputSignatures = "public static final int DOMAIN_STATE_NONE\npublic static final int DOMAIN_STATE_SELECTED\npublic static final int DOMAIN_STATE_VERIFIED\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 android.os.UserHandle mUser\nprivate final @android.annotation.NonNull boolean mLinkHandlingAllowed\nprivate final @android.annotation.NonNull java.util.Map mHostToStateMap\nprivate void parcelHostToStateMap(android.os.Parcel,int)\nprivate @android.annotation.NonNull java.util.Map unparcelHostToStateMap(android.os.Parcel)\nclass DomainVerificationUserSelection 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)") + sourceFile = "frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationUserState.java", + inputSignatures = "public static final int DOMAIN_STATE_NONE\npublic static final int DOMAIN_STATE_SELECTED\npublic static final int DOMAIN_STATE_VERIFIED\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 android.os.UserHandle mUser\nprivate final @android.annotation.NonNull boolean mLinkHandlingAllowed\nprivate final @android.annotation.NonNull java.util.Map mHostToStateMap\nprivate void parcelHostToStateMap(android.os.Parcel,int)\nprivate @android.annotation.NonNull java.util.Map unparcelHostToStateMap(android.os.Parcel)\npublic @android.annotation.SystemApi @android.annotation.NonNull java.util.UUID getIdentifier()\nclass DomainVerificationUserState 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/IDomainVerificationManager.aidl b/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl index 701af320fb019..332b925445813 100644 --- a/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl +++ b/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl @@ -19,7 +19,7 @@ package android.content.pm.verify.domain; import android.content.pm.verify.domain.DomainOwner; import android.content.pm.verify.domain.DomainSet; import android.content.pm.verify.domain.DomainVerificationInfo; -import android.content.pm.verify.domain.DomainVerificationUserSelection; +import android.content.pm.verify.domain.DomainVerificationUserState; import java.util.List; /** @@ -28,13 +28,13 @@ import java.util.List; */ interface IDomainVerificationManager { - List getValidVerificationPackageNames(); + List queryValidVerificationPackageNames(); @nullable DomainVerificationInfo getDomainVerificationInfo(String packageName); @nullable - DomainVerificationUserSelection getDomainVerificationUserSelection(String packageName, + DomainVerificationUserState getDomainVerificationUserState(String packageName, int userId); @nullable diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationDebug.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationDebug.java index c9067a3a9392e..b61fd8d633f61 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationDebug.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationDebug.java @@ -33,9 +33,9 @@ import android.util.SparseArray; import com.android.internal.util.CollectionUtils; import com.android.server.pm.PackageSetting; import com.android.server.pm.parsing.pkg.AndroidPackage; +import com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState; import com.android.server.pm.verify.domain.models.DomainVerificationPkgState; import com.android.server.pm.verify.domain.models.DomainVerificationStateMap; -import com.android.server.pm.verify.domain.models.DomainVerificationUserState; import java.util.Arrays; import java.util.function.Function; @@ -169,8 +169,8 @@ public class DomainVerificationDebug { } ArraySet allWebDomains = mCollector.collectAllWebDomains(pkg); - SparseArray userStates = - pkgState.getUserSelectionStates(); + SparseArray userStates = + pkgState.getUserStates(); if (userId == UserHandle.USER_ALL) { int size = userStates.size(); if (size == 0) { @@ -178,13 +178,13 @@ public class DomainVerificationDebug { wasHeaderPrinted); } else { for (int index = 0; index < size; index++) { - DomainVerificationUserState userState = userStates.valueAt(index); + DomainVerificationInternalUserState userState = userStates.valueAt(index); printState(writer, pkgState, userState.getUserId(), userState, reusedSet, allWebDomains, wasHeaderPrinted); } } } else { - DomainVerificationUserState userState = userStates.get(userId); + DomainVerificationInternalUserState userState = userStates.get(userId); printState(writer, pkgState, userId, userState, reusedSet, allWebDomains, wasHeaderPrinted); } @@ -192,8 +192,9 @@ public class DomainVerificationDebug { boolean printState(@NonNull IndentingPrintWriter writer, @NonNull DomainVerificationPkgState pkgState, @UserIdInt int userId, - @Nullable DomainVerificationUserState userState, @NonNull ArraySet reusedSet, - @NonNull ArraySet allWebDomains, boolean wasHeaderPrinted) { + @Nullable DomainVerificationInternalUserState userState, + @NonNull ArraySet reusedSet, @NonNull ArraySet allWebDomains, + boolean wasHeaderPrinted) { reusedSet.clear(); reusedSet.addAll(allWebDomains); if (userState != null) { diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java index ed37fa0da01f9..1721a18f4f604 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java @@ -129,6 +129,21 @@ public class DomainVerificationEnforcer { } } + /** + * Enforced when mutating user selection state inside an exposed API method. + */ + public boolean assertApprovedUserStateQuerent(int callingUid, @UserIdInt int callingUserId, + @NonNull String packageName, @UserIdInt int targetUserId) throws SecurityException { + if (callingUserId != targetUserId) { + mContext.enforcePermission( + Manifest.permission.INTERACT_ACROSS_USERS, + Binder.getCallingPid(), callingUid, + "Caller is not allowed to edit other users"); + } + + return !mCallback.filterAppAccess(packageName, callingUid, targetUserId); + } + /** * Enforced when mutating user selection state inside an exposed API method. */ diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java index a68b3da0f0b68..0c2b4c547daef 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java @@ -48,7 +48,7 @@ import java.util.Set; import java.util.UUID; import java.util.function.Function; -public interface DomainVerificationManagerInternal extends DomainVerificationManager { +public interface DomainVerificationManagerInternal { UUID DISABLED_ID = new UUID(0, 0); @@ -69,8 +69,8 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan * during the legacy transition period. * * TODO(b/177923646): The legacy values can be removed once the Settings API changes are - * shipped. These values are not stable, so just deleting the constant and shifting others is - * fine. + * shipped. These values are not stable, so just deleting the constant and shifting others is + * fine. */ int APPROVAL_LEVEL_LEGACY_ASK = 1; @@ -84,14 +84,15 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan /** * The app has been chosen by the user through - * {@link #setDomainVerificationUserSelection(UUID, Set, boolean)}, indictag an explicit - * choice to use this app to open an unverified domain. + * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, boolean)}, + * indicating an explicit choice to use this app to open an unverified domain. */ int APPROVAL_LEVEL_SELECTION = 2; /** * The app is approved through the digital asset link statement being hosted at the domain - * it is capturing. This is set through {@link #setDomainVerificationStatus(UUID, Set, int)} by + * it is capturing. This is set through + * {@link DomainVerificationManager#setDomainVerificationStatus(UUID, Set, int)} by * the domain verification agent on device. */ int APPROVAL_LEVEL_VERIFIED = 3; @@ -102,7 +103,7 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan * declares against the digital asset link statements before allowing it to be installed. * * The user is still able to disable instant app link handling through - * {@link #setDomainVerificationLinkHandlingAllowed(String, boolean)}. + * {@link DomainVerificationManager#setDomainVerificationLinkHandlingAllowed(String, boolean)}. */ int APPROVAL_LEVEL_INSTANT_APP = 4; @@ -122,7 +123,17 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan APPROVAL_LEVEL_VERIFIED, APPROVAL_LEVEL_INSTANT_APP }) - @interface ApprovalLevel{} + @interface ApprovalLevel { + } + + /** @see DomainVerificationManager#getDomainVerificationInfo(String) */ + @Nullable + @RequiresPermission(anyOf = { + android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, + android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION + }) + DomainVerificationInfo getDomainVerificationInfo(@NonNull String packageName) + throws NameNotFoundException; /** * Generate a new domain set ID to be used for attaching new packages. @@ -173,9 +184,9 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan /** * Migrates verification state from a previous install to a new one. It is expected that the * {@link PackageSetting#getDomainSetId()} already be set to the correct value, usually from - * {@link #generateNewId()}. This will preserve {@link #STATE_SUCCESS} domains under the - * assumption that the new package will pass the same server side config as the previous - * package, as they have matching signatures. + * {@link #generateNewId()}. This will preserve {@link DomainVerificationManager#STATE_SUCCESS} + * domains under the assumption that the new package will pass the same server side config as + * the previous package, as they have matching signatures. *

* This will mutate internal {@link DomainVerificationPkgState} and so will hold the internal * lock. This should never be called from within the domain verification classes themselves. @@ -229,8 +240,10 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan * tag has already been entered. *

* This is only for restore, and will override package states, ignoring if their {@link - * DomainVerificationInfo#getIdentifier()}s match. It's expected that any restored domains marked - * as success verify against the server correctly, although the verification agent may decide to + * DomainVerificationInfo#getIdentifier()}s match. It's expected that any restored domains + * marked + * as success verify against the server correctly, although the verification agent may decide + * to * re-verify them when it gets the chance. */ /* diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerStub.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerStub.java index 6f2810785c604..a7a52e0cd10c4 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerStub.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerStub.java @@ -23,29 +23,29 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.verify.domain.DomainOwner; import android.content.pm.verify.domain.DomainSet; import android.content.pm.verify.domain.DomainVerificationInfo; +import android.content.pm.verify.domain.DomainVerificationManager; import android.content.pm.verify.domain.DomainVerificationManager.InvalidDomainSetException; -import android.content.pm.verify.domain.DomainVerificationManagerImpl; -import android.content.pm.verify.domain.DomainVerificationUserSelection; +import android.content.pm.verify.domain.DomainVerificationUserState; import android.content.pm.verify.domain.IDomainVerificationManager; import android.os.ServiceSpecificException; import java.util.List; import java.util.UUID; -class DomainVerificationManagerStub extends IDomainVerificationManager.Stub { +public class DomainVerificationManagerStub extends IDomainVerificationManager.Stub { @NonNull - private DomainVerificationService mService; + private final DomainVerificationService mService; - DomainVerificationManagerStub(DomainVerificationService service) { + public DomainVerificationManagerStub(DomainVerificationService service) { mService = service; } @NonNull @Override - public List getValidVerificationPackageNames() { + public List queryValidVerificationPackageNames() { try { - return mService.getValidVerificationPackageNames(); + return mService.queryValidVerificationPackageNames(); } catch (Exception e) { throw rethrow(e); } @@ -95,10 +95,10 @@ class DomainVerificationManagerStub extends IDomainVerificationManager.Stub { @Nullable @Override - public DomainVerificationUserSelection getDomainVerificationUserSelection( + public DomainVerificationUserState getDomainVerificationUserState( String packageName, @UserIdInt int userId) { try { - return mService.getDomainVerificationUserSelection(packageName, userId); + return mService.getDomainVerificationUserState(packageName, userId); } catch (Exception e) { throw rethrow(e); } @@ -117,13 +117,13 @@ class DomainVerificationManagerStub extends IDomainVerificationManager.Stub { private RuntimeException rethrow(Exception exception) throws RuntimeException { if (exception instanceof InvalidDomainSetException) { - int packedErrorCode = DomainVerificationManagerImpl.ERROR_INVALID_DOMAIN_SET; + int packedErrorCode = DomainVerificationManager.ERROR_INVALID_DOMAIN_SET; packedErrorCode |= ((InvalidDomainSetException) exception).getReason() << 16; return new ServiceSpecificException(packedErrorCode, ((InvalidDomainSetException) exception).getPackageName()); } else if (exception instanceof NameNotFoundException) { return new ServiceSpecificException( - DomainVerificationManagerImpl.ERROR_NAME_NOT_FOUND); + DomainVerificationManager.ERROR_NAME_NOT_FOUND); } else if (exception instanceof RuntimeException) { return (RuntimeException) exception; } else { diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationPersistence.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationPersistence.java index c864b2937f6b0..abb8d2fb6e1e4 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationPersistence.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationPersistence.java @@ -27,9 +27,9 @@ import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; import com.android.server.pm.SettingsXml; +import com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState; import com.android.server.pm.verify.domain.models.DomainVerificationPkgState; import com.android.server.pm.verify.domain.models.DomainVerificationStateMap; -import com.android.server.pm.verify.domain.models.DomainVerificationUserState; import org.xmlpull.v1.XmlPullParserException; @@ -157,7 +157,7 @@ public class DomainVerificationPersistence { UUID id = UUID.fromString(idString); final ArrayMap stateMap = new ArrayMap<>(); - final SparseArray userStates = new SparseArray<>(); + final SparseArray userStates = new SparseArray<>(); SettingsXml.ChildSection child = section.children(); while (child.moveToNext()) { @@ -176,10 +176,10 @@ public class DomainVerificationPersistence { } private static void readUserStates(@NonNull SettingsXml.ReadSection section, - @NonNull SparseArray userStates) { + @NonNull SparseArray userStates) { SettingsXml.ChildSection child = section.children(); while (child.moveToNext(TAG_USER_STATE)) { - DomainVerificationUserState userState = createUserStateFromXml(child); + DomainVerificationInternalUserState userState = createUserStateFromXml(child); if (userState != null) { userStates.put(userState.getUserId(), userState); } @@ -205,12 +205,12 @@ public class DomainVerificationPersistence { .attribute(ATTR_HAS_AUTO_VERIFY_DOMAINS, pkgState.isHasAutoVerifyDomains())) { writeStateMap(parentSection, pkgState.getStateMap()); - writeUserStates(parentSection, pkgState.getUserSelectionStates()); + writeUserStates(parentSection, pkgState.getUserStates()); } } private static void writeUserStates(@NonNull SettingsXml.WriteSection parentSection, - @NonNull SparseArray states) throws IOException { + @NonNull SparseArray states) throws IOException { int size = states.size(); if (size == 0) { return; @@ -245,7 +245,7 @@ public class DomainVerificationPersistence { * entered. */ @Nullable - public static DomainVerificationUserState createUserStateFromXml( + public static DomainVerificationInternalUserState createUserStateFromXml( @NonNull SettingsXml.ReadSection section) { int userId = section.getInt(ATTR_USER_ID); if (userId == -1) { @@ -260,7 +260,7 @@ public class DomainVerificationPersistence { readEnabledHosts(child, enabledHosts); } - return new DomainVerificationUserState(userId, enabledHosts, allowLinkHandling); + return new DomainVerificationInternalUserState(userId, enabledHosts, allowLinkHandling); } private static void readEnabledHosts(@NonNull SettingsXml.ReadSection section, @@ -275,7 +275,7 @@ public class DomainVerificationPersistence { } public static void writeUserStateToXml(@NonNull SettingsXml.WriteSection parentSection, - @NonNull DomainVerificationUserState userState) throws IOException { + @NonNull DomainVerificationInternalUserState userState) throws IOException { try (SettingsXml.WriteSection section = parentSection.startSection(TAG_USER_STATE) .attribute(ATTR_USER_ID, userState.getUserId()) diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java index dbd7f96f2cbc1..e85bbe41f7479 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java @@ -34,8 +34,9 @@ import android.content.pm.parsing.component.ParsedActivity; import android.content.pm.verify.domain.DomainOwner; import android.content.pm.verify.domain.DomainVerificationInfo; import android.content.pm.verify.domain.DomainVerificationManager; +import android.content.pm.verify.domain.DomainVerificationManager.InvalidDomainSetException; import android.content.pm.verify.domain.DomainVerificationState; -import android.content.pm.verify.domain.DomainVerificationUserSelection; +import android.content.pm.verify.domain.DomainVerificationUserState; import android.content.pm.verify.domain.IDomainVerificationManager; import android.os.UserHandle; import android.util.ArrayMap; @@ -55,9 +56,9 @@ import com.android.server.SystemService; import com.android.server.compat.PlatformCompat; import com.android.server.pm.PackageSetting; import com.android.server.pm.parsing.pkg.AndroidPackage; +import com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState; import com.android.server.pm.verify.domain.models.DomainVerificationPkgState; import com.android.server.pm.verify.domain.models.DomainVerificationStateMap; -import com.android.server.pm.verify.domain.models.DomainVerificationUserState; import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy; import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyUnavailable; @@ -208,8 +209,7 @@ public class DomainVerificationService extends SystemService } @NonNull - @Override - public List getValidVerificationPackageNames() { + public List queryValidVerificationPackageNames() { mEnforcer.assertApprovedVerifier(mConnection.getCallingUid(), mProxy); List packageNames = new ArrayList<>(); synchronized (mLock) { @@ -272,7 +272,6 @@ public class DomainVerificationService extends SystemService } } - @Override public void setDomainVerificationStatus(@NonNull UUID domainSetId, @NonNull Set domains, int state) throws InvalidDomainSetException, NameNotFoundException { if (state < DomainVerificationState.STATE_FIRST_VERIFIER_DEFINED) { @@ -314,7 +313,7 @@ public class DomainVerificationService extends SystemService int size = verifiedDomains.size(); for (int index = 0; index < size; index++) { - removeUserSelectionsForDomain(verifiedDomains.get(index)); + removeUserStatesForDomain(verifiedDomains.get(index)); } } @@ -401,12 +400,12 @@ public class DomainVerificationService extends SystemService } } - private void removeUserSelectionsForDomain(@NonNull String domain) { + private void removeUserStatesForDomain(@NonNull String domain) { synchronized (mLock) { final int size = mAttachedPkgStates.size(); for (int index = 0; index < size; index++) { DomainVerificationPkgState pkgState = mAttachedPkgStates.valueAt(index); - SparseArray array = pkgState.getUserSelectionStates(); + SparseArray array = pkgState.getUserStates(); int arraySize = array.size(); for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { array.valueAt(arrayIndex).removeHost(domain); @@ -415,13 +414,6 @@ public class DomainVerificationService extends SystemService } } - @Override - public void setDomainVerificationLinkHandlingAllowed(@NonNull String packageName, - boolean allowed) throws NameNotFoundException { - setDomainVerificationLinkHandlingAllowed(packageName, allowed, - mConnection.getCallingUserId()); - } - public void setDomainVerificationLinkHandlingAllowed(@NonNull String packageName, boolean allowed, @UserIdInt int userId) throws NameNotFoundException { if (!mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), @@ -434,7 +426,7 @@ public class DomainVerificationService extends SystemService throw DomainVerificationUtils.throwPackageUnavailable(packageName); } - pkgState.getOrCreateUserSelectionState(userId) + pkgState.getOrCreateUserState(userId) .setLinkHandlingAllowed(allowed); } @@ -452,11 +444,11 @@ public class DomainVerificationService extends SystemService DomainVerificationPkgState pkgState = mAttachedPkgStates.valueAt(pkgStateIndex); if (userId == UserHandle.USER_ALL) { for (int aUserId : mConnection.getAllUserIds()) { - pkgState.getOrCreateUserSelectionState(aUserId) + pkgState.getOrCreateUserState(aUserId) .setLinkHandlingAllowed(allowed); } } else { - pkgState.getOrCreateUserSelectionState(userId) + pkgState.getOrCreateUserState(userId) .setLinkHandlingAllowed(allowed); } } @@ -468,7 +460,7 @@ public class DomainVerificationService extends SystemService throw DomainVerificationUtils.throwPackageUnavailable(packageName); } - pkgState.getOrCreateUserSelectionState(userId) + pkgState.getOrCreateUserState(userId) .setLinkHandlingAllowed(allowed); } } @@ -476,14 +468,6 @@ public class DomainVerificationService extends SystemService mConnection.scheduleWriteSettings(); } - @Override - public void setDomainVerificationUserSelection(@NonNull UUID domainSetId, - @NonNull Set domains, boolean enabled) - throws InvalidDomainSetException, NameNotFoundException { - setDomainVerificationUserSelection(domainSetId, domains, enabled, - mConnection.getCallingUserId()); - } - public void setDomainVerificationUserSelection(@NonNull UUID domainSetId, @NonNull Set domains, boolean enabled, @UserIdInt int userId) throws InvalidDomainSetException, NameNotFoundException { @@ -500,7 +484,8 @@ public class DomainVerificationService extends SystemService DomainVerificationPkgState pkgState = getAndValidateAttachedLocked(domainSetId, domains, false /* forAutoVerify */, callingUid, userId); - DomainVerificationUserState userState = pkgState.getOrCreateUserSelectionState(userId); + DomainVerificationInternalUserState userState = + pkgState.getOrCreateUserState(userId); // Disable other packages if approving this one. Note that this check is only done for // enabling. This allows an escape hatch in case multiple packages somehow get selected. @@ -540,8 +525,8 @@ public class DomainVerificationService extends SystemService continue; } - DomainVerificationUserState approvedUserState = - approvedPkgState.getUserSelectionState(userId); + DomainVerificationInternalUserState approvedUserState = + approvedPkgState.getUserState(userId); if (approvedUserState == null) { continue; } @@ -623,8 +608,8 @@ public class DomainVerificationService extends SystemService if (userId == UserHandle.USER_ALL) { for (int aUserId : mConnection.getAllUserIds()) { - DomainVerificationUserState userState = - pkgState.getOrCreateUserSelectionState(aUserId); + DomainVerificationInternalUserState userState = + pkgState.getOrCreateUserState(aUserId); if (enabled) { userState.addHosts(domains); } else { @@ -632,7 +617,8 @@ public class DomainVerificationService extends SystemService } } } else { - DomainVerificationUserState userState = pkgState.getOrCreateUserSelectionState(userId); + DomainVerificationInternalUserState userState = + pkgState.getOrCreateUserState(userId); if (enabled) { userState.addHosts(domains); } else { @@ -643,17 +629,9 @@ public class DomainVerificationService extends SystemService @Nullable @Override - public DomainVerificationUserSelection getDomainVerificationUserSelection( - @NonNull String packageName) throws NameNotFoundException { - return getDomainVerificationUserSelection(packageName, - mConnection.getCallingUserId()); - } - - @Nullable - @Override - public DomainVerificationUserSelection getDomainVerificationUserSelection( + public DomainVerificationUserState getDomainVerificationUserState( @NonNull String packageName, @UserIdInt int userId) throws NameNotFoundException { - if (!mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), + if (!mEnforcer.assertApprovedUserStateQuerent(mConnection.getCallingUid(), mConnection.getCallingUserId(), packageName, userId)) { throw DomainVerificationUtils.throwPackageUnavailable(packageName); } @@ -673,7 +651,7 @@ public class DomainVerificationService extends SystemService Map domains = new ArrayMap<>(webDomainsSize); ArrayMap stateMap = pkgState.getStateMap(); - DomainVerificationUserState userState = pkgState.getUserSelectionState(userId); + DomainVerificationInternalUserState userState = pkgState.getUserState(userId); Set enabledHosts = userState == null ? emptySet() : userState.getEnabledHosts(); for (int index = 0; index < webDomainsSize; index++) { @@ -682,11 +660,11 @@ public class DomainVerificationService extends SystemService int domainState; if (state != null && DomainVerificationManager.isStateVerified(state)) { - domainState = DomainVerificationUserSelection.DOMAIN_STATE_VERIFIED; + domainState = DomainVerificationUserState.DOMAIN_STATE_VERIFIED; } else if (enabledHosts.contains(host)) { - domainState = DomainVerificationUserSelection.DOMAIN_STATE_SELECTED; + domainState = DomainVerificationUserState.DOMAIN_STATE_SELECTED; } else { - domainState = DomainVerificationUserSelection.DOMAIN_STATE_NONE; + domainState = DomainVerificationUserState.DOMAIN_STATE_NONE; } domains.put(host, domainState); @@ -694,17 +672,11 @@ public class DomainVerificationService extends SystemService boolean linkHandlingAllowed = userState == null || userState.isLinkHandlingAllowed(); - return new DomainVerificationUserSelection(pkgState.getId(), packageName, + return new DomainVerificationUserState(pkgState.getId(), packageName, UserHandle.of(userId), linkHandlingAllowed, domains); } } - @NonNull - @Override - public List getOwnersForDomain(@NonNull String domain) { - return getOwnersForDomain(domain, mConnection.getCallingUserId()); - } - public List getOwnersForDomain(@NonNull String domain, @UserIdInt int userId) { mEnforcer.assertOwnerQuerent(mConnection.getCallingUid(), mConnection.getCallingUserId(), userId); @@ -795,7 +767,7 @@ public class DomainVerificationService extends SystemService AndroidPackage newPkg = newPkgSetting.getPkg(); ArrayMap newStateMap = new ArrayMap<>(); - SparseArray newUserStates = new SparseArray<>(); + SparseArray newUserStates = new SparseArray<>(); if (oldPkgState == null || oldPkg == null || newPkg == null) { // Should be impossible, but to be safe, continue with a new blank state instead @@ -838,21 +810,22 @@ public class DomainVerificationService extends SystemService } } - SparseArray oldUserStates = - oldPkgState.getUserSelectionStates(); + SparseArray oldUserStates = + oldPkgState.getUserStates(); int oldUserStatesSize = oldUserStates.size(); if (oldUserStatesSize > 0) { ArraySet newWebDomains = mCollector.collectValidAutoVerifyDomains(newPkg); for (int oldUserStatesIndex = 0; oldUserStatesIndex < oldUserStatesSize; oldUserStatesIndex++) { int userId = oldUserStates.keyAt(oldUserStatesIndex); - DomainVerificationUserState oldUserState = oldUserStates.valueAt( + DomainVerificationInternalUserState oldUserState = oldUserStates.valueAt( oldUserStatesIndex); ArraySet oldEnabledHosts = oldUserState.getEnabledHosts(); ArraySet newEnabledHosts = new ArraySet<>(oldEnabledHosts); newEnabledHosts.retainAll(newWebDomains); - DomainVerificationUserState newUserState = new DomainVerificationUserState( - userId, newEnabledHosts, oldUserState.isLinkHandlingAllowed()); + DomainVerificationInternalUserState newUserState = + new DomainVerificationInternalUserState(userId, newEnabledHosts, + oldUserState.isLinkHandlingAllowed()); newUserStates.put(userId, newUserState); } } @@ -926,7 +899,7 @@ public class DomainVerificationService extends SystemService webDomains = mCollector.collectAllWebDomains(pkg); } - pkgState.getOrCreateUserSelectionState(userId).addHosts(webDomains); + pkgState.getOrCreateUserState(userId).addHosts(webDomains); } } @@ -1295,7 +1268,7 @@ public class DomainVerificationService extends SystemService } @Override - public void clearUserSelections(@Nullable List packageNames, @UserIdInt int userId) { + public void clearUserStates(@Nullable List packageNames, @UserIdInt int userId) { mEnforcer.assertInternal(mConnection.getCallingUid()); synchronized (mLock) { if (packageNames == null) { @@ -1545,7 +1518,7 @@ public class DomainVerificationService extends SystemService return APPROVAL_LEVEL_NONE; } - DomainVerificationUserState userState = pkgState.getUserSelectionState(userId); + DomainVerificationInternalUserState userState = pkgState.getUserState(userId); if (userState != null && !userState.isLinkHandlingAllowed()) { if (DEBUG_APPROVAL) { diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationSettings.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationSettings.java index a8e937cf2b902..f3d1dbb1f6ada 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationSettings.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationSettings.java @@ -29,9 +29,9 @@ import android.util.TypedXmlSerializer; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState; import com.android.server.pm.verify.domain.models.DomainVerificationPkgState; import com.android.server.pm.verify.domain.models.DomainVerificationStateMap; -import com.android.server.pm.verify.domain.models.DomainVerificationUserState; import org.xmlpull.v1.XmlPullParserException; @@ -216,21 +216,22 @@ class DomainVerificationSettings { } } - SparseArray oldSelectionStates = - oldState.getUserSelectionStates(); + SparseArray oldSelectionStates = + oldState.getUserStates(); - SparseArray newSelectionStates = - newState.getUserSelectionStates(); + SparseArray newSelectionStates = + newState.getUserStates(); - DomainVerificationUserState newUserState = newSelectionStates.get(UserHandle.USER_SYSTEM); + DomainVerificationInternalUserState newUserState = + newSelectionStates.get(UserHandle.USER_SYSTEM); if (newUserState != null) { ArraySet newEnabledHosts = newUserState.getEnabledHosts(); - DomainVerificationUserState oldUserState = + DomainVerificationInternalUserState oldUserState = oldSelectionStates.get(UserHandle.USER_SYSTEM); boolean linkHandlingAllowed = newUserState.isLinkHandlingAllowed(); if (oldUserState == null) { - oldUserState = new DomainVerificationUserState(UserHandle.USER_SYSTEM, + oldUserState = new DomainVerificationInternalUserState(UserHandle.USER_SYSTEM, newEnabledHosts, linkHandlingAllowed); oldSelectionStates.put(UserHandle.USER_SYSTEM, oldUserState); } else { diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationShell.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationShell.java index d083d11cb2e29..94767f555574c 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationShell.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationShell.java @@ -24,7 +24,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.verify.domain.DomainVerificationManager; import android.content.pm.verify.domain.DomainVerificationState; -import android.content.pm.verify.domain.DomainVerificationUserSelection; +import android.content.pm.verify.domain.DomainVerificationUserState; import android.os.Binder; import android.os.UserHandle; import android.text.TextUtils; @@ -118,7 +118,7 @@ public class DomainVerificationShell { case "set-app-links": return runSetAppLinks(commandHandler); case "set-app-links-user-selection": - return runSetAppLinksUserSelection(commandHandler); + return runSetAppLinksUserState(commandHandler); case "set-app-links-allowed": return runSetAppLinksAllowed(commandHandler); } @@ -193,7 +193,7 @@ public class DomainVerificationShell { } // pm set-app-links-user-selection --user [--package ] ... - private boolean runSetAppLinksUserSelection(@NonNull BasicShellCommandHandler commandHandler) { + private boolean runSetAppLinksUserState(@NonNull BasicShellCommandHandler commandHandler) { Integer userId = null; String packageName = null; @@ -224,7 +224,7 @@ public class DomainVerificationShell { return false; } - userId = translateUserId(userId, "runSetAppLinksUserSelection"); + userId = translateUserId(userId, "runSetAppLinksUserState"); String enabledString = commandHandler.getNextArgRequired(); @@ -326,7 +326,7 @@ public class DomainVerificationShell { } if (userId != null) { - mCallback.clearUserSelections(packageNames, userId); + mCallback.clearUserStates(packageNames, userId); } else { mCallback.clearDomainVerificationState(packageNames); } @@ -457,10 +457,10 @@ public class DomainVerificationShell { throws PackageManager.NameNotFoundException; /** - * @see DomainVerificationManager#getDomainVerificationUserSelection(String) + * @see DomainVerificationManager#getDomainVerificationUserState(String) */ @Nullable - DomainVerificationUserSelection getDomainVerificationUserSelection( + DomainVerificationUserState getDomainVerificationUserState( @NonNull String packageName, @UserIdInt int userId) throws PackageManager.NameNotFoundException; @@ -486,7 +486,7 @@ public class DomainVerificationShell { * Reset all the user selections for the given package names, or all package names if null * is provided. */ - void clearUserSelections(@Nullable List packageNames, @UserIdInt int userId); + void clearUserStates(@Nullable List packageNames, @UserIdInt int userId); /** * Broadcast a verification request for the given package names, or all package names if diff --git a/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationUserState.java b/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationInternalUserState.java similarity index 74% rename from services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationUserState.java rename to services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationInternalUserState.java index 8fbb33afb6ca5..aa7407ce3fe84 100644 --- a/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationUserState.java +++ b/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationInternalUserState.java @@ -29,7 +29,7 @@ import java.util.Set; * when a web URL Intent is sent and the application is the highest priority for that domain. */ @DataClass(genSetters = true, genEqualsHashCode = true, genToString = true, genBuilder = false) -public class DomainVerificationUserState { +public class DomainVerificationInternalUserState { @UserIdInt private final int mUserId; @@ -43,32 +43,32 @@ public class DomainVerificationUserState { */ private boolean mLinkHandlingAllowed = true; - public DomainVerificationUserState(@UserIdInt int userId) { + public DomainVerificationInternalUserState(@UserIdInt int userId) { mUserId = userId; mEnabledHosts = new ArraySet<>(); } - public DomainVerificationUserState addHosts(@NonNull ArraySet newHosts) { + public DomainVerificationInternalUserState addHosts(@NonNull ArraySet newHosts) { mEnabledHosts.addAll(newHosts); return this; } - public DomainVerificationUserState addHosts(@NonNull Set newHosts) { + public DomainVerificationInternalUserState addHosts(@NonNull Set newHosts) { mEnabledHosts.addAll(newHosts); return this; } - public DomainVerificationUserState removeHost(String host) { + public DomainVerificationInternalUserState removeHost(String host) { mEnabledHosts.remove(host); return this; } - public DomainVerificationUserState removeHosts(@NonNull ArraySet newHosts) { + public DomainVerificationInternalUserState removeHosts(@NonNull ArraySet newHosts) { mEnabledHosts.removeAll(newHosts); return this; } - public DomainVerificationUserState removeHosts(@NonNull Set newHosts) { + public DomainVerificationInternalUserState removeHosts(@NonNull Set newHosts) { mEnabledHosts.removeAll(newHosts); return this; } @@ -81,8 +81,7 @@ public class DomainVerificationUserState { // CHECKSTYLE:OFF Generated code // // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/services/core/java/com/android/server/pm - // /verify/domain/models/DomainVerificationUserState.java + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationInternalUserState.java // // To exclude the generated code from IntelliJ auto-formatting enable (one-time): // Settings > Editor > Code Style > Formatter Control @@ -90,7 +89,7 @@ public class DomainVerificationUserState { /** - * Creates a new DomainVerificationUserState. + * Creates a new DomainVerificationInternalUserState. * * @param enabledHosts * List of domains which have been enabled by the user. * @@ -98,7 +97,7 @@ public class DomainVerificationUserState { * Whether to allow this package to automatically open links by auto verification. */ @DataClass.Generated.Member - public DomainVerificationUserState( + public DomainVerificationInternalUserState( @UserIdInt int userId, @NonNull ArraySet enabledHosts, boolean linkHandlingAllowed) { @@ -138,7 +137,7 @@ public class DomainVerificationUserState { * Whether to allow this package to automatically open links by auto verification. */ @DataClass.Generated.Member - public @NonNull DomainVerificationUserState setLinkHandlingAllowed( boolean value) { + public @NonNull DomainVerificationInternalUserState setLinkHandlingAllowed( boolean value) { mLinkHandlingAllowed = value; return this; } @@ -149,7 +148,7 @@ public class DomainVerificationUserState { // You can override field toString logic by defining methods like: // String fieldNameToString() { ... } - return "DomainVerificationUserState { " + + return "DomainVerificationInternalUserState { " + "userId = " + mUserId + ", " + "enabledHosts = " + mEnabledHosts + ", " + "linkHandlingAllowed = " + mLinkHandlingAllowed + @@ -160,13 +159,13 @@ public class DomainVerificationUserState { @DataClass.Generated.Member public boolean equals(@android.annotation.Nullable Object o) { // You can override field equality logic by defining either of the methods like: - // boolean fieldNameEquals(DomainVerificationUserState other) { ... } + // boolean fieldNameEquals(DomainVerificationInternalUserState other) { ... } // boolean fieldNameEquals(FieldType otherValue) { ... } if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; @SuppressWarnings("unchecked") - DomainVerificationUserState that = (DomainVerificationUserState) o; + DomainVerificationInternalUserState that = (DomainVerificationInternalUserState) o; //noinspection PointlessBooleanExpression return true && mUserId == that.mUserId @@ -188,10 +187,10 @@ public class DomainVerificationUserState { } @DataClass.Generated( - time = 1612894390039L, + time = 1614714563905L, codegenVersion = "1.0.22", - sourceFile = "frameworks/base/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationUserState.java", - inputSignatures = "private final @android.annotation.UserIdInt int mUserId\nprivate final @android.annotation.NonNull android.util.ArraySet mEnabledHosts\nprivate boolean mLinkHandlingAllowed\npublic com.android.server.pm.verify.domain.models.DomainVerificationUserState addHosts(android.util.ArraySet)\npublic com.android.server.pm.verify.domain.models.DomainVerificationUserState addHosts(java.util.Set)\npublic com.android.server.pm.verify.domain.models.DomainVerificationUserState removeHosts(android.util.ArraySet)\npublic com.android.server.pm.verify.domain.models.DomainVerificationUserState removeHosts(java.util.Set)\nclass DomainVerificationUserState extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genSetters=true, genEqualsHashCode=true, genToString=true, genBuilder=false)") + sourceFile = "frameworks/base/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationInternalUserState.java", + inputSignatures = "private final @android.annotation.UserIdInt int mUserId\nprivate final @android.annotation.NonNull android.util.ArraySet mEnabledHosts\nprivate boolean mLinkHandlingAllowed\npublic com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState addHosts(android.util.ArraySet)\npublic com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState addHosts(java.util.Set)\npublic com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState removeHost(java.lang.String)\npublic com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState removeHosts(android.util.ArraySet)\npublic com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState removeHosts(java.util.Set)\nclass DomainVerificationInternalUserState extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genSetters=true, genEqualsHashCode=true, genToString=true, genBuilder=false)") @Deprecated private void __metadata() {} diff --git a/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationPkgState.java b/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationPkgState.java index 48099aa5382bb..a089a60227352 100644 --- a/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationPkgState.java +++ b/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationPkgState.java @@ -19,7 +19,6 @@ package com.android.server.pm.verify.domain.models; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; -import android.content.pm.verify.domain.DomainVerificationManager; import android.content.pm.verify.domain.DomainVerificationState; import android.util.ArrayMap; import android.util.SparseArray; @@ -44,9 +43,9 @@ public class DomainVerificationPkgState { /** * Whether or not the package declares any autoVerify domains. This is separate from an empty - * check on the map itself, because an empty map means no response recorded, not necessarily no - * domains declared. When this is false, {@link #mStateMap} will be empty, but - * {@link #mUserSelectionStates} may contain any domains the user has explicitly chosen to + * check on the map itself, because an empty map means no response recorded, not necessarily + * no domains declared. When this is false, {@link #mStateMap} will be empty, but + * {@link #mUserStates} may contain any domains the user has explicitly chosen to * allow this package to open, which may or may not be marked autoVerify. */ private final boolean mHasAutoVerifyDomains; @@ -62,7 +61,7 @@ public class DomainVerificationPkgState { private final ArrayMap mStateMap; @NonNull - private final SparseArray mUserSelectionStates; + private final SparseArray mUserStates; public DomainVerificationPkgState(@NonNull String packageName, @NonNull UUID id, boolean hasAutoVerifyDomains) { @@ -70,16 +69,17 @@ public class DomainVerificationPkgState { } @Nullable - public DomainVerificationUserState getUserSelectionState(@UserIdInt int userId) { - return mUserSelectionStates.get(userId); + public DomainVerificationInternalUserState getUserState(@UserIdInt int userId) { + return mUserStates.get(userId); } @Nullable - public DomainVerificationUserState getOrCreateUserSelectionState(@UserIdInt int userId) { - DomainVerificationUserState userState = mUserSelectionStates.get(userId); + public DomainVerificationInternalUserState getOrCreateUserState( + @UserIdInt int userId) { + DomainVerificationInternalUserState userState = mUserStates.get(userId); if (userState == null) { - userState = new DomainVerificationUserState(userId); - mUserSelectionStates.put(userId, userState); + userState = new DomainVerificationInternalUserState(userId); + mUserStates.put(userId, userState); } return userState; } @@ -89,20 +89,20 @@ public class DomainVerificationPkgState { } public void removeUser(@UserIdInt int userId) { - mUserSelectionStates.remove(userId); + mUserStates.remove(userId); } public void removeAllUsers() { - mUserSelectionStates.clear(); + mUserStates.clear(); } - private int userSelectionStatesHashCode() { - return mUserSelectionStates.contentHashCode(); + private int userStatesHashCode() { + return mUserStates.contentHashCode(); } - private boolean userSelectionStatesEquals( - @NonNull SparseArray other) { - return mUserSelectionStates.contentEquals(other); + private boolean userStatesEquals( + @NonNull SparseArray other) { + return mUserStates.contentEquals(other); } @@ -113,7 +113,7 @@ public class DomainVerificationPkgState { // CHECKSTYLE:OFF Generated code // // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/services/core/java/com/android/server/pm/domain/verify/models/DomainVerificationPkgState.java + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationPkgState.java // // To exclude the generated code from IntelliJ auto-formatting enable (one-time): // Settings > Editor > Code Style > Formatter Control @@ -123,9 +123,15 @@ public class DomainVerificationPkgState { /** * Creates a new DomainVerificationPkgState. * + * @param hasAutoVerifyDomains + * Whether or not the package declares any autoVerify domains. This is separate from an empty + * check on the map itself, because an empty map means no response recorded, not necessarily + * no domains declared. When this is false, {@link #mStateMap} will be empty, but + * {@link #mUserStates} may contain any domains the user has explicitly chosen to + * allow this package to open, which may or may not be marked autoVerify. * @param stateMap * Map of domains to state integers. Only domains that are not set to the default value of - * {@link DomainVerificationManager#STATE_NO_RESPONSE} are included. + * {@link DomainVerificationState#STATE_NO_RESPONSE} are included. * * TODO(b/159952358): Hide the state map entirely from the caller, to allow optimizations, * such as storing no state when the package is marked as a linked app in SystemConfig. @@ -136,7 +142,7 @@ public class DomainVerificationPkgState { @NonNull UUID id, boolean hasAutoVerifyDomains, @NonNull ArrayMap stateMap, - @NonNull SparseArray userSelectionStates) { + @NonNull SparseArray userStates) { this.mPackageName = packageName; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mPackageName); @@ -147,9 +153,9 @@ public class DomainVerificationPkgState { this.mStateMap = stateMap; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mStateMap); - this.mUserSelectionStates = userSelectionStates; + this.mUserStates = userStates; com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mUserSelectionStates); + NonNull.class, null, mUserStates); // onConstructed(); // You can define this method to get a callback } @@ -164,6 +170,13 @@ public class DomainVerificationPkgState { return mId; } + /** + * Whether or not the package declares any autoVerify domains. This is separate from an empty + * check on the map itself, because an empty map means no response recorded, not necessarily + * no domains declared. When this is false, {@link #mStateMap} will be empty, but + * {@link #mUserStates} may contain any domains the user has explicitly chosen to + * allow this package to open, which may or may not be marked autoVerify. + */ @DataClass.Generated.Member public boolean isHasAutoVerifyDomains() { return mHasAutoVerifyDomains; @@ -171,7 +184,7 @@ public class DomainVerificationPkgState { /** * Map of domains to state integers. Only domains that are not set to the default value of - * {@link DomainVerificationManager#STATE_NO_RESPONSE} are included. + * {@link DomainVerificationState#STATE_NO_RESPONSE} are included. * * TODO(b/159952358): Hide the state map entirely from the caller, to allow optimizations, * such as storing no state when the package is marked as a linked app in SystemConfig. @@ -182,8 +195,8 @@ public class DomainVerificationPkgState { } @DataClass.Generated.Member - public @NonNull SparseArray getUserSelectionStates() { - return mUserSelectionStates; + public @NonNull SparseArray getUserStates() { + return mUserStates; } @Override @@ -197,7 +210,7 @@ public class DomainVerificationPkgState { "id = " + mId + ", " + "hasAutoVerifyDomains = " + mHasAutoVerifyDomains + ", " + "stateMap = " + mStateMap + ", " + - "userSelectionStates = " + mUserSelectionStates + + "userStates = " + mUserStates + " }"; } @@ -218,7 +231,7 @@ public class DomainVerificationPkgState { && Objects.equals(mId, that.mId) && mHasAutoVerifyDomains == that.mHasAutoVerifyDomains && Objects.equals(mStateMap, that.mStateMap) - && userSelectionStatesEquals(that.mUserSelectionStates); + && userStatesEquals(that.mUserStates); } @Override @@ -232,15 +245,15 @@ public class DomainVerificationPkgState { _hash = 31 * _hash + Objects.hashCode(mId); _hash = 31 * _hash + Boolean.hashCode(mHasAutoVerifyDomains); _hash = 31 * _hash + Objects.hashCode(mStateMap); - _hash = 31 * _hash + userSelectionStatesHashCode(); + _hash = 31 * _hash + userStatesHashCode(); return _hash; } @DataClass.Generated( - time = 1608234185474L, + time = 1614818362549L, codegenVersion = "1.0.22", - sourceFile = "frameworks/base/services/core/java/com/android/server/pm/domain/verify/models/DomainVerificationPkgState.java", - inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate @android.annotation.NonNull java.util.UUID mId\nprivate final boolean mHasAutoVerifyDomains\nprivate final @android.annotation.NonNull android.util.ArrayMap mStateMap\nprivate final @android.annotation.NonNull android.util.SparseArray mUserSelectionStates\npublic @android.annotation.Nullable com.android.server.pm.verify.domain.models.DomainVerificationUserState getUserSelectionState(int)\npublic @android.annotation.Nullable com.android.server.pm.verify.domain.models.DomainVerificationUserState getOrCreateUserSelectionState(int)\npublic void setId(java.util.UUID)\npublic void removeUser(int)\npublic void removeAllUsers()\nprivate int userSelectionStatesHashCode()\nprivate boolean userSelectionStatesEquals(android.util.SparseArray)\nclass DomainVerificationPkgState extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true)") + sourceFile = "frameworks/base/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationPkgState.java", + inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate @android.annotation.NonNull java.util.UUID mId\nprivate final boolean mHasAutoVerifyDomains\nprivate final @android.annotation.NonNull android.util.ArrayMap mStateMap\nprivate final @android.annotation.NonNull android.util.SparseArray mUserStates\npublic @android.annotation.Nullable com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState getUserState(int)\npublic @android.annotation.Nullable com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState getOrCreateUserState(int)\npublic void setId(java.util.UUID)\npublic void removeUser(int)\npublic void removeAllUsers()\nprivate int userStatesHashCode()\nprivate boolean userStatesEquals(android.util.SparseArray)\nclass DomainVerificationPkgState extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true)") @Deprecated private void __metadata() {} diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCoreApiTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCoreApiTest.kt index 9447f390ada06..8ef92393242a9 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCoreApiTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCoreApiTest.kt @@ -19,7 +19,7 @@ package com.android.server.pm.test.verify.domain import android.content.pm.verify.domain.DomainSet import android.content.pm.verify.domain.DomainVerificationInfo import android.content.pm.verify.domain.DomainVerificationRequest -import android.content.pm.verify.domain.DomainVerificationUserSelection +import android.content.pm.verify.domain.DomainVerificationUserState import android.os.Parcel import android.os.Parcelable import android.os.UserHandle @@ -28,7 +28,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import java.util.UUID -import kotlin.random.Random @RunWith(Parameterized::class) class DomainVerificationCoreApiTest { @@ -92,9 +91,9 @@ class DomainVerificationCoreApiTest { } ), Parameter( - testName = "DomainVerificationUserSelection", + testName = "DomainVerificationUserState", initial = { - DomainVerificationUserSelection( + DomainVerificationUserState( UUID.fromString("703f6d34-6241-4cfd-8176-2e1d23355811"), "com.test.pkg", UserHandle.of(10), @@ -103,22 +102,22 @@ class DomainVerificationCoreApiTest { .associate { it.value to (it.index % 3) } ) }, - unparcel = { DomainVerificationUserSelection.CREATOR.createFromParcel(it) }, + unparcel = { DomainVerificationUserState.CREATOR.createFromParcel(it) }, assertion = { first, second -> - assertAll(first, second, + assertAll(first, second, { it.identifier }, { it.component1() }, IS_EQUAL_TO ) - assertAll(first, second, + assertAll(first, second, { it.packageName }, { it.component2() }, IS_EQUAL_TO ) - assertAll(first, second, + assertAll(first, second, { it.user }, { it.component3() }, IS_EQUAL_TO ) - assertAll( + assertAll( first, second, { it.isLinkHandlingAllowed }, { it.component4() }, IS_EQUAL_TO ) - assertAll>( + assertAll>( first, second, { it.hostToStateMap }, { it.component5() }, IS_MAP_EQUAL_TO ) diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt index 89394837655a8..53f0ca20e787f 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt @@ -154,6 +154,15 @@ class DomainVerificationEnforcerTest { enforcer(Type.VERIFIER, "approvedVerifier") { assertApprovedVerifier(it.callingUid, it.proxy) }, + enforcer( + Type.SELECTION_QUERENT, + "approvedUserStateQuerent" + ) { + assertApprovedUserStateQuerent( + it.callingUid, it.callingUserId, + it.targetPackageName, it.userId + ) + }, enforcer( Type.SELECTOR, "approvedUserSelector" @@ -170,7 +179,7 @@ class DomainVerificationEnforcerTest { ArraySet(setOf("example.com")) ) }, - service(Type.INTERNAL, "setUserSelectionInternal") { + service(Type.INTERNAL, "setUserStateInternal") { setDomainVerificationUserSelectionInternal( it.userId, it.targetPackageName, @@ -184,11 +193,11 @@ class DomainVerificationEnforcerTest { service(Type.INTERNAL, "clearState") { clearDomainVerificationState(listOf(it.targetPackageName)) }, - service(Type.INTERNAL, "clearUserSelections") { - clearUserSelections(listOf(it.targetPackageName), it.userId) + service(Type.INTERNAL, "clearUserStates") { + clearUserStates(listOf(it.targetPackageName), it.userId) }, - service(Type.VERIFIER, "getPackageNames") { - validVerificationPackageNames + service(Type.VERIFIER, "queryValidPackageNames") { + queryValidVerificationPackageNames() }, service(Type.QUERENT, "getInfo") { getDomainVerificationInfo(it.targetPackageName) @@ -208,26 +217,13 @@ class DomainVerificationEnforcerTest { DomainVerificationManager.STATE_SUCCESS ) }, - service(Type.SELECTOR, "setLinkHandlingAllowed") { - setDomainVerificationLinkHandlingAllowed(it.targetPackageName, true) - }, service(Type.SELECTOR_USER, "setLinkHandlingAllowedUserId") { setDomainVerificationLinkHandlingAllowed(it.targetPackageName, true, it.userId) }, - service(Type.SELECTOR, "getUserSelection") { - getDomainVerificationUserSelection(it.targetPackageName) + service(Type.SELECTION_QUERENT, "getUserStateUserId") { + getDomainVerificationUserState(it.targetPackageName, it.userId) }, - service(Type.SELECTOR_USER, "getUserSelectionUserId") { - getDomainVerificationUserSelection(it.targetPackageName, it.userId) - }, - service(Type.SELECTOR, "setUserSelection") { - setDomainVerificationUserSelection( - it.targetDomainSetId, - setOf("example.com"), - true - ) - }, - service(Type.SELECTOR_USER, "setUserSelectionUserId") { + service(Type.SELECTOR_USER, "setUserStateUserId") { setDomainVerificationUserSelection( it.targetDomainSetId, setOf("example.com"), @@ -244,10 +240,6 @@ class DomainVerificationEnforcerTest { service(Type.LEGACY_QUERENT, "getLegacyUserState") { getLegacyState(it.targetPackageName, it.userId) }, - service(Type.OWNER_QUERENT, "getOwnersForDomain") { - // Re-use package name, since the result itself isn't relevant - getOwnersForDomain(it.targetPackageName) - }, service(Type.OWNER_QUERENT_USER, "getOwnersForDomainUserId") { // Re-use package name, since the result itself isn't relevant getOwnersForDomain(it.targetPackageName, it.userId) @@ -362,6 +354,7 @@ class DomainVerificationEnforcerTest { Type.INTERNAL -> internal() Type.QUERENT -> approvedQuerent() Type.VERIFIER -> approvedVerifier() + Type.SELECTION_QUERENT -> approvedUserStateQuerent(verifyCrossUser = true) Type.SELECTOR -> approvedUserSelector(verifyCrossUser = false) Type.SELECTOR_USER -> approvedUserSelector(verifyCrossUser = true) Type.LEGACY_QUERENT -> legacyQuerent() @@ -371,7 +364,7 @@ class DomainVerificationEnforcerTest { }.run { /*exhaust*/ } } - fun internal() { + private fun internal() { val context: Context = mockThrowOnUnmocked() val target = params.construct(context) @@ -385,13 +378,13 @@ class DomainVerificationEnforcerTest { } } - fun approvedQuerent() { - val allowUserSelection = AtomicBoolean(false) + private fun approvedQuerent() { + val allowUserState = AtomicBoolean(false) val allowPreferredApps = AtomicBoolean(false) val allowQueryAll = AtomicBoolean(false) val context: Context = mockThrowOnUnmocked { initPermission( - allowUserSelection, + allowUserState, android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION ) initPermission( @@ -418,7 +411,7 @@ class DomainVerificationEnforcerTest { assertFails { runMethod(target, NON_VERIFIER_UID) } - allowUserSelection.set(true) + allowUserState.set(true) assertFails { runMethod(target, NON_VERIFIER_UID) } @@ -427,7 +420,7 @@ class DomainVerificationEnforcerTest { runMethod(target, NON_VERIFIER_UID) } - fun approvedVerifier() { + private fun approvedVerifier() { val allowDomainVerificationAgent = AtomicBoolean(false) val allowIntentVerificationAgent = AtomicBoolean(false) val allowQueryAll = AtomicBoolean(false) @@ -469,12 +462,61 @@ class DomainVerificationEnforcerTest { assertFails { runMethod(target, NON_VERIFIER_UID) } } - fun approvedUserSelector(verifyCrossUser: Boolean) { - val allowUserSelection = AtomicBoolean(false) + private fun approvedUserStateQuerent(verifyCrossUser: Boolean) { val allowInteractAcrossUsers = AtomicBoolean(false) val context: Context = mockThrowOnUnmocked { initPermission( - allowUserSelection, + allowInteractAcrossUsers, + android.Manifest.permission.INTERACT_ACROSS_USERS + ) + } + val target = params.construct(context) + + fun runTestCases(callingUserId: Int, targetUserId: Int, throws: Boolean) { + // User selector makes no distinction by UID + val allUids = INTERNAL_UIDS + VERIFIER_UID + NON_VERIFIER_UID + if (throws) { + allUids.forEach { + assertFails { + runMethod(target, it, visible = true, callingUserId, targetUserId) + } + } + } else { + allUids.forEach { + runMethod(target, it, visible = true, callingUserId, targetUserId) + } + } + + // User selector doesn't use QUERY_ALL, so the invisible package should always fail + allUids.forEach { + assertFails { + runMethod(target, it, visible = false, callingUserId, targetUserId) + } + } + } + + val callingUserId = 0 + val notCallingUserId = 1 + + runTestCases(callingUserId, callingUserId, throws = false) + if (verifyCrossUser) { + runTestCases(callingUserId, notCallingUserId, throws = true) + } + + allowInteractAcrossUsers.set(true) + + runTestCases(callingUserId, callingUserId, throws = false) + if (verifyCrossUser) { + runTestCases(callingUserId, notCallingUserId, throws = false) + } + } + + private fun approvedUserSelector(verifyCrossUser: Boolean) { + val allowUserState = AtomicBoolean(false) + val allowInteractAcrossUsers = AtomicBoolean(false) + val context: Context = mockThrowOnUnmocked { + initPermission( + allowUserState, android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION ) initPermission( @@ -515,7 +557,7 @@ class DomainVerificationEnforcerTest { runTestCases(callingUserId, notCallingUserId, throws = true) } - allowUserSelection.set(true) + allowUserState.set(true) runTestCases(callingUserId, callingUserId, throws = false) if (verifyCrossUser) { @@ -641,7 +683,7 @@ class DomainVerificationEnforcerTest { private fun ownerQuerent(verifyCrossUser: Boolean) { val allowQueryAll = AtomicBoolean(false) - val allowUserSelection = AtomicBoolean(false) + val allowUserState = AtomicBoolean(false) val allowInteractAcrossUsers = AtomicBoolean(false) val context: Context = mockThrowOnUnmocked { initPermission( @@ -649,7 +691,7 @@ class DomainVerificationEnforcerTest { android.Manifest.permission.QUERY_ALL_PACKAGES ) initPermission( - allowUserSelection, + allowUserState, android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION ) initPermission( @@ -690,7 +732,7 @@ class DomainVerificationEnforcerTest { runTestCases(callingUserId, notCallingUserId, throws = true) } - allowUserSelection.set(true) + allowUserState.set(true) runTestCases(callingUserId, callingUserId, throws = false) if (verifyCrossUser) { @@ -769,6 +811,9 @@ class DomainVerificationEnforcerTest { // INTERNAL || domain verification agent VERIFIER, + // No permissions, allows all apps to view domain state for visible packages + SELECTION_QUERENT, + // Holding the user setting permission SELECTOR, diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationModelExtensions.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationModelExtensions.kt index 439048ce51bb6..8c31c65e1b0a1 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationModelExtensions.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationModelExtensions.kt @@ -18,7 +18,7 @@ package com.android.server.pm.test.verify.domain import android.content.pm.verify.domain.DomainVerificationRequest import android.content.pm.verify.domain.DomainVerificationInfo -import android.content.pm.verify.domain.DomainVerificationUserSelection +import android.content.pm.verify.domain.DomainVerificationUserState import com.android.server.pm.verify.domain.DomainVerificationPersistence operator fun android.util.Pair.component1() = first @@ -30,11 +30,11 @@ operator fun DomainVerificationInfo.component1() = identifier operator fun DomainVerificationInfo.component2() = packageName operator fun DomainVerificationInfo.component3() = hostToStateMap -operator fun DomainVerificationUserSelection.component1() = identifier -operator fun DomainVerificationUserSelection.component2() = packageName -operator fun DomainVerificationUserSelection.component3() = user -operator fun DomainVerificationUserSelection.component4() = isLinkHandlingAllowed -operator fun DomainVerificationUserSelection.component5() = hostToStateMap +operator fun DomainVerificationUserState.component1() = identifier +operator fun DomainVerificationUserState.component2() = packageName +operator fun DomainVerificationUserState.component3() = user +operator fun DomainVerificationUserState.component4() = isLinkHandlingAllowed +operator fun DomainVerificationUserState.component5() = hostToStateMap operator fun DomainVerificationPersistence.ReadResult.component1() = active operator fun DomainVerificationPersistence.ReadResult.component2() = restored diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPersistenceTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPersistenceTest.kt index a92ab9e35ddca..ad9aa7b6e3ae0 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPersistenceTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPersistenceTest.kt @@ -22,9 +22,9 @@ import android.util.TypedXmlPullParser import android.util.TypedXmlSerializer import android.util.Xml import com.android.server.pm.verify.domain.DomainVerificationPersistence +import com.android.server.pm.verify.domain.models.DomainVerificationInternalUserState import com.android.server.pm.verify.domain.models.DomainVerificationPkgState import com.android.server.pm.verify.domain.models.DomainVerificationStateMap -import com.android.server.pm.verify.domain.models.DomainVerificationUserState import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import org.junit.Rule @@ -102,14 +102,14 @@ class DomainVerificationPersistenceTest { // A domain without a written state falls back to default stateMap["missing-state.com"] = DomainVerificationManager.STATE_NO_RESPONSE - userSelectionStates[1] = DomainVerificationUserState(1).apply { + userStates[1] = DomainVerificationInternalUserState(1).apply { addHosts(setOf("example-user1.com", "example-user1.org")) isLinkHandlingAllowed = true } } val stateOne = mockEmptyPkgState(1).apply { // It's valid to have a user selection without any autoVerify domains - userSelectionStates[1] = DomainVerificationUserState(1).apply { + userStates[1] = DomainVerificationInternalUserState(1).apply { addHosts(setOf("example-user1.com", "example-user1.org")) isLinkHandlingAllowed = false } @@ -214,7 +214,7 @@ class DomainVerificationPersistenceTest { private fun mockPkgState(id: Int) = mockEmptyPkgState(id).apply { stateMap["$packageName.com"] = id - userSelectionStates[id] = DomainVerificationUserState(id).apply { + userStates[id] = DomainVerificationInternalUserState(id).apply { addHosts(setOf("$packageName-user.com")) isLinkHandlingAllowed = true } diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt index 010eacf3f51f8..0d8f275be09c7 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt @@ -122,8 +122,8 @@ class DomainVerificationSettingsMutationTest { service("clearState") { clearDomainVerificationState(listOf(TEST_PKG)) }, - service("clearUserSelections") { - clearUserSelections(listOf(TEST_PKG), TEST_USER_ID) + service("clearUserStates") { + clearUserStates(listOf(TEST_PKG), TEST_USER_ID) }, service("setStatus") { setDomainVerificationStatus( @@ -147,19 +147,13 @@ class DomainVerificationSettingsMutationTest { DomainVerificationManager.STATE_SUCCESS ) }, - service("setLinkHandlingAllowed") { - setDomainVerificationLinkHandlingAllowed(TEST_PKG, true) - }, service("setLinkHandlingAllowedUserId") { setDomainVerificationLinkHandlingAllowed(TEST_PKG, true, TEST_USER_ID) }, service("setLinkHandlingAllowedInternal") { setDomainVerificationLinkHandlingAllowedInternal(TEST_PKG, true, TEST_USER_ID) }, - service("setUserSelection") { - setDomainVerificationUserSelection(TEST_UUID, setOf("example.com"), true) - }, - service("setUserSelectionUserId") { + service("setUserStateUserId") { setDomainVerificationUserSelection( TEST_UUID, setOf("example.com"), @@ -167,7 +161,7 @@ class DomainVerificationSettingsMutationTest { TEST_USER_ID ) }, - service("setUserSelectionInternal") { + service("setUserStateInternal") { setDomainVerificationUserSelectionInternal( TEST_USER_ID, TEST_PKG, diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerUserSelectionOverrideTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt similarity index 82% rename from services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerUserSelectionOverrideTest.kt rename to services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt index 48056a2b54d14..0576125748fb1 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerUserSelectionOverrideTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt @@ -16,18 +16,16 @@ package com.android.server.pm.test.verify.domain -import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.content.pm.parsing.component.ParsedActivity import android.content.pm.parsing.component.ParsedIntentInfo import android.content.pm.verify.domain.DomainVerificationManager -import android.content.pm.verify.domain.DomainVerificationUserSelection +import android.content.pm.verify.domain.DomainVerificationUserState import android.os.Build import android.os.PatternMatcher import android.os.Process import android.util.ArraySet -import androidx.test.InstrumentationRegistry import com.android.server.pm.PackageSetting import com.android.server.pm.parsing.pkg.AndroidPackage import com.android.server.pm.verify.domain.DomainVerificationService @@ -41,7 +39,7 @@ import org.mockito.ArgumentMatchers.anyLong import org.mockito.ArgumentMatchers.anyString import java.util.UUID -class DomainVerificationManagerUserSelectionOverrideTest { +class DomainVerificationUserStateOverrideTest { companion object { private const val PKG_ONE = "com.test.one" @@ -50,17 +48,19 @@ class DomainVerificationManagerUserSelectionOverrideTest { private val UUID_TWO = UUID.fromString("a3389c16-7f9f-4e86-85e3-500d1249c74c") private val DOMAIN_ONE = - DomainVerificationManagerUserSelectionOverrideTest::class.java.packageName + DomainVerificationUserStateOverrideTest::class.java.packageName - private const val STATE_NONE = DomainVerificationUserSelection.DOMAIN_STATE_NONE - private const val STATE_SELECTED = DomainVerificationUserSelection.DOMAIN_STATE_SELECTED - private const val STATE_VERIFIED = DomainVerificationUserSelection.DOMAIN_STATE_VERIFIED + private const val STATE_NONE = DomainVerificationUserState.DOMAIN_STATE_NONE + private const val STATE_SELECTED = DomainVerificationUserState.DOMAIN_STATE_SELECTED + private const val STATE_VERIFIED = DomainVerificationUserState.DOMAIN_STATE_VERIFIED + + private const val USER_ID = 0 } private val pkg1 = mockPkgSetting(PKG_ONE, UUID_ONE) private val pkg2 = mockPkgSetting(PKG_TWO, UUID_TWO) - fun makeManager(): DomainVerificationManager = + fun makeService() = DomainVerificationService(mockThrowOnUnmocked { // Assume the test has every permission necessary whenever(enforcePermission(anyString(), anyInt(), anyInt(), anyString())) @@ -88,7 +88,7 @@ class DomainVerificationManagerUserSelectionOverrideTest { addPackage(pkg2) // Starting state for all tests is to have domain 1 enabled for the first package - setDomainVerificationUserSelection(UUID_ONE, setOf(DOMAIN_ONE), true) + setDomainVerificationUserSelection(UUID_ONE, setOf(DOMAIN_ONE), true, USER_ID) assertThat(stateFor(PKG_ONE, DOMAIN_ONE)).isEqualTo(STATE_SELECTED) } @@ -138,37 +138,37 @@ class DomainVerificationManagerUserSelectionOverrideTest { @Test fun anotherPackageTakeoverSuccess() { - val manager = makeManager() + val service = makeService() // Attempt override by package 2 - manager.setDomainVerificationUserSelection(UUID_TWO, setOf(DOMAIN_ONE), true) + service.setDomainVerificationUserSelection(UUID_TWO, setOf(DOMAIN_ONE), true, USER_ID) // 1 loses approval - assertThat(manager.stateFor(PKG_ONE, DOMAIN_ONE)).isEqualTo(STATE_NONE) + assertThat(service.stateFor(PKG_ONE, DOMAIN_ONE)).isEqualTo(STATE_NONE) // 2 gains approval - assertThat(manager.stateFor(PKG_TWO, DOMAIN_ONE)).isEqualTo(STATE_SELECTED) + assertThat(service.stateFor(PKG_TWO, DOMAIN_ONE)).isEqualTo(STATE_SELECTED) // 2 is the only owner - assertThat(manager.getOwnersForDomain(DOMAIN_ONE).map { it.packageName }) + assertThat(service.getOwnersForDomain(DOMAIN_ONE, USER_ID).map { it.packageName }) .containsExactly(PKG_TWO) } @Test(expected = IllegalArgumentException::class) fun anotherPackageTakeoverFailure() { - val manager = makeManager() + val service = makeService() // Verify 1 to give it a higher approval level - manager.setDomainVerificationStatus(UUID_ONE, setOf(DOMAIN_ONE), + service.setDomainVerificationStatus(UUID_ONE, setOf(DOMAIN_ONE), DomainVerificationManager.STATE_SUCCESS) - assertThat(manager.stateFor(PKG_ONE, DOMAIN_ONE)).isEqualTo(STATE_VERIFIED) - assertThat(manager.getOwnersForDomain(DOMAIN_ONE).map { it.packageName }) + assertThat(service.stateFor(PKG_ONE, DOMAIN_ONE)).isEqualTo(STATE_VERIFIED) + assertThat(service.getOwnersForDomain(DOMAIN_ONE, USER_ID).map { it.packageName }) .containsExactly(PKG_ONE) // Attempt override by package 2 - manager.setDomainVerificationUserSelection(UUID_TWO, setOf(DOMAIN_ONE), true) + service.setDomainVerificationUserSelection(UUID_TWO, setOf(DOMAIN_ONE), true, USER_ID) } - private fun DomainVerificationManager.stateFor(pkgName: String, host: String) = - getDomainVerificationUserSelection(pkgName)!!.hostToStateMap[host] + private fun DomainVerificationService.stateFor(pkgName: String, host: String) = + getDomainVerificationUserState(pkgName, USER_ID)!!.hostToStateMap[host] }