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.ui; 18 19 import android.annotation.NonNull; 20 import android.annotation.SuppressLint; 21 import android.annotation.TestApi; 22 import android.content.ComponentName; 23 import android.content.Intent; 24 import android.content.res.Resources; 25 import android.os.IBinder; 26 import android.os.Parcel; 27 import android.os.ResultReceiver; 28 29 import java.util.ArrayList; 30 31 /** 32 * Helpers for generating the intents and related extras parameters to launch the UI activities. 33 * 34 * @hide 35 */ 36 @TestApi 37 public class IntentFactory { 38 /** Generate a new launch intent to the Credential Selector UI. */ 39 @NonNull createCredentialSelectorIntent( @onNull RequestInfo requestInfo, @SuppressLint(R) @NonNull ArrayList<ProviderData> enabledProviderDataList, @SuppressLint(R) @NonNull ArrayList<DisabledProviderData> disabledProviderDataList, @NonNull ResultReceiver resultReceiver)40 public static Intent createCredentialSelectorIntent( 41 @NonNull RequestInfo requestInfo, 42 @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling. 43 @NonNull 44 ArrayList<ProviderData> enabledProviderDataList, 45 @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling. 46 @NonNull 47 ArrayList<DisabledProviderData> disabledProviderDataList, 48 @NonNull ResultReceiver resultReceiver) { 49 Intent intent = new Intent(); 50 ComponentName componentName = 51 ComponentName.unflattenFromString( 52 Resources.getSystem() 53 .getString( 54 com.android.internal.R.string 55 .config_credentialManagerDialogComponent)); 56 intent.setComponent(componentName); 57 58 intent.putParcelableArrayListExtra( 59 ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST, enabledProviderDataList); 60 intent.putParcelableArrayListExtra( 61 ProviderData.EXTRA_DISABLED_PROVIDER_DATA_LIST, disabledProviderDataList); 62 intent.putExtra(RequestInfo.EXTRA_REQUEST_INFO, requestInfo); 63 intent.putExtra( 64 Constants.EXTRA_RESULT_RECEIVER, toIpcFriendlyResultReceiver(resultReceiver)); 65 66 return intent; 67 } 68 69 /** 70 * Creates an Intent that cancels any UI matching the given request token id. 71 * 72 * @hide 73 */ 74 @NonNull createCancelUiIntent(@onNull IBinder requestToken, boolean shouldShowCancellationUi, @NonNull String appPackageName)75 public static Intent createCancelUiIntent(@NonNull IBinder requestToken, 76 boolean shouldShowCancellationUi, @NonNull String appPackageName) { 77 Intent intent = new Intent(); 78 ComponentName componentName = 79 ComponentName.unflattenFromString( 80 Resources.getSystem() 81 .getString( 82 com.android.internal.R.string 83 .config_credentialManagerDialogComponent)); 84 intent.setComponent(componentName); 85 intent.putExtra(CancelUiRequest.EXTRA_CANCEL_UI_REQUEST, 86 new CancelUiRequest(requestToken, shouldShowCancellationUi, appPackageName)); 87 return intent; 88 } 89 90 /** 91 * Notify the UI that providers have been enabled/disabled. 92 * 93 * @hide 94 */ 95 @NonNull createProviderUpdateIntent()96 public static Intent createProviderUpdateIntent() { 97 Intent intent = new Intent(); 98 ComponentName componentName = 99 ComponentName.unflattenFromString( 100 Resources.getSystem() 101 .getString( 102 com.android.internal.R.string 103 .config_credentialManagerReceiverComponent)); 104 intent.setComponent(componentName); 105 intent.setAction(Constants.CREDMAN_ENABLED_PROVIDERS_UPDATED); 106 return intent; 107 } 108 109 /** 110 * Convert an instance of a "locally-defined" ResultReceiver to an instance of {@link 111 * android.os.ResultReceiver} itself, which the receiving process will be able to unmarshall. 112 */ toIpcFriendlyResultReceiver( T resultReceiver)113 private static <T extends ResultReceiver> ResultReceiver toIpcFriendlyResultReceiver( 114 T resultReceiver) { 115 final Parcel parcel = Parcel.obtain(); 116 resultReceiver.writeToParcel(parcel, 0); 117 parcel.setDataPosition(0); 118 119 final ResultReceiver ipcFriendly = ResultReceiver.CREATOR.createFromParcel(parcel); 120 parcel.recycle(); 121 122 return ipcFriendly; 123 } 124 IntentFactory()125 private IntentFactory() {} 126 } 127