1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.pm 18 19 import android.os.Build 20 import com.android.server.testutils.any 21 import com.android.server.testutils.spy 22 import com.android.server.testutils.whenever 23 import com.google.common.truth.Truth.assertThat 24 import org.junit.Before 25 import org.junit.Rule 26 import org.junit.Test 27 import org.junit.runner.RunWith 28 import org.junit.runners.JUnit4 29 import org.mockito.Mockito.eq 30 import org.mockito.Mockito.times 31 import org.mockito.Mockito.verify 32 import kotlin.test.assertFailsWith 33 34 @RunWith(JUnit4::class) 35 class PackageFreezerTest { 36 37 companion object { 38 const val TEST_PACKAGE = "com.android.test.package" 39 const val TEST_REASON = "test reason" 40 const val TEST_EXIT_REASON = 1 41 const val TEST_USER_ID = 0 42 } 43 44 @Rule 45 @JvmField 46 val rule = MockSystemRule() 47 48 lateinit var pms: PackageManagerService 49 createPackageManagerServicenull50 private fun createPackageManagerService(vararg stageExistingPackages: String): 51 PackageManagerService { 52 stageExistingPackages.forEach { 53 rule.system().stageScanExistingPackage(it, 1L, 54 rule.system().dataAppDirectory) 55 } 56 var pms = PackageManagerService(rule.mocks().injector, 57 false /*factoryTest*/, 58 MockSystem.DEFAULT_VERSION_INFO.fingerprint, 59 false /*isEngBuild*/, 60 false /*isUserDebugBuild*/, 61 Build.VERSION_CODES.CUR_DEVELOPMENT, 62 Build.VERSION.INCREMENTAL) 63 rule.system().validateFinalState() 64 return pms 65 } 66 frozenMessagenull67 private fun frozenMessage(packageName: String) = "Package $packageName is currently frozen!" 68 69 private fun <T : Throwable> assertThrowContainsMessage( 70 exceptionClass: kotlin.reflect.KClass<T>, 71 message: String, 72 block: () -> Unit 73 ) { 74 assertThat(assertFailsWith(exceptionClass, block).message).contains(message) 75 } 76 checkPackageStartablenull77 private fun checkPackageStartable() { 78 pms.checkPackageStartable(pms.snapshotComputer(), TEST_PACKAGE, TEST_USER_ID) 79 } 80 81 @Before 82 @Throws(Exception::class) setupnull83 fun setup() { 84 rule.system().stageNominalSystemState() 85 pms = spy(createPackageManagerService(TEST_PACKAGE)) 86 whenever(pms.killApplication(any(), any(), any(), any(), any())) 87 } 88 89 @Test freezePackagenull90 fun freezePackage() { 91 val freezer = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms, 92 TEST_EXIT_REASON, null /* request */) 93 verify(pms, times(1)) 94 .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON), 95 eq(TEST_EXIT_REASON)) 96 97 assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) { 98 checkPackageStartable() 99 } 100 101 freezer.close() 102 checkPackageStartable() 103 } 104 105 @Test freezePackage_twicenull106 fun freezePackage_twice() { 107 val freezer1 = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms, 108 TEST_EXIT_REASON, null /* request */) 109 val freezer2 = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms, 110 TEST_EXIT_REASON, null /* request */) 111 verify(pms, times(2)) 112 .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON), 113 eq(TEST_EXIT_REASON)) 114 115 assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) { 116 checkPackageStartable() 117 } 118 119 freezer1.close() 120 assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) { 121 checkPackageStartable() 122 } 123 124 freezer2.close() 125 checkPackageStartable() 126 } 127 128 @Test freezePackage_withoutClosingnull129 fun freezePackage_withoutClosing() { 130 var freezer: PackageFreezer? = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms, 131 TEST_EXIT_REASON, null /* request */) 132 verify(pms, times(1)) 133 .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON), 134 eq(TEST_EXIT_REASON)) 135 136 assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) { 137 checkPackageStartable() 138 } 139 140 freezer = null 141 System.gc() 142 System.runFinalization() 143 144 checkPackageStartable() 145 } 146 } 147