1 /*
2  * Copyright (C) 2019 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.tests.rollback.host;
18 
19 import static org.junit.Assert.assertTrue;
20 import static org.junit.Assert.fail;
21 
22 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
23 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
24 
25 import org.junit.After;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 
30 /**
31  * Runs rollback tests for multiple users.
32  */
33 @RunWith(DeviceJUnit4ClassRunner.class)
34 public class MultiUserRollbackTest extends BaseHostJUnit4Test {
35     // The user that was running originally when the test starts.
36     private int mOriginalUserId;
37     private int mSecondaryUserId = -1;
38     private static final long SWITCH_USER_COMPLETED_NUMBER_OF_POLLS = 60;
39     private static final long SWITCH_USER_COMPLETED_POLL_INTERVAL_IN_MILLIS = 1000;
40 
41 
42     @After
tearDown()43     public void tearDown() throws Exception {
44         getDevice().switchUser(mOriginalUserId);
45         getDevice().executeShellCommand("pm uninstall com.android.cts.install.lib.testapp.A");
46         removeSecondaryUserIfNecessary();
47     }
48 
49     @Before
setup()50     public void setup() throws Exception {
51         mOriginalUserId = getDevice().getCurrentUser();
52         installPackageAsUser("RollbackTest.apk", true, mOriginalUserId);
53         createAndSwitchToSecondaryUserIfNecessary();
54         installPackageAsUser("RollbackTest.apk", true, mSecondaryUserId);
55     }
56 
57     @Test
testBasicForSecondaryUser()58     public void testBasicForSecondaryUser() throws Exception {
59         runPhaseForUsers("testBasic", mSecondaryUserId);
60     }
61 
62     @Test
testMultipleUsers()63     public void testMultipleUsers() throws Exception {
64         runPhaseForUsers("testMultipleUsersInstallV1", mOriginalUserId, mSecondaryUserId);
65         runPhaseForUsers("testMultipleUsersUpgradeToV2", mOriginalUserId);
66         runPhaseForUsers("testMultipleUsersUpdateUserData", mOriginalUserId, mSecondaryUserId);
67         switchToUser(mOriginalUserId);
68         getDevice().executeShellCommand("pm rollback-app com.android.cts.install.lib.testapp.A");
69         runPhaseForUsers("testMultipleUsersVerifyUserdataRollback", mOriginalUserId,
70                 mSecondaryUserId);
71     }
72 
73     /**
74      * Run the phase for the given user ids, in the order they are given.
75      */
runPhaseForUsers(String phase, int... userIds)76     private void runPhaseForUsers(String phase, int... userIds) throws Exception {
77         for (int userId: userIds) {
78             switchToUser(userId);
79             assertTrue(runDeviceTests("com.android.tests.rollback",
80                     "com.android.tests.rollback.MultiUserRollbackTest",
81                     phase));
82         }
83     }
84 
removeSecondaryUserIfNecessary()85     private void removeSecondaryUserIfNecessary() throws Exception {
86         if (mSecondaryUserId != -1) {
87             getDevice().removeUser(mSecondaryUserId);
88             mSecondaryUserId = -1;
89         }
90     }
91 
createAndSwitchToSecondaryUserIfNecessary()92     private void createAndSwitchToSecondaryUserIfNecessary() throws Exception {
93         if (mSecondaryUserId == -1) {
94             mOriginalUserId = getDevice().getCurrentUser();
95             mSecondaryUserId = getDevice().createUser("MultiUserRollbackTest_User"
96                     + System.currentTimeMillis());
97             switchToUser(mSecondaryUserId);
98         }
99     }
100 
switchToUser(int userId)101     private void switchToUser(int userId) throws Exception {
102         if (getDevice().getCurrentUser() == userId) {
103             return;
104         }
105 
106         assertTrue(getDevice().switchUser(userId));
107         for (int i = 0; i < SWITCH_USER_COMPLETED_NUMBER_OF_POLLS; ++i) {
108             String userState = getDevice().executeShellCommand("am get-started-user-state "
109                     + userId);
110             if (userState.contains("RUNNING_UNLOCKED")) {
111                 return;
112             }
113             Thread.sleep(SWITCH_USER_COMPLETED_POLL_INTERVAL_IN_MILLIS);
114         }
115         fail("User switch to user " + userId + " timed out");
116     }
117 }
118