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;
21f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.content.ComponentName;
22aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Lemeimport android.content.Context;
23aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Lemeimport android.content.DialogInterface;
24f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.content.Intent;
25f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.content.pm.PackageManager;
26f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.content.pm.ResolveInfo;
27f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.content.pm.ServiceInfo;
282aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmannimport android.net.Uri;
29aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Lemeimport android.os.Bundle;
30f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.provider.Settings;
314fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Lemeimport android.service.autofill.AutofillService;
324fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Lemeimport android.service.autofill.AutofillServiceInfo;
332aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmannimport android.support.v7.preference.Preference;
344fafa4e403d3f71455c995963ce48c334732f957Svet Ganovimport android.text.Html;
35f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport android.text.TextUtils;
3661d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Lemeimport android.util.Log;
37f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
382aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmannimport com.android.internal.content.PackageMonitor;
39f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport com.android.internal.logging.nano.MetricsProto;
40f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport com.android.settings.R;
41fef14cac00b7e4f1ef0481845421618bc3810643Dake Guimport com.android.settingslib.applications.DefaultAppInfo;
42a7f135596d2af74fc97ecde9bff8a403252d4c2eFan Zhangimport com.android.settingslib.utils.ThreadUtils;
43fef14cac00b7e4f1ef0481845421618bc3810643Dake Guimport com.android.settingslib.widget.CandidateInfo;
44f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
45f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport java.util.ArrayList;
46f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhangimport java.util.List;
47f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
484fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Lemepublic class DefaultAutofillPicker extends DefaultAppPickerFragment {
49f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
5061d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme    private static final String TAG = "DefaultAutofillPicker";
5161d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme
524fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme    static final String SETTING = Settings.Secure.AUTOFILL_SERVICE;
534fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme    static final Intent AUTOFILL_PROBE = new Intent(AutofillService.SERVICE_INTERFACE);
54f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
55aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    /**
56aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme     * Extra set when the fragment is implementing ACTION_REQUEST_SET_AUTOFILL_SERVICE.
57aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme     */
58aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    public static final String EXTRA_PACKAGE_NAME = "package_name";
59aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme
60aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    /**
61aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme     * Set when the fragment is implementing ACTION_REQUEST_SET_AUTOFILL_SERVICE.
62aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme     */
63e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme    private DialogInterface.OnClickListener mCancelListener;
64aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme
65aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    @Override
66aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    public void onCreate(Bundle savedInstanceState) {
67aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme        super.onCreate(savedInstanceState);
68aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme
69aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme        final Activity activity = getActivity();
70aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme        if (activity != null && activity.getIntent().getStringExtra(EXTRA_PACKAGE_NAME) != null) {
71aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme            mCancelListener = (d, w) -> {
72aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme                activity.setResult(Activity.RESULT_CANCELED);
73aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme                activity.finish();
74aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme            };
75aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme        }
762aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
77e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        mSettingsPackageMonitor.register(activity, activity.getMainLooper(), false);
782aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        update();
79aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    }
80aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme
81aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    @Override
82aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    protected ConfirmationDialogFragment newConfirmationDialogFragment(String selectedKey,
83aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme            CharSequence confirmationMessage) {
84e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        final AutofillPickerConfirmationDialogFragment fragment =
85e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme                new AutofillPickerConfirmationDialogFragment();
86e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        fragment.init(this, selectedKey, confirmationMessage);
87e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        return fragment;
88e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme    }
89e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme
90e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme    /**
91e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme     * Custom dialog fragment that has a cancel listener used to propagate the result back to
92e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme     * caller (for the cases where the picker is launched by
93e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme     * {@code android.settings.REQUEST_SET_AUTOFILL_SERVICE}.
94e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme     */
95e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme    public static class AutofillPickerConfirmationDialogFragment
96e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme            extends ConfirmationDialogFragment {
97e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme
98e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        @Override
99e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        public void onCreate(Bundle savedInstanceState) {
100e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme            final DefaultAutofillPicker target = (DefaultAutofillPicker) getTargetFragment();
101e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme            setCancelListener(target.mCancelListener);
102e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme            super.onCreate(savedInstanceState);
103e78e851fffb934e53b8e10161144a0e321aa5843Felipe Leme        }
104aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    }
105db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme
106f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
10703a3b518debfb3870d780a6e29c8f115013cd866Doris Ling    protected int getPreferenceScreenResId() {
10803a3b518debfb3870d780a6e29c8f115013cd866Doris Ling        return R.xml.default_autofill_settings;
10903a3b518debfb3870d780a6e29c8f115013cd866Doris Ling    }
11003a3b518debfb3870d780a6e29c8f115013cd866Doris Ling
11103a3b518debfb3870d780a6e29c8f115013cd866Doris Ling    @Override
112f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    public int getMetricsCategory() {
113f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        return MetricsProto.MetricsEvent.DEFAULT_AUTOFILL_PICKER;
114f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
115f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
116f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
117f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    protected boolean shouldShowItemNone() {
118f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        return true;
119f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
120f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
1212aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    /**
1222aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * Monitor coming and going auto fill services and calls {@link #update()} when necessary
1232aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     */
1242aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() {
1252aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        @Override
1262aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        public void onPackageAdded(String packageName, int uid) {
127a7f135596d2af74fc97ecde9bff8a403252d4c2eFan Zhang            ThreadUtils.postOnMainThread(() -> update());
1282aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        }
1292aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1302aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        @Override
1312aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        public void onPackageModified(String packageName) {
132a7f135596d2af74fc97ecde9bff8a403252d4c2eFan Zhang            ThreadUtils.postOnMainThread(() -> update());
1332aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        }
1342aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1352aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        @Override
1362aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        public void onPackageRemoved(String packageName, int uid) {
137a7f135596d2af74fc97ecde9bff8a403252d4c2eFan Zhang            ThreadUtils.postOnMainThread(() -> update());
1382aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        }
1392aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    };
1402aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1412aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    /**
1422aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * Update the data in this UI.
1432aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     */
1442aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    private void update() {
1452aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        updateCandidates();
1462aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        addAddServicePreference();
1472aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    }
1482aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1492aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    @Override
1502aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    public void onDestroy() {
1512aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        mSettingsPackageMonitor.unregister();
1522aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        super.onDestroy();
1532aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    }
1542aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1552aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    /**
1562aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * Gets the preference that allows to add a new autofill service.
1572aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     *
1582aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * @return The preference or {@code null} if no service can be added
1592aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     */
1602aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    private Preference newAddServicePreferenceOrNull() {
1612aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        final String searchUri = Settings.Secure.getString(getActivity().getContentResolver(),
1622aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann                Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI);
1632aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        if (TextUtils.isEmpty(searchUri)) {
1642aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann            return null;
1652aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        }
1662aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1672aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        final Intent addNewServiceIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(searchUri));
1682aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        Preference preference = new Preference(getPrefContext());
1692aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        preference.setTitle(R.string.print_menu_item_add_service);
1702aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        preference.setIcon(R.drawable.ic_menu_add);
1712aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        preference.setOrder(Integer.MAX_VALUE -1);
1722aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        preference.setIntent(addNewServiceIntent);
1732aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        preference.setPersistent(false);
1742aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        return preference;
1752aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    }
1762aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
1772aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    /**
1782aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * Add a preference that allows the user to add a service if the market link for that is
1792aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     * configured.
1802aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann     */
1812aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    private void addAddServicePreference() {
1822aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        final Preference addNewServicePreference = newAddServicePreferenceOrNull();
1832aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        if (addNewServicePreference != null) {
1842aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann            getPreferenceScreen().addPreference(addNewServicePreference);
1852aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann        }
1862aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann    }
1872aff7dbfda8376b289b30d1d0a6f31e5b75f0a88Philip P. Moltmann
188f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
189f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    protected List<DefaultAppInfo> getCandidates() {
190f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        final List<DefaultAppInfo> candidates = new ArrayList<>();
191fef14cac00b7e4f1ef0481845421618bc3810643Dake Gu        final List<ResolveInfo> resolveInfos = mPm.queryIntentServices(
192fef14cac00b7e4f1ef0481845421618bc3810643Dake Gu                AUTOFILL_PROBE, PackageManager.GET_META_DATA);
193efa763624a86f77c99b5cac53d8cf81e474ffc4bFan Zhang        final Context context = getContext();
194f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        for (ResolveInfo info : resolveInfos) {
19561d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme            final String permission = info.serviceInfo.permission;
196b628d1ed53a73b00ffafaf60a1979ed978bca87bFelipe Leme            if (Manifest.permission.BIND_AUTOFILL_SERVICE.equals(permission)) {
197efa763624a86f77c99b5cac53d8cf81e474ffc4bFan Zhang                candidates.add(new DefaultAppInfo(context, mPm, mUserId, new ComponentName(
19861d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                        info.serviceInfo.packageName, info.serviceInfo.name)));
19961d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme            }
200b25ffe2c9faab58e6859e2c8b06ea5f50215572dFelipe Leme            if (Manifest.permission.BIND_AUTOFILL.equals(permission)) {
201b25ffe2c9faab58e6859e2c8b06ea5f50215572dFelipe Leme                // Let it go for now...
202b25ffe2c9faab58e6859e2c8b06ea5f50215572dFelipe Leme                Log.w(TAG, "AutofillService from '" + info.serviceInfo.packageName
203b25ffe2c9faab58e6859e2c8b06ea5f50215572dFelipe Leme                        + "' uses unsupported permission " + Manifest.permission.BIND_AUTOFILL
204b25ffe2c9faab58e6859e2c8b06ea5f50215572dFelipe Leme                        + ". It works for now, but might not be supported on future releases");
205b25ffe2c9faab58e6859e2c8b06ea5f50215572dFelipe Leme                candidates.add(new DefaultAppInfo(context, mPm, mUserId, new ComponentName(
206b25ffe2c9faab58e6859e2c8b06ea5f50215572dFelipe Leme                        info.serviceInfo.packageName, info.serviceInfo.name)));
207b25ffe2c9faab58e6859e2c8b06ea5f50215572dFelipe Leme            }
208f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        }
209f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        return candidates;
210f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
211f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
212aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    public static String getDefaultKey(Context context) {
2137d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov        String setting = Settings.Secure.getString(context.getContentResolver(), SETTING);
2147d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov        if (setting != null) {
2157d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov            ComponentName componentName = ComponentName.unflattenFromString(setting);
2167d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov            if (componentName != null) {
2177d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov                return componentName.flattenToString();
2187d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov            }
2197d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov        }
2207d3fb0481dd42af4f359fa3b2f5039c52f5825c0Svet Ganov        return null;
221aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme    }
222aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme
223f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
224a278962dbc545f69ca3712159d438f2e50dab0a5Fan Zhang    protected String getDefaultKey() {
225aa7a23b40d3175897759c840db8e0ea9081129ecFelipe Leme        return getDefaultKey(getContext());
226f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
227f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
228f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
2294fafa4e403d3f71455c995963ce48c334732f957Svet Ganov    protected CharSequence getConfirmationMessage(CandidateInfo appInfo) {
230f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        if (appInfo == null) {
231f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang            return null;
232f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        }
233a278962dbc545f69ca3712159d438f2e50dab0a5Fan Zhang        final CharSequence appName = appInfo.loadLabel();
2344fafa4e403d3f71455c995963ce48c334732f957Svet Ganov        final String message = getContext().getString(
2354fafa4e403d3f71455c995963ce48c334732f957Svet Ganov                R.string.autofill_confirmation_message, appName);
2364fafa4e403d3f71455c995963ce48c334732f957Svet Ganov        return Html.fromHtml(message);
237f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
238f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
239f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    @Override
240a278962dbc545f69ca3712159d438f2e50dab0a5Fan Zhang    protected boolean setDefaultKey(String key) {
241f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        Settings.Secure.putString(getContext().getContentResolver(), SETTING, key);
242db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme
243db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme        // Check if activity was launched from Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE
244db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme        // intent, and set proper result if so...
245db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme        final Activity activity = getActivity();
246db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme        if (activity != null) {
247db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme            final String packageName = activity.getIntent().getStringExtra(EXTRA_PACKAGE_NAME);
248db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme            if (packageName != null) {
249db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme                final int result = key != null && key.startsWith(packageName) ? Activity.RESULT_OK
250db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme                        : Activity.RESULT_CANCELED;
251db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme                activity.setResult(result);
252db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme                activity.finish();
253db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme            }
254db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme        }
255f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        return true;
256f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
257f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
258f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    /**
259db2b55a2440991449d7c1f7d87938ee3b6fda6aaFelipe Leme     * Provides Intent to setting activity for the specified autofill service.
260f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang     */
2614fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme    static final class AutofillSettingIntentProvider implements SettingIntentProvider {
262f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
263f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        private final String mSelectedKey;
264c21cfe9ea21d72a658c68954b3ddc99d7fff9cabSvetoslav Ganov        private final Context mContext;
265f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
266c21cfe9ea21d72a658c68954b3ddc99d7fff9cabSvetoslav Ganov        public AutofillSettingIntentProvider(Context context, String key) {
267f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang            mSelectedKey = key;
268c21cfe9ea21d72a658c68954b3ddc99d7fff9cabSvetoslav Ganov            mContext = context;
269f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        }
270f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
271f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        @Override
272f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        public Intent getIntent() {
273c21cfe9ea21d72a658c68954b3ddc99d7fff9cabSvetoslav Ganov            final List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentServices(
2744fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                    AUTOFILL_PROBE, PackageManager.GET_META_DATA);
275f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang
276f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang            for (ResolveInfo resolveInfo : resolveInfos) {
277f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang                final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
278f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang                final String flattenKey = new ComponentName(
279f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang                        serviceInfo.packageName, serviceInfo.name).flattenToString();
280f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang                if (TextUtils.equals(mSelectedKey, flattenKey)) {
28161d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                    final String settingsActivity;
28261d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                    try {
283c21cfe9ea21d72a658c68954b3ddc99d7fff9cabSvetoslav Ganov                        settingsActivity = new AutofillServiceInfo(mContext, serviceInfo)
28461d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                                .getSettingsActivity();
28561d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                    } catch (SecurityException e) {
28661d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                        // Service does not declare the proper permission, ignore it.
28761d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                        Log.w(TAG, "Error getting info for " + serviceInfo + ": " + e);
28861d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                        return null;
28961d6ec61aa2677ff6a1ee47234088ef318bbd760Felipe Leme                    }
2904fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                    if (TextUtils.isEmpty(settingsActivity)) {
2914fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                        return null;
2924fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                    }
2934fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                    return new Intent(Intent.ACTION_MAIN).setComponent(
2944fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                            new ComponentName(serviceInfo.packageName, settingsActivity));
2954fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme                }
2964fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme            }
2974fa4a2e3f5383dfa0f82470188ba2ea12601f689Felipe Leme
298f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang            return null;
299f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang        }
300f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang    }
301f8f55e574dbf03688d5d9b28bed0dd3802167fe5Fan Zhang}
302