summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageUserState.java14
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java31
-rw-r--r--services/core/java/com/android/server/pm/PackageSettingBase.java50
-rw-r--r--services/core/java/com/android/server/pm/Settings.java54
-rw-r--r--services/core/java/com/android/server/pm/domain/verify/DomainVerificationCollector.java20
-rw-r--r--services/core/java/com/android/server/pm/domain/verify/DomainVerificationEnforcer.java7
-rw-r--r--services/core/java/com/android/server/pm/domain/verify/DomainVerificationLegacySettings.java228
-rw-r--r--services/core/java/com/android/server/pm/domain/verify/DomainVerificationManagerInternal.java42
-rw-r--r--services/core/java/com/android/server/pm/domain/verify/DomainVerificationService.java105
-rw-r--r--services/core/java/com/android/server/pm/domain/verify/DomainVerificationUtils.java33
-rw-r--r--services/core/java/com/android/server/pm/intent/verify/legacy/IntentFilterVerificationSettings.java27
-rw-r--r--services/core/java/com/android/server/pm/intent/verify/legacy/IntentVerifyUtils.java15
-rw-r--r--services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationEnforcerTest.kt1
-rw-r--r--services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationLegacySettingsTest.kt103
-rw-r--r--services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationPersistenceTest.kt46
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java8
17 files changed, 573 insertions, 213 deletions
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 99258712030c..5cc74c0a1c8e 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -77,8 +77,6 @@ public class PackageUserState {
public boolean virtualPreload;
public int enabled;
public String lastDisableAppCaller;
- public int domainVerificationStatus;
- public int appLinkGeneration;
public int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
public int installReason;
public @PackageManager.UninstallReason int uninstallReason;
@@ -100,8 +98,6 @@ public class PackageUserState {
hidden = false;
suspended = false;
enabled = COMPONENT_ENABLED_STATE_DEFAULT;
- domainVerificationStatus =
- PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
installReason = PackageManager.INSTALL_REASON_UNKNOWN;
uninstallReason = PackageManager.UNINSTALL_REASON_UNKNOWN;
}
@@ -120,8 +116,6 @@ public class PackageUserState {
virtualPreload = o.virtualPreload;
enabled = o.enabled;
lastDisableAppCaller = o.lastDisableAppCaller;
- domainVerificationStatus = o.domainVerificationStatus;
- appLinkGeneration = o.appLinkGeneration;
categoryHint = o.categoryHint;
installReason = o.installReason;
uninstallReason = o.uninstallReason;
@@ -416,12 +410,6 @@ public class PackageUserState {
&& !lastDisableAppCaller.equals(oldState.lastDisableAppCaller))) {
return false;
}
- if (domainVerificationStatus != oldState.domainVerificationStatus) {
- return false;
- }
- if (appLinkGeneration != oldState.appLinkGeneration) {
- return false;
- }
if (categoryHint != oldState.categoryHint) {
return false;
}
@@ -481,8 +469,6 @@ public class PackageUserState {
hashCode = 31 * hashCode + Boolean.hashCode(virtualPreload);
hashCode = 31 * hashCode + enabled;
hashCode = 31 * hashCode + Objects.hashCode(lastDisableAppCaller);
- hashCode = 31 * hashCode + domainVerificationStatus;
- hashCode = 31 * hashCode + appLinkGeneration;
hashCode = 31 * hashCode + categoryHint;
hashCode = 31 * hashCode + installReason;
hashCode = 31 * hashCode + uninstallReason;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 42d900f04060..cbc66ac64436 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -238,7 +238,6 @@ import android.content.pm.VersionedPackage;
import android.content.pm.dex.ArtManager;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.dex.IArtManager;
-import android.content.pm.domain.verify.DomainVerificationManager;
import android.content.pm.parsing.ApkLiteParseUtils;
import android.content.pm.parsing.PackageLite;
import android.content.pm.parsing.ParsingPackageUtils;
@@ -386,7 +385,6 @@ import com.android.server.pm.domain.verify.proxy.DomainVerificationProxyV2;
import com.android.server.pm.intent.verify.legacy.IntentFilterVerificationManager;
import com.android.server.pm.intent.verify.legacy.IntentFilterVerificationParams;
import com.android.server.pm.intent.verify.legacy.IntentVerifierProxy;
-import com.android.server.pm.intent.verify.legacy.IntentVerifyUtils;
import com.android.server.pm.parsing.PackageCacher;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.PackageParser2;
@@ -1814,7 +1812,7 @@ public class PackageManagerService extends IPackageManager.Stub
@NonNull
@Override
public WatchedSparseIntArray getNextAppLinkGeneration() {
- return mSettings.mNextAppLinkGeneration;
+ return null;
}
@NonNull
@@ -2753,7 +2751,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
// Try to get the status from User settings first
- long packedStatus = IntentVerifyUtils.getDomainVerificationStatus(ps, userId);
+ long packedStatus = 0;
+ //IntentVerifyUtils.getDomainVerificationStatus(ps, userId);
int status = (int)(packedStatus >> 32);
int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
@@ -2980,8 +2979,8 @@ public class PackageManagerService extends IPackageManager.Stub
result.wereAnyDomainsVerificationApproved |= mDomainVerificationManager
.isApprovedForDomain(ps, intent, riTargetUser.targetUserId);
} else {
- long verificationState =
- IntentVerifyUtils.getDomainVerificationStatus(ps, parentUserId);
+ long verificationState = 0;
+ //IntentVerifyUtils.getDomainVerificationStatus(ps, parentUserId);
int status = (int) (verificationState >> 32);
result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
result.bestDomainVerificationStatus);
@@ -3257,8 +3256,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- final long packedStatus =
- IntentVerifyUtils.getDomainVerificationStatus(ps, userId);
+ final long packedStatus = 0;
+ //IntentVerifyUtils.getDomainVerificationStatus(ps, userId);
final int status = (int)(packedStatus >> 32);
if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
// there's a local instant application installed, but, the user has
@@ -4202,8 +4201,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
} else {
// Try to get the status from User settings first
- final long packedStatus =
- IntentVerifyUtils.getDomainVerificationStatus(ps, userId);
+ final long packedStatus = 0;
+ //IntentVerifyUtils.getDomainVerificationStatus(ps, userId);
final int status = (int) (packedStatus >> 32);
if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
|| status
@@ -9655,8 +9654,8 @@ public class PackageManagerService extends IPackageManager.Stub
return ri;
}
} else {
- final long packedStatus =
- IntentVerifyUtils.getDomainVerificationStatus(ps, userId);
+ final long packedStatus = 0;
+ //IntentVerifyUtils.getDomainVerificationStatus(ps, userId);
final int status = (int) (packedStatus >> 32);
if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
return ri;
@@ -16447,13 +16446,13 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public int getIntentVerificationStatus(String packageName, int userId) {
- return mIntentFilterVerificationManager.getIntentVerificationStatus(packageName, userId);
+ return mDomainVerificationManager.getLegacyState(packageName, userId);
}
@Override
public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
- return mIntentFilterVerificationManager.updateIntentVerificationStatus(packageName, status,
- userId);
+ mDomainVerificationManager.setLegacyUserState(packageName, userId, status);
+ return true;
}
@Override
@@ -21681,8 +21680,6 @@ public class PackageManagerService extends IPackageManager.Stub
null /*lastDisableAppCaller*/,
null /*enabledComponents*/,
null /*disabledComponents*/,
- ps.readUserState(nextUserId).domainVerificationStatus,
- 0 /*linkGeneration*/,
PackageManager.INSTALL_REASON_UNKNOWN,
PackageManager.UNINSTALL_REASON_UNKNOWN,
null /*harmfulAppWarning*/);
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index b69d2b015d6c..d3005184e087 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -133,8 +133,6 @@ public abstract class PackageSettingBase extends SettingBase {
/** Whether or not an update is available. Ostensibly only for instant apps. */
boolean updateAvailable;
- IntentFilterVerificationInfo verificationInfo;
-
boolean forceQueryableOverride;
@NonNull
@@ -260,7 +258,6 @@ public abstract class PackageSettingBase extends SettingBase {
for (int i = 0; i < orig.mUserState.size(); i++) {
mUserState.put(orig.mUserState.keyAt(i), orig.mUserState.valueAt(i));
}
- verificationInfo = orig.verificationInfo;
versionCode = orig.versionCode;
volumeUuid = orig.volumeUuid;
categoryHint = orig.categoryHint;
@@ -354,12 +351,6 @@ public abstract class PackageSettingBase extends SettingBase {
/**
* Only use for testing. Do NOT use in production code.
- *
- * Unless you're {@link DomainVerificationService} and you need to migrate legacy state.
- * This is done rather than passing in the user IDs to
- * {@link DomainVerificationManagerInternal#addPackage(PackageSetting)} to make the v2 APIs
- * completely correct, without legacy details, since that method inherently does not care about
- * the users on the device.
*/
@VisibleForTesting
@Deprecated
@@ -507,8 +498,7 @@ public abstract class PackageSettingBase extends SettingBase {
ArrayMap<String, PackageUserState.SuspendParams> suspendParams, boolean instantApp,
boolean virtualPreload, String lastDisableAppCaller,
ArraySet<String> enabledComponents, ArraySet<String> disabledComponents,
- int domainVerifState, int linkGeneration, int installReason, int uninstallReason,
- String harmfulAppWarning) {
+ int installReason, int uninstallReason, String harmfulAppWarning) {
PackageUserState state = modifyUserState(userId);
state.ceDataInode = ceDataInode;
state.enabled = enabled;
@@ -522,8 +512,6 @@ public abstract class PackageSettingBase extends SettingBase {
state.lastDisableAppCaller = lastDisableAppCaller;
state.enabledComponents = enabledComponents;
state.disabledComponents = disabledComponents;
- state.domainVerificationStatus = domainVerifState;
- state.appLinkGeneration = linkGeneration;
state.installReason = installReason;
state.uninstallReason = uninstallReason;
state.instantApp = instantApp;
@@ -539,7 +527,6 @@ public abstract class PackageSettingBase extends SettingBase {
otherState.instantApp,
otherState.virtualPreload, otherState.lastDisableAppCaller,
otherState.enabledComponents, otherState.disabledComponents,
- otherState.domainVerificationStatus, otherState.appLinkGeneration,
otherState.installReason, otherState.uninstallReason, otherState.harmfulAppWarning);
}
@@ -655,40 +642,6 @@ public abstract class PackageSettingBase extends SettingBase {
return excludedUserIds;
}
- public IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
- return verificationInfo;
- }
-
- public void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
- verificationInfo = info;
- onChanged();
- }
-
- // Returns a packed value as a long:
- //
- // high 'int'-sized word: link status: undefined/ask/never/always.
- // low 'int'-sized word: relative priority among 'always' results.
- public long getDomainVerificationStatusForUser(int userId) {
- PackageUserState state = readUserState(userId);
- long result = (long) state.appLinkGeneration;
- result |= ((long) state.domainVerificationStatus) << 32;
- return result;
- }
-
- public void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
- PackageUserState state = modifyUserState(userId);
- state.domainVerificationStatus = status;
- if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
- state.appLinkGeneration = generation;
- onChanged();
- }
- }
-
- public void clearDomainVerificationStatusForUser(int userId) {
- modifyUserState(userId).domainVerificationStatus =
- PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
- }
-
protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) {
int count = mUserState.size();
for (int i = 0; i < count; i++) {
@@ -856,7 +809,6 @@ public abstract class PackageSettingBase extends SettingBase {
this.volumeUuid = other.volumeUuid;
this.categoryHint = other.categoryHint;
this.updateAvailable = other.updateAvailable;
- this.verificationInfo = other.verificationInfo;
this.forceQueryableOverride = other.forceQueryableOverride;
this.incrementalStates = other.incrementalStates;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 689830bd6b98..43617cf9a0c9 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -21,7 +21,6 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
-import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
import static android.content.pm.PackageManager.UNINSTALL_REASON_USER_TYPE;
@@ -106,6 +105,7 @@ import com.android.permission.persistence.RuntimePermissionsState;
import com.android.server.LocalServices;
import com.android.server.backup.PreferredActivityBackupHelper;
import com.android.server.pm.Installer.InstallerException;
+import com.android.server.pm.domain.verify.DomainVerificationLegacySettings;
import com.android.server.pm.domain.verify.DomainVerificationManagerInternal;
import com.android.server.pm.domain.verify.DomainVerificationPersistence;
import com.android.server.pm.intent.verify.legacy.IntentFilterVerificationManager;
@@ -557,7 +557,6 @@ public final class Settings implements Watchable, Snappable {
mOtherAppIds.registerObserver(mObserver);
mRenamedPackages.registerObserver(mObserver);
mDefaultBrowserApp.registerObserver(mObserver);
- mNextAppLinkGeneration.registerObserver(mObserver);
Watchable.verifyWatchedAttributes(this, mObserver);
}
@@ -610,7 +609,6 @@ public final class Settings implements Watchable, Snappable {
mOtherAppIds.registerObserver(mObserver);
mRenamedPackages.registerObserver(mObserver);
mDefaultBrowserApp.registerObserver(mObserver);
- mNextAppLinkGeneration.registerObserver(mObserver);
Watchable.verifyWatchedAttributes(this, mObserver);
}
@@ -659,7 +657,6 @@ public final class Settings implements Watchable, Snappable {
mKeySetRefs.putAll(r.mKeySetRefs);
mRenamedPackages.snapshot(r.mRenamedPackages);
mDefaultBrowserApp.snapshot(r.mDefaultBrowserApp);
- mNextAppLinkGeneration.snapshot(r.mNextAppLinkGeneration);
// mReadMessages
mPendingPackages.addAll(r.mPendingPackages);
mSystemDir = null;
@@ -938,8 +935,6 @@ public final class Settings implements Watchable, Snappable {
null /*lastDisableAppCaller*/,
null /*enabledComponents*/,
null /*disabledComponents*/,
- INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
- 0 /*linkGeneration*/,
PackageManager.INSTALL_REASON_UNKNOWN,
PackageManager.UNINSTALL_REASON_UNKNOWN,
null /*harmfulAppWarning*/);
@@ -1182,12 +1177,6 @@ public final class Settings implements Watchable, Snappable {
replaceAppIdLPw(p.appId, sharedUser);
}
}
-
- IntentFilterVerificationInfo info =
- mIntentFilterVerificationManager.getRestoredIntentFilterVerificationInfo(p.name);
- if (info != null) {
- p.setIntentFilterVerificationInfo(info);
- }
}
int removePackageLPw(String name) {
@@ -1582,8 +1571,6 @@ public final class Settings implements Watchable, Snappable {
null /*lastDisableAppCaller*/,
null /*enabledComponents*/,
null /*disabledComponents*/,
- INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
- 0 /*linkGeneration*/,
PackageManager.INSTALL_REASON_UNKNOWN,
PackageManager.UNINSTALL_REASON_UNKNOWN,
null /*harmfulAppWarning*/);
@@ -1608,8 +1595,6 @@ public final class Settings implements Watchable, Snappable {
return;
}
- int maxAppLinkGeneration = 0;
-
int outerDepth = parser.getDepth();
PackageSetting ps = null;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
@@ -1672,11 +1657,6 @@ public final class Settings implements Watchable, Snappable {
final int verifState = parser.getAttributeInt(null,
ATTR_DOMAIN_VERIFICATON_STATE,
PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
- final int linkGeneration =
- parser.getAttributeInt(null, ATTR_APP_LINK_GENERATION, 0);
- if (linkGeneration > maxAppLinkGeneration) {
- maxAppLinkGeneration = linkGeneration;
- }
final int installReason = parser.getAttributeInt(null, ATTR_INSTALL_REASON,
PackageManager.INSTALL_REASON_UNKNOWN);
final int uninstallReason = parser.getAttributeInt(null, ATTR_UNINSTALL_REASON,
@@ -1752,9 +1732,10 @@ public final class Settings implements Watchable, Snappable {
}
ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
hidden, distractionFlags, suspended, suspendParamsMap,
- instantApp, virtualPreload,
- enabledCaller, enabledComponents, disabledComponents, verifState,
- linkGeneration, installReason, uninstallReason, harmfulAppWarning);
+ instantApp, virtualPreload, enabledCaller, enabledComponents,
+ disabledComponents, installReason, uninstallReason, harmfulAppWarning);
+
+ mDomainVerificationManager.setLegacyUserState(name, userId, verifState);
} else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLPw(parser, userId);
} else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
@@ -1773,9 +1754,6 @@ public final class Settings implements Watchable, Snappable {
}
str.close();
-
- mNextAppLinkGeneration.put(userId, maxAppLinkGeneration + 1);
-
} catch (XmlPullParserException e) {
mReadMessages.append("Error reading: " + e.toString());
PackageManagerService.reportSettingsProblem(Log.ERROR,
@@ -2002,15 +1980,6 @@ public final class Settings implements Watchable, Snappable {
ustate.lastDisableAppCaller);
}
}
- if (ustate.domainVerificationStatus !=
- PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
- serializer.attributeInt(null, ATTR_DOMAIN_VERIFICATON_STATE,
- ustate.domainVerificationStatus);
- }
- if (ustate.appLinkGeneration != 0) {
- serializer.attributeInt(null, ATTR_APP_LINK_GENERATION,
- ustate.appLinkGeneration);
- }
if (ustate.installReason != PackageManager.INSTALL_REASON_UNKNOWN) {
serializer.attributeInt(null, ATTR_INSTALL_REASON, ustate.installReason);
}
@@ -2747,8 +2716,7 @@ public final class Settings implements Watchable, Snappable {
writeSigningKeySetLPr(serializer, pkg.keySetData);
writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
writeKeySetAliasesLPr(serializer, pkg.keySetData);
- mIntentFilterVerificationManager.writeDomainVerificationsLPr(serializer,
- pkg.verificationInfo);
+ mDomainVerificationManager.writeLegacySettings(serializer, pkg.name);
writeMimeGroupLPr(serializer, pkg.mimeGroups);
serializer.endTag(null, "package");
@@ -2924,7 +2892,10 @@ public final class Settings implements Watchable, Snappable {
ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
} else if (tagName.equals(DomainVerificationPersistence.TAG_DOMAIN_VERIFICATIONS)) {
mDomainVerificationManager.readSettings(parser);
- }else {
+ } else if (tagName.equals(
+ DomainVerificationLegacySettings.TAG_DOMAIN_VERIFICATIONS_LEGACY)) {
+ mDomainVerificationManager.readLegacySettings(parser);
+ } else {
Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
@@ -3739,9 +3710,8 @@ public final class Settings implements Watchable, Snappable {
packageSetting.installSource =
packageSetting.installSource.setInitiatingPackageSignatures(signatures);
} else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
- IntentFilterVerificationInfo ivi =
- mIntentFilterVerificationManager.readDomainVerificationLPw(parser);
- packageSetting.setIntentFilterVerificationInfo(ivi);
+ IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
+ mDomainVerificationManager.addLegacySetting(packageSetting.name, ivi);
if (DEBUG_PARSER) {
Log.d(TAG, "Read domain verification for package: " + ivi.getPackageName());
}
diff --git a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationCollector.java b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationCollector.java
index 5aaa37e9dadd..832714f2bfe6 100644
--- a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationCollector.java
+++ b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationCollector.java
@@ -88,9 +88,8 @@ public class DomainVerificationCollector {
@NonNull
private ArraySet<String> collectDomains(@NonNull AndroidPackage pkg,
boolean checkAutoVerify) {
- @SuppressWarnings("ConstantConditions")
- boolean restrictDomains = Binder.withCleanCallingIdentity(
- () -> mPlatformCompat.isChangeEnabled(RESTRICT_DOMAINS, buildMockAppInfo(pkg)));
+ boolean restrictDomains =
+ DomainVerificationUtils.isChangeEnabled(mPlatformCompat, pkg, RESTRICT_DOMAINS);
ArraySet<String> domains = new ArraySet<>();
@@ -198,19 +197,4 @@ public class DomainVerificationCollector {
}
}
}
-
- /**
- * Passed to {@link PlatformCompat} because this can be invoked mid-install process, and
- * {@link PlatformCompat} will not be able to query the pending {@link ApplicationInfo} from
- * {@link PackageManager}.
- *
- * TODO(b/177613575): Can a different API be used?
- */
- @NonNull
- private ApplicationInfo buildMockAppInfo(@NonNull AndroidPackage pkg) {
- ApplicationInfo appInfo = new ApplicationInfo();
- appInfo.packageName = pkg.getPackageName();
- appInfo.targetSdkVersion = pkg.getTargetSdkVersion();
- return appInfo;
- }
}
diff --git a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationEnforcer.java b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationEnforcer.java
index 05b1c47f8b27..cdcc5fcba7b5 100644
--- a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationEnforcer.java
+++ b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationEnforcer.java
@@ -118,4 +118,11 @@ public class DomainVerificationEnforcer {
Binder.getCallingPid(), callingUid,
"Caller is not allowed to edit user selections");
}
+
+ public void callerIsLegacyUserSelector(int callingUid) {
+ mContext.enforcePermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS,
+ Binder.getCallingPid(), callingUid,
+ "Caller is not allowed to edit user state");
+ }
}
diff --git a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationLegacySettings.java b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationLegacySettings.java
new file mode 100644
index 000000000000..09307d2a2db1
--- /dev/null
+++ b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationLegacySettings.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2021 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 com.android.server.pm.domain.verify;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.pm.IntentFilterVerificationInfo;
+import android.content.pm.PackageManager;
+import android.util.ArrayMap;
+import android.util.SparseIntArray;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.pm.SettingsXml;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Reads and writes the old {@link android.content.pm.IntentFilterVerificationInfo} so that it can
+ * be migrated in to the new API. Will throw away the state once it's successfully applied so that
+ * eventually there will be no legacy state on the device.
+ *
+ * This attempt is best effort, and if the legacy state is lost that's acceptable. The user setting
+ * in the legacy API may have been set incorrectly because it was never made obvious to the user
+ * what it actually toggled, so there's a strong argument to prevent migration anyways. The user
+ * can just set their preferences again, this time with finer grained control, if the legacy state
+ * gets dropped.
+ */
+public class DomainVerificationLegacySettings {
+
+ public static final String TAG_DOMAIN_VERIFICATIONS_LEGACY = "domain-verifications-legacy";
+ public static final String TAG_USER_STATES = "user-states";
+ public static final String ATTR_PACKAGE_NAME = "packageName";
+ public static final String TAG_USER_STATE = "user-state";
+ public static final String ATTR_USER_ID = "userId";
+ public static final String ATTR_STATE = "state";
+
+ @NonNull
+ private final Object mLock = new Object();
+
+ @NonNull
+ private final ArrayMap<String, LegacyState> mStates = new ArrayMap<>();
+
+ public void add(@NonNull String packageName, @NonNull IntentFilterVerificationInfo info) {
+ synchronized (mLock) {
+ getOrCreateStateLocked(packageName).setInfo(info);
+ }
+ }
+
+ public void add(@NonNull String packageName, @UserIdInt int userId, int state) {
+ synchronized (mLock) {
+ getOrCreateStateLocked(packageName).addUserState(userId, state);
+ }
+ }
+
+ public int getUserState(@NonNull String packageName, @UserIdInt int userId) {
+ synchronized (mLock) {
+ LegacyState state = mStates.get(packageName);
+ if (state != null) {
+ return state.getUserState(userId);
+ }
+ }
+ return PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
+ }
+
+ @Nullable
+ public SparseIntArray getUserStates(@NonNull String packageName) {
+ synchronized (mLock) {
+ LegacyState state = mStates.get(packageName);
+ if (state != null) {
+ // Yes, this returns outside of the lock, but we assume that retrieval generally
+ // only happens after all adding has concluded from reading settings.
+ return state.getUserStates();
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ public IntentFilterVerificationInfo remove(@NonNull String packageName) {
+ synchronized (mLock) {
+ LegacyState state = mStates.get(packageName);
+ if (state != null && !state.isAttached()) {
+ state.markAttached();
+ return state.getInfo();
+ }
+ }
+ return null;
+ }
+
+ @GuardedBy("mLock")
+ @NonNull
+ private LegacyState getOrCreateStateLocked(@NonNull String packageName) {
+ LegacyState state = mStates.get(packageName);
+ if (state == null) {
+ state = new LegacyState();
+ mStates.put(packageName, state);
+ }
+
+ return state;
+ }
+
+ public void writeSettings(TypedXmlSerializer xmlSerializer) throws IOException {
+ try (SettingsXml.Serializer serializer = SettingsXml.serializer(xmlSerializer)) {
+ try (SettingsXml.WriteSection ignored =
+ serializer.startSection(TAG_DOMAIN_VERIFICATIONS_LEGACY)) {
+ synchronized (mLock) {
+ final int statesSize = mStates.size();
+ for (int stateIndex = 0; stateIndex < statesSize; stateIndex++) {
+ final LegacyState state = mStates.valueAt(stateIndex);
+ final SparseIntArray userStates = state.getUserStates();
+ if (userStates == null) {
+ continue;
+ }
+
+ final String packageName = mStates.keyAt(stateIndex);
+ try (SettingsXml.WriteSection userStatesSection =
+ serializer.startSection(TAG_USER_STATES)
+ .attribute(ATTR_PACKAGE_NAME, packageName)) {
+ final int userStatesSize = userStates.size();
+ for (int userStateIndex = 0; userStateIndex < userStatesSize;
+ userStateIndex++) {
+ final int userId = userStates.keyAt(userStateIndex);
+ final int userState = userStates.valueAt(userStateIndex);
+ userStatesSection.startSection(TAG_USER_STATE)
+ .attribute(ATTR_USER_ID, userId)
+ .attribute(ATTR_STATE, userState)
+ .finish();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void readSettings(TypedXmlPullParser xmlParser)
+ throws IOException, XmlPullParserException {
+ final SettingsXml.ChildSection child = SettingsXml.parser(xmlParser).children();
+ while (child.moveToNext()) {
+ if (TAG_USER_STATES.equals(child.getName())) {
+ readUserStates(child);
+ }
+ }
+ }
+
+ private void readUserStates(SettingsXml.ReadSection section) {
+ String packageName = section.getString(ATTR_PACKAGE_NAME);
+ synchronized (mLock) {
+ final LegacyState legacyState = getOrCreateStateLocked(packageName);
+ final SettingsXml.ChildSection child = section.children();
+ while (child.moveToNext()) {
+ if (TAG_USER_STATE.equals(child.getName())) {
+ readUserState(child, legacyState);
+ }
+ }
+ }
+ }
+
+ private void readUserState(SettingsXml.ReadSection section, LegacyState legacyState) {
+ int userId = section.getInt(ATTR_USER_ID);
+ int state = section.getInt(ATTR_STATE);
+ legacyState.addUserState(userId, state);
+ }
+
+ static class LegacyState {
+ @Nullable
+ private IntentFilterVerificationInfo mInfo;
+
+ @Nullable
+ private SparseIntArray mUserStates;
+
+ private boolean attached;
+
+ @Nullable
+ public IntentFilterVerificationInfo getInfo() {
+ return mInfo;
+ }
+
+ public int getUserState(int userId) {
+ return mUserStates.get(userId,
+ PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
+ }
+
+ @Nullable
+ public SparseIntArray getUserStates() {
+ return mUserStates;
+ }
+
+ public void setInfo(@NonNull IntentFilterVerificationInfo info) {
+ mInfo = info;
+ }
+
+ public void addUserState(@UserIdInt int userId, int state) {
+ if (mUserStates == null) {
+ mUserStates = new SparseIntArray(1);
+ }
+ mUserStates.put(userId, state);
+ }
+
+ public boolean isAttached() {
+ return attached;
+ }
+
+ public void markAttached() {
+ attached = true;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationManagerInternal.java b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationManagerInternal.java
index 9ef498780393..56994c864870 100644
--- a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationManagerInternal.java
+++ b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationManagerInternal.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.content.Intent;
+import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.domain.verify.DomainVerificationManager;
import android.content.pm.domain.verify.DomainVerificationSet;
@@ -31,6 +32,7 @@ import android.util.TypedXmlSerializer;
import com.android.server.pm.PackageSetting;
import com.android.server.pm.domain.verify.models.DomainVerificationPkgState;
import com.android.server.pm.domain.verify.proxy.DomainVerificationProxy;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
import org.xmlpull.v1.XmlPullParserException;
@@ -103,15 +105,14 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan
/**
* Serializes the entire internal state. This is equivalent to a full backup of the existing
- * verification state.
+ * verification state. This write includes legacy state, as a sibling tag the modern state.
*/
void writeSettings(@NonNull TypedXmlSerializer serializer) throws IOException;
/**
* Read back a list of {@link DomainVerificationPkgState}s previously written by {@link
* #writeSettings(TypedXmlSerializer)}. Assumes that the
- * {@link DomainVerificationPersistence#TAG_DOMAIN_VERIFICATIONS}
- * tag has already been entered.
+ * {@link DomainVerificationPersistence#TAG_DOMAIN_VERIFICATIONS} tag has already been entered.
* <p>
* This is expected to only be used to re-attach states for packages already known to be on the
* device. If restoring from a backup, use {@link #restoreSettings(TypedXmlPullParser)}.
@@ -120,6 +121,15 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan
throws IOException, XmlPullParserException;
/**
+ * Read back data from
+ * {@link DomainVerificationLegacySettings#writeSettings(TypedXmlSerializer)}. Assumes that the
+ * {@link DomainVerificationLegacySettings#TAG_DOMAIN_VERIFICATIONS_LEGACY} tag has already
+ * been entered.
+ */
+ void readLegacySettings(@NonNull TypedXmlPullParser parser)
+ throws IOException, XmlPullParserException;
+
+ /**
* Remove all state for the given package.
*/
void clearPackage(@NonNull String packageName);
@@ -149,6 +159,32 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan
throws IOException, XmlPullParserException;
/**
+ * Set aside a legacy {@link IntentFilterVerificationInfo} that will be restored to a pending
+ * {@link DomainVerificationPkgState} once it's added through
+ * {@link #addPackage(PackageSetting)}.
+ */
+ void addLegacySetting(@NonNull String packageName, @NonNull IntentFilterVerificationInfo info);
+
+ /**
+ * Set aside a legacy user selection that will be restored to a pending
+ * {@link DomainVerificationPkgState} once it's added through
+ * {@link #addPackage(PackageSetting)}.
+ */
+ void setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state);
+
+ /**
+ * Until the legacy APIs are entirely removed, returns the legacy state from the previously
+ * written info stored in {@link com.android.server.pm.Settings}.
+ */
+ int getLegacyState(@NonNull String packageName, @UserIdInt int userId);
+
+ /**
+ * Serialize a legacy setting that wasn't attached yet.
+ * TODO: Does this even matter? Should consider for removal.
+ */
+ void writeLegacySettings(TypedXmlSerializer serializer, String name);
+
+ /**
* Print the verification state and user selection state of a package.
*
* @param packageName the package whose state to change, or all packages if none is specified
diff --git a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationService.java b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationService.java
index 0a28069017d4..ace72090193a 100644
--- a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationService.java
+++ b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationService.java
@@ -19,6 +19,8 @@ package com.android.server.pm.domain.verify;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
import android.content.Context;
import android.content.Intent;
import android.content.pm.IntentFilterVerificationInfo;
@@ -38,6 +40,7 @@ import android.util.IndentingPrintWriter;
import android.util.Singleton;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseIntArray;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
@@ -74,6 +77,19 @@ public class DomainVerificationService extends SystemService
public static final boolean DEBUG_APPROVAL = true;
/**
+ * The new user preference API for verifying domains marked autoVerify=true in
+ * AndroidManifest.xml intent filters is not yet implemented in the current platform preview.
+ * This is anticipated to ship before S releases.
+ *
+ * For now, it is possible to preview the new user preference changes by enabling this
+ * ChangeId and using the <code>adb shell pm set-app-links-user-selection</code> and similar
+ * commands.
+ */
+ @ChangeId
+ @Disabled
+ private static final long SETTINGS_API_V2 = 178111421;
+
+ /**
* States that are currently alive and attached to a package. Entries are exclusive with the
* state stored in {@link DomainVerificationSettings}, as any pending/restored state should be
* immediately attached once its available.
@@ -100,6 +116,9 @@ public class DomainVerificationService extends SystemService
private final SystemConfig mSystemConfig;
@NonNull
+ private final PlatformCompat mPlatformCompat;
+
+ @NonNull
private final DomainVerificationSettings mSettings;
@NonNull
@@ -115,6 +134,9 @@ public class DomainVerificationService extends SystemService
private final DomainVerificationShell mShell;
@NonNull
+ private final DomainVerificationLegacySettings mLegacySettings;
+
+ @NonNull
private final IDomainVerificationManager.Stub mStub = new DomainVerificationManagerStub(this);
@NonNull
@@ -125,11 +147,13 @@ public class DomainVerificationService extends SystemService
super(context);
mConnection = connection;
mSystemConfig = systemConfig;
+ mPlatformCompat = platformCompat;
mSettings = new DomainVerificationSettings();
mCollector = new DomainVerificationCollector(platformCompat, systemConfig);
mEnforcer = new DomainVerificationEnforcer(context);
mDebug = new DomainVerificationDebug(mCollector);
mShell = new DomainVerificationShell(this);
+ mLegacySettings = new DomainVerificationLegacySettings();
}
@Override
@@ -401,6 +425,8 @@ public class DomainVerificationService extends SystemService
.setDisallowLinkHandling(!allowed);
}
}
+
+ mConnection.get().scheduleWriteSettings();
}
@Override
@@ -473,6 +499,8 @@ public class DomainVerificationService extends SystemService
enabled, domains);
}
}
+
+ mConnection.get().scheduleWriteSettings();
}
private void setDomainVerificationUserSelectionInternal(int userId,
@@ -500,6 +528,8 @@ public class DomainVerificationService extends SystemService
userState.removeHosts(domains);
}
}
+
+ mConnection.get().scheduleWriteSettings();
}
@Nullable
@@ -693,12 +723,11 @@ public class DomainVerificationService extends SystemService
// and disable them if appropriate.
ArraySet<String> webDomains = null;
- @SuppressWarnings("deprecation")
- SparseArray<PackageUserState> userState = newPkgSetting.getUserState();
- int userStateSize = userState.size();
+ SparseIntArray legacyUserStates = mLegacySettings.getUserStates(pkgName);
+ int userStateSize = legacyUserStates == null ? 0 : legacyUserStates.size();
for (int index = 0; index < userStateSize; index++) {
- int userId = userState.keyAt(index);
- int legacyStatus = userState.valueAt(index).domainVerificationStatus;
+ int userId = legacyUserStates.keyAt(index);
+ int legacyStatus = legacyUserStates.valueAt(index);
if (legacyStatus
== PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
if (webDomains == null) {
@@ -709,8 +738,7 @@ public class DomainVerificationService extends SystemService
}
}
- IntentFilterVerificationInfo legacyInfo =
- newPkgSetting.getIntentFilterVerificationInfo();
+ IntentFilterVerificationInfo legacyInfo = mLegacySettings.remove(pkgName);
if (legacyInfo != null
&& legacyInfo.getStatus()
== PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
@@ -772,6 +800,8 @@ public class DomainVerificationService extends SystemService
synchronized (mLock) {
mSettings.writeSettings(serializer, mAttachedPkgStates);
}
+
+ mLegacySettings.writeSettings(serializer);
}
@Override
@@ -783,6 +813,12 @@ public class DomainVerificationService extends SystemService
}
@Override
+ public void readLegacySettings(@NonNull TypedXmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ mLegacySettings.readSettings(parser);
+ }
+
+ @Override
public void restoreSettings(@NonNull TypedXmlPullParser parser)
throws IOException, XmlPullParserException {
synchronized (mLock) {
@@ -791,6 +827,28 @@ public class DomainVerificationService extends SystemService
}
@Override
+ public void addLegacySetting(@NonNull String packageName,
+ @NonNull IntentFilterVerificationInfo info) {
+ mLegacySettings.add(packageName, info);
+ }
+
+ @Override
+ public void setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state) {
+ mEnforcer.callerIsLegacyUserSelector(mConnection.get().getCallingUid());
+ mLegacySettings.add(packageName, userId, state);
+ }
+
+ @Override
+ public int getLegacyState(@NonNull String packageName, @UserIdInt int userId) {
+ return mLegacySettings.getUserState(packageName, userId);
+ }
+
+ @Override
+ public void writeLegacySettings(TypedXmlSerializer serializer, String name) {
+
+ }
+
+ @Override
public void clearPackage(@NonNull String packageName) {
synchronized (mLock) {
mAttachedPkgStates.remove(packageName);
@@ -1051,13 +1109,36 @@ public class DomainVerificationService extends SystemService
return false;
}
- // To allow an instant app to immediately open domains after being installed by the user,
- // auto approve them for any declared autoVerify domains.
String host = intent.getData().getHost();
final AndroidPackage pkg = pkgSetting.getPkg();
- if (pkgSetting.getInstantApp(userId) && pkg != null
- && mCollector.collectAutoVerifyDomains(pkg).contains(host)) {
- return true;
+
+ // Should never be null, but if it is, skip this and assume that v2 is enabled
+ if (pkg != null) {
+ // To allow an instant app to immediately open domains after being installed by the
+ // user, auto approve them for any declared autoVerify domains.
+ if (pkgSetting.getInstantApp(userId)
+ && mCollector.collectAutoVerifyDomains(pkg).contains(host)) {
+ return true;
+ }
+
+ if (!DomainVerificationUtils.isChangeEnabled(mPlatformCompat, pkg, SETTINGS_API_V2)) {
+ int legacyState = mLegacySettings.getUserState(packageName, userId);
+ switch (legacyState) {
+ case PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
+ // If nothing specifically set, assume v2 rules
+ break;
+ case PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
+ case PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
+ case PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK:
+ // With v2 split into 2 lists, always and undefined, the concept of whether
+ // or not to ask is irrelevant. Assume the user wants this application to
+ // open the domain.
+ return true;
+ case PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER:
+ // Never has the same semantics are before
+ return false;
+ }
+ }
}
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationUtils.java b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationUtils.java
index ff030710274e..f704478b92a5 100644
--- a/services/core/java/com/android/server/pm/domain/verify/DomainVerificationUtils.java
+++ b/services/core/java/com/android/server/pm/domain/verify/DomainVerificationUtils.java
@@ -19,13 +19,20 @@ package com.android.server.pm.domain.verify;
import android.annotation.CheckResult;
import android.annotation.NonNull;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Binder;
+
+import com.android.server.compat.PlatformCompat;
+import com.android.server.pm.PackageManagerService;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
final class DomainVerificationUtils {
/**
- * Consolidates package exception messages. A generic unavailable message is included since
- * the caller doesn't bother to check why the package isn't available.
+ * Consolidates package exception messages. A generic unavailable message is included since the
+ * caller doesn't bother to check why the package isn't available.
*/
@CheckResult
static NameNotFoundException throwPackageUnavailable(@NonNull String packageName)
@@ -38,4 +45,26 @@ final class DomainVerificationUtils {
&& intent.hasCategory(Intent.CATEGORY_BROWSABLE)
&& intent.hasCategory(Intent.CATEGORY_DEFAULT);
}
+
+ static boolean isChangeEnabled(PlatformCompat platformCompat, AndroidPackage pkg,
+ long changeId) {
+ //noinspection ConstantConditions
+ return Binder.withCleanCallingIdentity(
+ () -> platformCompat.isChangeEnabled(changeId, buildMockAppInfo(pkg)));
+ }
+
+ /**
+ * Passed to {@link PlatformCompat} because this can be invoked mid-install process or when
+ * {@link PackageManagerService#mLock} is being held, and {@link PlatformCompat} will not be
+ * able to query the pending {@link ApplicationInfo} from {@link PackageManager}.
+ * <p>
+ * TODO(b/177613575): Can a different API be used?
+ */
+ @NonNull
+ private static ApplicationInfo buildMockAppInfo(@NonNull AndroidPackage pkg) {
+ ApplicationInfo appInfo = new ApplicationInfo();
+ appInfo.packageName = pkg.getPackageName();
+ appInfo.targetSdkVersion = pkg.getTargetSdkVersion();
+ return appInfo;
+ }
}
diff --git a/services/core/java/com/android/server/pm/intent/verify/legacy/IntentFilterVerificationSettings.java b/services/core/java/com/android/server/pm/intent/verify/legacy/IntentFilterVerificationSettings.java
index 2aac51402d10..3ff770d5fb3a 100644
--- a/services/core/java/com/android/server/pm/intent/verify/legacy/IntentFilterVerificationSettings.java
+++ b/services/core/java/com/android/server/pm/intent/verify/legacy/IntentFilterVerificationSettings.java
@@ -176,10 +176,10 @@ public class IntentFilterVerificationSettings {
public IntentFilterVerificationInfo updatePackageSetting(@NonNull PackageSetting pkgSetting,
ArraySet<String> domains) {
String pkgName = pkgSetting.name;
- IntentFilterVerificationInfo ivi = pkgSetting.getIntentFilterVerificationInfo();
+ IntentFilterVerificationInfo ivi = null;//pkgSetting.getIntentFilterVerificationInfo();
if (ivi == null) {
ivi = new IntentFilterVerificationInfo(pkgName, domains);
- pkgSetting.setIntentFilterVerificationInfo(ivi);
+ // pkgSetting.setIntentFilterVerificationInfo(ivi);
mConnection.debugLog("Creating new IntentFilterVerificationInfo for pkg: " + pkgName);
} else {
ivi.setDomains(domains);
@@ -197,7 +197,7 @@ public class IntentFilterVerificationSettings {
mConnection.warnLog("No package known: " + packageName);
return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
}
- return (int) (pkgSetting.getDomainVerificationStatusForUser(userId) >> 32);
+ return 0;//(int) (pkgSetting.getDomainVerificationStatusForUser(userId) >> 32);
}
@Nullable
@@ -208,7 +208,7 @@ public class IntentFilterVerificationSettings {
mConnection.warnLog("No package known: " + packageName);
return null;
}
- return ps.getIntentFilterVerificationInfo();
+ return null;//ps.getIntentFilterVerificationInfo();
}
boolean updateIntentFilterVerificationStatusLPw(String packageName, final int status,
@@ -222,14 +222,14 @@ public class IntentFilterVerificationSettings {
final int alwaysGeneration;
if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
- WatchedSparseIntArray nextAppLinkGeneration = mConnection.getNextAppLinkGeneration();
- alwaysGeneration = nextAppLinkGeneration.get(userId) + 1;
- nextAppLinkGeneration.put(userId, alwaysGeneration);
+// WatchedSparseIntArray nextAppLinkGeneration = mConnection.getNextAppLinkGeneration();
+// alwaysGeneration = nextAppLinkGeneration.get(userId) + 1;
+// nextAppLinkGeneration.put(userId, alwaysGeneration);
} else {
alwaysGeneration = 0;
}
- current.setDomainVerificationStatusForUser(status, alwaysGeneration, userId);
+// current.setDomainVerificationStatusForUser(status, alwaysGeneration, userId);
return true;
}
@@ -241,9 +241,8 @@ public class IntentFilterVerificationSettings {
return false;
}
if (alsoResetStatus) {
- ps.clearDomainVerificationStatusForUser(userId);
+// ps.clearDomainVerificationStatusForUser(userId);
}
- ps.setIntentFilterVerificationInfo(null);
return true;
}
@@ -262,7 +261,7 @@ public class IntentFilterVerificationSettings {
}
ArrayList<IntentFilterVerificationInfo> result = new ArrayList<>();
for (PackageSetting ps : mConnection.getPackageSettingsLPr().values()) {
- IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
+ IntentFilterVerificationInfo ivi = null;//ps.getIntentFilterVerificationInfo();
if (ivi == null || TextUtils.isEmpty(ivi.getPackageName()) ||
!ivi.getPackageName().equalsIgnoreCase(packageName)) {
continue;
@@ -278,7 +277,7 @@ public class IntentFilterVerificationSettings {
throws IllegalArgumentException, IllegalStateException, IOException {
serializer.startTag(null, Settings.TAG_ALL_INTENT_FILTER_VERIFICATION);
for (PackageSetting value : pkgSettings.values()) {
- IntentFilterVerificationInfo ivi = value.getIntentFilterVerificationInfo();
+ IntentFilterVerificationInfo ivi = null;//value.getIntentFilterVerificationInfo();
if (ivi != null) {
writeDomainVerificationsLPr(serializer, ivi);
}
@@ -318,7 +317,9 @@ public class IntentFilterVerificationSettings {
final PackageSetting ps = mConnection.getPackageSettingLPr(pkgName);
if (ps != null) {
// known/existing package; update in place
- ps.setIntentFilterVerificationInfo(ivi);
+ // TODO: Removed, commented out to allow compile, awaiting removal of entire
+ // class
+ // ps.setIntentFilterVerificationInfo(ivi);
mConnection.debugLog("Restored IVI for existing app " + pkgName
+ " status=" + ivi.getStatusString());
} else {
diff --git a/services/core/java/com/android/server/pm/intent/verify/legacy/IntentVerifyUtils.java b/services/core/java/com/android/server/pm/intent/verify/legacy/IntentVerifyUtils.java
index 389aa20e9ff0..b64ac94ba07f 100644
--- a/services/core/java/com/android/server/pm/intent/verify/legacy/IntentVerifyUtils.java
+++ b/services/core/java/com/android/server/pm/intent/verify/legacy/IntentVerifyUtils.java
@@ -31,19 +31,4 @@ public class IntentVerifyUtils {
&& (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
}
-
- // Returns a packed value as a long:
- //
- // high 'int'-sized word: link status: undefined/ask/never/always.
- // low 'int'-sized word: relative priority among 'always' results.
- public static long getDomainVerificationStatus(PackageSetting ps, int userId) {
- long result = ps.getDomainVerificationStatusForUser(userId);
- // if none available, get the status
- if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
- if (ps.getIntentFilterVerificationInfo() != null) {
- result = ((long) ps.getIntentFilterVerificationInfo().getStatus()) << 32;
- }
- }
- return result;
- }
}
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationEnforcerTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationEnforcerTest.kt
index 13a37ffe77d6..c944cff8c04f 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationEnforcerTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationEnforcerTest.kt
@@ -149,6 +149,7 @@ class DomainVerificationEnforcerTest {
whenever(getPackageSettingLocked(TEST_PKG)) { mockPkgSetting }
whenever(getPackageLocked(TEST_PKG)) { mockPkg }
whenever(schedule(anyInt(), any()))
+ whenever(scheduleWriteSettings())
}
})
)
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationLegacySettingsTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationLegacySettingsTest.kt
new file mode 100644
index 000000000000..47601a499d62
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationLegacySettingsTest.kt
@@ -0,0 +1,103 @@
+/*
+ * 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 com.android.server.pm.test.domain.verify
+
+import android.content.pm.IntentFilterVerificationInfo
+import android.content.pm.PackageManager
+import android.util.ArraySet
+import com.android.server.pm.domain.verify.DomainVerificationLegacySettings
+import com.android.server.pm.test.domain.verify.DomainVerificationPersistenceTest.Companion.readXml
+import com.android.server.pm.test.domain.verify.DomainVerificationPersistenceTest.Companion.writeXml
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+
+class DomainVerificationLegacySettingsTest {
+
+ @Rule
+ @JvmField
+ val tempFolder = TemporaryFolder()
+
+ @Test
+ fun writeAndReadBackNormal() {
+ val settings = DomainVerificationLegacySettings().apply {
+ add(
+ "com.test.one",
+ IntentFilterVerificationInfo(
+ "com.test.one",
+ ArraySet(setOf("example1.com", "example2.com"))
+ ).apply {
+ status = PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK
+ }
+ )
+ add(
+ "com.test.one",
+ 0, PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
+ )
+ add(
+ "com.test.one",
+ 10, PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER
+ )
+
+ add(
+ "com.test.two",
+ IntentFilterVerificationInfo(
+ "com.test.two",
+ ArraySet(setOf("example3.com"))
+ )
+ )
+
+ add(
+ "com.test.three",
+ 11, PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
+ )
+ }
+
+
+ val file = tempFolder.newFile().writeXml(settings::writeSettings)
+ val newSettings = file.readXml {
+ DomainVerificationLegacySettings().apply {
+ readSettings(it)
+ }
+ }
+
+ val xml = file.readText()
+
+ // Legacy migrated settings doesn't bother writing the legacy verification info
+ assertWithMessage(xml).that(newSettings.remove("com.test.one")).isNull()
+ assertWithMessage(xml).that(newSettings.getUserState("com.test.one", 0))
+ .isEqualTo(PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS)
+ assertWithMessage(xml).that(newSettings.getUserState("com.test.one", 10))
+ .isEqualTo(PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)
+
+ val firstUserStates = newSettings.getUserStates("com.test.one")
+ assertWithMessage(xml).that(firstUserStates).isNotNull()
+ assertWithMessage(xml).that(firstUserStates!!.size()).isEqualTo(2)
+ assertWithMessage(xml).that(firstUserStates[0])
+ .isEqualTo(PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS)
+ assertWithMessage(xml).that(firstUserStates[10])
+ .isEqualTo(PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)
+
+ assertWithMessage(xml).that(newSettings.remove("com.test.two")).isNull()
+ assertWithMessage(xml).that(newSettings.getUserStates("com.test.two")).isNull()
+
+ assertWithMessage(xml).that(newSettings.remove("com.test.three")).isNull()
+ assertWithMessage(xml).that(newSettings.getUserState("com.test.three", 11))
+ .isEqualTo(PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS)
+ }
+}
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationPersistenceTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationPersistenceTest.kt
index cf331d5ce775..ada5c1b063fa 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationPersistenceTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/domain/verify/DomainVerificationPersistenceTest.kt
@@ -18,6 +18,7 @@ package com.android.server.pm.test.domain.verify
import android.content.pm.domain.verify.DomainVerificationManager
import android.util.ArrayMap
+import android.util.TypedXmlPullParser
import android.util.TypedXmlSerializer
import android.util.Xml
import com.android.server.pm.domain.verify.DomainVerificationPersistence
@@ -29,12 +30,33 @@ import com.google.common.truth.Truth.assertWithMessage
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
+import java.io.File
+import java.nio.charset.StandardCharsets
import java.util.UUID
class DomainVerificationPersistenceTest {
companion object {
private val PKG_PREFIX = DomainVerificationPersistenceTest::class.java.`package`!!.name
+
+ internal fun File.writeXml(block: (serializer: TypedXmlSerializer) -> Unit) = apply {
+ outputStream().use {
+ // Explicitly use string based XML so it can printed in the test failure output
+ Xml.newFastSerializer()
+ .apply {
+ setOutput(it, StandardCharsets.UTF_8.name())
+ startDocument(null, true)
+ setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true)
+ }
+ .apply(block)
+ .endDocument()
+ }
+ }
+
+ internal fun <T> File.readXml(block: (parser: TypedXmlPullParser) -> T) =
+ inputStream().use {
+ block(Xml.resolvePullParser(it))
+ }
}
@Rule
@@ -56,17 +78,18 @@ class DomainVerificationPersistenceTest {
mockPkgState(5).let { put(it.packageName, it) }
}
- val file = writeXml {
+ val file = tempFolder.newFile().writeXml {
DomainVerificationPersistence.writeToXml(it, attached, pending, restored)
}
val xml = file.readText()
- val (readActive, readRestored) = file.inputStream()
- .use { DomainVerificationPersistence.readFromXml(Xml.resolvePullParser(it)) }
+ val (readActive, readRestored) = file.readXml {
+ DomainVerificationPersistence.readFromXml(it)
+ }
assertWithMessage(xml).that(readActive.values)
- .containsExactlyElementsIn(attached.values() + pending.values)
+ .containsExactlyElementsIn(attached.values() + pending.values)
assertWithMessage(xml).that(readRestored.values).containsExactlyElementsIn(restored.values)
}
@@ -172,25 +195,12 @@ class DomainVerificationPersistenceTest {
""".trimIndent()
val (active, restored) = DomainVerificationPersistence
- .readFromXml(Xml.resolvePullParser(xml.byteInputStream()))
+ .readFromXml(Xml.resolvePullParser(xml.byteInputStream()))
assertThat(active.values).containsExactly(stateZero)
assertThat(restored.values).containsExactly(stateOne, stateTwo)
}
- private fun writeXml(block: (TypedXmlSerializer) -> Unit) = tempFolder.newFile()
- .apply {
- outputStream().use {
- Xml.resolveSerializer(it)
- .apply {
- startDocument(null, true)
- setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true)
- }
- .apply(block)
- .endDocument()
- }
- }
-
private fun mockEmptyPkgState(
id: Int,
hasAutoVerifyDomains: Boolean = true
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index 850a031d7ad6..beeae7df6956 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -961,8 +961,6 @@ public class PackageManagerSettingsTests {
assertNotSame(origPkgSetting.getUserState(), is(testPkgSetting.getUserState()));
// No equals() method for SparseArray object
// assertThat(origPkgSetting.getUserState(), is(testPkgSetting.getUserState()));
- assertSame(origPkgSetting.verificationInfo, testPkgSetting.verificationInfo);
- assertThat(origPkgSetting.verificationInfo, is(testPkgSetting.verificationInfo));
assertThat(origPkgSetting.versionCode, is(testPkgSetting.versionCode));
assertSame(origPkgSetting.volumeUuid, testPkgSetting.volumeUuid);
assertThat(origPkgSetting.volumeUuid, is(testPkgSetting.volumeUuid));
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
index 1cfbad93c2e5..938e4cc84e62 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
@@ -53,18 +53,10 @@ public class PackageUserStateTest {
assertThat(testUserState.equals(oldUserState), is(true));
oldUserState = new PackageUserState();
- oldUserState.appLinkGeneration = 6;
- assertThat(testUserState.equals(oldUserState), is(false));
-
- oldUserState = new PackageUserState();
oldUserState.ceDataInode = 4000L;
assertThat(testUserState.equals(oldUserState), is(false));
oldUserState = new PackageUserState();
- oldUserState.domainVerificationStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
- assertThat(testUserState.equals(oldUserState), is(false));
-
- oldUserState = new PackageUserState();
oldUserState.enabled = COMPONENT_ENABLED_STATE_ENABLED;
assertThat(testUserState.equals(oldUserState), is(false));