13a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze/*
23a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze * Copyright (C) 2017 The Android Open Source Project
33a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze *
43a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
53a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze * except in compliance with the License. You may obtain a copy of the License at
63a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze *
73a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze *      http://www.apache.org/licenses/LICENSE-2.0
83a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze *
93a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze * Unless required by applicable law or agreed to in writing, software distributed under the
103a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
113a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze * KIND, either express or implied. See the License for the specific language governing
123a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze * permissions and limitations under the License.
133a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze */
143a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzepackage com.android.settings.core;
153a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
163a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzeimport android.annotation.IntDef;
173a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzeimport android.content.Context;
184a6f058552f85727f0d55d73e76a6031dc62717fMatthew Fritzeimport android.content.IntentFilter;
193a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzeimport android.text.TextUtils;
203a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzeimport android.util.Log;
213a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
223a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzeimport com.android.settings.search.ResultPayload;
233a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzeimport com.android.settings.search.SearchIndexableRaw;
241e9d9c7054270f92b4b7db4d3f405cb9ed38c051Matthew Fritzeimport com.android.settings.slices.SliceData;
253a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzeimport com.android.settingslib.core.AbstractPreferenceController;
263a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
273a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzeimport java.lang.annotation.Retention;
283a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzeimport java.lang.annotation.RetentionPolicy;
29fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhangimport java.lang.reflect.Constructor;
30fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhangimport java.lang.reflect.InvocationTargetException;
313a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzeimport java.util.List;
323a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
338c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritzeimport android.support.v7.preference.Preference;
348c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritzeimport android.support.v7.preference.PreferenceGroup;
358c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritzeimport android.support.v7.preference.PreferenceScreen;
368c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze
373a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze/**
383a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze * Abstract class to consolidate utility between preference controllers and act as an interface
393a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze * for Slices. The abstract classes that inherit from this class will act as the direct interfaces
403a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze * for each type when plugging into Slices.
413a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze */
423a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritzepublic abstract class BasePreferenceController extends AbstractPreferenceController {
433a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
443a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    private static final String TAG = "SettingsPrefController";
453a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
468c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze    /**
478c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * Denotes the availability of the Setting.
488c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * <p>
498c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * Used both explicitly and by the convenience methods {@link #isAvailable()} and
508c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * {@link #isSupported()}.
518c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     */
523a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    @Retention(RetentionPolicy.SOURCE)
53bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze    @IntDef({AVAILABLE, UNSUPPORTED_ON_DEVICE, DISABLED_FOR_USER, DISABLED_DEPENDENT_SETTING,
54bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze            CONDITIONALLY_UNAVAILABLE})
553a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    public @interface AvailabilityStatus {
563a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    }
573a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
583a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    /**
593a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * The setting is available.
603a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     */
613a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    public static final int AVAILABLE = 0;
623a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
633a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    /**
64bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze     * A generic catch for settings which are currently unavailable, but may become available in
65bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze     * the future. You should use {@link #DISABLED_FOR_USER} or {@link #DISABLED_DEPENDENT_SETTING}
66bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze     * if they describe the condition more accurately.
67bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze     */
68bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze    public static final int CONDITIONALLY_UNAVAILABLE = 1;
69bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze
70bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze    /**
71bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze     * The setting is not, and will not supported by this device.
728c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * <p>
738c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * There is no guarantee that the setting page exists, and any links to the Setting should take
748c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * you to the home page of Settings.
753a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     */
76bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze    public static final int UNSUPPORTED_ON_DEVICE = 2;
77bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze
783a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
793a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    /**
803a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * The setting cannot be changed by the current user.
818c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * <p>
828c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * Links to the Setting should take you to the page of the Setting, even if it cannot be
838c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * changed.
843a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     */
85bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze    public static final int DISABLED_FOR_USER = 3;
863a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
873a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    /**
883a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * The setting has a dependency in the Settings App which is currently blocking access.
898c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * <p>
908c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * It must be possible for the Setting to be enabled by changing the configuration of the device
918c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * settings. That is, a setting that cannot be changed because of the state of another setting.
928c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * This should not be used for a setting that would be hidden from the UI entirely.
938c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * <p>
948c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * Correct use: Intensity of night display should be {@link #DISABLED_DEPENDENT_SETTING} when
958c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * night display is off.
968c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * Incorrect use: Mobile Data is {@link #DISABLED_DEPENDENT_SETTING} when there is no
978c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * data-enabled sim.
988c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * <p>
998c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * Links to the Setting should take you to the page of the Setting, even if it cannot be
1008c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * changed.
1013a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     */
102bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze    public static final int DISABLED_DEPENDENT_SETTING = 4;
1033a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
1043a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
1056eb88778484fde825092e8b880dda7948fbdb042Doris Ling    protected final String mPreferenceKey;
1063a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
107fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang    /**
108fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang     * Instantiate a controller as specified controller type and user-defined key.
109fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang     * <p/>
110fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang     * This is done through reflection. Do not use this method unless you know what you are doing.
111fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang     */
112fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang    public static BasePreferenceController createInstance(Context context,
113fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            String controllerName, String key) {
114fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang        try {
115fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            final Class<?> clazz = Class.forName(controllerName);
116fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            final Constructor<?> preferenceConstructor =
117fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang                    clazz.getConstructor(Context.class, String.class);
118fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            final Object[] params = new Object[] {context, key};
119fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            return (BasePreferenceController) preferenceConstructor.newInstance(params);
120fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang        } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
121fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang                IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
122fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            throw new IllegalStateException(
123fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang                    "Invalid preference controller: " + controllerName, e);
124fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang        }
125fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang    }
126fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang
127fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang    /**
128fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang     * Instantiate a controller as specified controller type.
129fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang     * <p/>
130fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang     * This is done through reflection. Do not use this method unless you know what you are doing.
131fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang     */
132fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang    public static BasePreferenceController createInstance(Context context, String controllerName) {
133fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang        try {
134fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            final Class<?> clazz = Class.forName(controllerName);
135fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            final Constructor<?> preferenceConstructor = clazz.getConstructor(Context.class);
136fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            final Object[] params = new Object[] {context};
137fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            return (BasePreferenceController) preferenceConstructor.newInstance(params);
138fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang        } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
139fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang                IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
140fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang            throw new IllegalStateException(
141fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang                    "Invalid preference controller: " + controllerName, e);
142fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang        }
143fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang    }
144fc520ee38a4df4119e41fb28a9a7864c447f7ad2Fan Zhang
1453a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    public BasePreferenceController(Context context, String preferenceKey) {
1463a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze        super(context);
1473a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze        mPreferenceKey = preferenceKey;
148917f101899e0584edde44567f7939a563cc2dc05Fan Zhang        if (TextUtils.isEmpty(mPreferenceKey)) {
149917f101899e0584edde44567f7939a563cc2dc05Fan Zhang            throw new IllegalArgumentException("Preference key must be set");
150917f101899e0584edde44567f7939a563cc2dc05Fan Zhang        }
1513a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    }
1523a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
1533a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    /**
1543a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * @return {@AvailabilityStatus} for the Setting. This status is used to determine if the
1553a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * Setting should be shown or disabled in Settings. Further, it can be used to produce
1563a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * appropriate error / warning Slice in the case of unavailability.
1573a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * </p>
1583a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * The status is used for the convenience methods: {@link #isAvailable()},
1593a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * {@link #isSupported()}
1603a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     */
1613a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    @AvailabilityStatus
1623a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    public abstract int getAvailabilityStatus();
1633a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
1643a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    @Override
1653a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    public String getPreferenceKey() {
1663a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze        return mPreferenceKey;
1673a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    }
1683a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
1698c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze    /**
1708c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * @return {@code true} when the controller can be changed on the device.
1718c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     *
1728c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * <p>
1738c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * Will return true for {@link #AVAILABLE} and {@link #DISABLED_DEPENDENT_SETTING}.
1748c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * <p>
1758c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * When the availability status returned by {@link #getAvailabilityStatus()} is
1768c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * {@link #DISABLED_DEPENDENT_SETTING}, then the setting will be disabled by default in the
1778c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * DashboardFragment, and it is up to the {@link BasePreferenceController} to enable the
1788c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * preference at the right time.
1798c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     *
1808c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * TODO (mfritze) Build a dependency mechanism to allow a controller to easily define the
1818c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * dependent setting.
1828c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     */
1833a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    @Override
1843a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    public final boolean isAvailable() {
1858c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze        final int availabilityStatus = getAvailabilityStatus();
186bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze        return (availabilityStatus == AVAILABLE
187bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze                || availabilityStatus == DISABLED_DEPENDENT_SETTING);
1883a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    }
1893a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
1903a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    /**
1913a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * @return {@code false} if the setting is not applicable to the device. This covers both
1923a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * settings which were only introduced in future versions of android, or settings that have
1933a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * hardware dependencies.
1943a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * </p>
1953a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * Note that a return value of {@code true} does not mean that the setting is available.
1963a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     */
1973a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    public final boolean isSupported() {
198bd376296cd5b5a41c421b4d831036957915336ceMatthew Fritze        return getAvailabilityStatus() != UNSUPPORTED_ON_DEVICE;
1993a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    }
2003a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
2013a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    /**
2028c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     * Displays preference in this controller.
2038c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze     */
2048c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze    @Override
2058c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze    public void displayPreference(PreferenceScreen screen) {
2068c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze        super.displayPreference(screen);
2078c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze        if (getAvailabilityStatus() == DISABLED_DEPENDENT_SETTING) {
2088c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze            // Disable preference if it depends on another setting.
2098c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze            final Preference preference = screen.findPreference(getPreferenceKey());
2108c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze            if (preference != null) {
2118c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze                preference.setEnabled(false);
2128c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze            }
2138c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze        }
2148c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze    }
2158c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze
2168c48defb521d82d9c08320a950f8306dc833ee57Matthew Fritze    /**
2171e9d9c7054270f92b4b7db4d3f405cb9ed38c051Matthew Fritze     * @return the UI type supported by the controller.
2181e9d9c7054270f92b4b7db4d3f405cb9ed38c051Matthew Fritze     */
2191e9d9c7054270f92b4b7db4d3f405cb9ed38c051Matthew Fritze    @SliceData.SliceType
2201e9d9c7054270f92b4b7db4d3f405cb9ed38c051Matthew Fritze    public int getSliceType() {
2211e9d9c7054270f92b4b7db4d3f405cb9ed38c051Matthew Fritze        return SliceData.SliceType.INTENT;
2221e9d9c7054270f92b4b7db4d3f405cb9ed38c051Matthew Fritze    }
2231e9d9c7054270f92b4b7db4d3f405cb9ed38c051Matthew Fritze
2241e9d9c7054270f92b4b7db4d3f405cb9ed38c051Matthew Fritze    /**
2254a6f058552f85727f0d55d73e76a6031dc62717fMatthew Fritze     * @return an {@link IntentFilter} that includes all broadcasts which can affect the state of
2264a6f058552f85727f0d55d73e76a6031dc62717fMatthew Fritze     * this Setting.
2274a6f058552f85727f0d55d73e76a6031dc62717fMatthew Fritze     */
2284a6f058552f85727f0d55d73e76a6031dc62717fMatthew Fritze    public IntentFilter getIntentFilter() {
2294a6f058552f85727f0d55d73e76a6031dc62717fMatthew Fritze        return null;
2304a6f058552f85727f0d55d73e76a6031dc62717fMatthew Fritze    }
2314a6f058552f85727f0d55d73e76a6031dc62717fMatthew Fritze
2324a6f058552f85727f0d55d73e76a6031dc62717fMatthew Fritze    /**
2331dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     * Determines if the controller should be used as a Slice.
2341dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     * <p>
2351dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     *     Important criteria for a Slice are:
2361dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     *     - Must be secure
2371dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     *     - Must not be a privacy leak
2381dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     *     - Must be understandable as a stand-alone Setting.
2391dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     * <p>
2401dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     *     This does not guarantee the setting is available. {@link #isAvailable()} should sill be
2411dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     *     called.
2421dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     *
2431dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     * @return {@code true} if the controller should be used externally as a Slice.
2441dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze     */
2451dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze    public boolean isSliceable() {
2461dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze        return false;
2471dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze    }
2481dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze
2491dd25fd87c727fbf175027faf6a9a533c5cf7220Matthew Fritze    /**
2506719a9b73e7b72292a98db322a26396da6385db7Chihhang Chuang     * @return {@code true} if the setting update asynchronously.
2516719a9b73e7b72292a98db322a26396da6385db7Chihhang Chuang     * <p>
2526719a9b73e7b72292a98db322a26396da6385db7Chihhang Chuang     * For example, a Wifi controller would return true, because it needs to update the radio
2536719a9b73e7b72292a98db322a26396da6385db7Chihhang Chuang     * and wait for it to turn on.
2546719a9b73e7b72292a98db322a26396da6385db7Chihhang Chuang     */
2556719a9b73e7b72292a98db322a26396da6385db7Chihhang Chuang    public boolean hasAsyncUpdate() {
2566719a9b73e7b72292a98db322a26396da6385db7Chihhang Chuang        return false;
2576719a9b73e7b72292a98db322a26396da6385db7Chihhang Chuang    }
2586719a9b73e7b72292a98db322a26396da6385db7Chihhang Chuang
2596719a9b73e7b72292a98db322a26396da6385db7Chihhang Chuang    /**
2603a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * Updates non-indexable keys for search provider.
2613a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     *
2623a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * Called by SearchIndexProvider#getNonIndexableKeys
2633a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     */
2643a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    public void updateNonIndexableKeys(List<String> keys) {
2653a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze        if (this instanceof AbstractPreferenceController) {
2663a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze            if (!isAvailable()) {
2673a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze                final String key = getPreferenceKey();
2683a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze                if (TextUtils.isEmpty(key)) {
2693a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze                    Log.w(TAG,
2703a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze                            "Skipping updateNonIndexableKeys due to empty key " + this.toString());
2713a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze                    return;
2723a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze                }
2733a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze                keys.add(key);
2743a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze            }
2753a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze        }
2763a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    }
2773a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
2783a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    /**
2793a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * Updates raw data for search provider.
2803a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     *
2813a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * Called by SearchIndexProvider#getRawDataToIndex
2823a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     */
2833a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    public void updateRawDataToIndex(List<SearchIndexableRaw> rawData) {
2843a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    }
2853a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze
2863a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    /**
2873a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * @return the {@link ResultPayload} corresponding to the search result type for the preference.
2883a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * TODO (b/69808376) Remove this method.
2893a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     * Do not extend this method. It will not launch with P.
2903a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze     */
2913a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    @Deprecated
2923a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    public ResultPayload getResultPayload() {
2933a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze        return null;
2943a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze    }
2953a4168360b94ac3fdefeafa2f4a39169b6905c1bMatthew Fritze}