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