Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d506ddfc authored by Jason Long's avatar Jason Long
Browse files

Add autofill app preference to Default Apps.

Add an option to AppListPreference to disable saving/restoring state.

Bug: 34396007
Test: Manual verification
Change-Id: I80103bd3d4e8fadfa30b7d3631d24c1b159da0dd
parent 2a7c6bd8
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -8126,4 +8126,14 @@
    <!-- UI webview setting: WebView disabled-for-user explanatory text [CHAR LIMIT=30] -->
    <string name="webview_disabled_for_user">Disabled for user <xliff:g id="user" example="John Doe">%s</xliff:g>\n</string>
    <!-- AutoFill strings -->
    <!-- Preference label for the auto-fill app. [CHAR LIMIT=60] -->
    <string name="autofill_app">Autofill app</string>
    <!-- Keywords for the auto-fill feature. [CHAR LIMIT=NONE] -->
    <string name="autofill_keywords">auto, fill, autofill</string>
    <!-- Title of the warning dialog for setting the auto-fill app. [CHAR_LIMIT=NONE] -->
    <string name="autofill_confirmation_message">
        Make <xliff:g id="app_name">%1$s</xliff:g> your autofill app? <xliff:g id="app_name">%1$s</xliff:g> will be able to read your screen and fill fields in other apps.
    </string>
</resources>
+14 −10
Original line number Diff line number Diff line
@@ -26,12 +26,19 @@
        android:fragment="com.android.settings.applications.ManageAssist"
        android:order="-20"/>

    <com.android.settings.applications.DefaultAutoFillPreference
        android:key="default_autofill"
        android:title="@string/autofill_app"
        android:summary="@string/app_list_preference_none"
        settings:keywords="@string/autofill_keywords"
        android:order="-19"/>

    <Preference
        android:key="default_browser"
        android:title="@string/default_browser_title"
        android:summary="@string/default_browser_title_none"
        android:fragment="com.android.settings.applications.defaultapps.DefaultBrowserPicker"
        android:order="-19">
        android:order="-18">
        <extra android:name="for_work" android:value="false"/>
    </Preference>

@@ -40,35 +47,32 @@
        android:title="@string/home_app"
        android:summary="@string/no_default_home"
        settings:keywords="@string/keywords_home"
        android:fragment="com.android.settings.applications.defaultapps.DefaultHomePicker"
        android:order="-18"/>
        android:order="-17"/>

    <Preference
        android:key="default_phone_app"
        android:title="@string/default_phone_title"
        android:fragment="com.android.settings.applications.defaultapps.DefaultPhonePicker"
        settings:keywords="@string/keywords_default_phone_app"
        android:order="-17"/>
        android:order="-16"/>

    <Preference
        android:key="default_sms_app"
        android:title="@string/sms_application_title"
        android:fragment="com.android.settings.applications.defaultapps.DefaultSmsPicker"
        settings:keywords="@string/keywords_more_default_sms_app"
        android:order="-16"/>
        android:order="-15"/>

    <Preference
        android:key="default_emergency_app"
        android:title="@string/default_emergency_app"
        settings:keywords="@string/keywords_emergency_app"
        android:fragment="com.android.settings.applications.defaultapps.DefaultEmergencyPicker"
        android:order="-15"/>
        android:order="-14"/>

    <Preference
        android:key="default_notification_asst_app"
        android:title="@string/default_notification_assistant"
        android:fragment="com.android.settings.applications.defaultapps.DefaultNotificationAssistantPicker"
        android:order="-14"/>
        android:order="-13"/>

    <Preference
        android:key="domain_urls"
+12 −2
Original line number Diff line number Diff line
@@ -61,6 +61,8 @@ public class AppListPreference extends CustomListPreference {
    protected final boolean mForWork;
    protected final int mUserId;


    private boolean mSavesState = true;
    private Drawable[] mEntryDrawables;
    private boolean mShowItemNone = false;
    private CharSequence[] mSummaries;
@@ -130,6 +132,10 @@ public class AppListPreference extends CustomListPreference {
                : UserHandle.myUserId();
    }

    public void setSavesState(boolean savesState) {
        mSavesState = savesState;
    }

    public void setShowItemNone(boolean showItemNone) {
        mShowItemNone = showItemNone;
    }
@@ -261,12 +267,16 @@ public class AppListPreference extends CustomListPreference {
    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        if (mSavesState) {
            return new SavedState(getEntryValues(), getValue(), mSummaries, mShowItemNone, superState);
        } else {
            return superState;
        }
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof SavedState) {
        if (mSavesState || state instanceof SavedState) {
            SavedState savedState = (SavedState) state;
            mShowItemNone = savedState.showItemNone;
            setPackageNames(savedState.entryValues, savedState.value);
+141 −0
Original line number Diff line number Diff line
/**
 * Copyright (C) 2017 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;

import android.annotation.Nullable;
import android.app.ActivityManager;
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.os.Parcelable;
import android.provider.Settings;
import android.service.autofill.AutoFillService;
import android.service.autofill.AutoFillServiceInfo;
import android.util.AttributeSet;
import android.util.Log;

import com.android.settings.R;
import com.android.settings.AppListPreferenceWithSettings;

import java.util.ArrayList;
import java.util.List;

public class DefaultAutoFillPreference extends AppListPreferenceWithSettings {
    private static final String TAG = "DefaultAutoFill";

    private static final String SETTING = Settings.Secure.AUTO_FILL_SERVICE;

    public DefaultAutoFillPreference(Context context, AttributeSet attrs) {
        super(context, attrs);

        setSavesState(false);
        setShowItemNone(true);

        refreshData();
    }

    @Override
    protected CharSequence getConfirmationMessage(String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }

        int index = findIndexOfValue(value);
        CharSequence[] entries = getEntries();
        if (index < 0 || index >= entries.length) {
            return null;
        }

        CharSequence entry = entries[index];
        return getContext().getString(R.string.autofill_confirmation_message, entry);
    }

    @Override
    protected boolean persistString(String value) {
        Settings.Secure.putString(getContext().getContentResolver(), SETTING, value);
        refreshData();
        return true;
    }

    private void refreshData() {
        ComponentName selectedComponent = getSelectedComponentName();
        List<AutoFillServiceInfo> infos = getInfos();

        AutoFillServiceInfo selectedInfo = null;
        int numberOfComponents = infos.size();
        ComponentName[] components = new ComponentName[numberOfComponents];
        for (int i = 0; i < numberOfComponents; ++i) {
            AutoFillServiceInfo info = infos.get(i);
            ServiceInfo serviceInfo = info.getServiceInfo();
            ComponentName component =
                    new ComponentName(serviceInfo.packageName, serviceInfo.name);
            components[i] = component;

            if (component.equals(selectedComponent)) {
                selectedInfo = info;
            }
        }

        ComponentName selectedComponentSettings = null;
        if (selectedInfo != null) {
            String settingsActivity = selectedInfo.getSettingsActivity();
            selectedComponentSettings = settingsActivity != null
                    ? new ComponentName(selectedComponent.getPackageName(), settingsActivity)
                    : null;
        } else { // selected component not found
            Log.w(TAG, "Selected AutoFillService not found " + selectedComponent);
            selectedComponent = null;
            selectedComponentSettings = null;
        }

        setComponentNames(components, selectedComponent);
        setSettingsComponent(selectedComponentSettings);
        setSummary(getEntry());
    }

    @Nullable
    private ComponentName getSelectedComponentName() {
        String componentString =
                Settings.Secure.getString(getContext().getContentResolver(), SETTING);
        if (componentString == null) {
            return null;
        }

        return ComponentName.unflattenFromString(componentString);
    }

    private List<AutoFillServiceInfo> getInfos() {
        PackageManager pm = getContext().getPackageManager();
        List<ResolveInfo> resolveInfos = pm.queryIntentServices(
                new Intent(AutoFillService.SERVICE_INTERFACE),
                PackageManager.GET_META_DATA);
        List<AutoFillServiceInfo> infos = new ArrayList<>(resolveInfos.size());
        for (ResolveInfo resolveInfo : resolveInfos) {
            ServiceInfo serviceInfo = resolveInfo.serviceInfo;
            AutoFillServiceInfo info = new AutoFillServiceInfo(pm, serviceInfo);
            if (info.getParseError() == null) {
                infos.add(info);
            } else {
                Log.i(TAG, "Invalid AutoFillService " + serviceInfo + ": " + info.getParseError());
            }
        }
        return infos;
    }
}