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 17 package android.car.user; 18 19 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE; 20 21 import android.annotation.IntDef; 22 import android.annotation.Nullable; 23 import android.annotation.TestApi; 24 import android.car.annotation.AddedInOrBefore; 25 import android.os.Parcelable; 26 import android.os.UserManager; 27 28 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport; 29 import com.android.car.internal.util.DataClass; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 34 /** 35 * User switch results. 36 * 37 * @hide 38 */ 39 @DataClass( 40 genToString = true, 41 genHiddenConstructor = true, 42 genHiddenConstDefs = true) 43 @TestApi 44 public final class UserSwitchResult implements Parcelable, OperationResult { 45 46 /** 47 * When user switch is successful for both HAL and Android. 48 */ 49 @AddedInOrBefore(majorVersion = 33) 50 public static final int STATUS_SUCCESSFUL = CommonResults.STATUS_SUCCESSFUL; 51 52 /** 53 * When user switch is only successful for Hal but not for Android. Hal user switch rollover 54 * message have been sent. 55 */ 56 @AddedInOrBefore(majorVersion = 33) 57 public static final int STATUS_ANDROID_FAILURE = CommonResults.STATUS_ANDROID_FAILURE; 58 59 /** 60 * When user switch fails for HAL. User switch for Android is not called. 61 */ 62 @AddedInOrBefore(majorVersion = 33) 63 public static final int STATUS_HAL_FAILURE = CommonResults.STATUS_HAL_FAILURE; 64 65 /** 66 * When user switch fails for HAL for some internal error. User switch for Android is not 67 * called. 68 */ 69 @AddedInOrBefore(majorVersion = 33) 70 public static final int STATUS_HAL_INTERNAL_FAILURE = CommonResults.STATUS_HAL_INTERNAL_FAILURE; 71 72 /** 73 * When given parameters or environment states are invalid for switching user. HAL or Android 74 * user switch is not requested. 75 */ 76 @AddedInOrBefore(majorVersion = 33) 77 public static final int STATUS_INVALID_REQUEST = CommonResults.STATUS_INVALID_REQUEST; 78 79 /** 80 * When user switch fails because of driving safety UX restrictions. 81 */ 82 @AddedInOrBefore(majorVersion = 33) 83 public static final int STATUS_UX_RESTRICTION_FAILURE = 84 CommonResults.STATUS_UX_RESTRICTION_FAILURE; 85 86 /** 87 * When target user is same as current user. 88 */ 89 @AddedInOrBefore(majorVersion = 33) 90 public static final int STATUS_OK_USER_ALREADY_IN_FOREGROUND = 91 CommonResults.LAST_COMMON_STATUS + 1; 92 93 /** 94 * When another user switch request for the same target user is in process. 95 */ 96 @AddedInOrBefore(majorVersion = 33) 97 public static final int STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO = 98 CommonResults.LAST_COMMON_STATUS + 2; 99 100 /** 101 * When another user switch request for a new different target user is received. Previous 102 * request is abandoned. 103 */ 104 @AddedInOrBefore(majorVersion = 33) 105 public static final int STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST = 106 CommonResults.LAST_COMMON_STATUS + 3; 107 108 /** 109 * When switching users is currently not allowed for the user this process is running under. 110 */ 111 @AddedInOrBefore(majorVersion = 33) 112 public static final int STATUS_NOT_SWITCHABLE = 113 CommonResults.LAST_COMMON_STATUS + 4; 114 115 /** 116 * When logout was called but the current user was not switched by a device admin. 117 */ 118 @AddedInOrBefore(majorVersion = 33) 119 public static final int STATUS_NOT_LOGGED_IN = 120 CommonResults.LAST_COMMON_STATUS + 5; 121 122 /** 123 * Gets the user switch result status. 124 * 125 * @return either {@link UserSwitchResult#STATUS_SUCCESSFUL}, 126 * {@link UserSwitchResult#STATUS_ANDROID_FAILURE}, 127 * {@link UserSwitchResult#STATUS_HAL_FAILURE}, 128 * {@link UserSwitchResult#STATUS_HAL_INTERNAL_FAILURE}, 129 * {@link UserSwitchResult#STATUS_INVALID_REQUEST}, 130 * {@link UserSwitchResult#STATUS_UX_RESTRICTION_FAILURE}, 131 * {@link UserSwitchResult#STATUS_OK_USER_ALREADY_IN_FOREGROUND}, 132 * {@link UserSwitchResult#STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO}, 133 * {@link UserSwitchResult#STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST}, 134 * {@link UserSwitchResult#STATUS_NOT_SWITCHABLE}, or 135 * {@link UserSwitchResult#STATUS_NOT_LOGGED_IN}. 136 */ 137 private final @Status int mStatus; 138 139 // TODO(b/214443810): codegen generates call to writeInteger() / readInteger(), we need to 140 // manually change to writeInt() / readInt() 141 /** 142 * Gets the failure status returned by {@link UserManager} when the {@link #getStatus() status} 143 * is {@link #STATUS_ANDROID_FAILURE}. 144 * 145 * @return {@code USER_OPERATION_ERROR_} constants defined by {@link UserManager}, or 146 * {@code null} when the {@link #getStatus() status} is not {@link #STATUS_ANDROID_FAILURE}. 147 * 148 * @hide 149 */ 150 @Nullable 151 private final Integer mAndroidFailureStatus; 152 153 /** 154 * Gets the error message, if any. 155 */ 156 @Nullable 157 private final String mErrorMessage; 158 159 @Override 160 @AddedInOrBefore(majorVersion = 33) isSuccess()161 public boolean isSuccess() { 162 return mStatus == STATUS_SUCCESSFUL || mStatus == STATUS_OK_USER_ALREADY_IN_FOREGROUND; 163 } 164 165 /** @hide */ UserSwitchResult(@tatus int status, @Nullable String errorMessage)166 public UserSwitchResult(@Status int status, @Nullable String errorMessage) { 167 this(status, /* androidFailureStatus= */ null, errorMessage); 168 } 169 170 // NOTE: codegen generates this method, but without @ExcludeFromCodeCoverageGeneratedReport 171 @Override 172 @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE) 173 @AddedInOrBefore(majorVersion = 33) describeContents()174 public int describeContents() { 175 return 0; 176 } 177 178 179 180 // Code below generated by codegen v1.0.23. 181 // 182 // DO NOT MODIFY! 183 // CHECKSTYLE:OFF Generated code 184 // 185 // To regenerate run: 186 // $ codegen $ANDROID_BUILD_TOP/packages/services/Car/car-lib/src/android/car/user/UserSwitchResult.java 187 // 188 // To exclude the generated code from IntelliJ auto-formatting enable (one-time): 189 // Settings > Editor > Code Style > Formatter Control 190 //@formatter:off 191 192 193 /** @hide */ 194 @IntDef(prefix = "STATUS_", value = { 195 STATUS_SUCCESSFUL, 196 STATUS_ANDROID_FAILURE, 197 STATUS_HAL_FAILURE, 198 STATUS_HAL_INTERNAL_FAILURE, 199 STATUS_INVALID_REQUEST, 200 STATUS_UX_RESTRICTION_FAILURE, 201 STATUS_OK_USER_ALREADY_IN_FOREGROUND, 202 STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO, 203 STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST, 204 STATUS_NOT_SWITCHABLE, 205 STATUS_NOT_LOGGED_IN 206 }) 207 @Retention(RetentionPolicy.SOURCE) 208 @DataClass.Generated.Member 209 public @interface Status {} 210 211 /** @hide */ 212 @DataClass.Generated.Member 213 @AddedInOrBefore(majorVersion = 33) statusToString(@tatus int value)214 public static String statusToString(@Status int value) { 215 switch (value) { 216 case STATUS_SUCCESSFUL: 217 return "STATUS_SUCCESSFUL"; 218 case STATUS_ANDROID_FAILURE: 219 return "STATUS_ANDROID_FAILURE"; 220 case STATUS_HAL_FAILURE: 221 return "STATUS_HAL_FAILURE"; 222 case STATUS_HAL_INTERNAL_FAILURE: 223 return "STATUS_HAL_INTERNAL_FAILURE"; 224 case STATUS_INVALID_REQUEST: 225 return "STATUS_INVALID_REQUEST"; 226 case STATUS_UX_RESTRICTION_FAILURE: 227 return "STATUS_UX_RESTRICTION_FAILURE"; 228 case STATUS_OK_USER_ALREADY_IN_FOREGROUND: 229 return "STATUS_OK_USER_ALREADY_IN_FOREGROUND"; 230 case STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO: 231 return "STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO"; 232 case STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST: 233 return "STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST"; 234 case STATUS_NOT_SWITCHABLE: 235 return "STATUS_NOT_SWITCHABLE"; 236 case STATUS_NOT_LOGGED_IN: 237 return "STATUS_NOT_LOGGED_IN"; 238 default: return Integer.toHexString(value); 239 } 240 } 241 242 /** 243 * Creates a new UserSwitchResult. 244 * 245 * @param status 246 * Gets the user switch result status. 247 * 248 * @return either {@link UserSwitchResult#STATUS_SUCCESSFUL}, 249 * {@link UserSwitchResult#STATUS_ANDROID_FAILURE}, 250 * {@link UserSwitchResult#STATUS_HAL_FAILURE}, 251 * {@link UserSwitchResult#STATUS_HAL_INTERNAL_FAILURE}, 252 * {@link UserSwitchResult#STATUS_INVALID_REQUEST}, 253 * {@link UserSwitchResult#STATUS_UX_RESTRICTION_FAILURE}, 254 * {@link UserSwitchResult#STATUS_OK_USER_ALREADY_IN_FOREGROUND}, 255 * {@link UserSwitchResult#STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO}, 256 * {@link UserSwitchResult#STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST}, 257 * {@link UserSwitchResult#STATUS_NOT_SWITCHABLE}, or 258 * {@link UserSwitchResult#STATUS_NOT_LOGGED_IN}. 259 * @param androidFailureStatus 260 * Gets the failure status returned by {@link UserManager} when the {@link #getStatus() status} 261 * is {@link #STATUS_ANDROID_FAILURE}. 262 * 263 * @return {@code USER_OPERATION_ERROR_} constants defined by {@link UserManager}, or 264 * {@code null} when the {@link #getStatus() status} is not {@link #STATUS_ANDROID_FAILURE}. 265 * @param errorMessage 266 * Gets the error message, if any. 267 * @hide 268 */ 269 @DataClass.Generated.Member UserSwitchResult( @tatus int status, @Nullable Integer androidFailureStatus, @Nullable String errorMessage)270 public UserSwitchResult( 271 @Status int status, 272 @Nullable Integer androidFailureStatus, 273 @Nullable String errorMessage) { 274 this.mStatus = status; 275 276 if (!(mStatus == STATUS_SUCCESSFUL) 277 && !(mStatus == STATUS_ANDROID_FAILURE) 278 && !(mStatus == STATUS_HAL_FAILURE) 279 && !(mStatus == STATUS_HAL_INTERNAL_FAILURE) 280 && !(mStatus == STATUS_INVALID_REQUEST) 281 && !(mStatus == STATUS_UX_RESTRICTION_FAILURE) 282 && !(mStatus == STATUS_OK_USER_ALREADY_IN_FOREGROUND) 283 && !(mStatus == STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO) 284 && !(mStatus == STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST) 285 && !(mStatus == STATUS_NOT_SWITCHABLE) 286 && !(mStatus == STATUS_NOT_LOGGED_IN)) { 287 throw new java.lang.IllegalArgumentException( 288 "status was " + mStatus + " but must be one of: " 289 + "STATUS_SUCCESSFUL(" + STATUS_SUCCESSFUL + "), " 290 + "STATUS_ANDROID_FAILURE(" + STATUS_ANDROID_FAILURE + "), " 291 + "STATUS_HAL_FAILURE(" + STATUS_HAL_FAILURE + "), " 292 + "STATUS_HAL_INTERNAL_FAILURE(" + STATUS_HAL_INTERNAL_FAILURE + "), " 293 + "STATUS_INVALID_REQUEST(" + STATUS_INVALID_REQUEST + "), " 294 + "STATUS_UX_RESTRICTION_FAILURE(" + STATUS_UX_RESTRICTION_FAILURE + "), " 295 + "STATUS_OK_USER_ALREADY_IN_FOREGROUND(" + STATUS_OK_USER_ALREADY_IN_FOREGROUND + "), " 296 + "STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO(" + STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO + "), " 297 + "STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST(" + STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST + "), " 298 + "STATUS_NOT_SWITCHABLE(" + STATUS_NOT_SWITCHABLE + "), " 299 + "STATUS_NOT_LOGGED_IN(" + STATUS_NOT_LOGGED_IN + ")"); 300 } 301 302 this.mAndroidFailureStatus = androidFailureStatus; 303 this.mErrorMessage = errorMessage; 304 305 // onConstructed(); // You can define this method to get a callback 306 } 307 308 /** 309 * Gets the user switch result status. 310 * 311 * @return either {@link UserSwitchResult#STATUS_SUCCESSFUL}, 312 * {@link UserSwitchResult#STATUS_ANDROID_FAILURE}, 313 * {@link UserSwitchResult#STATUS_HAL_FAILURE}, 314 * {@link UserSwitchResult#STATUS_HAL_INTERNAL_FAILURE}, 315 * {@link UserSwitchResult#STATUS_INVALID_REQUEST}, 316 * {@link UserSwitchResult#STATUS_UX_RESTRICTION_FAILURE}, 317 * {@link UserSwitchResult#STATUS_OK_USER_ALREADY_IN_FOREGROUND}, 318 * {@link UserSwitchResult#STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO}, 319 * {@link UserSwitchResult#STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST}, 320 * {@link UserSwitchResult#STATUS_NOT_SWITCHABLE}, or 321 * {@link UserSwitchResult#STATUS_NOT_LOGGED_IN}. 322 */ 323 @DataClass.Generated.Member 324 @AddedInOrBefore(majorVersion = 33) getStatus()325 public @Status int getStatus() { 326 return mStatus; 327 } 328 329 /** 330 * Gets the failure status returned by {@link UserManager} when the {@link #getStatus() status} 331 * is {@link #STATUS_ANDROID_FAILURE}. 332 * 333 * @return {@code USER_OPERATION_ERROR_} constants defined by {@link UserManager}, or 334 * {@code null} when the {@link #getStatus() status} is not {@link #STATUS_ANDROID_FAILURE}. 335 * @hide 336 */ 337 @DataClass.Generated.Member 338 @AddedInOrBefore(majorVersion = 33) getAndroidFailureStatus()339 public @Nullable Integer getAndroidFailureStatus() { 340 return mAndroidFailureStatus; 341 } 342 343 /** 344 * Gets the error message, if any. 345 */ 346 @DataClass.Generated.Member 347 @AddedInOrBefore(majorVersion = 33) getErrorMessage()348 public @Nullable String getErrorMessage() { 349 return mErrorMessage; 350 } 351 352 @Override 353 @DataClass.Generated.Member 354 @AddedInOrBefore(majorVersion = 33) toString()355 public String toString() { 356 // You can override field toString logic by defining methods like: 357 // String fieldNameToString() { ... } 358 359 return "UserSwitchResult { " + 360 "status = " + statusToString(mStatus) + ", " + 361 "androidFailureStatus = " + mAndroidFailureStatus + ", " + 362 "errorMessage = " + mErrorMessage + 363 " }"; 364 } 365 366 @Override 367 @DataClass.Generated.Member 368 @AddedInOrBefore(majorVersion = 33) writeToParcel(@ndroid.annotation.NonNull android.os.Parcel dest, int flags)369 public void writeToParcel(@android.annotation.NonNull android.os.Parcel dest, int flags) { 370 // You can override field parcelling by defining methods like: 371 // void parcelFieldName(Parcel dest, int flags) { ... } 372 373 byte flg = 0; 374 if (mAndroidFailureStatus != null) flg |= 0x2; 375 if (mErrorMessage != null) flg |= 0x4; 376 dest.writeByte(flg); 377 dest.writeInt(mStatus); 378 if (mAndroidFailureStatus != null) dest.writeInt(mAndroidFailureStatus); 379 if (mErrorMessage != null) dest.writeString(mErrorMessage); 380 } 381 382 /** @hide */ 383 @SuppressWarnings({"unchecked", "RedundantCast"}) 384 @DataClass.Generated.Member UserSwitchResult(@ndroid.annotation.NonNull android.os.Parcel in)385 /* package-private */ UserSwitchResult(@android.annotation.NonNull android.os.Parcel in) { 386 // You can override field unparcelling by defining methods like: 387 // static FieldType unparcelFieldName(Parcel in) { ... } 388 389 byte flg = in.readByte(); 390 int status = in.readInt(); 391 Integer androidFailureStatus = (flg & 0x2) == 0 ? null : (Integer) in.readInt(); 392 String errorMessage = (flg & 0x4) == 0 ? null : in.readString(); 393 394 this.mStatus = status; 395 396 if (!(mStatus == STATUS_SUCCESSFUL) 397 && !(mStatus == STATUS_ANDROID_FAILURE) 398 && !(mStatus == STATUS_HAL_FAILURE) 399 && !(mStatus == STATUS_HAL_INTERNAL_FAILURE) 400 && !(mStatus == STATUS_INVALID_REQUEST) 401 && !(mStatus == STATUS_UX_RESTRICTION_FAILURE) 402 && !(mStatus == STATUS_OK_USER_ALREADY_IN_FOREGROUND) 403 && !(mStatus == STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO) 404 && !(mStatus == STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST) 405 && !(mStatus == STATUS_NOT_SWITCHABLE) 406 && !(mStatus == STATUS_NOT_LOGGED_IN)) { 407 throw new java.lang.IllegalArgumentException( 408 "status was " + mStatus + " but must be one of: " 409 + "STATUS_SUCCESSFUL(" + STATUS_SUCCESSFUL + "), " 410 + "STATUS_ANDROID_FAILURE(" + STATUS_ANDROID_FAILURE + "), " 411 + "STATUS_HAL_FAILURE(" + STATUS_HAL_FAILURE + "), " 412 + "STATUS_HAL_INTERNAL_FAILURE(" + STATUS_HAL_INTERNAL_FAILURE + "), " 413 + "STATUS_INVALID_REQUEST(" + STATUS_INVALID_REQUEST + "), " 414 + "STATUS_UX_RESTRICTION_FAILURE(" + STATUS_UX_RESTRICTION_FAILURE + "), " 415 + "STATUS_OK_USER_ALREADY_IN_FOREGROUND(" + STATUS_OK_USER_ALREADY_IN_FOREGROUND + "), " 416 + "STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO(" + STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO + "), " 417 + "STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST(" + STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST + "), " 418 + "STATUS_NOT_SWITCHABLE(" + STATUS_NOT_SWITCHABLE + "), " 419 + "STATUS_NOT_LOGGED_IN(" + STATUS_NOT_LOGGED_IN + ")"); 420 } 421 422 this.mAndroidFailureStatus = androidFailureStatus; 423 this.mErrorMessage = errorMessage; 424 425 // onConstructed(); // You can define this method to get a callback 426 } 427 428 @DataClass.Generated.Member 429 @AddedInOrBefore(majorVersion = 33) 430 public static final @android.annotation.NonNull Parcelable.Creator<UserSwitchResult> CREATOR 431 = new Parcelable.Creator<UserSwitchResult>() { 432 @Override 433 public UserSwitchResult[] newArray(int size) { 434 return new UserSwitchResult[size]; 435 } 436 437 @Override 438 public UserSwitchResult createFromParcel(@android.annotation.NonNull android.os.Parcel in) { 439 return new UserSwitchResult(in); 440 } 441 }; 442 443 @DataClass.Generated( 444 time = 1643074560926L, 445 codegenVersion = "1.0.23", 446 sourceFile = "packages/services/Car/car-lib/src/android/car/user/UserSwitchResult.java", 447 inputSignatures = "public static final int STATUS_SUCCESSFUL\npublic static final int STATUS_ANDROID_FAILURE\npublic static final int STATUS_HAL_FAILURE\npublic static final int STATUS_HAL_INTERNAL_FAILURE\npublic static final int STATUS_INVALID_REQUEST\npublic static final int STATUS_UX_RESTRICTION_FAILURE\npublic static final int STATUS_OK_USER_ALREADY_IN_FOREGROUND\npublic static final int STATUS_TARGET_USER_ALREADY_BEING_SWITCHED_TO\npublic static final int STATUS_TARGET_USER_ABANDONED_DUE_TO_A_NEW_REQUEST\npublic static final int STATUS_NOT_SWITCHABLE\npublic static final int STATUS_NOT_LOGGED_IN\nprivate final @android.car.user.UserSwitchResult.Status int mStatus\nprivate final @android.annotation.Nullable java.lang.Integer mAndroidFailureStatus\nprivate final @android.annotation.Nullable java.lang.String mErrorMessage\npublic @java.lang.Override boolean isSuccess()\npublic @java.lang.Override @com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport int describeContents()\nclass UserSwitchResult extends java.lang.Object implements [android.os.Parcelable, android.car.user.OperationResult]\n@com.android.car.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)") 448 @Deprecated __metadata()449 private void __metadata() {} 450 451 452 //@formatter:on 453 // End of generated code 454 455 } 456