1 /*
2  * Copyright (C) 2022 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.content.pm.PackageManager
20 import android.content.pm.UserInfo
21 import android.os.Build
22 import android.util.Log
23 import com.android.server.testutils.any
24 import com.android.server.testutils.spy
25 import com.android.server.testutils.whenever
26 import com.google.common.truth.Truth.assertThat
27 import org.junit.Before
28 import org.junit.Rule
29 import org.junit.Test
30 import org.junit.runner.RunWith
31 import org.junit.runners.JUnit4
32 import org.mockito.Mockito.doAnswer
33 
34 @RunWith(JUnit4::class)
35 class DeletePackageHelperTest {
36 
37     @Rule
38     @JvmField
39     val rule = MockSystemRule()
40 
41     private lateinit var mPms: PackageManagerService
42     private lateinit var mUserManagerInternal: UserManagerInternal
43 
44     @Before
45     @Throws(Exception::class)
46     fun setup() {
47         Log.i("system.out", "setup", Exception())
48         rule.system().stageNominalSystemState()
49         rule.system().stageScanExistingPackage(
50             "a.data.package", 1L, rule.system().dataAppDirectory)
51 
52         mUserManagerInternal = rule.mocks().injector.userManagerInternal
53         whenever(mUserManagerInternal.getUserIds()).thenReturn(intArrayOf(0, 1))
54         whenever(mUserManagerInternal.getUserTypesForStatsd(any())).thenReturn(intArrayOf(1, 1))
55 
56         mPms = createPackageManagerService()
57         doAnswer { false }.`when`(mPms).isPackageDeviceAdmin(any(), any())
58         doAnswer { null }.`when`(mPms).freezePackageForDelete(any(), any(), any(), any(), any())
59     }
60 
61     private fun createPackageManagerService(): PackageManagerService {
62         return spy(PackageManagerService(rule.mocks().injector,
63             false /*factoryTest*/,
64             MockSystem.DEFAULT_VERSION_INFO.fingerprint,
65             false /*isEngBuild*/,
66             false /*isUserDebugBuild*/,
67             Build.VERSION_CODES.CUR_DEVELOPMENT,
68             Build.VERSION.INCREMENTAL))
69     }
70 
71     @Test
72     fun deleteSystemPackageFailsIfNotAdminAndNotProfile() {
73         val ps = mPms.mSettings.getPackageLPr("a.data.package")
74         whenever(PackageManagerServiceUtils.isUpdatedSystemApp(ps)).thenReturn(true)
75         whenever(mUserManagerInternal.getUserInfo(1)).thenReturn(UserInfo(1, "test", 0))
76         whenever(mUserManagerInternal.getProfileParentId(1)).thenReturn(1)
77 
78         val dph = DeletePackageHelper(mPms)
79         val result = dph.deletePackageX("a.data.package", 1L, 1, 0, false)
80 
81         assertThat(result).isEqualTo(PackageManager.DELETE_FAILED_USER_RESTRICTED)
82     }
83 
84     @Test
85     fun deleteSystemPackageFailsIfProfileOfNonAdmin() {
86         val userId = 1
87         val parentId = 5
88         val ps = mPms.mSettings.getPackageLPr("a.data.package")
89         whenever(PackageManagerServiceUtils.isUpdatedSystemApp(ps)).thenReturn(true)
90         whenever(mUserManagerInternal.getUserInfo(userId)).thenReturn(
91             UserInfo(userId, "test", UserInfo.FLAG_PROFILE))
92         whenever(mUserManagerInternal.getProfileParentId(userId)).thenReturn(parentId)
93         whenever(mUserManagerInternal.getUserInfo(parentId)).thenReturn(
94             UserInfo(userId, "testparent", 0))
95 
96         val dph = DeletePackageHelper(mPms)
97         val result = dph.deletePackageX("a.data.package", 1L, userId, 0, false)
98 
99         assertThat(result).isEqualTo(PackageManager.DELETE_FAILED_USER_RESTRICTED)
100     }
101 
102     @Test
103     fun deleteSystemPackageSucceedsIfAdmin() {
104         val ps = mPms.mSettings.getPackageLPr("a.data.package")
105         whenever(PackageManagerServiceUtils.isSystemApp(ps)).thenReturn(true)
106         whenever(mUserManagerInternal.getUserInfo(1)).thenReturn(
107             UserInfo(1, "test", UserInfo.FLAG_ADMIN))
108 
109         val dph = DeletePackageHelper(mPms)
110         val result = dph.deletePackageX("a.data.package", 1L, 1,
111             PackageManager.DELETE_SYSTEM_APP, false)
112 
113         assertThat(result).isEqualTo(PackageManager.DELETE_SUCCEEDED)
114     }
115 
116     @Test
117     fun deleteSystemPackageSucceedsIfProfileOfAdmin() {
118         val userId = 1
119         val parentId = 5
120         val ps = mPms.mSettings.getPackageLPr("a.data.package")
121         whenever(PackageManagerServiceUtils.isSystemApp(ps)).thenReturn(true)
122         whenever(mUserManagerInternal.getUserInfo(userId)).thenReturn(
123             UserInfo(userId, "test", UserInfo.FLAG_PROFILE))
124         whenever(mUserManagerInternal.getProfileParentId(userId)).thenReturn(parentId)
125         whenever(mUserManagerInternal.getUserInfo(parentId)).thenReturn(
126             UserInfo(userId, "testparent", UserInfo.FLAG_ADMIN))
127 
128         val dph = DeletePackageHelper(mPms)
129         val result = dph.deletePackageX("a.data.package", 1L, userId,
130             PackageManager.DELETE_SYSTEM_APP, false)
131 
132         assertThat(result).isEqualTo(PackageManager.DELETE_SUCCEEDED)
133     }
134 
135     @Test
136     fun deleteSystemPackageSucceedsIfNotAdminButDeleteSystemAppSpecified() {
137         val ps = mPms.mSettings.getPackageLPr("a.data.package")
138         whenever(PackageManagerServiceUtils.isUpdatedSystemApp(ps)).thenReturn(true)
139         whenever(mUserManagerInternal.getUserInfo(1)).thenReturn(UserInfo(1, "test", 0))
140         whenever(mUserManagerInternal.getProfileParentId(1)).thenReturn(1)
141 
142         val dph = DeletePackageHelper(mPms)
143         val result = dph.deletePackageX("a.data.package", 1L, 1,
144                 PackageManager.DELETE_SYSTEM_APP, false)
145 
146         assertThat(result).isEqualTo(PackageManager.DELETE_SUCCEEDED)
147     }
148 }
149