Add isSliceable API to BasePrefController

Only support explicitly approved Settings Slices,
dictated by controllers which return true for the new
method isSliceable.

Updating the supported settings to a whitelist means that
the method to return all available slices must be updated,
and checking slicability when we index slices.

Test: robotests
Bug: 79779103
Change-Id: Ib2b9690cdd0036b5cc4a1cb846c52bce7c824ab9
This commit is contained in:
Matthew Fritze
2018-05-18 17:59:26 -07:00
parent 49d8b0a3e4
commit bf1f5b5813
47 changed files with 475 additions and 18 deletions

View File

@@ -90,6 +90,11 @@ public class AccessibilitySlicePreferenceController extends TogglePreferenceCont
return getAccessibilityServiceInfo() == null ? UNSUPPORTED_ON_DEVICE : AVAILABLE; return getAccessibilityServiceInfo() == null ? UNSUPPORTED_ON_DEVICE : AVAILABLE;
} }
@Override
public boolean isSliceable() {
return true;
}
private AccessibilityServiceInfo getAccessibilityServiceInfo() { private AccessibilityServiceInfo getAccessibilityServiceInfo() {
final AccessibilityManager accessibilityManager = mContext.getSystemService( final AccessibilityManager accessibilityManager = mContext.getSystemService(
AccessibilityManager.class); AccessibilityManager.class);

View File

@@ -234,6 +234,23 @@ public abstract class BasePreferenceController extends AbstractPreferenceControl
return null; return null;
} }
/**
* Determines if the controller should be used as a Slice.
* <p>
* Important criteria for a Slice are:
* - Must be secure
* - Must not be a privacy leak
* - Must be understandable as a stand-alone Setting.
* <p>
* This does not guarantee the setting is available. {@link #isAvailable()} should sill be
* called.
*
* @return {@code true} if the controller should be used externally as a Slice.
*/
public boolean isSliceable() {
return false;
}
/** /**
* Updates non-indexable keys for search provider. * Updates non-indexable keys for search provider.
* *

View File

@@ -19,6 +19,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.R; import com.android.settings.R;
@@ -54,6 +55,11 @@ public class AmbientDisplayAlwaysOnPreferenceController extends TogglePreference
return isAvailable(mConfig) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; return isAvailable(mConfig) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "ambient_display_always_on");
}
@Override @Override
public boolean isChecked() { public boolean isChecked() {
return mConfig.alwaysOnEnabled(MY_USER); return mConfig.alwaysOnEnabled(MY_USER);

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.R; import com.android.settings.R;
@@ -90,6 +91,11 @@ public class AmbientDisplayNotificationsPreferenceController extends
return mConfig.pulseOnNotificationAvailable() ? AVAILABLE : UNSUPPORTED_ON_DEVICE; return mConfig.pulseOnNotificationAvailable() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "ambient_display_notification");
}
@Override @Override
//TODO (b/69808376): Remove result payload //TODO (b/69808376): Remove result payload
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {

View File

@@ -16,6 +16,7 @@ package com.android.settings.display;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import com.android.settings.DisplaySettings; import com.android.settings.DisplaySettings;
import com.android.settings.core.TogglePreferenceController; import com.android.settings.core.TogglePreferenceController;
@@ -60,6 +61,11 @@ public class AutoBrightnessPreferenceController extends TogglePreferenceControll
: UNSUPPORTED_ON_DEVICE; : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "auto_brightness");
}
@Override @Override
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {
// TODO remove result payload // TODO remove result payload

View File

@@ -15,6 +15,7 @@ package com.android.settings.display;
import android.content.Context; import android.content.Context;
import androidx.preference.Preference; import androidx.preference.Preference;
import android.text.TextUtils;
import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.view.RotationPolicy; import com.android.internal.view.RotationPolicy;
@@ -71,7 +72,12 @@ public class AutoRotatePreferenceController extends TogglePreferenceController i
@Override @Override
public int getAvailabilityStatus() { public int getAvailabilityStatus() {
return RotationPolicy.isRotationLockToggleVisible(mContext) return RotationPolicy.isRotationLockToggleVisible(mContext)
? AVAILABLE : CONDITIONALLY_UNAVAILABLE; ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "auto_rotate");
} }
@Override @Override

View File

@@ -19,6 +19,7 @@ package com.android.settings.display;
import android.content.Context; import android.content.Context;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.Button; import android.widget.Button;
@@ -53,6 +54,11 @@ public class NightDisplayActivationPreferenceController extends TogglePreference
return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; return ColorDisplayController.isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "night_display_activated");
}
@Override @Override
public void displayPreference(PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);

View File

@@ -16,9 +16,12 @@
package com.android.settings.display; package com.android.settings.display;
import android.content.Context;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import android.content.Context;
import android.text.TextUtils;
import com.android.internal.app.ColorDisplayController; import com.android.internal.app.ColorDisplayController;
import com.android.settings.core.SliderPreferenceController; import com.android.settings.core.SliderPreferenceController;
import com.android.settings.widget.SeekBarPreference; import com.android.settings.widget.SeekBarPreference;
@@ -42,6 +45,11 @@ public class NightDisplayIntensityPreferenceController extends SliderPreferenceC
return AVAILABLE; return AVAILABLE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "night_display_temperature");
}
@Override @Override
public void displayPreference(PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);

View File

@@ -23,6 +23,7 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.provider.Settings; import android.provider.Settings;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import android.text.TextUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.search.DatabaseIndexingUtils; import com.android.settings.search.DatabaseIndexingUtils;
@@ -61,6 +62,11 @@ public class DoubleTapPowerPreferenceController extends GesturePreferenceControl
return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "gesture_double_tap_power");
}
@Override @Override
protected String getVideoPrefKey() { protected String getVideoPrefKey() {
return PREF_KEY_VIDEO; return PREF_KEY_VIDEO;

View File

@@ -90,6 +90,11 @@ public class DoubleTapScreenPreferenceController extends GesturePreferenceContro
return AVAILABLE; return AVAILABLE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "gesture_double_tap_screen");
}
@Override @Override
public boolean setChecked(boolean isChecked) { public boolean setChecked(boolean isChecked) {
return Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY, return Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY,

View File

@@ -71,6 +71,11 @@ public class DoubleTwistPreferenceController extends GesturePreferenceController
return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "gesture_double_twist");
}
@Override @Override
protected String getVideoPrefKey() { protected String getVideoPrefKey() {
return PREF_KEY_VIDEO; return PREF_KEY_VIDEO;

View File

@@ -83,6 +83,11 @@ public class PickupGesturePreferenceController extends GesturePreferenceControll
return AVAILABLE; return AVAILABLE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "gesture_pick_up");
}
@Override @Override
protected String getVideoPrefKey() { protected String getVideoPrefKey() {
return PREF_KEY_VIDEO; return PREF_KEY_VIDEO;

View File

@@ -21,6 +21,7 @@ import static android.provider.Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import com.android.settings.Utils; import com.android.settings.Utils;
@@ -59,6 +60,11 @@ public class SwipeToNotificationPreferenceController extends GesturePreferenceCo
return isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; return isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "gesture_swipe_down_fingerprint");
}
@Override @Override
public boolean setChecked(boolean isChecked) { public boolean setChecked(boolean isChecked) {
setSwipeToNotification(mContext, isChecked); setSwipeToNotification(mContext, isChecked);

View File

@@ -22,6 +22,7 @@ import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.UserManager; import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import com.android.internal.R; import com.android.internal.R;
@@ -60,6 +61,11 @@ public class SwipeUpPreferenceController extends GesturePreferenceController {
return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "gesture_swipe_up");
}
@Override @Override
protected String getVideoPrefKey() { protected String getVideoPrefKey() {
return PREF_KEY_VIDEO; return PREF_KEY_VIDEO;

View File

@@ -23,6 +23,7 @@ import android.os.SystemProperties;
import androidx.preference.SwitchPreference; import androidx.preference.SwitchPreference;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import android.text.TextUtils;
import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.TelephonyProperties;
@@ -90,6 +91,11 @@ public class AirplaneModePreferenceController extends TogglePreferenceController
&& !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK); && !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "toggle_airplane");
}
@Override @Override
@AvailabilityStatus @AvailabilityStatus
public int getAvailabilityStatus() { public int getAvailabilityStatus() {

View File

@@ -28,10 +28,10 @@ import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.preference.TwoStatePreference; import androidx.preference.TwoStatePreference;
import android.text.TextUtils;
import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.TogglePreferenceController; import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.search.DatabaseIndexingUtils; import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settings.search.InlineSwitchPayload; import com.android.settings.search.InlineSwitchPayload;
@@ -88,6 +88,11 @@ public class BadgingNotificationPreferenceController extends TogglePreferenceCon
? AVAILABLE : UNSUPPORTED_ON_DEVICE; ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "notification_badging");
}
@Override @Override
public boolean isChecked() { public boolean isChecked() {
return Settings.Secure.getInt(mContext.getContentResolver(), return Settings.Secure.getInt(mContext.getContentResolver(),

View File

@@ -18,6 +18,7 @@ package com.android.settings.notification;
import android.content.Context; import android.content.Context;
import android.media.AudioManager; import android.media.AudioManager;
import android.text.TextUtils;
import com.android.settings.R; import com.android.settings.R;
@@ -37,6 +38,11 @@ public class CallVolumePreferenceController extends VolumeSeekBarPreferenceContr
&& !mHelper.isSingleVolume() ? AVAILABLE : UNSUPPORTED_ON_DEVICE; && !mHelper.isSingleVolume() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "call_volume");
}
@Override @Override
public int getAudioStream() { public int getAudioStream() {
if (mAudioManager.isBluetoothScoOn()) { if (mAudioManager.isBluetoothScoOn()) {

View File

@@ -18,6 +18,7 @@ package com.android.settings.notification;
import android.content.Context; import android.content.Context;
import android.media.AudioManager; import android.media.AudioManager;
import android.text.TextUtils;
import com.android.settings.R; import com.android.settings.R;
@@ -37,6 +38,11 @@ public class MediaVolumePreferenceController extends
: UNSUPPORTED_ON_DEVICE; : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), KEY_MEDIA_VOLUME);
}
@Override @Override
public String getPreferenceKey() { public String getPreferenceKey() {
return KEY_MEDIA_VOLUME; return KEY_MEDIA_VOLUME;

View File

@@ -18,6 +18,7 @@ package com.android.settings.notification;
import android.content.Context; import android.content.Context;
import android.media.AudioManager; import android.media.AudioManager;
import android.text.TextUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
@@ -38,6 +39,11 @@ public class NotificationVolumePreferenceController extends
? AVAILABLE : UNSUPPORTED_ON_DEVICE; ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), KEY_NOTIFICATION_VOLUME);
}
@Override @Override
public String getPreferenceKey() { public String getPreferenceKey() {
return KEY_NOTIFICATION_VOLUME; return KEY_NOTIFICATION_VOLUME;

View File

@@ -29,6 +29,7 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.Vibrator; import android.os.Vibrator;
import android.text.TextUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
@@ -89,6 +90,11 @@ public class RingVolumePreferenceController extends VolumeSeekBarPreferenceContr
? AVAILABLE : UNSUPPORTED_ON_DEVICE; ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), KEY_RING_VOLUME);
}
@Override @Override
public int getAudioStream() { public int getAudioStream() {
return AudioManager.STREAM_RING; return AudioManager.STREAM_RING;

View File

@@ -24,6 +24,8 @@ import android.database.ContentObserver;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
@@ -63,6 +65,11 @@ public class VibrateWhenRingPreferenceController extends TogglePreferenceControl
return Utils.isVoiceCapable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; return Utils.isVoiceCapable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override
public boolean isSliceable() {
return TextUtils.equals(getPreferenceKey(), "vibrate_when_ringing");
}
@Override @Override
public void displayPreference(PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);

View File

@@ -23,9 +23,11 @@ import android.content.ContentResolver;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.Uri; import android.net.Uri;
import android.provider.Settings;
import android.provider.SettingsSlicesContract; import android.provider.SettingsSlicesContract;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.KeyValueListParser;
import android.util.Log; import android.util.Log;
import android.util.Pair; import android.util.Pair;
@@ -42,6 +44,7 @@ import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -115,10 +118,13 @@ public class SettingsSliceProvider extends SliceProvider {
@VisibleForTesting @VisibleForTesting
Map<Uri, SliceData> mSliceDataCache; Map<Uri, SliceData> mSliceDataCache;
private final KeyValueListParser mParser;
final Set<Uri> mRegisteredUris = new ArraySet<>(); final Set<Uri> mRegisteredUris = new ArraySet<>();
public SettingsSliceProvider() { public SettingsSliceProvider() {
super(READ_SEARCH_INDEXABLES); super(READ_SEARCH_INDEXABLES);
mParser = new KeyValueListParser(',');
} }
@Override @Override
@@ -352,4 +358,32 @@ public class SettingsSliceProvider extends SliceProvider {
SliceBroadcastRelay.registerReceiver(getContext(), sliceUri, SliceBroadcastReceiver.class, SliceBroadcastRelay.registerReceiver(getContext(), sliceUri, SliceBroadcastReceiver.class,
intentFilter); intentFilter);
} }
@VisibleForTesting
Set<String> getBlockedKeys() {
final String value = Settings.Global.getString(getContext().getContentResolver(),
Settings.Global.BLOCKED_SLICES);
final Set<String> set = new ArraySet<>();
try {
mParser.setString(value);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Bad Settings Slices Whitelist flags", e);
return set;
}
final String[] parsedValues = parseStringArray(value);
Collections.addAll(set, parsedValues);
return set;
}
private String[] parseStringArray(String value) {
if (value != null) {
String[] parts = value.split(":");
if (parts.length > 0) {
return parts;
}
}
return new String[0];
}
} }

View File

@@ -19,7 +19,6 @@ package com.android.settings.slices;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_CONTROLLER; import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_CONTROLLER;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_ICON; import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_ICON;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY; import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEYWORDS;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_PLATFORM_SLICE_FLAG; import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_PLATFORM_SLICE_FLAG;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_SUMMARY; import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_SUMMARY;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_TITLE; import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_TITLE;
@@ -44,6 +43,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilitySettings; import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.accessibility.AccessibilitySlicePreferenceController; import com.android.settings.accessibility.AccessibilitySlicePreferenceController;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceXmlParserUtils; import com.android.settings.core.PreferenceXmlParserUtils;
import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag; import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
@@ -194,6 +194,7 @@ class SliceDataConverter {
if (TextUtils.isEmpty(controllerClassName)) { if (TextUtils.isEmpty(controllerClassName)) {
continue; continue;
} }
final String key = bundle.getString(METADATA_KEY); final String key = bundle.getString(METADATA_KEY);
final String title = bundle.getString(METADATA_TITLE); final String title = bundle.getString(METADATA_TITLE);
final String summary = bundle.getString(METADATA_SUMMARY); final String summary = bundle.getString(METADATA_SUMMARY);
@@ -214,8 +215,14 @@ class SliceDataConverter {
.setPlatformDefined(isPlatformSlice) .setPlatformDefined(isPlatformSlice)
.build(); .build();
final BasePreferenceController controller =
SliceBuilderUtils.getPreferenceController(mContext, xmlSlice);
// Only add pre-approved Slices available on the device.
if (controller.isAvailable() && controller.isSliceable()) {
xmlSliceData.add(xmlSlice); xmlSliceData.add(xmlSlice);
} }
}
} catch (SliceData.InvalidSliceDataException e) { } catch (SliceData.InvalidSliceDataException e) {
Log.w(TAG, "Invalid data when building SliceData for " + fragmentName, e); Log.w(TAG, "Invalid data when building SliceData for " + fragmentName, e);
} catch (XmlPullParserException e) { } catch (XmlPullParserException e) {

View File

@@ -150,4 +150,19 @@ public class AmbientDisplayAlwaysOnPreferenceControllerTest {
assertThat(newValue).isEqualTo(currentValue); assertThat(newValue).isEqualTo(currentValue);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final AmbientDisplayAlwaysOnPreferenceController controller =
new AmbientDisplayAlwaysOnPreferenceController(mContext,
"ambient_display_always_on");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final AmbientDisplayAlwaysOnPreferenceController controller =
new AmbientDisplayAlwaysOnPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -182,4 +182,19 @@ public class AmbientDisplayNotificationsPreferenceControllerTest {
assertThat(newValue).isEqualTo(currentValue); assertThat(newValue).isEqualTo(currentValue);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final AmbientDisplayNotificationsPreferenceController controller =
new AmbientDisplayNotificationsPreferenceController(mContext,
"ambient_display_notification");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final AmbientDisplayNotificationsPreferenceController controller =
new AmbientDisplayNotificationsPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -93,4 +93,19 @@ public class AutoBrightnessPreferenceControllerTest {
assertThat(newValue).isEqualTo(SCREEN_BRIGHTNESS_MODE_AUTOMATIC); assertThat(newValue).isEqualTo(SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final AutoBrightnessPreferenceController controller =
new AutoBrightnessPreferenceController(mContext,
"auto_brightness");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final AutoBrightnessPreferenceController controller =
new AutoBrightnessPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -104,7 +104,7 @@ public class AutoRotatePreferenceControllerTest {
@Test @Test
public void testGetAvailabilityStatus() { public void testGetAvailabilityStatus() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController
.CONDITIONALLY_UNAVAILABLE); .UNSUPPORTED_ON_DEVICE);
enableAutoRotationPreference(); enableAutoRotationPreference();
@@ -114,7 +114,7 @@ public class AutoRotatePreferenceControllerTest {
disableAutoRotationPreference(); disableAutoRotationPreference();
assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController
.CONDITIONALLY_UNAVAILABLE); .UNSUPPORTED_ON_DEVICE);
} }
@Test @Test
@@ -144,6 +144,20 @@ public class AutoRotatePreferenceControllerTest {
assertThat(RotationPolicy.isRotationLocked(mContext)).isFalse(); assertThat(RotationPolicy.isRotationLocked(mContext)).isFalse();
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final AutoRotatePreferenceController controller =
new AutoRotatePreferenceController(mContext, "auto_rotate");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final AutoRotatePreferenceController controller =
new AutoRotatePreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
private void enableAutoRotationPreference() { private void enableAutoRotationPreference() {
when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true); when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true);
when(mContext.getResources().getBoolean(anyInt())).thenReturn(true); when(mContext.getResources().getBoolean(anyInt())).thenReturn(true);

View File

@@ -72,6 +72,20 @@ public class NightDisplayActivationPreferenceControllerTest {
assertThat(mController.isAvailable()).isFalse(); assertThat(mController.isAvailable()).isFalse();
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final NightDisplayActivationPreferenceController controller =
new NightDisplayActivationPreferenceController(mContext,"night_display_activated");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final NightDisplayActivationPreferenceController controller =
new NightDisplayActivationPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
@Test @Test
public void onClick_activates() { public void onClick_activates() {
Secure.putInt(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_ACTIVATED, 0); Secure.putInt(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_ACTIVATED, 0);

View File

@@ -76,4 +76,18 @@ public class NightDisplayIntensityPreferenceControllerTest {
Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, -1)) Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, -1))
.isEqualTo(3030); .isEqualTo(3030);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final NightDisplayIntensityPreferenceController controller =
new NightDisplayIntensityPreferenceController(mContext,"night_display_temperature");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final NightDisplayIntensityPreferenceController controller =
new NightDisplayIntensityPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -17,10 +17,13 @@
package com.android.settings.gestures; package com.android.settings.gestures;
import static android.provider.Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED; import static android.provider.Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED;
import static com.android.settings.gestures.DoubleTapPowerPreferenceController.OFF; import static com.android.settings.gestures.DoubleTapPowerPreferenceController.OFF;
import static com.android.settings.gestures.DoubleTapPowerPreferenceController.ON; import static com.android.settings.gestures.DoubleTapPowerPreferenceController.ON;
import static com.android.settings.gestures.DoubleTapPowerPreferenceController.isSuggestionComplete; import static com.android.settings.gestures.DoubleTapPowerPreferenceController.isSuggestionComplete;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.ContentResolver; import android.content.ContentResolver;
@@ -29,6 +32,7 @@ import android.content.SharedPreferences;
import android.provider.Settings; import android.provider.Settings;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl; import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController;
import com.android.settings.search.InlinePayload; import com.android.settings.search.InlinePayload;
import com.android.settings.search.InlineSwitchPayload; import com.android.settings.search.InlineSwitchPayload;
import com.android.settings.search.ResultPayload; import com.android.settings.search.ResultPayload;
@@ -67,7 +71,8 @@ public class DoubleTapPowerPreferenceControllerTest {
@Test @Test
public void isAvailable_configIsTrue_shouldReturnTrue() { public void isAvailable_configIsTrue_shouldReturnTrue() {
SettingsShadowResources.overrideResource( SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled, Boolean.TRUE); com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled,
Boolean.TRUE);
assertThat(mController.isAvailable()).isTrue(); assertThat(mController.isAvailable()).isTrue();
} }
@@ -75,7 +80,8 @@ public class DoubleTapPowerPreferenceControllerTest {
@Test @Test
public void isAvailable_configIsTrue_shouldReturnFalse() { public void isAvailable_configIsTrue_shouldReturnFalse() {
SettingsShadowResources.overrideResource( SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled, Boolean.FALSE); com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled,
Boolean.FALSE);
assertThat(mController.isAvailable()).isFalse(); assertThat(mController.isAvailable()).isFalse();
} }
@@ -163,4 +169,18 @@ public class DoubleTapPowerPreferenceControllerTest {
assertThat(isSuggestionComplete(mContext, prefs)).isTrue(); assertThat(isSuggestionComplete(mContext, prefs)).isTrue();
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final DoubleTapPowerPreferenceController controller =
new DoubleTapPowerPreferenceController(mContext, "gesture_double_tap_power");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final DoubleTapPowerPreferenceController controller =
new DoubleTapPowerPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -178,5 +178,20 @@ public class DoubleTapScreenPreferenceControllerTest {
final int availabilityStatus = mController.getAvailabilityStatus(); final int availabilityStatus = mController.getAvailabilityStatus();
assertThat(availabilityStatus).isEqualTo(AVAILABLE); assertThat(availabilityStatus).isEqualTo(AVAILABLE);
}
@Test
public void isSliceableCorrectKey_returnsTrue() {
final DoubleTapScreenPreferenceController controller =
new DoubleTapScreenPreferenceController(mContext,"gesture_double_tap_screen");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final DoubleTapScreenPreferenceController controller =
new DoubleTapScreenPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
} }
} }

View File

@@ -155,4 +155,18 @@ public class DoubleTwistPreferenceControllerTest {
assertThat(mController.isChecked()).isFalse(); assertThat(mController.isChecked()).isFalse();
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final DoubleTwistPreferenceController controller =
new DoubleTwistPreferenceController(mContext,"gesture_double_twist");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final DoubleTwistPreferenceController controller =
new DoubleTwistPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -170,4 +170,18 @@ public class PickupGesturePreferenceControllerTest {
assertThat(availabilityStatus).isEqualTo(AVAILABLE); assertThat(availabilityStatus).isEqualTo(AVAILABLE);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final PickupGesturePreferenceController controller =
new PickupGesturePreferenceController(mContext,"gesture_pick_up");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final PickupGesturePreferenceController controller =
new PickupGesturePreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -168,4 +168,18 @@ public class SwipeToNotificationPreferenceControllerTest {
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
.thenReturn(enabled); .thenReturn(enabled);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final SwipeToNotificationPreferenceController controller = new
SwipeToNotificationPreferenceController(mContext,"gesture_swipe_down_fingerprint");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final SwipeToNotificationPreferenceController controller =
new SwipeToNotificationPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -123,4 +123,18 @@ public class SwipeUpPreferenceControllerTest {
mController.setChecked(false); mController.setChecked(false);
assertThat(mController.isChecked()).isFalse(); assertThat(mController.isChecked()).isFalse();
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final SwipeUpPreferenceController controller =
new SwipeUpPreferenceController(mContext,"gesture_swipe_up");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final SwipeUpPreferenceController controller =
new SwipeUpPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -177,4 +177,18 @@ public class AirplaneModePreferenceControllerTest {
assertThat(mPreference.isChecked()).isTrue(); assertThat(mPreference.isChecked()).isTrue();
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final AirplaneModePreferenceController controller =
new AirplaneModePreferenceController(mContext,"toggle_airplane");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final AirplaneModePreferenceController controller =
new AirplaneModePreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -183,4 +183,19 @@ public class BadgingNotificationPreferenceControllerTest {
assertThat(updatedValue).isEqualTo(ON); assertThat(updatedValue).isEqualTo(ON);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final BadgingNotificationPreferenceController controller =
new BadgingNotificationPreferenceController(mContext,
"notification_badging");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final BadgingNotificationPreferenceController controller =
new BadgingNotificationPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -92,4 +92,18 @@ public class CallVolumePreferenceControllerTest {
assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_BLUETOOTH_SCO); assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_BLUETOOTH_SCO);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final CallVolumePreferenceController controller =
new CallVolumePreferenceController(mContext,"call_volume");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final CallVolumePreferenceController controller =
new CallVolumePreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -18,6 +18,7 @@ package com.android.settings.notification;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.media.AudioManager; import android.media.AudioManager;
import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -33,9 +34,12 @@ public class MediaVolumePreferenceControllerTest {
private MediaVolumePreferenceController mController; private MediaVolumePreferenceController mController;
private Context mContext;
@Before @Before
public void setUp() { public void setUp() {
mController = new MediaVolumePreferenceController(RuntimeEnvironment.application); mContext = RuntimeEnvironment.application;
mController = new MediaVolumePreferenceController(mContext);
} }
@Test @Test
@@ -53,4 +57,11 @@ public class MediaVolumePreferenceControllerTest {
public void getAudioStream_shouldReturnMusic() { public void getAudioStream_shouldReturnMusic() {
assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_MUSIC); assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_MUSIC);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final MediaVolumePreferenceController controller = new MediaVolumePreferenceController(
mContext);
assertThat(controller.isSliceable()).isTrue();
}
} }

View File

@@ -95,4 +95,11 @@ public class NotificationVolumePreferenceControllerTest {
public void getAudioStream_shouldReturnNotification() { public void getAudioStream_shouldReturnNotification() {
assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_NOTIFICATION); assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_NOTIFICATION);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final NotificationVolumePreferenceController controller =
new NotificationVolumePreferenceController(mContext);
assertThat(controller.isSliceable()).isTrue();
}
} }

View File

@@ -97,4 +97,11 @@ public class RingVolumePreferenceControllerTest {
public void getAudioStream_shouldReturnRing() { public void getAudioStream_shouldReturnRing() {
assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_RING); assertThat(mController.getAudioStream()).isEqualTo(AudioManager.STREAM_RING);
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final RingVolumePreferenceController controller =
new RingVolumePreferenceController(mContext);
assertThat(controller.isSliceable()).isTrue();
}
} }

View File

@@ -183,4 +183,18 @@ public class VibrateWhenRingPreferenceControllerTest {
assertThat(shadowContentResolver.getContentObservers( assertThat(shadowContentResolver.getContentObservers(
Settings.System.getUriFor(VIBRATE_WHEN_RINGING))).isEmpty(); Settings.System.getUriFor(VIBRATE_WHEN_RINGING))).isEmpty();
} }
@Test
public void isSliceableCorrectKey_returnsTrue() {
final VibrateWhenRingPreferenceController controller =
new VibrateWhenRingPreferenceController(mContext, "vibrate_when_ringing");
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
final VibrateWhenRingPreferenceController controller =
new VibrateWhenRingPreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
} }

View File

@@ -35,4 +35,9 @@ public class FakePreferenceController extends BasePreferenceController {
public int getSliceType() { public int getSliceType() {
return SliceData.SliceType.SLIDER; return SliceData.SliceType.SLIDER;
} }
@Override
public boolean isSliceable() {
return true;
}
} }

View File

@@ -70,6 +70,11 @@ public class SlicesDatabaseAccessorTest {
mAccessor = spy(new SlicesDatabaseAccessor(mContext)); mAccessor = spy(new SlicesDatabaseAccessor(mContext));
mDb = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase(); mDb = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase();
SlicesDatabaseHelper.getInstance(mContext).setIndexedState(); SlicesDatabaseHelper.getInstance(mContext).setIndexedState();
// Register the fake a11y Service
ShadowAccessibilityManager shadowAccessibilityManager = Shadow.extract(
RuntimeEnvironment.application.getSystemService(AccessibilityManager.class));
shadowAccessibilityManager.setInstalledAccessibilityServiceList(new ArrayList<>());
} }
@After @After
@@ -173,10 +178,6 @@ public class SlicesDatabaseAccessorTest {
public void getSliceKeys_indexesDatabase() { public void getSliceKeys_indexesDatabase() {
// Force new indexing // Force new indexing
Locale.setDefault(new Locale("ca")); Locale.setDefault(new Locale("ca"));
// Register the fake a11y Service
ShadowAccessibilityManager shadowAccessibilityManager = Shadow.extract(
RuntimeEnvironment.application.getSystemService(AccessibilityManager.class));
shadowAccessibilityManager.setInstalledAccessibilityServiceList(new ArrayList<>());
final SearchFeatureProvider provider = new SearchFeatureProviderImpl(); final SearchFeatureProvider provider = new SearchFeatureProviderImpl();
final SlicesFeatureProvider sliceProvider = spy(new SlicesFeatureProviderImpl()); final SlicesFeatureProvider sliceProvider = spy(new SlicesFeatureProviderImpl());
final FakeFeatureFactory factory = FakeFeatureFactory.setupForTest(); final FakeFeatureFactory factory = FakeFeatureFactory.setupForTest();

View File

@@ -53,4 +53,9 @@ public class FakeSliderController extends SliderPreferenceController {
return Settings.Global.getInt(mContext.getContentResolver(), return Settings.Global.getInt(mContext.getContentResolver(),
AVAILABILITY_KEY, AVAILABLE); AVAILABILITY_KEY, AVAILABLE);
} }
@Override
public boolean isSliceable() {
return true;
}
} }

View File

@@ -62,4 +62,9 @@ public class FakeToggleController extends TogglePreferenceController {
public IntentFilter getIntentFilter() { public IntentFilter getIntentFilter() {
return INTENT_FILTER; return INTENT_FILTER;
} }
@Override
public boolean isSliceable() {
return true;
}
} }

View File

@@ -18,4 +18,9 @@ public class FakeUnavailablePreferenceController extends BasePreferenceControlle
return Settings.Global.getInt(mContext.getContentResolver(), return Settings.Global.getInt(mContext.getContentResolver(),
AVAILABILITY_KEY, 0); AVAILABILITY_KEY, 0);
} }
@Override
public boolean isSliceable() {
return true;
}
} }