Merge "Add service link when no providers are present"
This commit is contained in:
@@ -29,13 +29,16 @@ import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.credentials.CredentialManager;
|
||||
import android.credentials.CredentialProviderInfo;
|
||||
import android.credentials.SetEnabledProvidersException;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.OutcomeReceiver;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.IconDrawableFactory;
|
||||
@@ -48,6 +51,7 @@ import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
@@ -69,6 +73,7 @@ import java.util.concurrent.Executor;
|
||||
/** Queries available credential manager providers and adds preferences for them. */
|
||||
public class CredentialManagerPreferenceController extends BasePreferenceController
|
||||
implements LifecycleObserver {
|
||||
public static final String ADD_SERVICE_DEVICE_CONFIG = "credential_manager_service_search_uri";
|
||||
private static final String TAG = "CredentialManagerPreferenceController";
|
||||
private static final String ALTERNATE_INTENT = "android.settings.SYNC_SETTINGS";
|
||||
private static final int MAX_SELECTABLE_PROVIDERS = 5;
|
||||
@@ -84,6 +89,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
|
||||
private @Nullable FragmentManager mFragmentManager = null;
|
||||
private @Nullable Delegate mDelegate = null;
|
||||
private @Nullable String mFlagOverrideForTest = null;
|
||||
|
||||
public CredentialManagerPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
@@ -236,12 +242,16 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
setAvailableServices(
|
||||
lifecycleOwner,
|
||||
mCredentialManager.getCredentialProviderServices(
|
||||
getUser(), CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY));
|
||||
getUser(), CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY),
|
||||
null);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setAvailableServices(
|
||||
LifecycleOwner lifecycleOwner, List<CredentialProviderInfo> availableServices) {
|
||||
LifecycleOwner lifecycleOwner,
|
||||
List<CredentialProviderInfo> availableServices,
|
||||
String flagOverrideForTest) {
|
||||
mFlagOverrideForTest = flagOverrideForTest;
|
||||
mServices.clear();
|
||||
mServices.addAll(availableServices);
|
||||
|
||||
@@ -275,6 +285,65 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
PreferenceGroup group = screen.findPreference(getPreferenceKey());
|
||||
Context context = screen.getContext();
|
||||
mPrefs.putAll(buildPreferenceList(context, group));
|
||||
|
||||
// Add the "add service" button only when there are no providers.
|
||||
if (mPrefs.isEmpty()) {
|
||||
String searchUri = getAddServiceUri(context);
|
||||
if (!TextUtils.isEmpty(searchUri)) {
|
||||
group.addPreference(newAddServicePreference(searchUri, context));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "add service" URI to show the play store. It will first try and use the
|
||||
* credential manager specific search URI and if that is null it will fallback to the autofill
|
||||
* one.
|
||||
*/
|
||||
public @NonNull String getAddServiceUri(@NonNull Context context) {
|
||||
// Check the credential manager gflag for a link.
|
||||
String searchUri =
|
||||
DeviceConfig.getString(
|
||||
DeviceConfig.NAMESPACE_CREDENTIAL,
|
||||
ADD_SERVICE_DEVICE_CONFIG,
|
||||
mFlagOverrideForTest);
|
||||
if (!TextUtils.isEmpty(searchUri)) {
|
||||
return searchUri;
|
||||
}
|
||||
|
||||
// If not fall back on autofill.
|
||||
return Settings.Secure.getStringForUser(
|
||||
context.getContentResolver(),
|
||||
Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI,
|
||||
getUser());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the preference that allows to add a new cred man service.
|
||||
*
|
||||
* @return the pref to be added
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public Preference newAddServicePreference(String searchUri, Context context) {
|
||||
final Intent addNewServiceIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(searchUri));
|
||||
final Preference preference = new Preference(context);
|
||||
preference.setOnPreferenceClickListener(
|
||||
p -> {
|
||||
context.startActivityAsUser(addNewServiceIntent, UserHandle.of(getUser()));
|
||||
return true;
|
||||
});
|
||||
preference.setTitle(R.string.print_menu_item_add_service);
|
||||
preference.setOrder(Integer.MAX_VALUE - 1);
|
||||
preference.setPersistent(false);
|
||||
|
||||
// Try to set the icon this should fail in a test environment but work
|
||||
// in the actual app.
|
||||
try {
|
||||
preference.setIcon(R.drawable.ic_add_24dp);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
Log.e(TAG, "Failed to find icon for add services link", e);
|
||||
}
|
||||
return preference;
|
||||
}
|
||||
|
||||
/** Aggregates the list of services and builds a list of UI prefs to show. */
|
||||
|
@@ -33,9 +33,11 @@ import android.content.pm.ServiceInfo;
|
||||
import android.credentials.CredentialProviderInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Looper;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
@@ -120,11 +122,42 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_noServices_noPreferencesAdded() {
|
||||
public void displayPreference_noServices_noPreferencesAdded_useAutofillUri() {
|
||||
Settings.Secure.putStringForUser(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI,
|
||||
"test",
|
||||
UserHandle.myUserId());
|
||||
|
||||
CredentialManagerPreferenceController controller =
|
||||
createControllerWithServices(Collections.emptyList());
|
||||
controller.displayPreference(mScreen);
|
||||
assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(0);
|
||||
assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(1);
|
||||
|
||||
Preference pref = mCredentialsPreferenceCategory.getPreference(0);
|
||||
assertThat(pref.getTitle()).isEqualTo("Add service");
|
||||
|
||||
assertThat(controller.getAddServiceUri(mContext)).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_noServices_noPreferencesAdded_useCredManUri() {
|
||||
Settings.Secure.putStringForUser(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI,
|
||||
"test",
|
||||
UserHandle.myUserId());
|
||||
|
||||
CredentialManagerPreferenceController controller =
|
||||
createControllerWithServicesAndAddServiceOverride(
|
||||
Collections.emptyList(), "credman");
|
||||
controller.displayPreference(mScreen);
|
||||
assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(1);
|
||||
|
||||
Preference pref = mCredentialsPreferenceCategory.getPreference(0);
|
||||
assertThat(pref.getTitle()).isEqualTo("Add service");
|
||||
|
||||
assertThat(controller.getAddServiceUri(mContext)).isEqualTo("credman");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -134,6 +167,9 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
controller.displayPreference(mScreen);
|
||||
assertThat(controller.isConnected()).isFalse();
|
||||
assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(1);
|
||||
|
||||
Preference pref = mCredentialsPreferenceCategory.getPreference(0);
|
||||
assertThat(pref.getTitle()).isNotEqualTo("Add account");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -400,10 +436,15 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
|
||||
private CredentialManagerPreferenceController createControllerWithServices(
|
||||
List<CredentialProviderInfo> availableServices) {
|
||||
return createControllerWithServicesAndAddServiceOverride(availableServices, null);
|
||||
}
|
||||
|
||||
private CredentialManagerPreferenceController createControllerWithServicesAndAddServiceOverride(
|
||||
List<CredentialProviderInfo> availableServices, String addServiceOverride) {
|
||||
CredentialManagerPreferenceController controller =
|
||||
new CredentialManagerPreferenceController(
|
||||
mContext, mCredentialsPreferenceCategory.getKey());
|
||||
controller.setAvailableServices(() -> mock(Lifecycle.class), availableServices);
|
||||
controller.setAvailableServices(() -> mock(Lifecycle.class), availableServices, addServiceOverride);
|
||||
controller.setDelegate(mDelegate);
|
||||
return controller;
|
||||
}
|
||||
|
Reference in New Issue
Block a user