Loading core/java/android/credentials/ui/CancelUiRequest.java 0 → 100644 +79 −0 Original line number Diff line number Diff line /* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.credentials.ui; import android.annotation.NonNull; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import com.android.internal.util.AnnotationValidations; /** * A request to cancel any ongoing UI matching this request. * * @hide */ public final class CancelUiRequest implements Parcelable { /** * The intent extra key for the {@code CancelUiRequest} object when launching the UX * activities. */ @NonNull public static final String EXTRA_CANCEL_UI_REQUEST = "android.credentials.ui.extra.EXTRA_CANCEL_UI_REQUEST"; @NonNull private final IBinder mToken; /** Returns the request token matching the user request that should be cancelled. */ @NonNull public IBinder getToken() { return mToken; } public CancelUiRequest(@NonNull IBinder token) { mToken = token; } private CancelUiRequest(@NonNull Parcel in) { mToken = in.readStrongBinder(); AnnotationValidations.validate(NonNull.class, null, mToken); } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeStrongBinder(mToken); } @Override public int describeContents() { return 0; } @NonNull public static final Creator<CancelUiRequest> CREATOR = new Creator<>() { @Override public CancelUiRequest createFromParcel(@NonNull Parcel in) { return new CancelUiRequest(in); } @Override public CancelUiRequest[] newArray(int size) { return new CancelUiRequest[size]; } }; } core/java/android/credentials/ui/IntentFactory.java +20 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.annotation.TestApi; import android.content.ComponentName; import android.content.Intent; import android.content.res.Resources; import android.os.IBinder; import android.os.Parcel; import android.os.ResultReceiver; Loading Loading @@ -65,6 +66,25 @@ public class IntentFactory { return intent; } /** * Creates an Intent that cancels any UI matching the given request token id. * * @hide */ @NonNull public static Intent createCancelUiIntent(@NonNull IBinder requestToken) { Intent intent = new Intent(); ComponentName componentName = ComponentName.unflattenFromString( Resources.getSystem() .getString( com.android.internal.R.string .config_credentialManagerDialogComponent)); intent.setComponent(componentName); intent.putExtra(CancelUiRequest.EXTRA_CANCEL_UI_REQUEST, new CancelUiRequest(requestToken)); return intent; } /** * Notify the UI that providers have been enabled/disabled. * Loading packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +9 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL import android.credentials.CredentialOption import android.credentials.GetCredentialRequest import android.credentials.ui.AuthenticationEntry import android.credentials.ui.CancelUiRequest import android.credentials.ui.Constants import android.credentials.ui.Entry import android.credentials.ui.CreateCredentialProviderData Loading Loading @@ -223,6 +224,14 @@ class CredentialManagerRepo( resultReceiver.send(cancelCode, resultData) } } /** Return the request token whose UI should be cancelled, or null otherwise. */ fun getCancelUiRequestToken(intent: Intent): IBinder? { return intent.extras?.getParcelable( CancelUiRequest.EXTRA_CANCEL_UI_REQUEST, CancelUiRequest::class.java )?.token } } // TODO: below are prototype functionalities. To be removed for productionization. Loading packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt +18 −3 Original line number Diff line number Diff line Loading @@ -47,6 +47,12 @@ class CredentialSelectorActivity : ComponentActivity() { super.onCreate(savedInstanceState) Log.d(Constants.LOG_TAG, "Creating new CredentialSelectorActivity") try { if (CredentialManagerRepo.getCancelUiRequestToken(intent) != null) { Log.d( Constants.LOG_TAG, "Received UI cancellation intent; cancelling the activity.") this.finish() return } val userConfigRepo = UserConfigRepo(this) val credManRepo = CredentialManagerRepo(this, intent, userConfigRepo) setContent { Loading @@ -67,10 +73,19 @@ class CredentialSelectorActivity : ComponentActivity() { setIntent(intent) Log.d(Constants.LOG_TAG, "Existing activity received new intent") try { val cancelUiRequestToken = CredentialManagerRepo.getCancelUiRequestToken(intent) val viewModel: CredentialSelectorViewModel by viewModels() if (cancelUiRequestToken != null && viewModel.shouldCancelCurrentUi(cancelUiRequestToken)) { Log.d( Constants.LOG_TAG, "Received UI cancellation intent; cancelling the activity.") this.finish() return } else { val userConfigRepo = UserConfigRepo(this) val credManRepo = CredentialManagerRepo(this, intent, userConfigRepo) val viewModel: CredentialSelectorViewModel by viewModels() viewModel.onNewCredentialManagerRepo(credManRepo) } } catch (e: Exception) { onInitializationError(e, intent) } Loading packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.credentialmanager import android.app.Activity import android.os.IBinder import android.util.Log import androidx.activity.compose.ManagedActivityResultLauncher import androidx.activity.result.ActivityResult Loading Loading @@ -135,6 +136,11 @@ class CredentialSelectorViewModel( uiState = uiState.copy(dialogState = DialogState.COMPLETE) } /** Return true if the current UI's request token matches the UI cancellation request token. */ fun shouldCancelCurrentUi(cancelRequestToken: IBinder): Boolean { return credManRepo.requestInfo.token.equals(cancelRequestToken) } /**************************************************************************/ /***** Get Flow Callbacks *****/ /**************************************************************************/ Loading Loading
core/java/android/credentials/ui/CancelUiRequest.java 0 → 100644 +79 −0 Original line number Diff line number Diff line /* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.credentials.ui; import android.annotation.NonNull; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import com.android.internal.util.AnnotationValidations; /** * A request to cancel any ongoing UI matching this request. * * @hide */ public final class CancelUiRequest implements Parcelable { /** * The intent extra key for the {@code CancelUiRequest} object when launching the UX * activities. */ @NonNull public static final String EXTRA_CANCEL_UI_REQUEST = "android.credentials.ui.extra.EXTRA_CANCEL_UI_REQUEST"; @NonNull private final IBinder mToken; /** Returns the request token matching the user request that should be cancelled. */ @NonNull public IBinder getToken() { return mToken; } public CancelUiRequest(@NonNull IBinder token) { mToken = token; } private CancelUiRequest(@NonNull Parcel in) { mToken = in.readStrongBinder(); AnnotationValidations.validate(NonNull.class, null, mToken); } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeStrongBinder(mToken); } @Override public int describeContents() { return 0; } @NonNull public static final Creator<CancelUiRequest> CREATOR = new Creator<>() { @Override public CancelUiRequest createFromParcel(@NonNull Parcel in) { return new CancelUiRequest(in); } @Override public CancelUiRequest[] newArray(int size) { return new CancelUiRequest[size]; } }; }
core/java/android/credentials/ui/IntentFactory.java +20 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.annotation.TestApi; import android.content.ComponentName; import android.content.Intent; import android.content.res.Resources; import android.os.IBinder; import android.os.Parcel; import android.os.ResultReceiver; Loading Loading @@ -65,6 +66,25 @@ public class IntentFactory { return intent; } /** * Creates an Intent that cancels any UI matching the given request token id. * * @hide */ @NonNull public static Intent createCancelUiIntent(@NonNull IBinder requestToken) { Intent intent = new Intent(); ComponentName componentName = ComponentName.unflattenFromString( Resources.getSystem() .getString( com.android.internal.R.string .config_credentialManagerDialogComponent)); intent.setComponent(componentName); intent.putExtra(CancelUiRequest.EXTRA_CANCEL_UI_REQUEST, new CancelUiRequest(requestToken)); return intent; } /** * Notify the UI that providers have been enabled/disabled. * Loading
packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +9 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL import android.credentials.CredentialOption import android.credentials.GetCredentialRequest import android.credentials.ui.AuthenticationEntry import android.credentials.ui.CancelUiRequest import android.credentials.ui.Constants import android.credentials.ui.Entry import android.credentials.ui.CreateCredentialProviderData Loading Loading @@ -223,6 +224,14 @@ class CredentialManagerRepo( resultReceiver.send(cancelCode, resultData) } } /** Return the request token whose UI should be cancelled, or null otherwise. */ fun getCancelUiRequestToken(intent: Intent): IBinder? { return intent.extras?.getParcelable( CancelUiRequest.EXTRA_CANCEL_UI_REQUEST, CancelUiRequest::class.java )?.token } } // TODO: below are prototype functionalities. To be removed for productionization. Loading
packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt +18 −3 Original line number Diff line number Diff line Loading @@ -47,6 +47,12 @@ class CredentialSelectorActivity : ComponentActivity() { super.onCreate(savedInstanceState) Log.d(Constants.LOG_TAG, "Creating new CredentialSelectorActivity") try { if (CredentialManagerRepo.getCancelUiRequestToken(intent) != null) { Log.d( Constants.LOG_TAG, "Received UI cancellation intent; cancelling the activity.") this.finish() return } val userConfigRepo = UserConfigRepo(this) val credManRepo = CredentialManagerRepo(this, intent, userConfigRepo) setContent { Loading @@ -67,10 +73,19 @@ class CredentialSelectorActivity : ComponentActivity() { setIntent(intent) Log.d(Constants.LOG_TAG, "Existing activity received new intent") try { val cancelUiRequestToken = CredentialManagerRepo.getCancelUiRequestToken(intent) val viewModel: CredentialSelectorViewModel by viewModels() if (cancelUiRequestToken != null && viewModel.shouldCancelCurrentUi(cancelUiRequestToken)) { Log.d( Constants.LOG_TAG, "Received UI cancellation intent; cancelling the activity.") this.finish() return } else { val userConfigRepo = UserConfigRepo(this) val credManRepo = CredentialManagerRepo(this, intent, userConfigRepo) val viewModel: CredentialSelectorViewModel by viewModels() viewModel.onNewCredentialManagerRepo(credManRepo) } } catch (e: Exception) { onInitializationError(e, intent) } Loading
packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.credentialmanager import android.app.Activity import android.os.IBinder import android.util.Log import androidx.activity.compose.ManagedActivityResultLauncher import androidx.activity.result.ActivityResult Loading Loading @@ -135,6 +136,11 @@ class CredentialSelectorViewModel( uiState = uiState.copy(dialogState = DialogState.COMPLETE) } /** Return true if the current UI's request token matches the UI cancellation request token. */ fun shouldCancelCurrentUi(cancelRequestToken: IBinder): Boolean { return credManRepo.requestInfo.token.equals(cancelRequestToken) } /**************************************************************************/ /***** Get Flow Callbacks *****/ /**************************************************************************/ Loading