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.assertEquals;
20 import static org.junit.Assert.assertNull;
21 
22 import android.platform.test.annotations.AppModeFull;
23 
24 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
25 import com.android.tradefed.device.DeviceNotAvailableException;
26 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
27 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
28 
29 import org.junit.After;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 
34 /**
35  * Tests for ephemeral packages.
36  */
37 @RunWith(DeviceJUnit4ClassRunner.class)
38 @AppModeFull(reason = "Already handles instant installs when needed")
39 public class InstantAppUserTest extends BaseHostJUnit4Test {
40 
41     // a normally installed application
42     private static final String NORMAL_APK = "CtsEphemeralTestsNormalApp.apk";
43     private static final String NORMAL_PKG = "com.android.cts.normalapp";
44 
45     // a normally installed application with implicitly exposed components
46     private static final String IMPLICIT_APK = "CtsEphemeralTestsImplicitApp.apk";
47     private static final String IMPLICIT_PKG = "com.android.cts.implicitapp";
48 
49     // the first ephemerally installed application
50     private static final String EPHEMERAL_1_APK = "CtsEphemeralTestsEphemeralApp1.apk";
51     private static final String EPHEMERAL_1_PKG = "com.android.cts.ephemeralapp1";
52 
53     // an application to verify instant/full app per user
54     private static final String USER_APK = "CtsEphemeralTestsUserApp.apk";
55     private static final String USER_PKG = "com.android.cts.userapp";
56 
57     private static final String USER_TEST_APK = "CtsEphemeralTestsUserAppTest.apk";
58     private static final String USER_TEST_PKG = "com.android.cts.userapptest";
59 
60     private static final String TEST_CLASS = ".ClientTest";
61 
62     private boolean mSupportsMultiUser;
63     private int mPrimaryUserId;
64     private int mSecondaryUserId;
65     private int mStartingUserId;
66 
67     @Before
setUp()68     public void setUp() throws Exception {
69         // This test only runs when we have at least 2 users to work with
70         final int[] users = Utils.prepareMultipleUsers(getDevice(), 2);
71         mSupportsMultiUser = (users.length == 2);
72         if (!mSupportsMultiUser) {
73             return;
74         }
75         mPrimaryUserId = getDevice().getPrimaryUserId();
76         mStartingUserId = getDevice().getCurrentUser();
77         mSecondaryUserId = users[1];
78         getDevice().switchUser(mSecondaryUserId);
79         uninstallTestPackages();
80         installTestPackages();
81     }
82 
83     @After
tearDown()84     public void tearDown() throws Exception {
85         if (!mSupportsMultiUser) {
86             return;
87         }
88         uninstallTestPackages();
89         getDevice().switchUser(mStartingUserId);
90     }
91 
92     // each connection to an exposed component needs to run in its own test to
93     // avoid sharing state. once an instant app is exposed to a component, it's
94     // exposed until the device restarts or the instant app is removed.
95     @Test
testStartExposed01()96     public void testStartExposed01() throws Exception {
97         if (!mSupportsMultiUser) {
98             return;
99         }
100         runDeviceTestsAsUser(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed01", mSecondaryUserId);
101     }
102     @Test
testStartExposed02()103     public void testStartExposed02() throws Exception {
104         if (!mSupportsMultiUser) {
105             return;
106         }
107         runDeviceTestsAsUser(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed02", mSecondaryUserId);
108     }
109     @Test
testStartExposed03()110     public void testStartExposed03() throws Exception {
111         if (!mSupportsMultiUser) {
112             return;
113         }
114         runDeviceTestsAsUser(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed03", mSecondaryUserId);
115     }
116     @Test
testStartExposed04()117     public void testStartExposed04() throws Exception {
118         if (!mSupportsMultiUser) {
119             return;
120         }
121         runDeviceTestsAsUser(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed04", mSecondaryUserId);
122     }
123     @Test
testStartExposed05()124     public void testStartExposed05() throws Exception {
125         if (!mSupportsMultiUser) {
126             return;
127         }
128         runDeviceTestsAsUser(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed05", mSecondaryUserId);
129     }
130     @Test
testStartExposed06()131     public void testStartExposed06() throws Exception {
132         if (!mSupportsMultiUser) {
133             return;
134         }
135         runDeviceTestsAsUser(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed06", mSecondaryUserId);
136     }
137     @Test
testStartExposed07()138     public void testStartExposed07() throws Exception {
139         if (!mSupportsMultiUser) {
140             return;
141         }
142         runDeviceTestsAsUser(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed07", mSecondaryUserId);
143     }
144     @Test
testStartExposed08()145     public void testStartExposed08() throws Exception {
146         if (!mSupportsMultiUser) {
147             return;
148         }
149         runDeviceTestsAsUser(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed08", mSecondaryUserId);
150     }
151     @Test
testStartExposed09()152     public void testStartExposed09() throws Exception {
153         if (!mSupportsMultiUser) {
154             return;
155         }
156         runDeviceTestsAsUser(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed09", mSecondaryUserId);
157     }
158     @Test
testStartExposed10()159     public void testStartExposed10() throws Exception {
160         if (!mSupportsMultiUser) {
161             return;
162         }
163         runDeviceTestsAsUser(EPHEMERAL_1_PKG, TEST_CLASS, "testStartExposed10", mSecondaryUserId);
164     }
165 
166     @Test
testInstallInstant()167     public void testInstallInstant() throws Exception {
168         if (!mSupportsMultiUser) {
169             return;
170         }
171         installInstantApp(USER_APK);
172         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryInstant", mPrimaryUserId);
173         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryInstant", mSecondaryUserId);
174     }
175 
176     @Test
testInstallFull()177     public void testInstallFull() throws Exception {
178         if (!mSupportsMultiUser) {
179             return;
180         }
181         installApp(USER_APK);
182         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryFull", mPrimaryUserId);
183         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryFull", mSecondaryUserId);
184     }
185 
186     @Test
testInstallMultiple()187     public void testInstallMultiple() throws Exception {
188         if (!mSupportsMultiUser) {
189             return;
190         }
191         installAppAsUser(USER_APK, mPrimaryUserId);
192         installExistingInstantAppAsUser(USER_PKG, mSecondaryUserId);
193         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryFull", mPrimaryUserId);
194         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryInstant", mSecondaryUserId);
195     }
196 
197     @Test
testUpgradeExisting()198     public void testUpgradeExisting() throws Exception {
199         if (!mSupportsMultiUser) {
200             return;
201         }
202         installInstantApp(USER_APK);
203         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryInstant", mPrimaryUserId);
204         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryInstant", mSecondaryUserId);
205 
206         installExistingFullAppAsUser(USER_PKG, mSecondaryUserId);
207         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryInstant", mPrimaryUserId);
208         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryFull", mSecondaryUserId);
209     }
210 
211     @Test
testReplaceExisting()212     public void testReplaceExisting() throws Exception {
213         if (!mSupportsMultiUser) {
214             return;
215         }
216         installInstantApp(USER_APK);
217         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryInstant", mPrimaryUserId);
218         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryInstant", mSecondaryUserId);
219 
220         replaceFullAppAsUser(USER_APK, mSecondaryUserId);
221         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryInstant", mPrimaryUserId);
222         runDeviceTestsAsUser(USER_TEST_PKG, TEST_CLASS, "testQueryFull", mSecondaryUserId);
223     }
224 
installTestPackages()225     private void installTestPackages() throws Exception {
226         installApp(NORMAL_APK);
227         installApp(IMPLICIT_APK);
228         installInstantApp(EPHEMERAL_1_APK);
229         installApp(USER_TEST_APK);
230     }
231 
uninstallTestPackages()232     private void uninstallTestPackages() throws Exception {
233         getDevice().uninstallPackage(NORMAL_PKG);
234         getDevice().uninstallPackage(IMPLICIT_PKG);
235         getDevice().uninstallPackage(EPHEMERAL_1_PKG);
236         getDevice().uninstallPackage(USER_TEST_PKG);
237         getDevice().uninstallPackage(USER_PKG);
238     }
239 
runDeviceTestsAsUser(String packageName, String testClassName, String testMethodName, int userId)240     private void runDeviceTestsAsUser(String packageName, String testClassName,
241             String testMethodName, int userId)
242             throws DeviceNotAvailableException {
243         Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName, userId);
244     }
245 
installApp(String apk)246     private void installApp(String apk) throws Exception {
247         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
248         assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), false));
249     }
250 
installInstantApp(String apk)251     private void installInstantApp(String apk) throws Exception {
252         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
253         assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), false, "--instant"));
254     }
255 
installAppAsUser(String apk, int userId)256     private void installAppAsUser(String apk, int userId) throws Exception {
257         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
258         assertNull(getDevice().installPackageForUser(buildHelper.getTestFile(apk), false, userId));
259     }
260 
replaceFullAppAsUser(String apk, int userId)261     private void replaceFullAppAsUser(String apk, int userId) throws Exception {
262         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
263         assertNull(getDevice().installPackageForUser(
264                 buildHelper.getTestFile(apk), true, userId, "--full"));
265     }
266 
installExistingInstantAppAsUser(String packageName, int userId)267     private void installExistingInstantAppAsUser(String packageName, int userId) throws Exception {
268         final String installString =
269                 "Package " + packageName + " installed for user: " + userId + "\n";
270         assertEquals(installString, getDevice().executeShellCommand(
271                 "cmd package install-existing --instant"
272                         + " --user " + Integer.toString(userId)
273                         + " " + packageName));
274     }
275 
installExistingFullAppAsUser(String packageName, int userId)276     private void installExistingFullAppAsUser(String packageName, int userId) throws Exception {
277         final String installString =
278                 "Package " + packageName + " installed for user: " + userId + "\n";
279         assertEquals(installString, getDevice().executeShellCommand(
280                 "cmd package install-existing --full"
281                         + " --user " + Integer.toString(userId)
282                         + " " + packageName));
283     }
284 }
285