Fork autofill default app selection

We are merging the default app selection for autofill
with credman so this forks the existing UI (so we can
flag it off).

Test: ondevice
Bug: 278919696
Change-Id: I96bcf1ff86b169a182b9974f7384c45b474c3d5d
This commit is contained in:
Becca Hughes
2023-04-24 16:08:59 +00:00
parent 99f45dd59b
commit ddf359d0f8
13 changed files with 637 additions and 48 deletions

View File

@@ -10265,6 +10265,8 @@
<string name="autofill_keywords">auto, fill, autofill, password</string>
<!-- Keywords for the credman feature. [CHAR LIMIT=NONE] -->
<string name="credman_keywords">data, passkey, password</string>
<!-- Keywords for the credman feature. [CHAR LIMIT=NONE] -->
<string name="credman_autofill_keywords">auto, fill, autofill, data, passkey, password</string>
<!-- Message of the warning dialog for setting the auto-fill app. [CHAR_LIMIT=NONE] -->
<string name="autofill_confirmation_message">
@@ -10277,6 +10279,20 @@
]]>
</string>
<!-- Message of the warning dialog for setting the auto-fill/credman app. [CHAR_LIMIT=NONE] -->
<string name="credman_autofill_confirmation_message">
<![CDATA[
<b>Use <xliff:g id="app_name" example="Provider">%1$s</xliff:g>\?</b>
<br/>
<br/>
<xliff:g id="app_name" example="Provider">%1$s</xliff:g> uses what\'s on
your screen to determine what can be autofilled. New passwords, passkeys and other info will be saved here from now on.
]]>
</string>
<!-- Title of the screen where the user picks a provider. [CHAR_LIMIT=NONE] -->
<string name="credman_picker_title">Passwords, passkeys and data services</string>
<!-- Title of the warning dialog for disabling the credential provider. [CHAR_LIMIT=NONE] -->
<string name="credman_confirmation_message_title">Turn off %1$s\?</string>

View File

@@ -27,10 +27,10 @@
android:title="@string/credman_chosen_app_title">
<com.android.settings.widget.GearPreference
android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
android:key="default_autofill_main"
android:fragment="com.android.settings.applications.credentials.DefaultCombinedPicker"
android:key="default_credman_autofill_main"
android:title="@string/credman_chosen_app_title"
settings:keywords="@string/autofill_keywords">
settings:keywords="@string/credman_autofill_keywords">
<extra
android:name="for_work"
android:value="false" />

View File

@@ -28,10 +28,10 @@
android:title="@string/credman_chosen_app_title">
<com.android.settings.widget.GearPreference
android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
android:key="default_autofill_main"
android:fragment="com.android.settings.applications.credentials.DefaultCombinedPicker"
android:key="default_credman_autofill_main"
android:title="@string/credman_chosen_app_title"
settings:keywords="@string/autofill_keywords">
settings:keywords="@string/credman_autofill_keywords">
<extra
android:name="for_work"
android:value="false" />

View File

@@ -28,8 +28,8 @@
android:title="@string/credman_chosen_app_title">
<com.android.settings.widget.GearPreference
android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
android:key="default_autofill_work"
android:fragment="com.android.settings.applications.credentials.DefaultCombinedPicker"
android:key="default_credman_autofill_main"
android:title="@string/credman_chosen_app_title"
settings:searchable="false">
<extra

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2023 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/credman_picker_title" />

View File

@@ -30,6 +30,8 @@ import android.provider.SearchIndexableResource;
import com.android.settings.R;
import com.android.settings.applications.autofill.PasswordsPreferenceController;
import com.android.settings.applications.credentials.CredentialManagerPreferenceController;
import com.android.settings.applications.credentials.DefaultCombinedPreferenceController;
import com.android.settings.applications.credentials.DefaultWorkCombinedPreferenceController;
import com.android.settings.applications.defaultapps.DefaultAutofillPreferenceController;
import com.android.settings.applications.defaultapps.DefaultWorkAutofillPreferenceController;
import com.android.settings.dashboard.DashboardFragment;
@@ -76,7 +78,14 @@ public class AccountDashboardFragment extends DashboardFragment {
CredentialManagerPreferenceController cmpp =
use(CredentialManagerPreferenceController.class);
CredentialManagerPreferenceController.Delegate delegate =
result -> getActivity().setResult(result);
new CredentialManagerPreferenceController.Delegate() {
public void setActivityResult(int resultCode) {
getActivity().setResult(resultCode);
}
public void forceDelegateRefresh() {
forceUpdatePreferences();
}
};
cmpp.init(this, getFragmentManager(), getIntent(), delegate);
} else {
getSettingsLifecycle().addObserver(use(PasswordsPreferenceController.class));
@@ -99,8 +108,13 @@ public class AccountDashboardFragment extends DashboardFragment {
static void buildAutofillPreferenceControllers(
Context context, List<AbstractPreferenceController> controllers) {
controllers.add(new DefaultAutofillPreferenceController(context));
controllers.add(new DefaultWorkAutofillPreferenceController(context));
if (CredentialManager.isServiceEnabled(context)) {
controllers.add(new DefaultCombinedPreferenceController(context));
controllers.add(new DefaultWorkCombinedPreferenceController(context));
} else {
controllers.add(new DefaultAutofillPreferenceController(context));
controllers.add(new DefaultWorkAutofillPreferenceController(context));
}
}
private static void buildAccountPreferenceControllers(

View File

@@ -70,7 +70,14 @@ public class AccountPersonalDashboardFragment extends DashboardFragment {
CredentialManagerPreferenceController cmpp =
use(CredentialManagerPreferenceController.class);
CredentialManagerPreferenceController.Delegate delegate =
result -> getActivity().setResult(result);
new CredentialManagerPreferenceController.Delegate() {
public void setActivityResult(int resultCode) {
getActivity().setResult(resultCode);
}
public void forceDelegateRefresh() {
forceUpdatePreferences();
}
};
cmpp.init(this, getFragmentManager(), getIntent(), delegate);
} else {
getSettingsLifecycle().addObserver(use(PasswordsPreferenceController.class));

View File

@@ -70,7 +70,14 @@ public class AccountWorkProfileDashboardFragment extends DashboardFragment {
CredentialManagerPreferenceController cmpp =
use(CredentialManagerPreferenceController.class);
CredentialManagerPreferenceController.Delegate delegate =
result -> getActivity().setResult(result);
new CredentialManagerPreferenceController.Delegate() {
public void setActivityResult(int resultCode) {
getActivity().setResult(resultCode);
}
public void forceDelegateRefresh() {
forceUpdatePreferences();
}
};
cmpp.init(this, getFragmentManager(), getIntent(), delegate);
} else {
getSettingsLifecycle().addObserver(use(PasswordsPreferenceController.class));

View File

@@ -44,8 +44,6 @@ import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.text.TextUtils;
import com.android.settingslib.utils.ThreadUtils;
import com.android.internal.content.PackageMonitor;
import android.util.IconDrawableFactory;
import android.util.Log;
@@ -127,6 +125,23 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
return null;
}
@Override
public int getAvailabilityStatus() {
if (mCredentialManager == null) {
return UNSUPPORTED_ON_DEVICE;
}
if (!isAutofillPrefSelected()) {
return CONDITIONALLY_UNAVAILABLE;
}
if (mServices.isEmpty()) {
return CONDITIONALLY_UNAVAILABLE;
}
return AVAILABLE;
}
@VisibleForTesting
public boolean isConnected() {
return mCredentialManager != null;
@@ -266,12 +281,15 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
if (mPreferenceScreen != null) {
displayPreference(mPreferenceScreen);
}
if (mDelegate != null) {
mDelegate.forceDelegateRefresh();
}
}
@VisibleForTesting
void setAvailableServices(
List<CredentialProviderInfo> availableServices,
String flagOverrideForTest) {
List<CredentialProviderInfo> availableServices, String flagOverrideForTest) {
mFlagOverrideForTest = flagOverrideForTest;
mServices.clear();
mServices.addAll(availableServices);
@@ -291,11 +309,6 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
}
}
@Override
public int getAvailabilityStatus() {
return mServices.isEmpty() ? CONDITIONALLY_UNAVAILABLE : AVAILABLE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
@@ -305,6 +318,17 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
mPreferenceScreen = screen;
PreferenceGroup group = screen.findPreference(getPreferenceKey());
group.removeAll();
// Hide/show based on autofill pref.
boolean isVisible = isAutofillPrefSelected();
screen.setVisible(isVisible);
group.setVisible(isVisible);
if (!isVisible) {
return;
}
Context context = screen.getContext();
mPrefs.putAll(buildPreferenceList(context, group));
@@ -586,10 +610,9 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
/** If the provider is also the autofill provider then hide it. */
@VisibleForTesting
public boolean isProviderHiddenBecauseOfAutofill(String packageName) {
final String autofillService = Settings.Secure.getStringForUser(
mContext.getContentResolver(),
Settings.Secure.AUTOFILL_SERVICE,
getUser());
final String autofillService =
Settings.Secure.getStringForUser(
mContext.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, getUser());
if (autofillService == null || TextUtils.isEmpty(autofillService)) {
return false;
}
@@ -600,6 +623,13 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
return autofillService.startsWith(packageName);
}
private boolean isAutofillPrefSelected() {
final String autofillService =
Settings.Secure.getStringForUser(
mContext.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, getUser());
return !TextUtils.isEmpty(autofillService);
}
@VisibleForTesting
void completeEnableProviderDialogBox(
int whichButton, String packageName, boolean setActivityResult) {
@@ -682,27 +712,31 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
/** Called to send messages back to the parent fragment. */
public static interface Delegate {
void setActivityResult(int resultCode);
void forceDelegateRefresh();
}
/**
* Monitor coming and going credman services and calls {@link #update()} when necessary
* Monitor coming and going credman services and calls {@link #DefaultCombinedPicker} when
* necessary
*/
private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() {
@Override
public void onPackageAdded(String packageName, int uid) {
ThreadUtils.postOnMainThread(() -> update());
}
private final PackageMonitor mSettingsPackageMonitor =
new PackageMonitor() {
@Override
public void onPackageAdded(String packageName, int uid) {
ThreadUtils.postOnMainThread(() -> updateFromExternal());
}
@Override
public void onPackageModified(String packageName) {
ThreadUtils.postOnMainThread(() -> update());
}
@Override
public void onPackageModified(String packageName) {
ThreadUtils.postOnMainThread(() -> updateFromExternal());
}
@Override
public void onPackageRemoved(String packageName, int uid) {
ThreadUtils.postOnMainThread(() -> update());
}
};
@Override
public void onPackageRemoved(String packageName, int uid) {
ThreadUtils.postOnMainThread(() -> updateFromExternal());
}
};
/** Dialog fragment parent class. */
private abstract static class CredentialManagerDialogFragment extends DialogFragment

View File

@@ -0,0 +1,258 @@
/*
* Copyright (C) 2023 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 com.android.settings.applications.credentials;
import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.autofill.AutofillService;
import android.service.autofill.AutofillServiceInfo;
import android.text.Html;
import android.text.TextUtils;
import androidx.preference.Preference;
import com.android.internal.content.PackageMonitor;
import com.android.settings.R;
import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
import com.android.settingslib.applications.DefaultAppInfo;
import com.android.settingslib.utils.ThreadUtils;
import com.android.settingslib.widget.CandidateInfo;
import java.util.ArrayList;
import java.util.List;
public class DefaultCombinedPicker extends DefaultAppPickerFragment {
private static final String TAG = "DefaultCombinedPicker";
public static final String SETTING = Settings.Secure.AUTOFILL_SERVICE;
public static final Intent AUTOFILL_PROBE = new Intent(AutofillService.SERVICE_INTERFACE);
/** Extra set when the fragment is implementing ACTION_REQUEST_SET_AUTOFILL_SERVICE. */
public static final String EXTRA_PACKAGE_NAME = "package_name";
/** Set when the fragment is implementing ACTION_REQUEST_SET_AUTOFILL_SERVICE. */
private DialogInterface.OnClickListener mCancelListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Activity activity = getActivity();
if (activity != null && activity.getIntent().getStringExtra(EXTRA_PACKAGE_NAME) != null) {
mCancelListener =
(d, w) -> {
activity.setResult(Activity.RESULT_CANCELED);
activity.finish();
};
// If mCancelListener is not null, fragment is started from
// ACTION_REQUEST_SET_AUTOFILL_SERVICE and we should always use the calling uid.
mUserId = UserHandle.myUserId();
}
mSettingsPackageMonitor.register(activity, activity.getMainLooper(), false);
update();
}
@Override
protected DefaultAppPickerFragment.ConfirmationDialogFragment newConfirmationDialogFragment(
String selectedKey, CharSequence confirmationMessage) {
final AutofillPickerConfirmationDialogFragment fragment =
new AutofillPickerConfirmationDialogFragment();
fragment.init(this, selectedKey, confirmationMessage);
return fragment;
}
/**
* Custom dialog fragment that has a cancel listener used to propagate the result back to caller
* (for the cases where the picker is launched by {@code
* android.settings.REQUEST_SET_AUTOFILL_SERVICE}.
*/
public static class AutofillPickerConfirmationDialogFragment
extends DefaultAppPickerFragment.ConfirmationDialogFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
final DefaultCombinedPicker target = (DefaultCombinedPicker) getTargetFragment();
setCancelListener(target.mCancelListener);
super.onCreate(savedInstanceState);
}
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.default_credman_picker;
}
@Override
public int getMetricsCategory() {
return SettingsEnums.DEFAULT_AUTOFILL_PICKER;
}
@Override
protected boolean shouldShowItemNone() {
return true;
}
/** Monitor coming and going auto fill services and calls {@link #update()} when necessary */
private final PackageMonitor mSettingsPackageMonitor =
new PackageMonitor() {
@Override
public void onPackageAdded(String packageName, int uid) {
ThreadUtils.postOnMainThread(() -> update());
}
@Override
public void onPackageModified(String packageName) {
ThreadUtils.postOnMainThread(() -> update());
}
@Override
public void onPackageRemoved(String packageName, int uid) {
ThreadUtils.postOnMainThread(() -> update());
}
};
/** Update the data in this UI. */
private void update() {
updateCandidates();
addAddServicePreference();
}
@Override
public void onDestroy() {
mSettingsPackageMonitor.unregister();
super.onDestroy();
}
/**
* Gets the preference that allows to add a new autofill service.
*
* @return The preference or {@code null} if no service can be added
*/
private Preference newAddServicePreferenceOrNull() {
final String searchUri =
Settings.Secure.getStringForUser(
getActivity().getContentResolver(),
Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI,
mUserId);
if (TextUtils.isEmpty(searchUri)) {
return null;
}
final Intent addNewServiceIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(searchUri));
final Context context = getPrefContext();
final Preference preference = new Preference(context);
preference.setOnPreferenceClickListener(
p -> {
context.startActivityAsUser(addNewServiceIntent, UserHandle.of(mUserId));
return true;
});
preference.setTitle(R.string.print_menu_item_add_service);
preference.setIcon(R.drawable.ic_add_24dp);
preference.setOrder(Integer.MAX_VALUE - 1);
preference.setPersistent(false);
return preference;
}
/**
* Add a preference that allows the user to add a service if the market link for that is
* configured.
*/
private void addAddServicePreference() {
final Preference addNewServicePreference = newAddServicePreferenceOrNull();
if (addNewServicePreference != null) {
getPreferenceScreen().addPreference(addNewServicePreference);
}
}
@Override
protected List<DefaultAppInfo> getCandidates() {
final List<DefaultAppInfo> candidates = new ArrayList<>();
final List<AutofillServiceInfo> services =
AutofillServiceInfo.getAvailableServices(getContext(), mUserId);
for (AutofillServiceInfo asi : services) {
candidates.add(
new DefaultAppInfo(
getContext(), mPm, mUserId, asi.getServiceInfo().getComponentName()));
}
return candidates;
}
public static String getDefaultKey(Context context, int userId) {
String setting =
Settings.Secure.getStringForUser(context.getContentResolver(), SETTING, userId);
if (setting != null) {
ComponentName componentName = ComponentName.unflattenFromString(setting);
if (componentName != null) {
return componentName.flattenToString();
}
}
return null;
}
@Override
protected String getDefaultKey() {
return getDefaultKey(getContext(), mUserId);
}
@Override
protected CharSequence getConfirmationMessage(CandidateInfo appInfo) {
if (appInfo == null) {
return null;
}
final CharSequence appName = appInfo.loadLabel();
final String message =
getContext()
.getString(
R.string.credman_autofill_confirmation_message,
Html.escapeHtml(appName));
return Html.fromHtml(message);
}
@Override
protected boolean setDefaultKey(String key) {
Settings.Secure.putStringForUser(getContext().getContentResolver(), SETTING, key, mUserId);
// Check if activity was launched from Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE
// intent, and set proper result if so...
final Activity activity = getActivity();
if (activity != null) {
final String packageName = activity.getIntent().getStringExtra(EXTRA_PACKAGE_NAME);
if (packageName != null) {
final int result =
key != null && key.startsWith(packageName)
? Activity.RESULT_OK
: Activity.RESULT_CANCELED;
activity.setResult(result);
activity.finish();
}
}
// TODO: Notify the rest
return true;
}
}

View File

@@ -0,0 +1,150 @@
/*
* Copyright (C) 2023 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 com.android.settings.applications.credentials;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.credentials.CredentialManager;
import android.provider.Settings;
import android.service.autofill.AutofillServiceInfo;
import android.text.TextUtils;
import android.util.Log;
import android.view.autofill.AutofillManager;
import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
import com.android.settingslib.applications.DefaultAppInfo;
import java.util.List;
public class DefaultCombinedPreferenceController extends DefaultAppPreferenceController {
private final AutofillManager mAutofillManager;
private final CredentialManager mCredentialManager;
public DefaultCombinedPreferenceController(Context context) {
super(context);
mAutofillManager = mContext.getSystemService(AutofillManager.class);
if (CredentialManager.isServiceEnabled(context)) {
mCredentialManager = mContext.getSystemService(CredentialManager.class);
} else {
mCredentialManager = null;
}
}
@Override
public boolean isAvailable() {
return mAutofillManager != null
&& mCredentialManager != null
&& mAutofillManager.hasAutofillFeature()
&& mAutofillManager.isAutofillSupported();
}
@Override
public String getPreferenceKey() {
return "default_credman_autofill_main";
}
@Override
protected Intent getSettingIntent(DefaultAppInfo info) {
if (info == null) {
return null;
}
final AutofillSettingIntentProvider intentProvider =
new AutofillSettingIntentProvider(mContext, mUserId, info.getKey());
return intentProvider.getIntent();
}
@Override
protected DefaultAppInfo getDefaultAppInfo() {
final String flattenComponent =
Settings.Secure.getString(
mContext.getContentResolver(), DefaultCombinedPicker.SETTING);
if (!TextUtils.isEmpty(flattenComponent)) {
DefaultAppInfo appInfo =
new DefaultAppInfo(
mContext,
mPackageManager,
mUserId,
ComponentName.unflattenFromString(flattenComponent));
return appInfo;
}
return null;
}
@Override
protected boolean showLabelAsTitle() {
return true;
}
/** Provides Intent to setting activity for the specified autofill service. */
static final class AutofillSettingIntentProvider {
private final String mSelectedKey;
private final Context mContext;
private final int mUserId;
public AutofillSettingIntentProvider(Context context, int userId, String key) {
mSelectedKey = key;
mContext = context;
mUserId = userId;
}
public Intent getIntent() {
final List<ResolveInfo> resolveInfos =
mContext.getPackageManager()
.queryIntentServicesAsUser(
DefaultCombinedPicker.AUTOFILL_PROBE,
PackageManager.GET_META_DATA,
mUserId);
for (ResolveInfo resolveInfo : resolveInfos) {
final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
final String flattenKey =
new ComponentName(serviceInfo.packageName, serviceInfo.name)
.flattenToString();
if (TextUtils.equals(mSelectedKey, flattenKey)) {
final String settingsActivity;
try {
settingsActivity =
new AutofillServiceInfo(mContext, serviceInfo)
.getSettingsActivity();
} catch (SecurityException e) {
// Service does not declare the proper permission, ignore it.
Log.w(
"AutofillSettingIntentProvider",
"Error getting info for " + serviceInfo + ": " + e);
return null;
}
if (TextUtils.isEmpty(settingsActivity)) {
return null;
}
return new Intent(Intent.ACTION_MAIN)
.setComponent(
new ComponentName(serviceInfo.packageName, settingsActivity));
}
}
return null;
}
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2023 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 com.android.settings.applications.credentials;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import com.android.settings.Utils;
import com.android.settingslib.applications.DefaultAppInfo;
public class DefaultWorkCombinedPreferenceController extends DefaultCombinedPreferenceController {
private final UserHandle mUserHandle;
public DefaultWorkCombinedPreferenceController(Context context) {
super(context);
mUserHandle = Utils.getManagedProfile(mUserManager);
}
@Override
public boolean isAvailable() {
if (mUserHandle == null) {
return false;
}
return super.isAvailable();
}
@Override
public String getPreferenceKey() {
return "default_autofill_work";
}
@Override
protected DefaultAppInfo getDefaultAppInfo() {
final String flattenComponent =
Settings.Secure.getStringForUser(
mContext.getContentResolver(),
DefaultCombinedPicker.SETTING,
mUserHandle.getIdentifier());
if (!TextUtils.isEmpty(flattenComponent)) {
DefaultAppInfo appInfo =
new DefaultAppInfo(
mContext,
mPackageManager,
mUserHandle.getIdentifier(),
ComponentName.unflattenFromString(flattenComponent));
return appInfo;
}
return null;
}
@Override
protected Intent getSettingIntent(DefaultAppInfo info) {
if (info == null) {
return null;
}
final AutofillSettingIntentProvider intentProvider =
new AutofillSettingIntentProvider(
mContext, mUserHandle.getIdentifier(), info.getKey());
return intentProvider.getIntent();
}
@Override
protected void startActivity(Intent intent) {
mContext.startActivityAsUser(intent, mUserHandle);
}
}

View File

@@ -86,13 +86,12 @@ public class CredentialManagerPreferenceControllerTest {
mCredentialsPreferenceCategory.setKey("credentials_test");
mScreen.addPreference(mCredentialsPreferenceCategory);
mReceivedResultCode = Optional.empty();
mDelegate =
new CredentialManagerPreferenceController.Delegate() {
@Override
public void setActivityResult(int resultCode) {
mReceivedResultCode = Optional.of(resultCode);
}
};
mDelegate = new CredentialManagerPreferenceController.Delegate() {
public void setActivityResult(int resultCode) {
mReceivedResultCode = Optional.of(resultCode);
}
public void forceDelegateRefresh() {}
};
}
@Test