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 androidx.credentials.exceptions 18 19 import android.os.Bundle 20 import androidx.annotation.RestrictTo 21 import androidx.credentials.CredentialManager 22 import androidx.credentials.internal.toJetpackGetException 23 24 /** 25 * Represents an error thrown during a get flow with Credential Manager. See [CredentialManager] for 26 * more details on how Exceptions work for Credential Manager flows. 27 * 28 * @see CredentialManager 29 * @see GetCredentialUnknownException 30 * @see GetCredentialCancellationException 31 * @see GetCredentialInterruptedException 32 */ 33 abstract class GetCredentialException 34 @JvmOverloads 35 internal constructor( 36 @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) open val type: String, 37 @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) open val errorMessage: CharSequence? = null 38 ) : Exception(errorMessage?.toString()) { 39 companion object { 40 private const val EXTRA_GET_CREDENTIAL_EXCEPTION_TYPE = 41 "androidx.credentials.provider.extra.CREATE_CREDENTIAL_EXCEPTION_TYPE" 42 private const val EXTRA_GET_CREDENTIAL_EXCEPTION_MESSAGE = 43 "androidx.credentials.provider.extra.CREATE_CREDENTIAL_EXCEPTION_MESSAGE" 44 45 /** 46 * Helper method to convert the given [ex] to a parcelable [Bundle], in case the instance 47 * needs to be sent across a process. Consumers of this method should use [fromBundle] to 48 * reconstruct the class instance back from the bundle returned here. 49 */ 50 @JvmStatic asBundlenull51 fun asBundle(ex: GetCredentialException): Bundle { 52 val bundle = Bundle() 53 bundle.putString(EXTRA_GET_CREDENTIAL_EXCEPTION_TYPE, ex.type) 54 ex.errorMessage?.let { 55 bundle.putCharSequence(EXTRA_GET_CREDENTIAL_EXCEPTION_MESSAGE, it) 56 } 57 return bundle 58 } 59 60 /** 61 * Helper method to convert a [Bundle] retrieved through [asBundle], back to an instance of 62 * [GetCredentialException]. 63 * 64 * Throws [IllegalArgumentException] if the conversion fails. This means that the given 65 * [bundle] does not contain a `GetCredentialException`. The bundle should be constructed 66 * and retrieved from [asBundle] itself and never be created from scratch to avoid the 67 * failure. 68 */ 69 @JvmStatic fromBundlenull70 fun fromBundle(bundle: Bundle): GetCredentialException { 71 val type = 72 bundle.getString(EXTRA_GET_CREDENTIAL_EXCEPTION_TYPE) 73 ?: throw IllegalArgumentException("Bundle was missing exception type.") 74 val msg = bundle.getCharSequence(EXTRA_GET_CREDENTIAL_EXCEPTION_MESSAGE) 75 return toJetpackGetException(type, msg) 76 } 77 } 78 } 79