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

Commit db4355fe authored by Winson's avatar Winson Committed by Winson Chiu
Browse files

Add am compat enable/disable/reset test for not installed app

Should also cover installed apps, since this mocks at the
ApplicationInfo level.

The not installed behavior is used during package parsing to
pre-disable validation errors for an app that may not yet be
compliant with new targetSdk gated rules.

Bug: 152416067

Test: atest com.android.tests.gating.PlatformCompatCommandNotInstalledTest

Change-Id: Id7d1ff26f40626308d9b2e7c6cea60bce9b7f50f
parent 727da64b
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -17,7 +17,10 @@
android_test {
    name: "PlatformCompatGating",
    // Only compile source java files in this apk.
    srcs: ["src/**/*.java"],
    srcs: [
        "src/**/*.java",
        "src/**/*.kt",
    ],
    test_suites: ["device-tests"],
    static_libs: [
        "junit",
@@ -25,7 +28,8 @@ android_test {
        "androidx.test.core",
        "androidx.test.ext.junit",
        "mockito-target-minus-junit4",
        "testng",
        "truth-prebuilt",
        "platform-compat-test-rules"
        "platform-compat-test-rules",
    ],
}
+5 −0
Original line number Diff line number Diff line
@@ -2,6 +2,11 @@

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.tests.gating">

    <queries>
        <package android:name="com.android.tests.gating.app_not_installed" />
    </queries>

    <application android:label="GatingTest">
        <uses-library android:name="android.test.runner" />
    </application>
+133 −0
Original line number Diff line number Diff line
/*
 * 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.tests.gating

import android.Manifest
import android.app.UiAutomation
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.parsing.result.ParseInput
import android.os.Build
import android.os.ParcelFileDescriptor
import android.os.ServiceManager
import androidx.test.platform.app.InstrumentationRegistry
import com.android.internal.compat.IPlatformCompat
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.testng.Assert.assertThrows
import java.io.FileReader

/**
 * Verifies the shell commands "am compat enable/disable/reset" against a real server change ID
 * for a not installed package.
 *
 * This class intentionally does not use any PlatformCompat testing infrastructure since that could
 * interfere with what it's testing.
 */
@RunWith(Parameterized::class)
class PlatformCompatCommandNotInstalledTest {

    companion object {

        private const val TEST_PKG = "com.android.tests.gating.app_not_installed"
        private const val TEST_CHANGE_ID = ParseInput.DeferredError.MISSING_APP_TAG

        private val instrumentation = InstrumentationRegistry.getInstrumentation()

        @JvmStatic
        @BeforeClass
        fun assumeDebuggable() {
            assumeTrue(Build.IS_DEBUGGABLE)
        }

        @JvmStatic
        @BeforeClass
        fun assertNotInstalled() {
            assertThrows(PackageManager.NameNotFoundException::class.java) {
                instrumentation.context.packageManager
                        .getApplicationInfo(TEST_PKG, PackageManager.MATCH_ALL)
            }
        }

        @JvmStatic
        @Parameterized.Parameters(name = "{0}")
        fun parameters() = arrayOf(
                Params(enableDisable = null, targetSdk = 29, result = false),
                Params(enableDisable = null, targetSdk = 30, result = true),

                Params(enableDisable = true, targetSdk = 29, result = true),
                Params(enableDisable = true, targetSdk = 30, result = true),

                Params(enableDisable = false, targetSdk = 29, result = false),
                Params(enableDisable = false, targetSdk = 30, result = false)
        )
    }

    data class Params(val enableDisable: Boolean?, val targetSdk: Int, val result: Boolean)

    @Parameterized.Parameter(0)
    lateinit var params: Params

    private val uiAutomation: UiAutomation = instrumentation.getUiAutomation()
    private val platformCompat = IPlatformCompat.Stub.asInterface(
            ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE))

    @Before
    fun resetChangeId() {
        uiAutomation.adoptShellPermissionIdentity(Manifest.permission.LOG_COMPAT_CHANGE,
                Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG,
                Manifest.permission.READ_COMPAT_CHANGE_CONFIG)

        val result = command("am compat reset $TEST_CHANGE_ID $TEST_PKG")
        assertThat(result.startsWith("Reset change") || result.startsWith("No override"))
                .isTrue()
    }

    fun ParcelFileDescriptor.text() = FileReader(fileDescriptor).readText()

    @After
    fun resetIdentity() = uiAutomation.dropShellPermissionIdentity()

    @Test
    fun execute() {
        when (params.enableDisable) {
            null -> { /* do nothing */
            }
            true -> assertThat(command("am compat enable $TEST_CHANGE_ID $TEST_PKG"))
                    .startsWith("Enabled change")
            false -> assertThat(command("am compat disable $TEST_CHANGE_ID $TEST_PKG"))
                    .startsWith("Disabled change")
        }

        val appInfo = ApplicationInfo().apply {
            this.packageName = TEST_PKG
            this.targetSdkVersion = params.targetSdk
        }

        assertThat(platformCompat.isChangeEnabled(TEST_CHANGE_ID, appInfo)).isEqualTo(params.result)
    }

    private fun command(command: String) =
            FileReader(uiAutomation.executeShellCommand(command).fileDescriptor).readText()
}