• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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.credentials.selection;
18 
19 import static android.credentials.flags.Flags.FLAG_CONFIGURABLE_SELECTOR_UI_ENABLED;
20 
21 import android.annotation.FlaggedApi;
22 import android.annotation.IntDef;
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.annotation.SystemApi;
26 import android.content.Intent;
27 import android.os.Bundle;
28 import android.os.ResultReceiver;
29 
30 import java.lang.annotation.Retention;
31 import java.lang.annotation.RetentionPolicy;
32 
33 /**
34  * Failure or cancellation result encountered during a UI flow.
35  *
36  * @hide
37  */
38 @SystemApi
39 @FlaggedApi(FLAG_CONFIGURABLE_SELECTOR_UI_ENABLED)
40 public final class FailureResult {
41 
42     /**
43      * Sends the {@code failureResult} that caused the UI to stop back to the CredentialManager
44      * service.
45      *
46      * @param resultReceiver the ResultReceiver sent from the system service, that can be extracted
47      *                      from the launch intent via
48      *                      {@link IntentHelper#extractResultReceiver(Intent)}
49      */
sendFailureResult(@onNull ResultReceiver resultReceiver, @NonNull FailureResult failureResult)50     public static void sendFailureResult(@NonNull ResultReceiver resultReceiver,
51             @NonNull FailureResult failureResult) {
52         FailureDialogResult result = failureResult.toFailureDialogResult();
53         Bundle resultData = new Bundle();
54         FailureDialogResult.addToBundle(result, resultData);
55         resultReceiver.send(failureResult.errorCodeToResultCode(),
56                 resultData);
57     }
58 
59     @Nullable
60     private final String mErrorMessage;
61     @NonNull
62     private final int mErrorCode;
63 
64     /** @hide **/
65     @IntDef(prefix = {"ERROR_CODE_"}, value = {
66             ERROR_CODE_DIALOG_CANCELED_BY_USER,
67             ERROR_CODE_CANCELED_AND_LAUNCHED_SETTINGS,
68             ERROR_CODE_UI_FAILURE,
69     })
70     @Retention(RetentionPolicy.SOURCE)
71     public @interface ErrorCode {
72     }
73 
74     /**
75      * The UI was stopped due to a failure, e.g. because it failed to parse the incoming data,
76      * or it encountered an irrecoverable internal issue.
77      *
78      * This code also serves as a default value to use for failures that do not fall into any other
79      * error code category or for backward compatibility.
80      */
81     public static final int ERROR_CODE_UI_FAILURE = 0;
82     /** The user intentionally canceled the dialog. */
83     public static final int ERROR_CODE_DIALOG_CANCELED_BY_USER = 1;
84     /**
85      * The UI was stopped since the user has chosen to navigate to the Settings UI to reconfigure
86      * their providers.
87      */
88     public static final int ERROR_CODE_CANCELED_AND_LAUNCHED_SETTINGS = 2;
89 
90     /**
91      * Constructs a {@link FailureResult}.
92      *
93      * @throws IllegalArgumentException if {@code providerId} is empty
94      */
FailureResult(@rrorCode int errorCode, @Nullable String errorMessage)95     public FailureResult(@ErrorCode int errorCode, @Nullable String errorMessage) {
96         mErrorCode = errorCode;
97         mErrorMessage = errorMessage;
98     }
99 
100     /** Returns the error code. */
101     @ErrorCode
getErrorCode()102     public int getErrorCode() {
103         return mErrorCode;
104     }
105 
106     /** Returns the error message. */
107     @Nullable
getErrorMessage()108     public String getErrorMessage() {
109         return mErrorMessage;
110     }
111 
toFailureDialogResult()112     FailureDialogResult toFailureDialogResult() {
113         return new FailureDialogResult(/*requestToken=*/null, mErrorMessage);
114     }
115 
errorCodeToResultCode()116     int errorCodeToResultCode() {
117         switch (mErrorCode) {
118             case ERROR_CODE_DIALOG_CANCELED_BY_USER:
119                 return BaseDialogResult.RESULT_CODE_DIALOG_USER_CANCELED;
120             case ERROR_CODE_CANCELED_AND_LAUNCHED_SETTINGS:
121                 return BaseDialogResult.RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS;
122             default:
123                 return BaseDialogResult.RESULT_CODE_DATA_PARSING_FAILURE;
124         }
125     }
126 }
127