1 /*
2  * Copyright (C) 2016 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 android.appsecurity.cts;
18 
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.assertTrue;
21 
22 import android.platform.test.annotations.AppModeFull;
23 import android.platform.test.annotations.AppModeInstant;
24 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
25 
26 import org.junit.After;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 
31 /**
32  * Tests for visibility of packages installed in one user, in a different user.
33  */
34 @RunWith(DeviceJUnit4ClassRunner.class)
35 public class PackageVisibilityTest extends BaseAppSecurityTest {
36 
37     private static final String TINY_APK = "CtsPkgInstallTinyApp.apk";
38     private static final String TINY_PKG = "android.appsecurity.cts.tinyapp";
39 
40     private static final String TEST_APK = "CtsPkgAccessApp.apk";
41     private static final String TEST_PKG = "com.android.cts.packageaccessapp";
42 
43     private static final boolean MATCH_UNINSTALLED = true;
44     private static final boolean MATCH_NORMAL = false;
45 
46     private int[] mUsers;
47     private String mOldVerifierValue;
48 
49     @Before
setUpPackage()50     public void setUpPackage() throws Exception {
51 
52         mUsers = Utils.prepareMultipleUsers(getDevice());
53         mOldVerifierValue =
54                 getDevice().executeShellCommand("settings get global package_verifier_enable");
55         getDevice().executeShellCommand("settings put global package_verifier_enable 0");
56         getDevice().uninstallPackage(TEST_PKG);
57         getDevice().uninstallPackage(TINY_PKG);
58         installTestAppForUser(TEST_APK, mPrimaryUserId);
59     }
60 
61     @After
tearDown()62     public void tearDown() throws Exception {
63         getDevice().uninstallPackage(TEST_PKG);
64         getDevice().uninstallPackage(TINY_PKG);
65         getDevice().executeShellCommand("settings put global package_verifier_enable "
66                 + mOldVerifierValue);
67     }
68 
69     @Test
70     @AppModeFull(reason = "'full' portion of the hostside test")
testUninstalledPackageVisibility_full()71     public void testUninstalledPackageVisibility_full() throws Exception {
72         testUninstalledPackageVisibility(false);
73     }
74     @Test
75     @AppModeInstant(reason = "'instant' portion of the hostside test")
testUninstalledPackageVisibility_instant()76     public void testUninstalledPackageVisibility_instant() throws Exception {
77         testUninstalledPackageVisibility(true);
78     }
testUninstalledPackageVisibility(boolean instant)79     private void testUninstalledPackageVisibility(boolean instant) throws Exception {
80         if (!mSupportsMultiUser) {
81             return;
82         }
83 
84         int userId = mUsers[1];
85         assertTrue(userId > 0);
86         getDevice().startUser(userId);
87         installTestAppForUser(TEST_APK, userId);
88         installTestAppForUser(TEST_APK, mPrimaryUserId);
89 
90         installTestAppForUser(TINY_APK, mPrimaryUserId);
91 
92         // It is visible for the installed user, using shell commands
93         assertTrue(isAppVisibleForUser(TINY_PKG, mPrimaryUserId, MATCH_NORMAL));
94         assertTrue(isAppVisibleForUser(TINY_PKG, mPrimaryUserId, MATCH_UNINSTALLED));
95 
96         // Try the same from an app
97         Utils.runDeviceTests(getDevice(), TEST_PKG,
98                 ".PackageAccessTest", "testPackageAccess_inUser", mPrimaryUserId);
99         Utils.runDeviceTests(getDevice(), TEST_PKG,
100                 ".PackageAccessTest", "testPackageAccess_inUserUninstalled", mPrimaryUserId);
101 
102         // It is not visible for the other user using shell commands
103         assertFalse(isAppVisibleForUser(TINY_PKG, userId, MATCH_NORMAL));
104         assertFalse(isAppVisibleForUser(TINY_PKG, userId, MATCH_UNINSTALLED));
105 
106         // Try the same from an app
107         Utils.runDeviceTests(getDevice(), TEST_PKG,
108                 ".PackageAccessTest", "testPackageAccess_notInOtherUser", userId);
109         Utils.runDeviceTests(getDevice(), TEST_PKG,
110                 ".PackageAccessTest", "testPackageAccess_notInOtherUserUninstalled", userId);
111 
112         Utils.runDeviceTests(getDevice(), TEST_PKG,
113                 ".PackageAccessTest", "testPackageAccess_getPackagesCantSeeTiny", userId);
114 
115         getDevice().uninstallPackage(TINY_PKG);
116 
117         // Install for the new user
118         installTestAppForUser(TINY_APK, userId);
119 
120         // It is visible for the installed user
121         assertTrue(isAppVisibleForUser(TINY_PKG, userId, MATCH_NORMAL));
122         assertTrue(isAppVisibleForUser(TINY_PKG, userId, MATCH_UNINSTALLED));
123 
124         // It is not visible for the other user
125         assertFalse(isAppVisibleForUser(TINY_PKG, mPrimaryUserId, MATCH_NORMAL));
126         assertFalse(isAppVisibleForUser(TINY_PKG, mPrimaryUserId, MATCH_UNINSTALLED));
127 
128         // Uninstall with keep data
129         uninstallWithKeepDataForUser(TINY_PKG, userId);
130 
131         // It is visible for the installed user, but only if match uninstalled
132         assertFalse(isAppVisibleForUser(TINY_PKG, userId, MATCH_NORMAL));
133         assertTrue(isAppVisibleForUser(TINY_PKG, userId, MATCH_UNINSTALLED));
134 
135         Utils.runDeviceTests(getDevice(), TEST_PKG,
136                 ".PackageAccessTest", "testPackageAccess_getPackagesCanSeeTiny", userId);
137 
138         Utils.runDeviceTests(getDevice(), TEST_PKG,
139                 ".PackageAccessTest", "testPackageAccess_notInOtherUserUninstalled",
140                 mPrimaryUserId);
141         Utils.runDeviceTests(getDevice(), TEST_PKG,
142                 ".PackageAccessTest", "testPackageAccess_getPackagesCantSeeTiny", mPrimaryUserId);
143 
144         getDevice().uninstallPackage(TINY_PKG);
145         getDevice().uninstallPackage(TEST_PKG);
146     }
147 
uninstallWithKeepDataForUser(String packageName, int userId)148     private void uninstallWithKeepDataForUser(String packageName, int userId) throws Exception {
149         final String command = "pm uninstall -k --user " + userId + " " + packageName;
150         getDevice().executeShellCommand(command);
151     }
152 }
153