1 /*
2  * Copyright (C) 2023 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.car.cts;
18 
19 import static com.google.common.truth.Truth.assertWithMessage;
20 
21 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
22 
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 
26 import java.util.ArrayList;
27 import java.util.Objects;
28 
29 @RunWith(DeviceJUnit4ClassRunner.class)
30 public final class CarUserManagerHostTest extends CarHostJUnit4TestCase {
31     private static final String TAG = CarUserManagerHostTest.class.getSimpleName();
32     private static final String STATUS_SUCCESSFUL = "STATUS_SUCCESSFUL";
33     private static final String STATUS_INVALID_REQUEST = "STATUS_INVALID_REQUEST";
34     private static final String STATUS_OK_USER_ALREADY_IN_FOREGROUND =
35             "STATUS_OK_USER_ALREADY_IN_FOREGROUND";
36     private static final String STATUS_UX_RESTRICTION_FAILURE = "STATUS_UX_RESTRICTION_FAILURE";
37     private static final long TEST_WAIT_MS = 50;
38     private static final long TEST_TIMEOUT_MS = 10_000;
39 
40     @Test
testSwitchUserExists()41     public void testSwitchUserExists() throws Exception {
42         int newUserid = createFullUser("CarUserManagerHostTest_User");
43 
44         switchUser(newUserid, STATUS_SUCCESSFUL);
45     }
46 
47     @Test
testSwitchUserDoesNotExist()48     public void testSwitchUserDoesNotExist() throws Exception {
49         switchUser(getNonExistentUser(), STATUS_INVALID_REQUEST);
50     }
51 
52     @Test
testSwitchUserAlreadyForeGroundUser()53     public void testSwitchUserAlreadyForeGroundUser() throws Exception {
54         switchUser(getCurrentUserId(), STATUS_OK_USER_ALREADY_IN_FOREGROUND);
55     }
56 
57     @Test
testRemoveUser()58     public void testRemoveUser() throws Exception {
59         int newUserid = createFullUser("CarUserManagerHostTest_User");
60 
61         String result = executeCommand("cmd car_service remove-user %d", newUserid);
62 
63         assertWithMessage("removeUser(%s)", newUserid).that(result).contains(STATUS_SUCCESSFUL);
64     }
65 
66     @Test
testSwitchUserIgnoringUxRestriction()67     public void testSwitchUserIgnoringUxRestriction() throws Exception {
68         int newUserid = createFullUser("CarUserManagerHostTest_User");
69 
70         switchUser(newUserid, STATUS_SUCCESSFUL, "--ignore-uxr");
71     }
72 
73     /**
74      * Switches the current user and checks that the expected result is emitted.
75      */
switchUser(int userId, String expected)76     private void switchUser(int userId, String expected) throws Exception {
77         switchUser(userId, expected, "");
78     }
79 
80     /**
81      * Switches the current user and checks that the expected result is emitted.
82      */
switchUser(int userId, String expected, String options)83     private void switchUser(int userId, String expected, String options) throws Exception {
84         waitForCarServiceReady();
85         String output = executeCommand("cmd car_service switch-user %d %s", userId, options);
86 
87         assertWithMessage("switchUser(%s) ", userId).that(output).contains(expected);
88 
89         if (Objects.equals(expected, STATUS_SUCCESSFUL)) {
90             waitUntilCurrentUser(userId);
91         }
92     }
93 
94     /**
95      * Returns the userId of a non-existent user.
96      */
getNonExistentUser()97     private int getNonExistentUser() throws Exception {
98         return onAllUsers(ArrayList::new).stream()
99                 .mapToInt((userInfo) -> userInfo.id)
100                 .max()
101                 .orElse(0) + 1;
102     }
103 }
104