Add settings intent dialog
Add a dialog that can be launched via an intent to prompt the user to enable the provider for credman. Test: make & atest & manual Bug: 267816998 Change-Id: Id88cc7b3bf2829d075fbba87ea5dc0a245b9ae32
This commit is contained in:
@@ -4200,6 +4200,12 @@
|
|||||||
<action android:name="android.settings.SYNC_SETTINGS" />
|
<action android:name="android.settings.SYNC_SETTINGS" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:scheme="package" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter android:priority="1">
|
||||||
|
<action android:name="android.settings.CREDENTIAL_PROVIDER" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:scheme="package" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<intent-filter android:priority="53">
|
<intent-filter android:priority="53">
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
@@ -10136,6 +10136,15 @@
|
|||||||
<!-- Message of the warning dialog for disabling the credential provider. [CHAR_LIMIT=NONE] -->
|
<!-- Message of the warning dialog for disabling the credential provider. [CHAR_LIMIT=NONE] -->
|
||||||
<string name="credman_confirmation_message">Saved info like addresses or payment methods won\'t be filled in when you sign in. To keep your saved info filled in, set enable a password, passkey and data/or service.</string>
|
<string name="credman_confirmation_message">Saved info like addresses or payment methods won\'t be filled in when you sign in. To keep your saved info filled in, set enable a password, passkey and data/or service.</string>
|
||||||
|
|
||||||
|
<!-- Title of the warning dialog for enabling the credential provider. [CHAR_LIMIT=NONE] -->
|
||||||
|
<string name="credman_enable_confirmation_message_title">Turn on %1$s\?</string>
|
||||||
|
|
||||||
|
<!-- Message of the warning dialog for enabling the credential provider. [CHAR_LIMIT=NONE] -->
|
||||||
|
<string name="credman_enable_confirmation_message">Saved info like addresses or payment methods will be shared with this provider.</string>
|
||||||
|
|
||||||
|
<!-- Positive button to turn on credential manager provider (confirmation). [CHAR LIMIT=60] -->
|
||||||
|
<string name="credman_enable_confirmation_message_positive_button">Turn on</string>
|
||||||
|
|
||||||
<!-- Title of the error dialog when too many credential providers are selected. [CHAR_LIMIT=NONE] -->
|
<!-- Title of the error dialog when too many credential providers are selected. [CHAR_LIMIT=NONE] -->
|
||||||
<string name="credman_error_message_title">Passwords, passkeys and data services limit</string>
|
<string name="credman_error_message_title">Passwords, passkeys and data services limit</string>
|
||||||
|
|
||||||
|
@@ -75,7 +75,9 @@ public class AccountDashboardFragment extends DashboardFragment {
|
|||||||
if (CredentialManager.isServiceEnabled(context)) {
|
if (CredentialManager.isServiceEnabled(context)) {
|
||||||
CredentialManagerPreferenceController cmpp =
|
CredentialManagerPreferenceController cmpp =
|
||||||
use(CredentialManagerPreferenceController.class);
|
use(CredentialManagerPreferenceController.class);
|
||||||
cmpp.init(this, getFragmentManager());
|
CredentialManagerPreferenceController.Delegate delegate =
|
||||||
|
result -> getActivity().setResult(result);
|
||||||
|
cmpp.init(this, getFragmentManager(), getIntent(), delegate);
|
||||||
} else {
|
} else {
|
||||||
getSettingsLifecycle().addObserver(use(PasswordsPreferenceController.class));
|
getSettingsLifecycle().addObserver(use(PasswordsPreferenceController.class));
|
||||||
}
|
}
|
||||||
|
@@ -69,7 +69,9 @@ public class AccountPersonalDashboardFragment extends DashboardFragment {
|
|||||||
if (CredentialManager.isServiceEnabled(context)) {
|
if (CredentialManager.isServiceEnabled(context)) {
|
||||||
CredentialManagerPreferenceController cmpp =
|
CredentialManagerPreferenceController cmpp =
|
||||||
use(CredentialManagerPreferenceController.class);
|
use(CredentialManagerPreferenceController.class);
|
||||||
cmpp.init(this, getFragmentManager());
|
CredentialManagerPreferenceController.Delegate delegate =
|
||||||
|
result -> getActivity().setResult(result);
|
||||||
|
cmpp.init(this, getFragmentManager(), getIntent(), delegate);
|
||||||
} else {
|
} else {
|
||||||
getSettingsLifecycle().addObserver(use(PasswordsPreferenceController.class));
|
getSettingsLifecycle().addObserver(use(PasswordsPreferenceController.class));
|
||||||
}
|
}
|
||||||
|
@@ -69,7 +69,9 @@ public class AccountWorkProfileDashboardFragment extends DashboardFragment {
|
|||||||
if (CredentialManager.isServiceEnabled(context)) {
|
if (CredentialManager.isServiceEnabled(context)) {
|
||||||
CredentialManagerPreferenceController cmpp =
|
CredentialManagerPreferenceController cmpp =
|
||||||
use(CredentialManagerPreferenceController.class);
|
use(CredentialManagerPreferenceController.class);
|
||||||
cmpp.init(this, getFragmentManager());
|
CredentialManagerPreferenceController.Delegate delegate =
|
||||||
|
result -> getActivity().setResult(result);
|
||||||
|
cmpp.init(this, getFragmentManager(), getIntent(), delegate);
|
||||||
} else {
|
} else {
|
||||||
getSettingsLifecycle().addObserver(use(PasswordsPreferenceController.class));
|
getSettingsLifecycle().addObserver(use(PasswordsPreferenceController.class));
|
||||||
}
|
}
|
||||||
|
@@ -20,10 +20,12 @@ import static androidx.lifecycle.Lifecycle.Event.ON_CREATE;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
@@ -34,6 +36,7 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.OutcomeReceiver;
|
import android.os.OutcomeReceiver;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.IconDrawableFactory;
|
import android.util.IconDrawableFactory;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -67,6 +70,7 @@ import java.util.concurrent.Executor;
|
|||||||
public class CredentialManagerPreferenceController extends BasePreferenceController
|
public class CredentialManagerPreferenceController extends BasePreferenceController
|
||||||
implements LifecycleObserver {
|
implements LifecycleObserver {
|
||||||
private static final String TAG = "CredentialManagerPreferenceController";
|
private static final String TAG = "CredentialManagerPreferenceController";
|
||||||
|
private static final String ALTERNATE_INTENT = "android.settings.SYNC_SETTINGS";
|
||||||
private static final int MAX_SELECTABLE_PROVIDERS = 5;
|
private static final int MAX_SELECTABLE_PROVIDERS = 5;
|
||||||
|
|
||||||
private final PackageManager mPm;
|
private final PackageManager mPm;
|
||||||
@@ -76,8 +80,10 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
|||||||
private final @Nullable CredentialManager mCredentialManager;
|
private final @Nullable CredentialManager mCredentialManager;
|
||||||
private final Executor mExecutor;
|
private final Executor mExecutor;
|
||||||
private final Map<String, SwitchPreference> mPrefs = new HashMap<>(); // key is package name
|
private final Map<String, SwitchPreference> mPrefs = new HashMap<>(); // key is package name
|
||||||
|
private final List<ServiceInfo> mPendingServiceInfos = new ArrayList<>();
|
||||||
|
|
||||||
private @Nullable FragmentManager mFragmentManager = null;
|
private @Nullable FragmentManager mFragmentManager = null;
|
||||||
|
private @Nullable Delegate mDelegate = null;
|
||||||
|
|
||||||
public CredentialManagerPreferenceController(Context context, String preferenceKey) {
|
public CredentialManagerPreferenceController(Context context, String preferenceKey) {
|
||||||
super(context, preferenceKey);
|
super(context, preferenceKey);
|
||||||
@@ -115,10 +121,110 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
|||||||
*
|
*
|
||||||
* @param fragment the fragment to use as the parent
|
* @param fragment the fragment to use as the parent
|
||||||
* @param fragmentManager the fragment manager to use
|
* @param fragmentManager the fragment manager to use
|
||||||
|
* @param intent the intent used to start the activity
|
||||||
|
* @param delegate the delegate to send results back to
|
||||||
*/
|
*/
|
||||||
public void init(DashboardFragment fragment, FragmentManager fragmentManager) {
|
public void init(
|
||||||
|
DashboardFragment fragment,
|
||||||
|
FragmentManager fragmentManager,
|
||||||
|
@Nullable Intent launchIntent,
|
||||||
|
@NonNull Delegate delegate) {
|
||||||
fragment.getSettingsLifecycle().addObserver(this);
|
fragment.getSettingsLifecycle().addObserver(this);
|
||||||
mFragmentManager = fragmentManager;
|
mFragmentManager = fragmentManager;
|
||||||
|
setDelegate(delegate);
|
||||||
|
verifyReceivedIntent(launchIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses and sets the package component name. Returns a boolean as to whether this was
|
||||||
|
* successful.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean verifyReceivedIntent(Intent launchIntent) {
|
||||||
|
if (launchIntent == null || launchIntent.getAction() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String action = launchIntent.getAction();
|
||||||
|
final boolean isCredProviderAction =
|
||||||
|
TextUtils.equals(action, Settings.ACTION_CREDENTIAL_PROVIDER);
|
||||||
|
final boolean isExistingAction = TextUtils.equals(action, ALTERNATE_INTENT);
|
||||||
|
final boolean isValid = isCredProviderAction || isExistingAction;
|
||||||
|
|
||||||
|
if (!isValid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// After this point we have received a set credential manager provider intent
|
||||||
|
// so we should return a cancelled result if the data we got is no good.
|
||||||
|
if (launchIntent.getData() == null) {
|
||||||
|
setActivityResult(Activity.RESULT_CANCELED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String packageName = launchIntent.getData().getSchemeSpecificPart();
|
||||||
|
if (packageName == null) {
|
||||||
|
setActivityResult(Activity.RESULT_CANCELED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPendingServiceInfos.clear();
|
||||||
|
for (CredentialProviderInfo cpi : mServices) {
|
||||||
|
final ServiceInfo serviceInfo = cpi.getServiceInfo();
|
||||||
|
if (serviceInfo.packageName.equals(packageName)) {
|
||||||
|
mPendingServiceInfos.add(serviceInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't set the result as RESULT_OK here because we should wait for the user to
|
||||||
|
// enable the provider.
|
||||||
|
if (!mPendingServiceInfos.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
setActivityResult(Activity.RESULT_CANCELED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void setDelegate(Delegate delegate) {
|
||||||
|
mDelegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setActivityResult(int resultCode) {
|
||||||
|
if (mDelegate == null) {
|
||||||
|
Log.e(TAG, "Missing delegate");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mDelegate.setActivityResult(resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleIntent() {
|
||||||
|
List<ServiceInfo> pendingServiceInfos = new ArrayList<>(mPendingServiceInfos);
|
||||||
|
mPendingServiceInfos.clear();
|
||||||
|
if (pendingServiceInfos.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceInfo serviceInfo = pendingServiceInfos.get(0);
|
||||||
|
ApplicationInfo appInfo = serviceInfo.applicationInfo;
|
||||||
|
CharSequence appName = "";
|
||||||
|
if (appInfo.nonLocalizedLabel != null) {
|
||||||
|
appName = appInfo.loadLabel(mPm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop if there is no name.
|
||||||
|
if (TextUtils.isEmpty(appName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewProviderConfirmationDialogFragment fragment =
|
||||||
|
newNewProviderConfirmationDialogFragment(serviceInfo.packageName, appName);
|
||||||
|
if (fragment == null || mFragmentManager == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment.show(mFragmentManager, NewProviderConfirmationDialogFragment.TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnLifecycleEvent(ON_CREATE)
|
@OnLifecycleEvent(ON_CREATE)
|
||||||
@@ -139,6 +245,9 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
|||||||
mServices.clear();
|
mServices.clear();
|
||||||
mServices.addAll(availableServices);
|
mServices.addAll(availableServices);
|
||||||
|
|
||||||
|
// If there is a pending dialog then show it.
|
||||||
|
handleIntent();
|
||||||
|
|
||||||
mEnabledPackageNames.clear();
|
mEnabledPackageNames.clear();
|
||||||
for (CredentialProviderInfo cpi : availableServices) {
|
for (CredentialProviderInfo cpi : availableServices) {
|
||||||
if (cpi.isEnabled()) {
|
if (cpi.isEnabled()) {
|
||||||
@@ -360,6 +469,49 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Create the new provider confirmation dialog. */
|
||||||
|
private @Nullable NewProviderConfirmationDialogFragment
|
||||||
|
newNewProviderConfirmationDialogFragment(
|
||||||
|
@NonNull String packageName, @NonNull CharSequence appName) {
|
||||||
|
DialogHost host =
|
||||||
|
new DialogHost() {
|
||||||
|
@Override
|
||||||
|
public void onDialogClick(int whichButton) {
|
||||||
|
completeEnableProviderDialogBox(whichButton, packageName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return new NewProviderConfirmationDialogFragment(host, packageName, appName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void completeEnableProviderDialogBox(int whichButton, String packageName) {
|
||||||
|
if (whichButton == DialogInterface.BUTTON_POSITIVE) {
|
||||||
|
if (togglePackageNameEnabled(packageName)) {
|
||||||
|
// Enable all prefs.
|
||||||
|
if (mPrefs.containsKey(packageName)) {
|
||||||
|
mPrefs.get(packageName).setChecked(true);
|
||||||
|
}
|
||||||
|
setActivityResult(Activity.RESULT_OK);
|
||||||
|
} else {
|
||||||
|
// There are too many providers so set the result as cancelled.
|
||||||
|
setActivityResult(Activity.RESULT_CANCELED);
|
||||||
|
|
||||||
|
// Show the error if too many enabled.
|
||||||
|
final DialogFragment fragment = newErrorDialogFragment();
|
||||||
|
|
||||||
|
if (fragment == null || mFragmentManager == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment.show(mFragmentManager, ErrorDialogFragment.TAG);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The user clicked the cancel button so send that result back.
|
||||||
|
setActivityResult(Activity.RESULT_CANCELED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private @Nullable ErrorDialogFragment newErrorDialogFragment() {
|
private @Nullable ErrorDialogFragment newErrorDialogFragment() {
|
||||||
DialogHost host =
|
DialogHost host =
|
||||||
new DialogHost() {
|
new DialogHost() {
|
||||||
@@ -399,10 +551,15 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Called when the dialog button is clicked. */
|
/** Called when the dialog button is clicked. */
|
||||||
private interface DialogHost {
|
private static interface DialogHost {
|
||||||
void onDialogClick(int whichButton);
|
void onDialogClick(int whichButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Called to send messages back to the parent fragment. */
|
||||||
|
public static interface Delegate {
|
||||||
|
void setActivityResult(int resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
/** Dialog fragment parent class. */
|
/** Dialog fragment parent class. */
|
||||||
private abstract static class CredentialManagerDialogFragment extends DialogFragment
|
private abstract static class CredentialManagerDialogFragment extends DialogFragment
|
||||||
implements DialogInterface.OnClickListener {
|
implements DialogInterface.OnClickListener {
|
||||||
@@ -482,4 +639,45 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
|||||||
getDialogHost().onDialogClick(which);
|
getDialogHost().onDialogClick(which);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirmation dialog fragment shows a dialog to the user to confirm that they would like to
|
||||||
|
* enable the new provider.
|
||||||
|
*/
|
||||||
|
public static class NewProviderConfirmationDialogFragment
|
||||||
|
extends CredentialManagerDialogFragment {
|
||||||
|
|
||||||
|
NewProviderConfirmationDialogFragment(
|
||||||
|
DialogHost dialogHost, @NonNull String packageName, @NonNull CharSequence appName) {
|
||||||
|
super(dialogHost);
|
||||||
|
|
||||||
|
final Bundle argument = new Bundle();
|
||||||
|
argument.putString(PACKAGE_NAME_KEY, packageName);
|
||||||
|
argument.putCharSequence(APP_NAME_KEY, appName);
|
||||||
|
setArguments(argument);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
final Bundle bundle = getArguments();
|
||||||
|
final Context context = getContext();
|
||||||
|
final String title =
|
||||||
|
context.getString(
|
||||||
|
R.string.credman_enable_confirmation_message_title,
|
||||||
|
bundle.getCharSequence(CredentialManagerDialogFragment.APP_NAME_KEY));
|
||||||
|
|
||||||
|
return new AlertDialog.Builder(getActivity())
|
||||||
|
.setTitle(title)
|
||||||
|
.setMessage(context.getString(R.string.credman_enable_confirmation_message))
|
||||||
|
.setPositiveButton(
|
||||||
|
R.string.credman_enable_confirmation_message_positive_button, this)
|
||||||
|
.setNegativeButton(android.R.string.cancel, this)
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
getDialogHost().onDialogClick(which);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,11 +24,16 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.credentials.CredentialProviderInfo;
|
import android.credentials.CredentialProviderInfo;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.provider.Settings;
|
||||||
|
|
||||||
import androidx.lifecycle.Lifecycle;
|
import androidx.lifecycle.Lifecycle;
|
||||||
import androidx.preference.PreferenceCategory;
|
import androidx.preference.PreferenceCategory;
|
||||||
@@ -48,6 +53,7 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@@ -56,6 +62,8 @@ public class CredentialManagerPreferenceControllerTest {
|
|||||||
private Context mContext;
|
private Context mContext;
|
||||||
private PreferenceScreen mScreen;
|
private PreferenceScreen mScreen;
|
||||||
private PreferenceCategory mCredentialsPreferenceCategory;
|
private PreferenceCategory mCredentialsPreferenceCategory;
|
||||||
|
private CredentialManagerPreferenceController.Delegate mDelegate;
|
||||||
|
private Optional<Integer> mReceivedResultCode;
|
||||||
|
|
||||||
private static final String TEST_PACKAGE_NAME_A = "com.android.providerA";
|
private static final String TEST_PACKAGE_NAME_A = "com.android.providerA";
|
||||||
private static final String TEST_PACKAGE_NAME_B = "com.android.providerB";
|
private static final String TEST_PACKAGE_NAME_B = "com.android.providerB";
|
||||||
@@ -74,6 +82,14 @@ public class CredentialManagerPreferenceControllerTest {
|
|||||||
mCredentialsPreferenceCategory = new PreferenceCategory(mContext);
|
mCredentialsPreferenceCategory = new PreferenceCategory(mContext);
|
||||||
mCredentialsPreferenceCategory.setKey("credentials_test");
|
mCredentialsPreferenceCategory.setKey("credentials_test");
|
||||||
mScreen.addPreference(mCredentialsPreferenceCategory);
|
mScreen.addPreference(mCredentialsPreferenceCategory);
|
||||||
|
mReceivedResultCode = Optional.empty();
|
||||||
|
mDelegate =
|
||||||
|
new CredentialManagerPreferenceController.Delegate() {
|
||||||
|
@Override
|
||||||
|
public void setActivityResult(int resultCode) {
|
||||||
|
mReceivedResultCode = Optional.of(resultCode);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -316,12 +332,79 @@ public class CredentialManagerPreferenceControllerTest {
|
|||||||
assertThat(pref3.isChecked()).isTrue();
|
assertThat(pref3.isChecked()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleIntentWithProviderServiceInfo_handleBadIntent_missingData() {
|
||||||
|
CredentialProviderInfo cpi = createCredentialProviderInfo();
|
||||||
|
CredentialManagerPreferenceController controller =
|
||||||
|
createControllerWithServices(Lists.newArrayList(cpi));
|
||||||
|
|
||||||
|
// Create an intent with missing data.
|
||||||
|
Intent missingDataIntent = new Intent(Settings.ACTION_CREDENTIAL_PROVIDER);
|
||||||
|
assertThat(controller.verifyReceivedIntent(missingDataIntent)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleIntentWithProviderServiceInfo_handleBadIntent_successDialog() {
|
||||||
|
CredentialProviderInfo cpi = createCredentialProviderInfo();
|
||||||
|
CredentialManagerPreferenceController controller =
|
||||||
|
createControllerWithServices(Lists.newArrayList(cpi));
|
||||||
|
String packageName = cpi.getServiceInfo().packageName;
|
||||||
|
|
||||||
|
// Create an intent with valid data.
|
||||||
|
Intent intent = new Intent(Settings.ACTION_CREDENTIAL_PROVIDER);
|
||||||
|
intent.setData(Uri.parse("package:" + packageName));
|
||||||
|
assertThat(controller.verifyReceivedIntent(intent)).isTrue();
|
||||||
|
controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_POSITIVE, packageName);
|
||||||
|
assertThat(mReceivedResultCode.get()).isEqualTo(Activity.RESULT_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleIntentWithProviderServiceInfo_handleIntent_cancelDialog() {
|
||||||
|
CredentialProviderInfo cpi = createCredentialProviderInfo();
|
||||||
|
CredentialManagerPreferenceController controller =
|
||||||
|
createControllerWithServices(Lists.newArrayList(cpi));
|
||||||
|
String packageName = cpi.getServiceInfo().packageName;
|
||||||
|
|
||||||
|
// Create an intent with valid data.
|
||||||
|
Intent intent = new Intent(Settings.ACTION_CREDENTIAL_PROVIDER);
|
||||||
|
intent.setData(Uri.parse("package:" + packageName));
|
||||||
|
assertThat(controller.verifyReceivedIntent(intent)).isTrue();
|
||||||
|
controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_NEGATIVE, packageName);
|
||||||
|
assertThat(mReceivedResultCode.get()).isEqualTo(Activity.RESULT_CANCELED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleIntentWithProviderServiceInfo_handleIntent_incorrectAction() {
|
||||||
|
CredentialProviderInfo cpi = createCredentialProviderInfo();
|
||||||
|
CredentialManagerPreferenceController controller =
|
||||||
|
createControllerWithServices(Lists.newArrayList(cpi));
|
||||||
|
String packageName = cpi.getServiceInfo().packageName;
|
||||||
|
|
||||||
|
// Create an intent with valid data.
|
||||||
|
Intent intent = new Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE);
|
||||||
|
intent.setData(Uri.parse("package:" + packageName));
|
||||||
|
assertThat(controller.verifyReceivedIntent(intent)).isFalse();
|
||||||
|
assertThat(mReceivedResultCode.isPresent()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleIntentWithProviderServiceInfo_handleNullIntent() {
|
||||||
|
CredentialProviderInfo cpi = createCredentialProviderInfo();
|
||||||
|
CredentialManagerPreferenceController controller =
|
||||||
|
createControllerWithServices(Lists.newArrayList(cpi));
|
||||||
|
|
||||||
|
// Use a null intent.
|
||||||
|
assertThat(controller.verifyReceivedIntent(null)).isFalse();
|
||||||
|
assertThat(mReceivedResultCode.isPresent()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
private CredentialManagerPreferenceController createControllerWithServices(
|
private CredentialManagerPreferenceController createControllerWithServices(
|
||||||
List<CredentialProviderInfo> availableServices) {
|
List<CredentialProviderInfo> availableServices) {
|
||||||
CredentialManagerPreferenceController controller =
|
CredentialManagerPreferenceController controller =
|
||||||
new CredentialManagerPreferenceController(
|
new CredentialManagerPreferenceController(
|
||||||
mContext, mCredentialsPreferenceCategory.getKey());
|
mContext, mCredentialsPreferenceCategory.getKey());
|
||||||
controller.setAvailableServices(() -> mock(Lifecycle.class), availableServices);
|
controller.setAvailableServices(() -> mock(Lifecycle.class), availableServices);
|
||||||
|
controller.setDelegate(mDelegate);
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user