1f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang/*
2f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang * Copyright (C) 2017 The Android Open Source Project
3f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang *
4f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang * Licensed under the Apache License, Version 2.0 (the "License");
5f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang * you may not use this file except in compliance with the License.
6f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang * You may obtain a copy of the License at
7f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang *
8f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang *      http://www.apache.org/licenses/LICENSE-2.0
9f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang *
10f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang * Unless required by applicable law or agreed to in writing, software
11f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang * distributed under the License is distributed on an "AS IS" BASIS,
12f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang * See the License for the specific language governing permissions and
14f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang * limitations under the License.
15f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang */
16f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
17f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangpackage com.android.settings.applications.defaultapps;
18f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
1961d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Lemeimport android.Manifest;
20db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Lemeimport android.app.Activity;
21e78e851fffb934e53b8e10161144a0e321aa5843Felipe Lemeimport android.app.Dialog;
22f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.content.ComponentName;
232aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmannimport android.content.ContentResolver;
24aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Lemeimport android.content.Context;
25aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Lemeimport android.content.DialogInterface;
26f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.content.Intent;
27f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.content.pm.PackageManager;
28f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.content.pm.ResolveInfo;
29f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.content.pm.ServiceInfo;
302aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmannimport android.net.Uri;
31aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Lemeimport android.os.Bundle;
322aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmannimport android.os.Handler;
332aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmannimport android.os.Looper;
34f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.provider.Settings;
354fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Lemeimport android.service.autofill.AutofillService;
364fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Lemeimport android.service.autofill.AutofillServiceInfo;
372aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmannimport android.support.v7.preference.Preference;
384fafa4e403d3f71455c995963ce48c334732f957Svet Ganovimport android.text.Html;
39f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.text.TextUtils;
4061d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Lemeimport android.util.Log;
41f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
422aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmannimport com.android.internal.content.PackageMonitor;
43f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport com.android.internal.logging.nano.MetricsProto;
44f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport com.android.settings.R;
45f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
46f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport java.util.ArrayList;
47f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport java.util.List;
48f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
494fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Lemepublic class DefaultAutofillPicker extends DefaultAppPickerFragment {
50f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
5161d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme    private static final String TAG = "DefaultAutofillPicker";
5261d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme
534fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme    static final String SETTING = Settings.Secure.AUTOFILL_SERVICE;
544fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme    static final Intent AUTOFILL_PROBE = new Intent(AutofillService.SERVICE_INTERFACE);
55f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
56aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    /**
57aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme     * Extra set when the fragment is implementing ACTION_REQUEST_SET_AUTOFILL_SERVICE.
58aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme     */
59aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    public static final String EXTRA_PACKAGE_NAME = "package_name";
60aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme
61aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    /**
62aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme     * Set when the fragment is implementing ACTION_REQUEST_SET_AUTOFILL_SERVICE.
63aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme     */
64e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme    private DialogInterface.OnClickListener mCancelListener;
652aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    private final Handler mHandler = new Handler();
66aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme
67aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    @Override
68aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    public void onCreate(Bundle savedInstanceState) {
69aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme        super.onCreate(savedInstanceState);
70aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme
71aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme        final Activity activity = getActivity();
72aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme        if (activity != null && activity.getIntent().getStringExtra(EXTRA_PACKAGE_NAME) != null) {
73aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme            mCancelListener = (d, w) -> {
74aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme                activity.setResult(Activity.RESULT_CANCELED);
75aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme                activity.finish();
76aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme            };
77aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme        }
782aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
79e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        mSettingsPackageMonitor.register(activity, activity.getMainLooper(), false);
802aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        update();
81aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    }
82aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme
83aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    @Override
84aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    protected ConfirmationDialogFragment newConfirmationDialogFragment(String selectedKey,
85aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme            CharSequence confirmationMessage) {
86e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        final AutofillPickerConfirmationDialogFragment fragment =
87e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme                new AutofillPickerConfirmationDialogFragment();
88e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        fragment.init(this, selectedKey, confirmationMessage);
89e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        return fragment;
90e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme    }
91e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme
92e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme    /**
93e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme     * Custom dialog fragment that has a cancel listener used to propagate the result back to
94e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme     * caller (for the cases where the picker is launched by
95e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme     * {@code android.settings.REQUEST_SET_AUTOFILL_SERVICE}.
96e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme     */
97e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme    public static class AutofillPickerConfirmationDialogFragment
98e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme            extends ConfirmationDialogFragment {
99e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme
100e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        @Override
101e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        public void onCreate(Bundle savedInstanceState) {
102e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme            final DefaultAutofillPicker target = (DefaultAutofillPicker) getTargetFragment();
103e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme            setCancelListener(target.mCancelListener);
104e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme            super.onCreate(savedInstanceState);
105e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        }
106aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    }
107db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme
108f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
109f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    public int getMetricsCategory() {
110f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        return MetricsProto.MetricsEvent.DEFAULT_AUTOFILL_PICKER;
111f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
112f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
113f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
114f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    protected boolean shouldShowItemNone() {
115f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        return true;
116f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
117f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
1182aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    /**
1192aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * Monitor coming and going auto fill services and calls {@link #update()} when necessary
1202aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     */
1212aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() {
1222aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        @Override
1232aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        public void onPackageAdded(String packageName, int uid) {
1242aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann            mHandler.post(() -> update());
1252aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        }
1262aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1272aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        @Override
1282aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        public void onPackageModified(String packageName) {
1292aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann            mHandler.post(() -> update());
1302aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        }
1312aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1322aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        @Override
1332aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        public void onPackageRemoved(String packageName, int uid) {
1342aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann            mHandler.post(() -> update());
1352aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        }
1362aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    };
1372aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1382aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    /**
1392aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * Update the data in this UI.
1402aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     */
1412aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    private void update() {
1422aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        updateCandidates();
1432aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        addAddServicePreference();
1442aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    }
1452aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1462aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    @Override
1472aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    public void onDestroy() {
1482aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        mSettingsPackageMonitor.unregister();
1492aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        super.onDestroy();
1502aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    }
1512aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1522aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    /**
1532aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * Gets the preference that allows to add a new autofill service.
1542aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     *
1552aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * @return The preference or {@code null} if no service can be added
1562aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     */
1572aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    private Preference newAddServicePreferenceOrNull() {
1582aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        final String searchUri = Settings.Secure.getString(getActivity().getContentResolver(),
1592aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann                Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI);
1602aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        if (TextUtils.isEmpty(searchUri)) {
1612aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann            return null;
1622aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        }
1632aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1642aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        final Intent addNewServiceIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(searchUri));
1652aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        Preference preference = new Preference(getPrefContext());
1662aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        preference.setTitle(R.string.print_menu_item_add_service);
1672aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        preference.setIcon(R.drawable.ic_menu_add);
1682aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        preference.setOrder(Integer.MAX_VALUE -1);
1692aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        preference.setIntent(addNewServiceIntent);
1702aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        preference.setPersistent(false);
1712aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        return preference;
1722aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    }
1732aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1742aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    /**
1752aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * Add a preference that allows the user to add a service if the market link for that is
1762aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * configured.
1772aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     */
1782aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    private void addAddServicePreference() {
1792aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        final Preference addNewServicePreference = newAddServicePreferenceOrNull();
1802aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        if (addNewServicePreference != null) {
1812aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann            getPreferenceScreen().addPreference(addNewServicePreference);
1822aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        }
1832aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    }
1842aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
185f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
186f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    protected List<DefaultAppInfo> getCandidates() {
187f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        final List<DefaultAppInfo> candidates = new ArrayList<>();
188f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        final List<ResolveInfo> resolveInfos = mPm.getPackageManager()
1894fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                .queryIntentServices(AUTOFILL_PROBE, PackageManager.GET_META_DATA);
190f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        for (ResolveInfo info : resolveInfos) {
19161d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme            final String permission = info.serviceInfo.permission;
19261d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme            // TODO(b/37563972): remove BIND_AUTOFILL once clients use BIND_AUTOFILL_SERVICE
19361d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme            if (Manifest.permission.BIND_AUTOFILL_SERVICE.equals(permission)
19461d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                    || Manifest.permission.BIND_AUTOFILL.equals(permission)) {
19561d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                candidates.add(new DefaultAppInfo(mPm, mUserId, new ComponentName(
19661d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                        info.serviceInfo.packageName, info.serviceInfo.name)));
19761d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme            }
198f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        }
199f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        return candidates;
200f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
201f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
202aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    public static String getDefaultKey(Context context) {
2037d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov        String setting = Settings.Secure.getString(context.getContentResolver(), SETTING);
2047d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov        if (setting != null) {
2057d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov            ComponentName componentName = ComponentName.unflattenFromString(setting);
2067d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov            if (componentName != null) {
2077d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov                return componentName.flattenToString();
2087d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov            }
2097d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov        }
2107d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov        return null;
211aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    }
212aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme
213f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
214a278962dbc545f69ca3712159d438f2e50dab0a5Fan Zhang    protected String getDefaultKey() {
215aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme        return getDefaultKey(getContext());
216f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
217f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
218f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
2194fafa4e403d3f71455c995963ce48c334732f957Svet Ganov    protected CharSequence getConfirmationMessage(CandidateInfo appInfo) {
220f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        if (appInfo == null) {
221f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang            return null;
222f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        }
223a278962dbc545f69ca3712159d438f2e50dab0a5Fan Zhang        final CharSequence appName = appInfo.loadLabel();
2244fafa4e403d3f71455c995963ce48c334732f957Svet Ganov        final String message = getContext().getString(
2254fafa4e403d3f71455c995963ce48c334732f957Svet Ganov                R.string.autofill_confirmation_message, appName);
2264fafa4e403d3f71455c995963ce48c334732f957Svet Ganov        return Html.fromHtml(message);
227f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
228f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
229f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
230a278962dbc545f69ca3712159d438f2e50dab0a5Fan Zhang    protected boolean setDefaultKey(String key) {
231f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        Settings.Secure.putString(getContext().getContentResolver(), SETTING, key);
232db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme
233db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme        // Check if activity was launched from Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE
234db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme        // intent, and set proper result if so...
235db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme        final Activity activity = getActivity();
236db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme        if (activity != null) {
237db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme            final String packageName = activity.getIntent().getStringExtra(EXTRA_PACKAGE_NAME);
238db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme            if (packageName != null) {
239db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme                final int result = key != null && key.startsWith(packageName) ? Activity.RESULT_OK
240db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme                        : Activity.RESULT_CANCELED;
241db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme                activity.setResult(result);
242db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme                activity.finish();
243db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme            }
244db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme        }
245f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        return true;
246f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
247f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
248f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    /**
249db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme     * Provides Intent to setting activity for the specified autofill service.
250f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang     */
2514fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme    static final class AutofillSettingIntentProvider implements SettingIntentProvider {
252f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
253f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        private final String mSelectedKey;
254f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        private final PackageManager mPackageManager;
255f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
2564fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme        public AutofillSettingIntentProvider(PackageManager packageManager, String key) {
257f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang            mSelectedKey = key;
258f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang            mPackageManager = packageManager;
259f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        }
260f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
261f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        @Override
262f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        public Intent getIntent() {
263f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang            final List<ResolveInfo> resolveInfos = mPackageManager.queryIntentServices(
2644fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                    AUTOFILL_PROBE, PackageManager.GET_META_DATA);
265f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
266f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang            for (ResolveInfo resolveInfo : resolveInfos) {
267f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang                final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
268f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang                final String flattenKey = new ComponentName(
269f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang                        serviceInfo.packageName, serviceInfo.name).flattenToString();
270f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang                if (TextUtils.equals(mSelectedKey, flattenKey)) {
27161d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                    final String settingsActivity;
27261d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                    try {
27361d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                        settingsActivity = new AutofillServiceInfo(mPackageManager, serviceInfo)
27461d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                                .getSettingsActivity();
27561d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                    } catch (SecurityException e) {
27661d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                        // Service does not declare the proper permission, ignore it.
27761d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                        Log.w(TAG, "Error getting info for " + serviceInfo + ": " + e);
27861d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                        return null;
27961d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                    }
2804fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                    if (TextUtils.isEmpty(settingsActivity)) {
2814fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                        return null;
2824fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                    }
2834fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                    return new Intent(Intent.ACTION_MAIN).setComponent(
2844fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                            new ComponentName(serviceInfo.packageName, settingsActivity));
2854fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                }
2864fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme            }
2874fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme
288f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang            return null;
289f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        }
290f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
291f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang}
292