Loading services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java +13 −17 Original line number Diff line number Diff line Loading @@ -892,7 +892,7 @@ public class DomainVerificationService extends SystemService boolean hasAutoVerifyDomains = newDomainsSize > 0; boolean needsBroadcast = applyImmutableState(pkgName, newStateMap, newAutoVerifyDomains); applyImmutableState(newPkgSetting, newStateMap, newAutoVerifyDomains); sendBroadcast = hasAutoVerifyDomains && needsBroadcast; Loading Loading @@ -943,7 +943,8 @@ public class DomainVerificationService extends SystemService pkgState = new DomainVerificationPkgState(pkgName, domainSetId, hasAutoVerifyDomains); } boolean needsBroadcast = applyImmutableState(pkgState, domains); boolean needsBroadcast = applyImmutableState(newPkgSetting, pkgState.getStateMap(), domains); if (needsBroadcast && !isPendingOrRestored) { // TODO(b/159952358): Test this behavior // Attempt to preserve user experience by automatically verifying all domains from Loading Loading @@ -990,22 +991,17 @@ public class DomainVerificationService extends SystemService } } private boolean applyImmutableState(@NonNull DomainVerificationPkgState pkgState, @NonNull ArraySet<String> autoVerifyDomains) { return applyImmutableState(pkgState.getPackageName(), pkgState.getStateMap(), autoVerifyDomains); } /** * Applies any immutable state as the final step when adding or migrating state. Currently only * applies {@link SystemConfig#getLinkedApps()}, which approves all domains for a package. * applies {@link SystemConfig#getLinkedApps()}, which approves all domains for a system app. * * @return whether or not a broadcast is necessary for this package */ private boolean applyImmutableState(@NonNull String packageName, private boolean applyImmutableState(@NonNull PackageSetting pkgSetting, @NonNull ArrayMap<String, Integer> stateMap, @NonNull ArraySet<String> autoVerifyDomains) { if (mSystemConfig.getLinkedApps().contains(packageName)) { if (pkgSetting.isSystem() && mSystemConfig.getLinkedApps().contains(pkgSetting.getName())) { int domainsSize = autoVerifyDomains.size(); for (int index = 0; index < domainsSize; index++) { stateMap.put(autoVerifyDomains.valueAt(index), Loading Loading @@ -1318,7 +1314,7 @@ public class DomainVerificationService extends SystemService if (pkgSetting == null || pkgSetting.getPkg() == null) { continue; } resetDomainState(pkgState, pkgSetting.getPkg()); resetDomainState(pkgState.getStateMap(), pkgSetting); } } else { int size = packageNames.size(); Loading @@ -1329,7 +1325,7 @@ public class DomainVerificationService extends SystemService if (pkgSetting == null || pkgSetting.getPkg() == null) { continue; } resetDomainState(pkgState, pkgSetting.getPkg()); resetDomainState(pkgState.getStateMap(), pkgSetting); } } } Loading @@ -1341,9 +1337,8 @@ public class DomainVerificationService extends SystemService /** * Reset states that are mutable by the domain verification agent. */ private void resetDomainState(@NonNull DomainVerificationPkgState pkgState, @NonNull AndroidPackage pkg) { ArrayMap<String, Integer> stateMap = pkgState.getStateMap(); private void resetDomainState(@NonNull ArrayMap<String, Integer> stateMap, @NonNull PackageSetting pkgSetting) { int size = stateMap.size(); for (int index = size - 1; index >= 0; index--) { Integer state = stateMap.valueAt(index); Loading @@ -1363,7 +1358,8 @@ public class DomainVerificationService extends SystemService } } applyImmutableState(pkgState, mCollector.collectValidAutoVerifyDomains(pkg)); applyImmutableState(pkgSetting, stateMap, mCollector.collectValidAutoVerifyDomains(pkgSetting.getPkg())); } @Override Loading services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,7 @@ class DomainVerificationEnforcerTest { whenever(readUserState(0)) { PackageUserState() } whenever(readUserState(1)) { PackageUserState() } whenever(getInstantApp(anyInt())) { false } whenever(isSystem()) { false } } } Loading services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerApiTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -527,6 +527,7 @@ class DomainVerificationManagerApiTest { whenever(firstInstallTime) { 0L } whenever(readUserState(0)) { pkgUserState0() } whenever(readUserState(1)) { pkgUserState1() } whenever(isSystem()) { false } } private fun DomainVerificationService.addPackages(vararg pkgSettings: PackageSetting) = Loading services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPackageTest.kt +104 −29 Original line number Diff line number Diff line Loading @@ -100,6 +100,70 @@ class DomainVerificationPackageTest { .containsExactly(pkg1.getName()) } @Test fun addPackageSystemConfigured() { val pkg1 = mockPkgSetting(PKG_ONE, UUID_ONE, SIGNATURE_ONE, isSystemApp = false) val pkg2 = mockPkgSetting(PKG_TWO, UUID_TWO, SIGNATURE_TWO, isSystemApp = true) val service = makeService( systemConfiguredPackageNames = ArraySet(setOf(pkg1.getName(), pkg2.getName())), pkg1, pkg2 ) service.addPackage(pkg1) service.addPackage(pkg2) service.getInfo(pkg1.getName()).apply { assertThat(packageName).isEqualTo(pkg1.getName()) assertThat(identifier).isEqualTo(pkg1.domainSetId) assertThat(hostToStateMap).containsExactlyEntriesIn( mapOf( DOMAIN_1 to STATE_NO_RESPONSE, DOMAIN_2 to STATE_NO_RESPONSE, ) ) } service.getUserState(pkg1.getName()).apply { assertThat(packageName).isEqualTo(pkg1.getName()) assertThat(identifier).isEqualTo(pkg1.domainSetId) assertThat(isLinkHandlingAllowed).isEqualTo(true) assertThat(user.identifier).isEqualTo(USER_ID) assertThat(hostToStateMap).containsExactlyEntriesIn( mapOf( DOMAIN_1 to DOMAIN_STATE_NONE, DOMAIN_2 to DOMAIN_STATE_NONE, ) ) } service.getInfo(pkg2.getName()).apply { assertThat(packageName).isEqualTo(pkg2.getName()) assertThat(identifier).isEqualTo(pkg2.domainSetId) assertThat(hostToStateMap).containsExactlyEntriesIn( mapOf( DOMAIN_1 to STATE_UNMODIFIABLE, DOMAIN_2 to STATE_UNMODIFIABLE, ) ) } service.getUserState(pkg2.getName()).apply { assertThat(packageName).isEqualTo(pkg2.getName()) assertThat(identifier).isEqualTo(pkg2.domainSetId) assertThat(isLinkHandlingAllowed).isEqualTo(true) assertThat(user.identifier).isEqualTo(USER_ID) assertThat(hostToStateMap).containsExactlyEntriesIn( mapOf( DOMAIN_1 to DOMAIN_STATE_VERIFIED, DOMAIN_2 to DOMAIN_STATE_VERIFIED, ) ) } assertThat(service.queryValidVerificationPackageNames()) .containsExactly(pkg1.getName(), pkg2.getName()) } @Test fun addPackageRestoredMatchingSignature() { // language=XML Loading Loading @@ -457,18 +521,27 @@ class DomainVerificationPackageTest { getDomainVerificationUserState(pkgName, USER_ID) .also { assertThat(it).isNotNull() }!! private fun makeService( systemConfiguredPackageNames: ArraySet<String> = ArraySet(), vararg pkgSettings: PackageSetting ) = makeService(systemConfiguredPackageNames = systemConfiguredPackageNames) { pkgName -> pkgSettings.find { pkgName == it.getName() } } private fun makeService(vararg pkgSettings: PackageSetting) = makeService { pkgName -> pkgSettings.find { pkgName == it.getName() } } private fun makeService(pkgSettingFunction: (String) -> PackageSetting? = { null }) = DomainVerificationService(mockThrowOnUnmocked { private fun makeService( systemConfiguredPackageNames: ArraySet<String> = ArraySet(), pkgSettingFunction: (String) -> PackageSetting? = { null } ) = DomainVerificationService(mockThrowOnUnmocked { // Assume the test has every permission necessary whenever(enforcePermission(anyString(), anyInt(), anyInt(), anyString())) whenever(checkPermission(anyString(), anyInt(), anyInt())) { PackageManager.PERMISSION_GRANTED } }, mockThrowOnUnmocked { whenever(linkedApps) { ArraySet<String>() } whenever(this.linkedApps) { systemConfiguredPackageNames } }, mockThrowOnUnmocked { whenever(isChangeEnabledInternalNoLogging(anyLong(), any())) { true } }).apply { Loading @@ -492,7 +565,8 @@ class DomainVerificationPackageTest { pkgName: String, domainSetId: UUID, signature: String, domains: List<String> = listOf(DOMAIN_1, DOMAIN_2) domains: List<String> = listOf(DOMAIN_1, DOMAIN_2), isSystemApp: Boolean = false ) = mockThrowOnUnmocked<PackageSetting> { val pkg = mockThrowOnUnmocked<AndroidPackage> { whenever(packageName) { pkgName } Loading Loading @@ -528,5 +602,6 @@ class DomainVerificationPackageTest { whenever(firstInstallTime) { 0L } whenever(readUserState(USER_ID)) { PackageUserState() } whenever(signatures) { arrayOf(Signature(signature)) } whenever(isSystem) { isSystemApp } } } services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,7 @@ class DomainVerificationSettingsMutationTest { whenever(readUserState(0)) { PackageUserState() } whenever(readUserState(10)) { PackageUserState() } whenever(getInstantApp(anyInt())) { false } whenever(isSystem()) { false } } } Loading Loading
services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java +13 −17 Original line number Diff line number Diff line Loading @@ -892,7 +892,7 @@ public class DomainVerificationService extends SystemService boolean hasAutoVerifyDomains = newDomainsSize > 0; boolean needsBroadcast = applyImmutableState(pkgName, newStateMap, newAutoVerifyDomains); applyImmutableState(newPkgSetting, newStateMap, newAutoVerifyDomains); sendBroadcast = hasAutoVerifyDomains && needsBroadcast; Loading Loading @@ -943,7 +943,8 @@ public class DomainVerificationService extends SystemService pkgState = new DomainVerificationPkgState(pkgName, domainSetId, hasAutoVerifyDomains); } boolean needsBroadcast = applyImmutableState(pkgState, domains); boolean needsBroadcast = applyImmutableState(newPkgSetting, pkgState.getStateMap(), domains); if (needsBroadcast && !isPendingOrRestored) { // TODO(b/159952358): Test this behavior // Attempt to preserve user experience by automatically verifying all domains from Loading Loading @@ -990,22 +991,17 @@ public class DomainVerificationService extends SystemService } } private boolean applyImmutableState(@NonNull DomainVerificationPkgState pkgState, @NonNull ArraySet<String> autoVerifyDomains) { return applyImmutableState(pkgState.getPackageName(), pkgState.getStateMap(), autoVerifyDomains); } /** * Applies any immutable state as the final step when adding or migrating state. Currently only * applies {@link SystemConfig#getLinkedApps()}, which approves all domains for a package. * applies {@link SystemConfig#getLinkedApps()}, which approves all domains for a system app. * * @return whether or not a broadcast is necessary for this package */ private boolean applyImmutableState(@NonNull String packageName, private boolean applyImmutableState(@NonNull PackageSetting pkgSetting, @NonNull ArrayMap<String, Integer> stateMap, @NonNull ArraySet<String> autoVerifyDomains) { if (mSystemConfig.getLinkedApps().contains(packageName)) { if (pkgSetting.isSystem() && mSystemConfig.getLinkedApps().contains(pkgSetting.getName())) { int domainsSize = autoVerifyDomains.size(); for (int index = 0; index < domainsSize; index++) { stateMap.put(autoVerifyDomains.valueAt(index), Loading Loading @@ -1318,7 +1314,7 @@ public class DomainVerificationService extends SystemService if (pkgSetting == null || pkgSetting.getPkg() == null) { continue; } resetDomainState(pkgState, pkgSetting.getPkg()); resetDomainState(pkgState.getStateMap(), pkgSetting); } } else { int size = packageNames.size(); Loading @@ -1329,7 +1325,7 @@ public class DomainVerificationService extends SystemService if (pkgSetting == null || pkgSetting.getPkg() == null) { continue; } resetDomainState(pkgState, pkgSetting.getPkg()); resetDomainState(pkgState.getStateMap(), pkgSetting); } } } Loading @@ -1341,9 +1337,8 @@ public class DomainVerificationService extends SystemService /** * Reset states that are mutable by the domain verification agent. */ private void resetDomainState(@NonNull DomainVerificationPkgState pkgState, @NonNull AndroidPackage pkg) { ArrayMap<String, Integer> stateMap = pkgState.getStateMap(); private void resetDomainState(@NonNull ArrayMap<String, Integer> stateMap, @NonNull PackageSetting pkgSetting) { int size = stateMap.size(); for (int index = size - 1; index >= 0; index--) { Integer state = stateMap.valueAt(index); Loading @@ -1363,7 +1358,8 @@ public class DomainVerificationService extends SystemService } } applyImmutableState(pkgState, mCollector.collectValidAutoVerifyDomains(pkg)); applyImmutableState(pkgSetting, stateMap, mCollector.collectValidAutoVerifyDomains(pkgSetting.getPkg())); } @Override Loading
services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,7 @@ class DomainVerificationEnforcerTest { whenever(readUserState(0)) { PackageUserState() } whenever(readUserState(1)) { PackageUserState() } whenever(getInstantApp(anyInt())) { false } whenever(isSystem()) { false } } } Loading
services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerApiTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -527,6 +527,7 @@ class DomainVerificationManagerApiTest { whenever(firstInstallTime) { 0L } whenever(readUserState(0)) { pkgUserState0() } whenever(readUserState(1)) { pkgUserState1() } whenever(isSystem()) { false } } private fun DomainVerificationService.addPackages(vararg pkgSettings: PackageSetting) = Loading
services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPackageTest.kt +104 −29 Original line number Diff line number Diff line Loading @@ -100,6 +100,70 @@ class DomainVerificationPackageTest { .containsExactly(pkg1.getName()) } @Test fun addPackageSystemConfigured() { val pkg1 = mockPkgSetting(PKG_ONE, UUID_ONE, SIGNATURE_ONE, isSystemApp = false) val pkg2 = mockPkgSetting(PKG_TWO, UUID_TWO, SIGNATURE_TWO, isSystemApp = true) val service = makeService( systemConfiguredPackageNames = ArraySet(setOf(pkg1.getName(), pkg2.getName())), pkg1, pkg2 ) service.addPackage(pkg1) service.addPackage(pkg2) service.getInfo(pkg1.getName()).apply { assertThat(packageName).isEqualTo(pkg1.getName()) assertThat(identifier).isEqualTo(pkg1.domainSetId) assertThat(hostToStateMap).containsExactlyEntriesIn( mapOf( DOMAIN_1 to STATE_NO_RESPONSE, DOMAIN_2 to STATE_NO_RESPONSE, ) ) } service.getUserState(pkg1.getName()).apply { assertThat(packageName).isEqualTo(pkg1.getName()) assertThat(identifier).isEqualTo(pkg1.domainSetId) assertThat(isLinkHandlingAllowed).isEqualTo(true) assertThat(user.identifier).isEqualTo(USER_ID) assertThat(hostToStateMap).containsExactlyEntriesIn( mapOf( DOMAIN_1 to DOMAIN_STATE_NONE, DOMAIN_2 to DOMAIN_STATE_NONE, ) ) } service.getInfo(pkg2.getName()).apply { assertThat(packageName).isEqualTo(pkg2.getName()) assertThat(identifier).isEqualTo(pkg2.domainSetId) assertThat(hostToStateMap).containsExactlyEntriesIn( mapOf( DOMAIN_1 to STATE_UNMODIFIABLE, DOMAIN_2 to STATE_UNMODIFIABLE, ) ) } service.getUserState(pkg2.getName()).apply { assertThat(packageName).isEqualTo(pkg2.getName()) assertThat(identifier).isEqualTo(pkg2.domainSetId) assertThat(isLinkHandlingAllowed).isEqualTo(true) assertThat(user.identifier).isEqualTo(USER_ID) assertThat(hostToStateMap).containsExactlyEntriesIn( mapOf( DOMAIN_1 to DOMAIN_STATE_VERIFIED, DOMAIN_2 to DOMAIN_STATE_VERIFIED, ) ) } assertThat(service.queryValidVerificationPackageNames()) .containsExactly(pkg1.getName(), pkg2.getName()) } @Test fun addPackageRestoredMatchingSignature() { // language=XML Loading Loading @@ -457,18 +521,27 @@ class DomainVerificationPackageTest { getDomainVerificationUserState(pkgName, USER_ID) .also { assertThat(it).isNotNull() }!! private fun makeService( systemConfiguredPackageNames: ArraySet<String> = ArraySet(), vararg pkgSettings: PackageSetting ) = makeService(systemConfiguredPackageNames = systemConfiguredPackageNames) { pkgName -> pkgSettings.find { pkgName == it.getName() } } private fun makeService(vararg pkgSettings: PackageSetting) = makeService { pkgName -> pkgSettings.find { pkgName == it.getName() } } private fun makeService(pkgSettingFunction: (String) -> PackageSetting? = { null }) = DomainVerificationService(mockThrowOnUnmocked { private fun makeService( systemConfiguredPackageNames: ArraySet<String> = ArraySet(), pkgSettingFunction: (String) -> PackageSetting? = { null } ) = DomainVerificationService(mockThrowOnUnmocked { // Assume the test has every permission necessary whenever(enforcePermission(anyString(), anyInt(), anyInt(), anyString())) whenever(checkPermission(anyString(), anyInt(), anyInt())) { PackageManager.PERMISSION_GRANTED } }, mockThrowOnUnmocked { whenever(linkedApps) { ArraySet<String>() } whenever(this.linkedApps) { systemConfiguredPackageNames } }, mockThrowOnUnmocked { whenever(isChangeEnabledInternalNoLogging(anyLong(), any())) { true } }).apply { Loading @@ -492,7 +565,8 @@ class DomainVerificationPackageTest { pkgName: String, domainSetId: UUID, signature: String, domains: List<String> = listOf(DOMAIN_1, DOMAIN_2) domains: List<String> = listOf(DOMAIN_1, DOMAIN_2), isSystemApp: Boolean = false ) = mockThrowOnUnmocked<PackageSetting> { val pkg = mockThrowOnUnmocked<AndroidPackage> { whenever(packageName) { pkgName } Loading Loading @@ -528,5 +602,6 @@ class DomainVerificationPackageTest { whenever(firstInstallTime) { 0L } whenever(readUserState(USER_ID)) { PackageUserState() } whenever(signatures) { arrayOf(Signature(signature)) } whenever(isSystem) { isSystemApp } } }
services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,7 @@ class DomainVerificationSettingsMutationTest { whenever(readUserState(0)) { PackageUserState() } whenever(readUserState(10)) { PackageUserState() } whenever(getInstantApp(anyInt())) { false } whenever(isSystem()) { false } } } Loading