Merge "Activity canceled due to settings launch should trigger a different code."
diff --git a/core/java/android/credentials/ui/BaseDialogResult.java b/core/java/android/credentials/ui/BaseDialogResult.java
index cf5f036..5223314 100644
--- a/core/java/android/credentials/ui/BaseDialogResult.java
+++ b/core/java/android/credentials/ui/BaseDialogResult.java
@@ -16,6 +16,7 @@
 
 package android.credentials.ui;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Bundle;
@@ -25,6 +26,9 @@
 
 import com.android.internal.util.AnnotationValidations;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Base dialog result data.
  *
@@ -55,29 +59,27 @@
     private static final String EXTRA_BASE_RESULT =
             "android.credentials.ui.extra.BASE_RESULT";
 
+    /** @hide **/
+    @IntDef(prefix = {"RESULT_CODE_"}, value = {
+            RESULT_CODE_DIALOG_USER_CANCELED,
+            RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS,
+            RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ResultCode {}
+
     /** User intentionally canceled the dialog. */
-    public static final int RESULT_CODE_DIALOG_CANCELED = 0;
-    /**
-     * User made a selection and the dialog finished. The user selection result is in the
-     * {@code resultData}.
-     */
-    public static final int RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION = 1;
-    /**
-     * The user has acknowledged the consent page rendered for when they first used Credential
-     * Manager on this device.
-     */
-    public static final int RESULT_CODE_CREDENTIAL_MANAGER_CONSENT_ACKNOWLEDGED = 2;
-    /**
-     * The user has acknowledged the consent page rendered for enabling a new provider.
-     * This should only happen during the first time use. The provider info is in the
-     * {@code resultData}.
-     */
-    public static final int RESULT_CODE_PROVIDER_ENABLED = 3;
+    public static final int RESULT_CODE_DIALOG_USER_CANCELED = 0;
     /**
      * The user has consented to switching to a new default provider. The provider info is in the
      * {@code resultData}.
      */
-    public static final int RESULT_CODE_DEFAULT_PROVIDER_CHANGED = 4;
+    public static final int RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS = 1;
+    /**
+     * User made a selection and the dialog finished. The user selection result is in the
+     * {@code resultData}.
+     */
+    public static final int RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION = 2;
 
     @NonNull
     private final IBinder mRequestToken;
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index a1392ba..0761b64 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -99,10 +99,20 @@
     )
   }
 
-  fun onCancel() {
+  // The dialog is canceled by the user.
+  fun onUserCancel() {
+    onCancel(BaseDialogResult.RESULT_CODE_DIALOG_USER_CANCELED)
+  }
+
+  // The dialog is canceled because we launched into settings.
+  fun onSettingLaunchCancel() {
+    onCancel(BaseDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION)
+  }
+
+  private fun onCancel(cancelCode: Int) {
     val resultData = Bundle()
     BaseDialogResult.addToBundle(BaseDialogResult(requestInfo.token), resultData)
-    resultReceiver?.send(BaseDialogResult.RESULT_CODE_DIALOG_CANCELED, resultData)
+    resultReceiver?.send(cancelCode, resultData)
   }
 
   fun onOptionSelected(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
index 7a04a8e..a9b1d332 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
@@ -147,12 +147,12 @@
   }
 
   fun onDisabledProvidersSelected() {
-    credManRepo.onCancel()
+    credManRepo.onSettingLaunchCancel()
     dialogResult.tryEmit(DialogResult(ResultState.LAUNCH_SETTING_CANCELED))
   }
 
   fun onCancel() {
-    credManRepo.onCancel()
+    credManRepo.onUserCancel()
     dialogResult.tryEmit(DialogResult(ResultState.NORMAL_CANCELED))
   }
 
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
index 9859c89..c72ae72 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
@@ -152,7 +152,7 @@
   }
 
   fun onCancel() {
-    credManRepo.onCancel()
+    credManRepo.onUserCancel()
     dialogResult.tryEmit(DialogResult(ResultState.NORMAL_CANCELED))
   }
 }
diff --git a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
index 668f8ed6..351afb9 100644
--- a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
@@ -107,9 +107,14 @@
     }
 
     @Override
-    public void onUiCancellation() {
-        respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_USER_CANCELED,
-                "User cancelled the selector");
+    public void onUiCancellation(boolean isUserCancellation) {
+        if (isUserCancellation) {
+            respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_USER_CANCELED,
+                    "User cancelled the selector");
+        } else {
+            respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_INTERRUPTED,
+                    "The UI was interrupted - please try again.");
+        }
     }
 
     private void respondToClientWithResponseAndFinish(CreateCredentialResponse response) {
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
index a380636..797601a 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
@@ -64,8 +64,11 @@
             } else {
                 Slog.i(TAG, "No selection found in UI result");
             }
-        } else if (resultCode == UserSelectionDialogResult.RESULT_CODE_DIALOG_CANCELED) {
-            mCallbacks.onUiCancellation();
+        } else if (resultCode == UserSelectionDialogResult.RESULT_CODE_DIALOG_USER_CANCELED) {
+            mCallbacks.onUiCancellation(/* isUserCancellation= */ true);
+        } else if (resultCode
+                == UserSelectionDialogResult.RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS) {
+            mCallbacks.onUiCancellation(/* isUserCancellation= */ false);
         }
     }
 
@@ -75,8 +78,8 @@
     public interface CredentialManagerUiCallback {
         /** Called when the user makes a selection. */
         void onUiSelection(UserSelectionDialogResult selection);
-        /** Called when the user cancels the UI. */
-        void onUiCancellation();
+        /** Called when the UI is canceled without a successful provider result. */
+        void onUiCancellation(boolean isUserCancellation);
     }
     public CredentialManagerUi(Context context, int userId,
             CredentialManagerUiCallback callbacks) {
diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
index f7c5905..e3a27ec 100644
--- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
@@ -124,9 +124,14 @@
     }
 
     @Override
-    public void onUiCancellation() {
-        respondToClientWithErrorAndFinish(GetCredentialException.TYPE_USER_CANCELED,
-                "User cancelled the selector");
+    public void onUiCancellation(boolean isUserCancellation) {
+        if (isUserCancellation) {
+            respondToClientWithErrorAndFinish(GetCredentialException.TYPE_USER_CANCELED,
+                    "User cancelled the selector");
+        } else {
+            respondToClientWithErrorAndFinish(GetCredentialException.TYPE_INTERRUPTED,
+                    "The UI was interrupted - please try again.");
+        }
     }
 
     @Override
diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java
index 8e44f0f..f92ffe2 100644
--- a/services/credentials/java/com/android/server/credentials/RequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/RequestSession.java
@@ -125,8 +125,8 @@
     }
 
     @Override // from CredentialManagerUiCallbacks
-    public void onUiCancellation() {
-        Log.i(TAG, "Ui canceled");
+    public void onUiCancellation(boolean isUserCancellation) {
+        Log.i(TAG, "Ui canceled. Canceled by user: " + isUserCancellation);
         // User canceled the activity
         finishSession();
     }