1 /*
2  * Copyright (C) 2020 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 package com.android.server.pm
17 
18 import android.content.pm.ApplicationInfo.FLAG_SYSTEM
19 import android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED
20 import android.content.pm.PackageManager
21 import android.os.Build
22 import android.os.Process
23 import android.util.Log
24 import com.android.server.pm.pkg.AndroidPackage
25 import com.android.server.testutils.whenever
26 import java.io.File
27 import org.hamcrest.MatcherAssert.assertThat
28 import org.hamcrest.Matchers.equalTo
29 import org.hamcrest.Matchers.notNullValue
30 import org.hamcrest.collection.IsMapContaining.hasKey
31 import org.hamcrest.core.IsNot.not
32 import org.junit.Before
33 import org.junit.Rule
34 import org.junit.Test
35 import org.junit.runner.RunWith
36 import org.junit.runners.JUnit4
37 import org.mockito.ArgumentMatchers.anyBoolean
38 import org.mockito.ArgumentMatchers.anyInt
39 import org.mockito.ArgumentMatchers.argThat
40 import org.mockito.Mockito
41 import org.mockito.Mockito.verify
42 
43 @RunWith(JUnit4::class)
44 class PackageManagerServiceBootTest {
45 
46     @Rule
47     @JvmField
48     val rule = MockSystemRule()
49 
50     @Before
51     @Throws(Exception::class)
52     fun setup() {
53         Log.i("system.out", "setup", Exception())
54         rule.system().stageNominalSystemState()
55     }
56 
57     private fun createPackageManagerService(): PackageManagerService {
58         return PackageManagerService(rule.mocks().injector,
59                 false /*factoryTest*/,
60                 MockSystem.DEFAULT_VERSION_INFO.fingerprint,
61                 false /*isEngBuild*/,
62                 false /*isUserDebugBuild*/,
63                 Build.VERSION_CODES.CUR_DEVELOPMENT,
64                 Build.VERSION.INCREMENTAL)
65     }
66 
67     @Test
68     @Throws(Exception::class)
69     fun simpleConstruction() {
70         val pm = createPackageManagerService()
71         verify(rule.mocks().injector).bootstrap(pm)
72         verify(rule.mocks().settings).addSharedUserLPw("android.uid.system",
73                 Process.SYSTEM_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
74         verify(rule.mocks().settings).addSharedUserLPw("android.uid.phone",
75                 Process.PHONE_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
76         verify(rule.mocks().settings).addSharedUserLPw("android.uid.log",
77                 Process.LOG_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
78         verify(rule.mocks().settings).addSharedUserLPw("android.uid.nfc",
79                 Process.NFC_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
80         verify(rule.mocks().settings).addSharedUserLPw("android.uid.bluetooth",
81                 Process.BLUETOOTH_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
82         verify(rule.mocks().settings).addSharedUserLPw("android.uid.shell",
83                 Process.SHELL_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
84         verify(rule.mocks().settings).addSharedUserLPw("android.uid.se",
85                 Process.SE_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
86         verify(rule.mocks().settings).addSharedUserLPw("android.uid.networkstack",
87                 Process.NETWORK_STACK_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
88         rule.system().validateFinalState()
89     }
90 
91     @Test
92     @Throws(Exception::class)
93     fun existingDataPackage_remains() {
94         rule.system().stageScanExistingPackage("a.data.package", 1L, rule.system().dataAppDirectory)
95         val pm = createPackageManagerService()
96         rule.system().validateFinalState()
97         assertThat(pm.mPackages, hasKey("a.data.package"))
98     }
99 
100     @Test
101     @Throws(Exception::class)
102     fun unexpectedDataPackage_isRemoved() {
103         rule.system().stageScanNewPackage(
104                 "a.data.package", 1L, rule.system().dataAppDirectory)
105         val pm = createPackageManagerService()
106         verify(rule.mocks().settings, Mockito.never()).insertPackageSettingLPw(
107                 argThat { setting: PackageSetting -> setting.name == "a.data.package" },
108                 argThat { pkg: AndroidPackage -> pkg.packageName == "a.data.package" })
109         assertThat(pm.mPackages, not(hasKey("a.data.package")))
110     }
111 
112     @Test
113     @Throws(Exception::class)
114     fun expectedPackageMissing_doesNotReplace() {
115         // setup existing package
116         rule.system().stageScanExistingPackage("a.data.package", 1L,
117                 rule.system().dataAppDirectory)
118         // simulate parsing failure for any path containing the package name.
119         whenever(rule.mocks().packageParser.parsePackage(
120                 argThat { path: File -> path.path.contains("a.data.package") },
121                 anyInt(),
122                 anyBoolean()))
123                 .thenThrow(PackageManagerException(
124                         PackageManager.INSTALL_FAILED_INVALID_APK, "Oh no!"))
125         val pm = createPackageManagerService()
126         verify(rule.mocks().settings, Mockito.never()).insertPackageSettingLPw(
127                 argThat { setting: PackageSetting -> setting.name == "a.data.package" },
128                 argThat { pkg: AndroidPackage -> pkg.packageName == "a.data.package" })
129         assertThat(pm.mPackages, not(hasKey("a.data.package")))
130     }
131 
132     @Test
133     @Throws(Exception::class)
134     fun expectingBetter_updateStillBetter() {
135         // Debug.waitForDebugger()
136         val systemAppPackageName = "com.android.test.updated.system.app"
137         val systemAppSigningDetails = rule.system().createRandomSigningDetails()
138         val systemVersionParent = rule.system()
139                 .getPartitionFromFlag(PackageManagerService.SCAN_AS_PRODUCT).privAppFolder
140 
141         // system app v1 is disabled
142         whenever(rule.mocks().settings.isDisabledSystemPackageLPr(systemAppPackageName)) {
143             true
144         }
145         whenever(rule.mocks().settings.getDisabledSystemPkgLPr(systemAppPackageName)) {
146             rule.system().createBasicSettingBuilder(
147                     File(systemVersionParent, systemAppPackageName),
148                     systemAppPackageName, 1, systemAppSigningDetails).build()
149         }
150 
151         // system app v3 is on data/app
152         rule.system().stageScanExistingPackage(
153                 systemAppPackageName,
154                 3,
155                 rule.system().dataAppDirectory,
156                 withPackage = { it.apply { signingDetails = systemAppSigningDetails } },
157                 withExistingSetting = { it.setPkgFlags(FLAG_SYSTEM) })
158 
159         // system app v2 is scanned from system
160         rule.system().stageScanNewPackage(systemAppPackageName, 2, systemVersionParent,
161                 withPackage = { it.apply { signingDetails = systemAppSigningDetails } },
162                 withSetting = { it.setPkgFlags(FLAG_SYSTEM) })
163 
164         val pm = createPackageManagerService()
165 
166         assertThat("system package should exist after boot",
167                 pm.mPackages[systemAppPackageName], notNullValue())
168         assertThat("system package should remain at version on data/app",
169                 pm.mPackages[systemAppPackageName]!!.longVersionCode, equalTo(3))
170     }
171 }
172