1 /* 2 * Copyright (C) 2020 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 package android.car.test.util; 17 18 import static com.android.compatibility.common.util.ShellUtils.runShellCommand; 19 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.UserIdInt; 23 import android.content.pm.UserInfo; 24 import android.content.pm.UserInfo.UserInfoFlag; 25 import android.os.UserManager; 26 27 import com.android.internal.util.Preconditions; 28 29 import java.util.Arrays; 30 import java.util.List; 31 import java.util.stream.Collectors; 32 33 /** 34 * Provides utilities for Android User related tasks. 35 */ 36 public final class UserTestingHelper { 37 38 /** 39 * Creates a simple {@link UserInfo}, containing just the given {@code userId}. 40 */ 41 @NonNull newUser(@serIdInt int userId)42 public static UserInfo newUser(@UserIdInt int userId) { 43 return new UserInfoBuilder(userId).build(); 44 } 45 46 /** 47 * Creates a list of {@link UserInfo UserInfos}, each containing just the given user ids. 48 */ 49 @NonNull newUsers(@serIdInt int... userIds)50 public static List<UserInfo> newUsers(@UserIdInt int... userIds) { 51 return Arrays.stream(userIds) 52 .mapToObj(id -> newUser(id)) 53 .collect(Collectors.toList()); 54 } 55 56 /** 57 * Creates a {@link UserInfo} with the type explicitly set and with the given {@code userId}. 58 */ 59 @NonNull newSecondaryUser(@serIdInt int userId)60 public static UserInfo newSecondaryUser(@UserIdInt int userId) { 61 return new UserInfoBuilder(userId).setType(UserManager.USER_TYPE_FULL_SECONDARY).build(); 62 } 63 64 /** 65 * Creates a new guest with the given {@code userId} and proper flags and types set. 66 */ 67 @NonNull newGuestUser(@serIdInt int userId, boolean ephemeral)68 public static UserInfo newGuestUser(@UserIdInt int userId, boolean ephemeral) { 69 return new UserInfoBuilder(userId).setGuest(true).setEphemeral(ephemeral).build(); 70 } 71 72 /** 73 * Creates a new guest with the given {@code userId} and without any flag.. 74 */ 75 @NonNull newGuestUser(@serIdInt int userId)76 public static UserInfo newGuestUser(@UserIdInt int userId) { 77 return new UserInfoBuilder(userId).setGuest(true).build(); 78 } 79 80 /** 81 * Gets the default {@link UserInfo#userType} for a guest / regular user. 82 */ 83 @NonNull getDefaultUserType(boolean isGuest)84 public static String getDefaultUserType(boolean isGuest) { 85 return isGuest ? UserManager.USER_TYPE_FULL_GUEST : UserManager.USER_TYPE_FULL_SECONDARY; 86 } 87 88 /** 89 * Sets the property that defines the maximum number of uses allowed in the device. 90 */ setMaxSupportedUsers(int max)91 public static void setMaxSupportedUsers(int max) { 92 runShellCommand("setprop fw.max_users %d", max); 93 } 94 95 /** 96 * Configures the user to use PIN credentials. 97 */ setUserLockCredentials(@serIdInt int userId, int pin)98 public static void setUserLockCredentials(@UserIdInt int userId, int pin) { 99 runShellCommand("locksettings set-pin %s --user %d ", pin, userId); 100 } 101 102 /** 103 * Clears the user credentials using current PIN. 104 */ clearUserLockCredentials(@serIdInt int userId, int pin)105 public static void clearUserLockCredentials(@UserIdInt int userId, int pin) { 106 runShellCommand("locksettings clear --old %d --user %d ", pin, userId); 107 } 108 109 /** 110 * Builder for {@link UserInfo} objects. 111 */ 112 public static final class UserInfoBuilder { 113 114 @UserIdInt 115 private final int mUserId; 116 117 @UserInfoFlag 118 private int mFlags; 119 120 @Nullable 121 private String mName; 122 123 @Nullable 124 private String mType; 125 126 private boolean mGuest; 127 private boolean mEphemeral; 128 private boolean mAdmin; 129 private boolean mPreCreated; 130 private boolean mInitialized; 131 132 /** 133 * Default constructor. 134 */ UserInfoBuilder(@serIdInt int userId)135 public UserInfoBuilder(@UserIdInt int userId) { 136 mUserId = userId; 137 } 138 139 /** 140 * Sets the user name. 141 */ 142 @NonNull setName(@ullable String name)143 public UserInfoBuilder setName(@Nullable String name) { 144 mName = name; 145 return this; 146 } 147 148 /** 149 * Sets the user type. 150 */ 151 @NonNull setType(@ullable String type)152 public UserInfoBuilder setType(@Nullable String type) { 153 Preconditions.checkState(!mGuest, "cannot set type (" + mType + ") after setting it as " 154 + "guest"); 155 mType = type; 156 return this; 157 } 158 159 /** 160 * Sets whether the user is a guest. 161 */ 162 @NonNull setGuest(boolean guest)163 public UserInfoBuilder setGuest(boolean guest) { 164 Preconditions.checkState(mType == null, "cannot set guest after setting type (" + mType 165 + ")"); 166 mGuest = guest; 167 return this; 168 } 169 170 /** 171 * Sets the user flags 172 */ 173 @NonNull setFlags(@serInfoFlag int flags)174 public UserInfoBuilder setFlags(@UserInfoFlag int flags) { 175 mFlags = flags; 176 return this; 177 } 178 179 /** 180 * Sets whether the user is ephemeral. 181 */ 182 @NonNull setEphemeral(boolean ephemeral)183 public UserInfoBuilder setEphemeral(boolean ephemeral) { 184 mEphemeral = ephemeral; 185 return this; 186 } 187 188 /** 189 * Sets whether the user is an admin. 190 */ 191 @NonNull setAdmin(boolean admin)192 public UserInfoBuilder setAdmin(boolean admin) { 193 mAdmin = admin; 194 return this; 195 } 196 197 /** 198 * Sets whether the user is an pre-created. 199 */ 200 @NonNull setPreCreated(boolean preCreated)201 public UserInfoBuilder setPreCreated(boolean preCreated) { 202 mPreCreated = preCreated; 203 return this; 204 } 205 206 /** 207 * Sets whether the user is initialized. 208 */ 209 @NonNull setInitialized(boolean initialized)210 public UserInfoBuilder setInitialized(boolean initialized) { 211 mInitialized = initialized; 212 return this; 213 } 214 215 /** 216 * Creates a new {@link UserInfo}. 217 */ 218 @NonNull build()219 public UserInfo build() { 220 int flags = mFlags; 221 if (mEphemeral) { 222 flags |= UserInfo.FLAG_EPHEMERAL; 223 } 224 if (mAdmin) { 225 flags |= UserInfo.FLAG_ADMIN; 226 } 227 if (mInitialized) { 228 flags |= UserInfo.FLAG_INITIALIZED; 229 } 230 if (mGuest) { 231 mType = UserManager.USER_TYPE_FULL_GUEST; 232 } 233 UserInfo info = new UserInfo(mUserId, mName, /* iconPath= */ null, flags, mType); 234 info.preCreated = mPreCreated; 235 return info; 236 } 237 } 238 UserTestingHelper()239 private UserTestingHelper() { 240 throw new UnsupportedOperationException("contains only static methods"); 241 } 242 } 243