Merge "Add SettingsPrefController for Slices"
This commit is contained in:
committed by
Android (Google) Code Review
commit
96c1ecd50f
159
src/com/android/settings/core/BasePreferenceController.java
Normal file
159
src/com/android/settings/core/BasePreferenceController.java
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.core;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.app.slice.Slice;
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.search.ResultPayload;
|
||||
import com.android.settings.search.SearchIndexableRaw;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract class to consolidate utility between preference controllers and act as an interface
|
||||
* for Slices. The abstract classes that inherit from this class will act as the direct interfaces
|
||||
* for each type when plugging into Slices.
|
||||
*/
|
||||
public abstract class BasePreferenceController extends AbstractPreferenceController {
|
||||
|
||||
private static final String TAG = "SettingsPrefController";
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({AVAILABLE, DISABLED_UNSUPPORTED, DISABLED_FOR_USER, DISABLED_DEPENDENT_SETTING,
|
||||
UNAVAILABLE_UNKNOWN})
|
||||
public @interface AvailabilityStatus {
|
||||
}
|
||||
|
||||
/**
|
||||
* The setting is available.
|
||||
*/
|
||||
public static final int AVAILABLE = 0;
|
||||
|
||||
/**
|
||||
* The setting is not supported by the device.
|
||||
*/
|
||||
public static final int DISABLED_UNSUPPORTED = 1;
|
||||
|
||||
/**
|
||||
* The setting cannot be changed by the current user.
|
||||
*/
|
||||
public static final int DISABLED_FOR_USER = 2;
|
||||
|
||||
/**
|
||||
* The setting has a dependency in the Settings App which is currently blocking access.
|
||||
*/
|
||||
public static final int DISABLED_DEPENDENT_SETTING = 3;
|
||||
|
||||
/**
|
||||
* A catch-all case for internal errors and inexplicable unavailability.
|
||||
*/
|
||||
public static final int UNAVAILABLE_UNKNOWN = 4;
|
||||
|
||||
private final String mPreferenceKey;
|
||||
|
||||
public BasePreferenceController(Context context, String preferenceKey) {
|
||||
super(context);
|
||||
mPreferenceKey = preferenceKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@AvailabilityStatus} for the Setting. This status is used to determine if the
|
||||
* Setting should be shown or disabled in Settings. Further, it can be used to produce
|
||||
* appropriate error / warning Slice in the case of unavailability.
|
||||
* </p>
|
||||
* The status is used for the convenience methods: {@link #isAvailable()},
|
||||
* {@link #isSupported()}
|
||||
*/
|
||||
@AvailabilityStatus
|
||||
public abstract int getAvailabilityStatus();
|
||||
|
||||
/**
|
||||
* @return A slice for the corresponding setting.
|
||||
*/
|
||||
public abstract Slice getSettingSlice();
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return mPreferenceKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isAvailable() {
|
||||
return getAvailabilityStatus() == AVAILABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code false} if the setting is not applicable to the device. This covers both
|
||||
* settings which were only introduced in future versions of android, or settings that have
|
||||
* hardware dependencies.
|
||||
* </p>
|
||||
* Note that a return value of {@code true} does not mean that the setting is available.
|
||||
*/
|
||||
public final boolean isSupported() {
|
||||
return getAvailabilityStatus() != DISABLED_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates non-indexable keys for search provider.
|
||||
*
|
||||
* Called by SearchIndexProvider#getNonIndexableKeys
|
||||
*/
|
||||
public void updateNonIndexableKeys(List<String> keys) {
|
||||
if (this instanceof AbstractPreferenceController) {
|
||||
if (!isAvailable()) {
|
||||
final String key = getPreferenceKey();
|
||||
if (TextUtils.isEmpty(key)) {
|
||||
Log.w(TAG,
|
||||
"Skipping updateNonIndexableKeys due to empty key " + this.toString());
|
||||
return;
|
||||
}
|
||||
keys.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates raw data for search provider.
|
||||
*
|
||||
* Called by SearchIndexProvider#getRawDataToIndex
|
||||
*/
|
||||
public void updateRawDataToIndex(List<SearchIndexableRaw> rawData) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link ResultPayload} corresponding to the search result type for the preference.
|
||||
* TODO (b/69808376) Remove this method.
|
||||
* Do not extend this method. It will not launch with P.
|
||||
*/
|
||||
@Deprecated
|
||||
public ResultPayload getResultPayload() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO (b/69380366) Add Method to get preference UI
|
||||
|
||||
// TODO (b/69380464) Add method to get intent
|
||||
|
||||
// TODO (b/69380560) Add method to get broadcast intent
|
||||
}
|
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* A controller mixin that adds mobile settings specific functionality
|
||||
* TODO (b/69808530) Replace with BasePreferenceController.
|
||||
*/
|
||||
public interface PreferenceControllerMixin {
|
||||
|
||||
@@ -60,7 +61,11 @@ public interface PreferenceControllerMixin {
|
||||
|
||||
/**
|
||||
* @return the {@link ResultPayload} corresponding to the search result type for the preference.
|
||||
*
|
||||
* Do not rely on this method for intent-based or inline results. It will be removed in the
|
||||
* unbundling effort.
|
||||
*/
|
||||
@Deprecated
|
||||
default ResultPayload getResultPayload() {
|
||||
return null;
|
||||
}
|
||||
|
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.core;
|
||||
|
||||
import android.app.slice.Slice;
|
||||
import android.content.Context;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
/**
|
||||
* Abstract class that consolidates logic for updating toggle controllers.
|
||||
* It automatically handles the getting and setting of the switch UI element.
|
||||
* Children of this class implement methods to get and set the underlying value of the setting.
|
||||
*/
|
||||
public abstract class TogglePreferenceController extends BasePreferenceController implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
|
||||
private static final String TAG = "TogglePrefController";
|
||||
|
||||
public TogglePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the Setting is enabled.
|
||||
*/
|
||||
public abstract boolean isChecked();
|
||||
|
||||
/**
|
||||
* Set the Setting to {@param isChecked}
|
||||
*
|
||||
* @param isChecked Is {@true} when the setting should be enabled.
|
||||
*/
|
||||
public abstract void setChecked(boolean isChecked);
|
||||
|
||||
@Override
|
||||
public final void updateState(Preference preference) {
|
||||
((SwitchPreference) preference).setChecked(isChecked());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean auto = (Boolean) newValue;
|
||||
setChecked(auto);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slice getSettingSlice() {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -16,65 +16,54 @@ package com.android.settings.display;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.provider.Settings;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import com.android.settings.DisplaySettings;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settings.search.DatabaseIndexingUtils;
|
||||
import com.android.settings.search.InlineSwitchPayload;
|
||||
import com.android.settings.search.ResultPayload;
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE;
|
||||
import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
|
||||
import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
|
||||
|
||||
|
||||
public class AutoBrightnessPreferenceController extends AbstractPreferenceController implements
|
||||
PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
|
||||
|
||||
private final String mAutoBrightnessKey;
|
||||
public class AutoBrightnessPreferenceController extends TogglePreferenceController {
|
||||
|
||||
private final String SYSTEM_KEY = SCREEN_BRIGHTNESS_MODE;
|
||||
private final int DEFAULT_VALUE = SCREEN_BRIGHTNESS_MODE_MANUAL;
|
||||
|
||||
public AutoBrightnessPreferenceController(Context context, String key) {
|
||||
super(context);
|
||||
mAutoBrightnessKey = key;
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_automatic_brightness_available);
|
||||
public boolean isChecked() {
|
||||
return Settings.System.getInt(mContext.getContentResolver(),
|
||||
SYSTEM_KEY, DEFAULT_VALUE) != DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return mAutoBrightnessKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
int brightnessMode = Settings.System.getInt(mContext.getContentResolver(),
|
||||
SYSTEM_KEY, DEFAULT_VALUE);
|
||||
((SwitchPreference) preference).setChecked(brightnessMode != DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean auto = (Boolean) newValue;
|
||||
public void setChecked(boolean isChecked) {
|
||||
Settings.System.putInt(mContext.getContentResolver(), SYSTEM_KEY,
|
||||
auto ? SCREEN_BRIGHTNESS_MODE_AUTOMATIC : DEFAULT_VALUE);
|
||||
return true;
|
||||
isChecked ? SCREEN_BRIGHTNESS_MODE_AUTOMATIC : DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@AvailabilityStatus
|
||||
public int getAvailabilityStatus() {
|
||||
return mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_automatic_brightness_available)
|
||||
? AVAILABLE
|
||||
: DISABLED_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultPayload getResultPayload() {
|
||||
// TODO remove result payload
|
||||
final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
|
||||
DisplaySettings.class.getName(), mAutoBrightnessKey,
|
||||
DisplaySettings.class.getName(), getPreferenceKey(),
|
||||
mContext.getString(R.string.display_settings));
|
||||
|
||||
return new InlineSwitchPayload(SYSTEM_KEY,
|
||||
|
@@ -27,6 +27,7 @@ import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
@@ -71,6 +72,9 @@ public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider {
|
||||
if (controller instanceof PreferenceControllerMixin) {
|
||||
((PreferenceControllerMixin) controller)
|
||||
.updateNonIndexableKeys(nonIndexableKeys);
|
||||
} else if (controller instanceof BasePreferenceController) {
|
||||
((BasePreferenceController) controller).updateNonIndexableKeys(
|
||||
nonIndexableKeys);
|
||||
} else {
|
||||
throw new IllegalStateException(controller.getClass().getName()
|
||||
+ " must implement " + PreferenceControllerMixin.class.getName());
|
||||
|
@@ -27,6 +27,7 @@ import android.util.Log;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
@@ -72,10 +73,11 @@ public class DatabaseIndexingUtils {
|
||||
* @return A map between {@link Uri}s and {@link PreferenceControllerMixin}s to get the payload
|
||||
* types for Settings.
|
||||
*/
|
||||
public static Map<String, PreferenceControllerMixin> getPreferenceControllerUriMap(
|
||||
public static Map<String, ResultPayload> getPayloadKeyMap(
|
||||
String className, Context context) {
|
||||
ArrayMap<String, ResultPayload> map = new ArrayMap<>();
|
||||
if (context == null) {
|
||||
return null;
|
||||
return map;
|
||||
}
|
||||
|
||||
final Class<?> clazz = getIndexableClass(className);
|
||||
@@ -83,7 +85,7 @@ public class DatabaseIndexingUtils {
|
||||
if (clazz == null) {
|
||||
Log.d(TAG, "SearchIndexableResource '" + className +
|
||||
"' should implement the " + Indexable.class.getName() + " interface!");
|
||||
return null;
|
||||
return map;
|
||||
}
|
||||
|
||||
// Will be non null only for a Local provider implementing a
|
||||
@@ -94,44 +96,28 @@ public class DatabaseIndexingUtils {
|
||||
provider.getPreferenceControllers(context);
|
||||
|
||||
if (controllers == null) {
|
||||
return null;
|
||||
return map;
|
||||
}
|
||||
|
||||
ArrayMap<String, PreferenceControllerMixin> map = new ArrayMap<>();
|
||||
|
||||
for (AbstractPreferenceController controller : controllers) {
|
||||
ResultPayload payload;
|
||||
if (controller instanceof PreferenceControllerMixin) {
|
||||
map.put(controller.getPreferenceKey(), (PreferenceControllerMixin) controller);
|
||||
payload = ((PreferenceControllerMixin) controller).getResultPayload();
|
||||
|
||||
} else if (controller instanceof BasePreferenceController) {
|
||||
payload = ((BasePreferenceController) controller).getResultPayload();
|
||||
} else {
|
||||
throw new IllegalStateException(controller.getClass().getName()
|
||||
+ " must implement " + PreferenceControllerMixin.class.getName());
|
||||
}
|
||||
if (payload != null) {
|
||||
map.put(controller.getPreferenceKey(), payload);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uriMap Map between the {@link PreferenceControllerMixin} keys
|
||||
* and the controllers themselves.
|
||||
* @param key The look-up key
|
||||
* @return The Payload from the {@link PreferenceControllerMixin} specified by the key,
|
||||
* if it exists. Otherwise null.
|
||||
*/
|
||||
public static ResultPayload getPayloadFromUriMap(Map<String, PreferenceControllerMixin> uriMap,
|
||||
String key) {
|
||||
if (uriMap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PreferenceControllerMixin controller = uriMap.get(key);
|
||||
if (controller == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return controller.getResultPayload();
|
||||
}
|
||||
|
||||
public static Class<?> getIndexableClass(String className) {
|
||||
final Class<?> clazz;
|
||||
try {
|
||||
@@ -164,4 +150,4 @@ public class DatabaseIndexingUtils {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -40,6 +40,7 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -178,11 +179,11 @@ public class IndexDataConverter {
|
||||
final String intentTargetPackage = sir.intentTargetPackage;
|
||||
final String intentTargetClass = sir.intentTargetClass;
|
||||
|
||||
Map<String, PreferenceControllerMixin> controllerUriMap = null;
|
||||
Map<String, ResultPayload> controllerUriMap = new HashMap<>();
|
||||
|
||||
if (fragmentName != null) {
|
||||
controllerUriMap = DatabaseIndexingUtils
|
||||
.getPreferenceControllerUriMap(fragmentName, context);
|
||||
.getPayloadKeyMap(fragmentName, context);
|
||||
}
|
||||
|
||||
headerTitle = XmlParserUtils.getDataTitle(context, attrs);
|
||||
@@ -249,7 +250,7 @@ public class IndexDataConverter {
|
||||
}
|
||||
|
||||
// TODO (b/62254931) index primitives instead of payload
|
||||
payload = DatabaseIndexingUtils.getPayloadFromUriMap(controllerUriMap, key);
|
||||
payload = controllerUriMap.get(key);
|
||||
childFragment = XmlParserUtils.getDataChildFragment(context, attrs);
|
||||
|
||||
builder.setSummaryOn(summary)
|
||||
|
Reference in New Issue
Block a user