Merge "Remove IntentFilterVerificationTest" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-04-05 21:11:03 +00:00
committed by Android (Google) Code Review
14 changed files with 1 additions and 1074 deletions

View File

@@ -46,15 +46,7 @@ java_test_host {
":PackageManagerTestAppVersion4",
":PackageManagerTestAppOriginalOverride",
":PackageManagerServiceDeviceSideTests",
":PackageManagerTestIntentVerifier",
":PackageManagerTestIntentVerifierTarget1",
":PackageManagerTestIntentVerifierTarget2",
":PackageManagerTestIntentVerifierTarget3",
":PackageManagerTestIntentVerifierTarget4Base",
":PackageManagerTestIntentVerifierTarget4NoAutoVerify",
":PackageManagerTestIntentVerifierTarget4Wildcard",
":PackageManagerTestIntentVerifierTarget4WildcardNoAutoVerify",
]
],
}
genrule {

View File

@@ -1,413 +0,0 @@
/*
* 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.intent.verify
import com.android.internal.util.test.SystemPreparer
import com.android.server.pm.test.Partition
import com.android.server.pm.test.deleteApkFolders
import com.android.server.pm.test.installJavaResourceApk
import com.android.server.pm.test.pushApk
import com.android.server.pm.test.uninstallPackages
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import java.io.File
import java.util.concurrent.TimeUnit
@RunWith(DeviceJUnit4ClassRunner::class)
class IntentFilterVerificationTest : BaseHostJUnit4Test() {
companion object {
private const val VERIFIER = "PackageManagerTestIntentVerifier.apk"
private const val VERIFIER_PKG_NAME = "com.android.server.pm.test.intent.verifier"
private const val TARGET_PKG_PREFIX = "$VERIFIER_PKG_NAME.target"
private const val TARGET_APK_PREFIX = "PackageManagerTestIntentVerifierTarget"
private const val TARGET_ONE = "${TARGET_APK_PREFIX}1.apk"
private const val TARGET_ONE_PKG_NAME = "$TARGET_PKG_PREFIX.one"
private const val TARGET_TWO = "${TARGET_APK_PREFIX}2.apk"
private const val TARGET_TWO_PKG_NAME = "$TARGET_PKG_PREFIX.two"
private const val TARGET_THREE = "${TARGET_APK_PREFIX}3.apk"
private const val TARGET_THREE_PKG_NAME = "$TARGET_PKG_PREFIX.three"
private const val TARGET_FOUR_BASE = "${TARGET_APK_PREFIX}4Base.apk"
private const val TARGET_FOUR_PKG_NAME = "$TARGET_PKG_PREFIX.four"
private const val TARGET_FOUR_NO_AUTO_VERIFY = "${TARGET_APK_PREFIX}4NoAutoVerify.apk"
private const val TARGET_FOUR_WILDCARD = "${TARGET_APK_PREFIX}4Wildcard.apk"
private const val TARGET_FOUR_WILDCARD_NO_AUTO_VERIFY =
"${TARGET_APK_PREFIX}4WildcardNoAutoVerify.apk"
@get:ClassRule
val deviceRebootRule = SystemPreparer.TestRuleDelegate(true)
}
private val tempFolder = TemporaryFolder()
private val preparer: SystemPreparer = SystemPreparer(tempFolder,
SystemPreparer.RebootStrategy.FULL, deviceRebootRule) { this.device }
@Rule
@JvmField
val rules = RuleChain.outerRule(tempFolder).around(preparer)!!
private val permissionsFile = File("/system/etc/permissions" +
"/privapp-PackageManagerIntentFilterVerificationTest-permissions.xml")
@Before
fun cleanupAndPushPermissionsFile() {
// In order for the test app to be the verification agent, it needs a permission file
// which can be pushed onto the system and removed afterwards.
val file = tempFolder.newFile().apply {
"""
<permissions>
<privapp-permissions package="$VERIFIER_PKG_NAME">
<permission name="android.permission.INTENT_FILTER_VERIFICATION_AGENT"/>
</privapp-permissions>
</permissions>
"""
.trimIndent()
.let { writeText(it) }
}
device.uninstallPackages(TARGET_ONE_PKG_NAME, TARGET_TWO_PKG_NAME, TARGET_THREE_PKG_NAME,
TARGET_FOUR_PKG_NAME)
preparer.pushApk(VERIFIER, Partition.SYSTEM_PRIVILEGED)
.pushFile(file, permissionsFile.toString())
.reboot()
runTest("clearResponse")
}
@After
fun cleanupAndDeletePermissionsFile() {
device.uninstallPackages(TARGET_ONE_PKG_NAME, TARGET_TWO_PKG_NAME, TARGET_THREE_PKG_NAME,
TARGET_FOUR_PKG_NAME)
preparer.deleteApkFolders(Partition.SYSTEM_PRIVILEGED, VERIFIER)
.deleteFile(permissionsFile.toString())
device.reboot()
}
@Test
fun verifyOne() {
installPackage(TARGET_ONE)
assertReceivedRequests(true, VerifyRequest(
scheme = "https",
hosts = listOf(
"https_only.pm.server.android.com",
"other_activity.pm.server.android.com",
"http_only.pm.server.android.com",
"verify.pm.server.android.com",
"https_plus_non_web_scheme.pm.server.android.com",
"multiple.pm.server.android.com",
// TODO(b/159952358): the following domain should not be
// verified, this is because the verifier tries to verify all web domains,
// even in intent filters not marked for auto verify
"no_verify.pm.server.android.com"
),
packageName = TARGET_ONE_PKG_NAME
))
runTest(StartActivityParams(
uri = "https://https_only.pm.server.android.com",
expected = "$TARGET_ONE_PKG_NAME.TargetActivity"
))
}
@Test
fun nonWebScheme() {
installPackage(TARGET_TWO)
assertReceivedRequests(null)
}
@Test
fun verifyHttpNonSecureOnly() {
installPackage(TARGET_THREE)
assertReceivedRequests(true, VerifyRequest(
scheme = "https",
hosts = listOf(
"multiple.pm.server.android.com"
),
packageName = TARGET_THREE_PKG_NAME
))
runTest(StartActivityParams(
uri = "http://multiple.pm.server.android.com",
expected = "$TARGET_THREE_PKG_NAME.TargetActivity"
))
}
@Test
fun multipleResults() {
installPackage(TARGET_ONE)
installPackage(TARGET_THREE)
assertReceivedRequests(true, VerifyRequest(
scheme = "https",
hosts = listOf(
"https_only.pm.server.android.com",
"other_activity.pm.server.android.com",
"http_only.pm.server.android.com",
"verify.pm.server.android.com",
"https_plus_non_web_scheme.pm.server.android.com",
"multiple.pm.server.android.com",
// TODO(b/159952358): the following domain should not be
// verified, this is because the verifier tries to verify all web domains,
// even in intent filters not marked for auto verify
"no_verify.pm.server.android.com"
),
packageName = TARGET_ONE_PKG_NAME
), VerifyRequest(
scheme = "https",
hosts = listOf(
"multiple.pm.server.android.com"
),
packageName = TARGET_THREE_PKG_NAME
))
// Target3 declares http non-s, so it should be included in the set here
runTest(StartActivityParams(
uri = "http://multiple.pm.server.android.com",
expected = listOf(
"$TARGET_ONE_PKG_NAME.TargetActivity2",
"$TARGET_THREE_PKG_NAME.TargetActivity"
)
))
// But it excludes https, so it shouldn't resolve here
runTest(StartActivityParams(
uri = "https://multiple.pm.server.android.com",
expected = "$TARGET_ONE_PKG_NAME.TargetActivity2"
))
// Remove Target3 and return to single verified Target1 app for http non-s
device.uninstallPackage(TARGET_THREE_PKG_NAME)
runTest(StartActivityParams(
uri = "http://multiple.pm.server.android.com",
expected = "$TARGET_ONE_PKG_NAME.TargetActivity2"
))
}
@Test
fun demoteAlways() {
installPackage(TARGET_FOUR_BASE)
assertReceivedRequests(false, VerifyRequest(
scheme = "https",
host = "failing.pm.server.android.com",
packageName = TARGET_FOUR_PKG_NAME
))
runTest(StartActivityParams(
uri = "https://failing.pm.server.android.com",
expected = "$TARGET_FOUR_PKG_NAME.TargetActivity",
withBrowsers = true
))
runTest(SetActivityAsAlwaysParams(
uri = "https://failing.pm.server.android.com",
packageName = TARGET_FOUR_PKG_NAME,
activityName = "$TARGET_FOUR_PKG_NAME.TargetActivity"
))
runTest(StartActivityParams(
uri = "https://failing.pm.server.android.com",
expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
))
// Re-installing with same host/verify set will maintain always setting
installPackage(TARGET_FOUR_BASE)
assertReceivedRequests(null)
runTest(StartActivityParams(
uri = "https://failing.pm.server.android.com",
expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
))
// Installing with new wildcard host will downgrade out of always, re-including browsers
installPackage(TARGET_FOUR_WILDCARD)
// TODO(b/159952358): The first request without the wildcard should not be sent. This is
// caused by the request being queued even if it should be dropped from the previous
// install case since the host set didn't change.
assertReceivedRequests(false, VerifyRequest(
scheme = "https",
hosts = listOf("failing.pm.server.android.com"),
packageName = TARGET_FOUR_PKG_NAME
), VerifyRequest(
scheme = "https",
hosts = listOf("failing.pm.server.android.com", "wildcard.tld"),
packageName = TARGET_FOUR_PKG_NAME
))
runTest(StartActivityParams(
uri = "https://failing.pm.server.android.com",
expected = "$TARGET_FOUR_PKG_NAME.TargetActivity",
withBrowsers = true
))
}
@Test
fun unverifiedReinstallResendRequest() {
installPackage(TARGET_FOUR_BASE)
assertReceivedRequests(false, VerifyRequest(
scheme = "https",
host = "failing.pm.server.android.com",
packageName = TARGET_FOUR_PKG_NAME
))
installPackage(TARGET_FOUR_BASE)
assertReceivedRequests(false, VerifyRequest(
scheme = "https",
host = "failing.pm.server.android.com",
packageName = TARGET_FOUR_PKG_NAME
))
}
@Test
fun unverifiedUpdateRemovingDomainNoRequestDemoteAlways() {
installPackage(TARGET_FOUR_WILDCARD)
assertReceivedRequests(false, VerifyRequest(
scheme = "https",
hosts = listOf("failing.pm.server.android.com", "wildcard.tld"),
packageName = TARGET_FOUR_PKG_NAME
))
runTest(SetActivityAsAlwaysParams(
uri = "https://failing.pm.server.android.com",
packageName = TARGET_FOUR_PKG_NAME,
activityName = "$TARGET_FOUR_PKG_NAME.TargetActivity"
))
// Re-installing with a smaller host/verify set will not request re-verification
installPackage(TARGET_FOUR_BASE)
assertReceivedRequests(null)
runTest(StartActivityParams(
uri = "https://failing.pm.server.android.com",
expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
))
// Re-installing with a (now) larger host/verify set will re-request and demote
installPackage(TARGET_FOUR_WILDCARD)
// TODO(b/159952358): The first request should not be sent. This is caused by the request
// being queued even if it should be dropped from the previous install case.
assertReceivedRequests(false, VerifyRequest(
scheme = "https",
host = "failing.pm.server.android.com",
packageName = TARGET_FOUR_PKG_NAME
), VerifyRequest(
scheme = "https",
hosts = listOf("failing.pm.server.android.com", "wildcard.tld"),
packageName = TARGET_FOUR_PKG_NAME
))
runTest(StartActivityParams(
uri = "https://failing.pm.server.android.com",
expected = "$TARGET_FOUR_PKG_NAME.TargetActivity",
withBrowsers = true
))
}
// TODO(b/159952358): I would expect this to demote
// TODO(b/32810168)
@Test
fun verifiedUpdateRemovingAutoVerifyMaintainsAlways() {
installPackage(TARGET_FOUR_BASE)
assertReceivedRequests(true, VerifyRequest(
scheme = "https",
host = "failing.pm.server.android.com",
packageName = TARGET_FOUR_PKG_NAME
))
runTest(StartActivityParams(
uri = "https://failing.pm.server.android.com",
expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
))
installPackage(TARGET_FOUR_NO_AUTO_VERIFY)
assertReceivedRequests(null)
runTest(StartActivityParams(
uri = "https://failing.pm.server.android.com",
expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
))
}
@Test
fun verifiedUpdateRemovingAutoVerifyAddingDomainDemotesAlways() {
installPackage(TARGET_FOUR_BASE)
assertReceivedRequests(true, VerifyRequest(
scheme = "https",
host = "failing.pm.server.android.com",
packageName = TARGET_FOUR_PKG_NAME
))
runTest(StartActivityParams(
uri = "https://failing.pm.server.android.com",
expected = "$TARGET_FOUR_PKG_NAME.TargetActivity"
))
installPackage(TARGET_FOUR_WILDCARD_NO_AUTO_VERIFY)
assertReceivedRequests(null)
runTest(StartActivityParams(
uri = "https://failing.pm.server.android.com",
expected = "$TARGET_FOUR_PKG_NAME.TargetActivity",
withBrowsers = true
))
}
private fun installPackage(javaResourceName: String) {
// Need to pass --user as verification is not currently run for all user installs
assertThat(device.installJavaResourceApk(tempFolder, javaResourceName,
extraArgs = arrayOf("--user", device.currentUser.toString()))).isNull()
}
private fun assertReceivedRequests(success: Boolean?, vararg expected: VerifyRequest?) {
// TODO(b/159952358): This can probably be less than 10
// Because tests have to assert that multiple broadcasts aren't received, there's no real
// better way to await for a value than sleeping for a long enough time.
TimeUnit.SECONDS.sleep(10)
val params = mutableMapOf<String, String>()
if (expected.any { it != null }) {
params["expected"] = expected.filterNotNull()
.joinToString(separator = "") { it.serializeToString() }
}
runTest("compareLastReceived", params)
if (success != null) {
if (success) {
runTest("verifyPreviousReceivedSuccess")
} else {
runTest("verifyPreviousReceivedFailure")
}
runTest("clearResponse")
}
}
private fun runTest(params: IntentVerifyTestParams) =
runTest(params.methodName, params.toArgsMap())
private fun runTest(testName: String, args: Map<String, String> = emptyMap()) {
val escapedArgs = args.mapValues {
// Need to escape strings so that args are passed properly through the shell command
"\"${it.value.trim('"')}\""
}
runDeviceTests(device, null, VERIFIER_PKG_NAME, "$VERIFIER_PKG_NAME.VerifyReceiverTest",
testName, null, 10 * 60 * 1000L, 10 * 60 * 1000L, 0L, true, false, escapedArgs)
}
}

View File

@@ -1,37 +0,0 @@
// 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 {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "frameworks_base_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["frameworks_base_license"],
}
android_test_helper_app {
name: "PackageManagerTestIntentVerifier",
srcs: [ "src/**/*.kt" ],
static_libs: [
"androidx.test.core",
"androidx.test.espresso.core",
"androidx.test.runner",
"compatibility-device-util-axt",
"junit",
"truth-prebuilt",
"PackageManagerServiceHostTestsIntentVerifyUtils",
],
platform_apis: true,
}

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.intent.verifier"
>
<uses-permission android:name="android.permission.INTENT_FILTER_VERIFICATION_AGENT" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.server.pm.test.intent.verifier"
/>
<application>
<receiver android:name=".VerifyReceiver" android:exported="true">
<intent-filter android:priority="999">
<action android:name="android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION"/>
<data android:mimeType="application/vnd.android.package-archive"/>
</intent-filter>
</receiver>
</application>
</manifest>

View File

@@ -1,62 +0,0 @@
/*
* 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.intent.verifier
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import com.android.server.pm.test.intent.verify.VerifyRequest
class VerifyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action != Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION) return
val params = intent.toVerifyParams()
// If the receiver is called for a normal request, proxy it to the real verifier on device
if (params.hosts.none { it.contains("pm.server.android.com") }) {
sendToRealVerifier(context, Intent(intent))
return
}
// When the receiver is invoked for a test install, there is no direct connection to host,
// so store the result in a file to read and assert on later. Append is intentional so that
// amount of invocations and clean up can be verified.
context.filesDir.resolve("test.txt")
.appendText(params.serializeToString())
}
private fun sendToRealVerifier(context: Context, intent: Intent) {
context.packageManager.queryBroadcastReceivers(intent, 0)
.first { it.activityInfo?.packageName != context.packageName }
.let { it.activityInfo!! }
.let { intent.setComponent(ComponentName(it.packageName, it.name)) }
.run { context.sendBroadcast(intent) }
}
private fun Intent.toVerifyParams() = VerifyRequest(
id = getIntExtra(PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, -1),
scheme = getStringExtra(PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME)!!,
hosts = getStringExtra(PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS)!!
.split(' '),
packageName = getStringExtra(
PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME)!!
)
}

View File

@@ -1,164 +0,0 @@
/*
* 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.intent.verifier
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.os.UserHandle
import androidx.test.InstrumentationRegistry
import androidx.test.runner.AndroidJUnit4
import com.android.compatibility.common.util.ShellIdentityUtils
import com.android.server.pm.test.intent.verify.SetActivityAsAlwaysParams
import com.android.server.pm.test.intent.verify.StartActivityParams
import com.android.server.pm.test.intent.verify.VerifyRequest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import java.io.File
@RunWith(AndroidJUnit4::class)
class VerifyReceiverTest {
val args: Bundle = InstrumentationRegistry.getArguments()
val context: Context = InstrumentationRegistry.getContext()
private val file = context.filesDir.resolve("test.txt")
@Test
fun clearResponse() {
file.delete()
}
@Test
fun compareLastReceived() {
val lastReceivedText = file.readTextIfExists()
val expectedText = args.getString("expected")
if (expectedText.isNullOrEmpty()) {
assertThat(lastReceivedText).isEmpty()
return
}
val expectedParams = expectedText.parseParams()
val lastReceivedParams = lastReceivedText.parseParams()
assertThat(lastReceivedParams).hasSize(expectedParams.size)
lastReceivedParams.zip(expectedParams).forEach { (actual, expected) ->
assertThat(actual.hosts).containsExactlyElementsIn(expected.hosts)
assertThat(actual.packageName).isEqualTo(expected.packageName)
assertThat(actual.scheme).isEqualTo(expected.scheme)
}
}
@Test
fun setActivityAsAlways() {
val params = SetActivityAsAlwaysParams.fromArgs(
args.keySet().associateWith { args.getString(it)!! })
val uri = Uri.parse(params.uri)
val filter = IntentFilter().apply {
addAction(Intent.ACTION_VIEW)
addCategory(Intent.CATEGORY_DEFAULT)
addCategory(Intent.CATEGORY_BROWSABLE)
addDataScheme(uri.scheme)
addDataAuthority(uri.authority, null)
}
val intent = Intent(Intent.ACTION_VIEW, uri).apply {
addCategory(Intent.CATEGORY_DEFAULT)
addCategory(Intent.CATEGORY_BROWSABLE)
}
val allResults = context.packageManager.queryIntentActivities(intent, 0)
val allComponents = allResults
.map { ComponentName(it.activityInfo.packageName, it.activityInfo.name) }
.toTypedArray()
val matchingInfo = allResults.first {
it.activityInfo.packageName == params.packageName &&
it.activityInfo.name == params.activityName
}
ShellIdentityUtils.invokeMethodWithShellPermissions(context.packageManager,
ShellIdentityUtils.ShellPermissionMethodHelper<Unit, PackageManager> {
it.addUniquePreferredActivity(filter, matchingInfo.match, allComponents,
ComponentName(matchingInfo.activityInfo.packageName,
matchingInfo.activityInfo.name))
it.updateIntentVerificationStatusAsUser(params.packageName,
PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
UserHandle.myUserId())
}, "android.permission.SET_PREFERRED_APPLICATIONS")
}
@Test
fun verifyPreviousReceivedSuccess() {
file.readTextIfExists()
.parseParams()
.forEach {
context.packageManager.verifyIntentFilter(it.id,
PackageManager.INTENT_FILTER_VERIFICATION_SUCCESS, emptyList())
}
}
@Test
fun verifyPreviousReceivedFailure() {
file.readTextIfExists()
.parseParams()
.forEach {
context.packageManager.verifyIntentFilter(it.id,
PackageManager.INTENT_FILTER_VERIFICATION_FAILURE, it.hosts)
}
}
@Test
fun verifyActivityStart() {
val params = StartActivityParams
.fromArgs(args.keySet().associateWith { args.getString(it)!! })
val uri = Uri.parse(params.uri)
val intent = Intent(Intent.ACTION_VIEW).apply {
data = uri
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addCategory(Intent.CATEGORY_DEFAULT)
addCategory(Intent.CATEGORY_BROWSABLE)
}
val expectedActivities = params.expected.toMutableList()
if (params.withBrowsers) {
// Since the host doesn't know what browsers the device has, query here and add it to
// set if it's expected that browser are returned
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com"))
expectedActivities += context.packageManager.queryIntentActivities(browserIntent, 0)
.map { it.activityInfo.name }
}
val infos = context.packageManager.queryIntentActivities(intent, 0)
.map { it.activityInfo.name }
assertThat(infos).containsExactlyElementsIn(expectedActivities)
}
private fun File.readTextIfExists() = if (exists()) readText() else ""
// Rudimentary list deserialization by splitting text block into 4 line sections
private fun String.parseParams() = trim()
.lines()
.windowed(4, 4)
.map { it.joinToString(separator = "\n") }
.map { VerifyRequest.deserialize(it) }
}

View File

@@ -1,57 +0,0 @@
// 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 {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "frameworks_base_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["frameworks_base_license"],
}
android_test_helper_app {
name: "PackageManagerTestIntentVerifierTarget1",
manifest: "AndroidManifest1.xml",
}
android_test_helper_app {
name: "PackageManagerTestIntentVerifierTarget2",
manifest: "AndroidManifest2.xml",
}
android_test_helper_app {
name: "PackageManagerTestIntentVerifierTarget3",
manifest: "AndroidManifest3.xml",
}
android_test_helper_app {
name: "PackageManagerTestIntentVerifierTarget4Base",
manifest: "AndroidManifest4Base.xml",
}
android_test_helper_app {
name: "PackageManagerTestIntentVerifierTarget4NoAutoVerify",
manifest: "AndroidManifest4NoAutoVerify.xml",
}
android_test_helper_app {
name: "PackageManagerTestIntentVerifierTarget4Wildcard",
manifest: "AndroidManifest4Wildcard.xml",
}
android_test_helper_app {
name: "PackageManagerTestIntentVerifierTarget4WildcardNoAutoVerify",
manifest: "AndroidManifest4WildcardNoAutoVerify.xml",
}

View File

@@ -1,94 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.intent.verifier.target.one" android:versionCode="1">
<application>
<activity android:name=".TargetActivity" android:exported="true">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="verify.pm.server.android.com" />
</intent-filter>
<intent-filter android:autoVerify="false">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="no_verify.pm.server.android.com" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:host="http_only.pm.server.android.com" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="https" />
<data android:host="https_only.pm.server.android.com" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="htttps" />
<data android:host="non_http.pm.server.android.com" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="https" />
<data android:scheme="non_web_scheme" />
<data android:host="https_plus_non_web_scheme.pm.server.android.com" />
</intent-filter>
</activity>
<activity android:name=".TargetActivity2" android:exported="true">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="other_activity.pm.server.android.com" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="multiple.pm.server.android.com" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.intent.verifier.target.two"
android:versionCode="1">
<application>
<activity android:name=".TargetActivity" android:exported="true">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:scheme="non_web_scheme" />
<data android:host="only_https_plus_non_web_scheme.pm.server.android.com" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.intent.verifier.target.three"
android:versionCode="1">
<application>
<activity android:name=".TargetActivity" android:exported="true">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:host="multiple.pm.server.android.com" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.intent.verifier.target.four"
android:versionCode="1">
<application>
<activity android:name=".TargetActivity" android:exported="true">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="failing.pm.server.android.com" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.intent.verifier.target.four"
android:versionCode="1">
<application>
<activity android:name=".TargetActivity" android:exported="true">
<intent-filter android:autoVerify="false">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="failing.pm.server.android.com" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.intent.verifier.target.four"
android:versionCode="1">
<application>
<activity android:name=".TargetActivity" android:exported="true">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="failing.pm.server.android.com" />
<data android:host="*.wildcard.tld" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.server.pm.test.intent.verifier.target.four"
android:versionCode="1">
<application>
<activity android:name=".TargetActivity" android:exported="true">
<intent-filter android:autoVerify="false">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="failing.pm.server.android.com" />
<data android:host="*.wildcard.tld" />
</intent-filter>
</activity>
</application>
</manifest>