Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f68089d authored by Winson's avatar Winson Committed by Winson Chiu
Browse files

Fix preserving app links user selection on package update

The wrong set of domains was being used for domain retainment during
migration. A test was added to check both verified and selected state
preservation on update.

Test: atest DomainVerificationPackageTest#migratePackageSelected

Bug: 205009465

Change-Id: I2c864a34f356e32948cbc4e5d249e12c691a5726
parent 08ff01e7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -899,7 +899,7 @@ public class DomainVerificationService extends SystemService
                    oldPkgState.getUserStates();
            int oldUserStatesSize = oldUserStates.size();
            if (oldUserStatesSize > 0) {
                ArraySet<String> newWebDomains = mCollector.collectValidAutoVerifyDomains(newPkg);
                ArraySet<String> newWebDomains = mCollector.collectAllWebDomains(newPkg);
                for (int oldUserStatesIndex = 0; oldUserStatesIndex < oldUserStatesSize;
                        oldUserStatesIndex++) {
                    int userId = oldUserStates.keyAt(oldUserStatesIndex);
+73 −16
Original line number Diff line number Diff line
@@ -623,6 +623,60 @@ class DomainVerificationPackageTest {
        assertThat(service.queryValidVerificationPackageNames()).containsExactly(pkgName)
    }

    @Test
    fun migratePackageSelected() {
        val pkgName = PKG_ONE
        val pkgBefore = mockPkgState(pkgName, UUID_ONE, SIGNATURE_ONE,
            listOf(DOMAIN_1), listOf(DOMAIN_2))
        val pkgAfter = mockPkgState(pkgName, UUID_TWO, SIGNATURE_TWO,
            listOf(DOMAIN_1), listOf(DOMAIN_2))

        val map = mutableMapOf<String, PackageStateInternal>()
        val service = makeService { map[it] }
        service.addPackage(pkgBefore)

        // Only insert the package after addPackage call to ensure the service doesn't access
        // a live package inside the addPackage logic. It should only use the provided input.
        map[pkgName] = pkgBefore

        assertThat(service.setStatus(UUID_ONE, setOf(DOMAIN_1), STATE_SUCCESS))
            .isEqualTo(DomainVerificationManager.STATUS_OK)

        assertThat(service.setUserSelection(UUID_ONE, setOf(DOMAIN_2), true, USER_ID))
            .isEqualTo(DomainVerificationManager.STATUS_OK)

        service.getInfo(pkgName).run {
            assertThat(identifier).isEqualTo(UUID_ONE)
            assertThat(hostToStateMap).containsExactlyEntriesIn(mapOf(
                DOMAIN_1 to STATE_SUCCESS,
            ))
        }
        assertThat(service.getUserState(pkgName).hostToStateMap).containsExactlyEntriesIn(mapOf(
                DOMAIN_1 to DOMAIN_STATE_VERIFIED,
                DOMAIN_2 to DOMAIN_STATE_SELECTED,
        ))
        assertThat(service.queryValidVerificationPackageNames()).containsExactly(pkgName)

        // Now remove the package because migrateState shouldn't use it either
        map.remove(pkgName)

        service.migrateState(pkgBefore, pkgAfter)

        map[pkgName] = pkgAfter

        service.getInfo(pkgName).run {
            assertThat(identifier).isEqualTo(UUID_TWO)
            assertThat(hostToStateMap).containsExactlyEntriesIn(mapOf(
                DOMAIN_1 to STATE_SUCCESS,
            ))
        }
        assertThat(service.getUserState(pkgName).hostToStateMap).containsExactlyEntriesIn(mapOf(
                DOMAIN_1 to DOMAIN_STATE_VERIFIED,
                DOMAIN_2 to DOMAIN_STATE_SELECTED,
        ))
        assertThat(service.queryValidVerificationPackageNames()).containsExactly(pkgName)
    }

    @Test
    fun backupAndRestore() {
        // This test acts as a proxy for true user restore through PackageManager,
@@ -804,7 +858,8 @@ class DomainVerificationPackageTest {
        pkgName: String,
        domainSetId: UUID,
        signature: String,
        domains: List<String> = listOf(DOMAIN_1, DOMAIN_2),
        autoVerifyDomains: List<String> = listOf(DOMAIN_1, DOMAIN_2),
        otherDomains: List<String> = listOf(),
        isSystemApp: Boolean = false
    ) = mockThrowOnUnmocked<PackageStateInternal> {
        val pkg = mockThrowOnUnmocked<AndroidPackage> {
@@ -812,23 +867,25 @@ class DomainVerificationPackageTest {
            whenever(targetSdkVersion) { Build.VERSION_CODES.S }
            whenever(isEnabled) { true }

            val activityList = listOf(
                ParsedActivityImpl().apply {
                    domains.forEach {
                        addIntent(
                            ParsedIntentInfoImpl().apply {
            fun baseIntent(domain: String) = ParsedIntentInfoImpl().apply {
                intentFilter.apply {
                                    autoVerify = true
                    addAction(Intent.ACTION_VIEW)
                    addCategory(Intent.CATEGORY_BROWSABLE)
                    addCategory(Intent.CATEGORY_DEFAULT)
                    addDataScheme("http")
                    addDataScheme("https")
                    addDataPath("/sub", PatternMatcher.PATTERN_LITERAL)
                                    addDataAuthority(it, null)
                    addDataAuthority(domain, null)
                }
            }
                        )

            val activityList = listOf(
                ParsedActivityImpl().apply {
                    autoVerifyDomains.forEach {
                        addIntent(baseIntent(it).apply { intentFilter.autoVerify = true })
                    }
                    otherDomains.forEach {
                        addIntent(baseIntent(it).apply { intentFilter.autoVerify = false })
                    }
                },
            )