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:
@@ -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
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user