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