Merge "Test scheduleWriteSettings inside DomainVerificationService" into sc-dev am: 081b3e4382

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13438572

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I6bb9f2a3af3eece943175b85e99488f7e438e979
This commit is contained in:
Winson Chiu
2021-02-08 23:57:56 +00:00
committed by Automerger Merge Worker
2 changed files with 276 additions and 2 deletions

View File

@@ -542,8 +542,6 @@ public class DomainVerificationService extends SystemService
userState.removeHosts(domains);
}
}
mConnection.scheduleWriteSettings();
}
@Nullable
@@ -849,6 +847,7 @@ public class DomainVerificationService extends SystemService
public void setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state) {
mEnforcer.callerIsLegacyUserSelector(mConnection.getCallingUid());
mLegacySettings.add(packageName, userId, state);
mConnection.scheduleWriteSettings();
}
@Override
@@ -1067,6 +1066,8 @@ public class DomainVerificationService extends SystemService
}
}
}
mConnection.scheduleWriteSettings();
}
/**
@@ -1124,6 +1125,8 @@ public class DomainVerificationService extends SystemService
}
}
}
mConnection.scheduleWriteSettings();
}
@Override

View File

@@ -0,0 +1,271 @@
/*
* 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.test.verify.domain
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.PackageUserState
import android.content.pm.verify.domain.DomainVerificationManager
import android.content.pm.parsing.component.ParsedActivity
import android.content.pm.parsing.component.ParsedIntentInfo
import android.os.Build
import android.os.Process
import android.util.ArraySet
import android.util.SparseArray
import com.android.server.pm.PackageSetting
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
import com.android.server.pm.verify.domain.DomainVerificationService
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy
import com.android.server.pm.parsing.pkg.AndroidPackage
import com.android.server.testutils.mockThrowOnUnmocked
import com.android.server.testutils.spyThrowOnUnmocked
import com.android.server.testutils.whenever
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.mockito.Mockito
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.anyLong
import org.mockito.Mockito.any
import org.mockito.Mockito.anyString
import org.mockito.Mockito.eq
import org.mockito.Mockito.verify
import java.io.File
import java.util.UUID
@RunWith(Parameterized::class)
class DomainVerificationSettingsMutationTest {
companion object {
private const val TEST_PKG = "com.test"
// Pretend to be the system. This class doesn't verify any enforcement behavior.
private const val TEST_UID = Process.SYSTEM_UID
private const val TEST_USER_ID = 10
private val TEST_UUID = UUID.fromString("5168e42e-327e-432b-b562-cfb553518a70")
@JvmStatic
@Parameterized.Parameters(name = "{0}")
fun parameters(): Array<Any> {
val context: Context = mockThrowOnUnmocked {
whenever(
enforcePermission(
eq(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT),
anyInt(), anyInt(), anyString()
)
)
whenever(
enforcePermission(
eq(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION),
anyInt(), anyInt(), anyString()
)
)
whenever(
enforcePermission(
eq(android.Manifest.permission.INTERACT_ACROSS_USERS),
anyInt(), anyInt(), anyString()
)
)
whenever(
enforcePermission(
eq(android.Manifest.permission.SET_PREFERRED_APPLICATIONS),
anyInt(), anyInt(), anyString()
)
)
}
val proxy: DomainVerificationProxy = mockThrowOnUnmocked {
whenever(isCallerVerifier(anyInt())) { true }
whenever(sendBroadcastForPackages(any()))
}
val makeService: (DomainVerificationManagerInternal.Connection) -> DomainVerificationService =
{ connection ->
DomainVerificationService(
context,
mockThrowOnUnmocked { whenever(linkedApps) { ArraySet<String>() } },
mockThrowOnUnmocked {
whenever(isChangeEnabled(anyLong(),any())) { true }
}).apply {
setConnection(connection)
}
}
fun service(name: String, block: DomainVerificationService.() -> Unit) =
Params(makeService, name) { service ->
service.proxy = proxy
service.addPackage(mockPkgSetting())
service.block()
}
return arrayOf(
service("clearPackage") {
clearPackage(TEST_PKG)
},
service("clearUser") {
clearUser(TEST_USER_ID)
},
service("clearState") {
clearDomainVerificationState(listOf(TEST_PKG))
},
service("clearUserSelections") {
clearUserSelections(listOf(TEST_PKG), TEST_USER_ID)
},
service("setStatus") {
setDomainVerificationStatus(
TEST_UUID,
setOf("example.com"),
DomainVerificationManager.STATE_SUCCESS
)
},
service("setStatusInternalPackageName") {
setDomainVerificationStatusInternal(
TEST_PKG,
DomainVerificationManager.STATE_SUCCESS,
ArraySet(setOf("example.com"))
)
},
service("setStatusInternalUid") {
setDomainVerificationStatusInternal(
TEST_UID,
TEST_UUID,
setOf("example.com"),
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") {
setDomainVerificationUserSelection(
TEST_UUID,
setOf("example.com"),
true,
TEST_USER_ID
)
},
service("setUserSelectionInternal") {
setDomainVerificationUserSelectionInternal(
TEST_USER_ID,
TEST_PKG,
true,
ArraySet(setOf("example.com")),
)
},
service("setLegacyUserState") {
setLegacyUserState(
TEST_PKG,
TEST_USER_ID,
PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER
)
},
)
}
data class Params(
val construct: (
DomainVerificationManagerInternal.Connection
) -> DomainVerificationService,
val name: String,
val method: (DomainVerificationService) -> Unit
) {
override fun toString() = name
}
fun mockPkg() = mockThrowOnUnmocked<AndroidPackage> {
whenever(packageName) { TEST_PKG }
whenever(targetSdkVersion) { Build.VERSION_CODES.S }
whenever(activities) {
listOf(
ParsedActivity().apply {
addIntent(
ParsedIntentInfo().apply {
autoVerify = true
addAction(Intent.ACTION_VIEW)
addCategory(Intent.CATEGORY_BROWSABLE)
addCategory(Intent.CATEGORY_DEFAULT)
addDataScheme("https")
addDataAuthority("example.com", null)
}
)
}
)
}
}
// TODO: PackageSetting field encapsulation to move to whenever(name)
fun mockPkgSetting() = spyThrowOnUnmocked(
PackageSetting(
TEST_PKG,
TEST_PKG,
File("/test"),
null,
null,
null,
null,
1,
0,
0,
0,
null,
null,
null,
TEST_UUID
)
) {
whenever(getPkg()) { mockPkg() }
whenever(domainSetId) { TEST_UUID }
whenever(userState) {
SparseArray<PackageUserState>().apply {
this[0] = PackageUserState()
}
}
}
}
@Parameterized.Parameter(0)
lateinit var params: Params
@Test
fun writeScheduled() {
val connection = mockConnection()
val service = params.construct(connection)
params.method(service)
verify(connection).scheduleWriteSettings()
}
private fun mockConnection(): DomainVerificationManagerInternal.Connection =
mockThrowOnUnmocked {
whenever(callingUid) { TEST_UID }
whenever(callingUserId) { TEST_USER_ID }
whenever(getPackageSettingLocked(TEST_PKG)) { mockPkgSetting() }
whenever(getPackageLocked(TEST_PKG)) { mockPkg() }
whenever(schedule(anyInt(), any()))
whenever(scheduleWriteSettings())
}
}