Remove duplicates between battery and display settings

Change preference keys of duplicate settings between
display and battery to avoid duplication in search.

Bug: 33701673
Test: make RunSettingsRoboTests
Change-Id: I56c82e9e7f163d345065ca478849de9b14c173fe
This commit is contained in:
Matthew Fritze
2017-04-11 13:22:40 -07:00
parent 7cfaa8ceb2
commit c6f2638009
14 changed files with 280 additions and 23 deletions

View File

@@ -46,7 +46,7 @@
<com.android.settings.widget.MasterSwitchPreference <com.android.settings.widget.MasterSwitchPreference
android:fragment="com.android.settings.fuelgauge.BatterySaverSettings" android:fragment="com.android.settings.fuelgauge.BatterySaverSettings"
android:key="battery_saver" android:key="battery_saver_summary"
android:title="@string/battery_saver"/> android:title="@string/battery_saver"/>
<SwitchPreference <SwitchPreference
@@ -56,14 +56,14 @@
<!-- Cross-listed item, if you change this, also change it in ia_display_settings.xml --> <!-- Cross-listed item, if you change this, also change it in ia_display_settings.xml -->
<SwitchPreference <SwitchPreference
android:key="auto_brightness" android:key="auto_brightness_battery"
android:title="@string/auto_brightness_title" android:title="@string/auto_brightness_title"
android:summary="@string/auto_brightness_summary" android:summary="@string/auto_brightness_summary"
settings:keywords="@string/keywords_display_auto_brightness"/> settings:keywords="@string/keywords_display_auto_brightness"/>
<!-- Cross-listed item, if you change this, also change it in ia_display_settings.xml --> <!-- Cross-listed item, if you change this, also change it in ia_display_settings.xml -->
<com.android.settings.TimeoutListPreference <com.android.settings.TimeoutListPreference
android:key="screen_timeout" android:key="screen_timeout_battery"
android:title="@string/screen_timeout" android:title="@string/screen_timeout"
android:summary="@string/screen_timeout_summary" android:summary="@string/screen_timeout_summary"
android:entries="@array/screen_timeout_entries" android:entries="@array/screen_timeout_entries"

View File

@@ -51,6 +51,9 @@ import java.util.List;
public class DisplaySettings extends DashboardFragment { public class DisplaySettings extends DashboardFragment {
private static final String TAG = "DisplaySettings"; private static final String TAG = "DisplaySettings";
public static final String KEY_AUTO_BRIGHTNESS = "auto_brightness";
private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return MetricsEvent.DISPLAY; return MetricsEvent.DISPLAY;
@@ -85,7 +88,7 @@ public class DisplaySettings extends DashboardFragment {
private static List<PreferenceController> buildPreferenceControllers( private static List<PreferenceController> buildPreferenceControllers(
Context context, Lifecycle lifecycle) { Context context, Lifecycle lifecycle) {
final List<PreferenceController> controllers = new ArrayList<>(); final List<PreferenceController> controllers = new ArrayList<>();
controllers.add(new AutoBrightnessPreferenceController(context)); controllers.add(new AutoBrightnessPreferenceController(context, KEY_AUTO_BRIGHTNESS));
controllers.add(new AutoRotatePreferenceController(context)); controllers.add(new AutoRotatePreferenceController(context));
controllers.add(new CameraGesturePreferenceController(context)); controllers.add(new CameraGesturePreferenceController(context));
controllers.add(new DozePreferenceController(context)); controllers.add(new DozePreferenceController(context));
@@ -100,7 +103,7 @@ public class DisplaySettings extends DashboardFragment {
controllers.add(new DoubleTapScreenPreferenceController( controllers.add(new DoubleTapScreenPreferenceController(
context, lifecycle, ambientDisplayConfig, UserHandle.myUserId())); context, lifecycle, ambientDisplayConfig, UserHandle.myUserId()));
controllers.add(new TapToWakePreferenceController(context)); controllers.add(new TapToWakePreferenceController(context));
controllers.add(new TimeoutPreferenceController(context)); controllers.add(new TimeoutPreferenceController(context, KEY_SCREEN_TIMEOUT));
controllers.add(new VrDisplayPreferenceController(context)); controllers.add(new VrDisplayPreferenceController(context));
controllers.add(new WallpaperPreferenceController(context)); controllers.add(new WallpaperPreferenceController(context));
controllers.add(new ThemePreferenceController(context)); controllers.add(new ThemePreferenceController(context));

View File

@@ -36,10 +36,11 @@ import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
public class AutoBrightnessPreferenceController extends PreferenceController implements public class AutoBrightnessPreferenceController extends PreferenceController implements
Preference.OnPreferenceChangeListener { Preference.OnPreferenceChangeListener {
private static final String KEY_AUTO_BRIGHTNESS = "auto_brightness"; private final String mAutoBrightnessKey;
public AutoBrightnessPreferenceController(Context context) { public AutoBrightnessPreferenceController(Context context, String key) {
super(context); super(context);
mAutoBrightnessKey = key;
} }
@Override @Override
@@ -50,7 +51,7 @@ public class AutoBrightnessPreferenceController extends PreferenceController imp
@Override @Override
public String getPreferenceKey() { public String getPreferenceKey() {
return KEY_AUTO_BRIGHTNESS; return mAutoBrightnessKey;
} }
@Override @Override
@@ -75,7 +76,7 @@ public class AutoBrightnessPreferenceController extends PreferenceController imp
valueMap.put(SCREEN_BRIGHTNESS_MODE_MANUAL, false); valueMap.put(SCREEN_BRIGHTNESS_MODE_MANUAL, false);
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
getClass().getName(), KEY_AUTO_BRIGHTNESS, getClass().getName(), mAutoBrightnessKey,
mContext.getString(R.string.display_settings)); mContext.getString(R.string.display_settings));
return new InlineSwitchPayload(SCREEN_BRIGHTNESS_MODE, return new InlineSwitchPayload(SCREEN_BRIGHTNESS_MODE,

View File

@@ -35,10 +35,11 @@ public class TimeoutPreferenceController extends PreferenceController implements
/** If there is no setting in the provider, use this. */ /** If there is no setting in the provider, use this. */
public static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000; public static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000;
private static final String KEY_SCREEN_TIMEOUT = "screen_timeout"; private final String mScreenTimeoutKey;
public TimeoutPreferenceController(Context context) { public TimeoutPreferenceController(Context context, String key) {
super(context); super(context);
mScreenTimeoutKey = key;
} }
@Override @Override
@@ -48,7 +49,7 @@ public class TimeoutPreferenceController extends PreferenceController implements
@Override @Override
public String getPreferenceKey() { public String getPreferenceKey() {
return KEY_SCREEN_TIMEOUT; return mScreenTimeoutKey;
} }
@Override @Override

View File

@@ -43,7 +43,7 @@ import static android.os.PowerManager.ACTION_POWER_SAVE_MODE_CHANGING;
public class BatterySaverController extends PreferenceController implements public class BatterySaverController extends PreferenceController implements
Preference.OnPreferenceChangeListener, LifecycleObserver, OnStart, OnStop { Preference.OnPreferenceChangeListener, LifecycleObserver, OnStart, OnStop {
private static final String KEY_BATTERY_SAVER = "battery_saver"; private static final String KEY_BATTERY_SAVER = "battery_saver_summary";
private static final String TAG = "BatterySaverController"; private static final String TAG = "BatterySaverController";
private static final boolean DEBUG = false; private static final boolean DEBUG = false;

View File

@@ -86,6 +86,9 @@ public class PowerUsageSummary extends PowerUsageBase {
private static final String KEY_SCREEN_USAGE = "screen_usage"; private static final String KEY_SCREEN_USAGE = "screen_usage";
private static final String KEY_TIME_SINCE_LAST_FULL_CHARGE = "last_full_charge"; private static final String KEY_TIME_SINCE_LAST_FULL_CHARGE = "last_full_charge";
private static final String KEY_AUTO_BRIGHTNESS = "auto_brightness_battery";
private static final String KEY_SCREEN_TIMEOUT = "screen_timeout_battery";
private static final String KEY_BATTERY_SAVER_SUMMARY = "battery_saver_summary";
private static final int MENU_STATS_TYPE = Menu.FIRST; private static final int MENU_STATS_TYPE = Menu.FIRST;
@VisibleForTesting @VisibleForTesting
@@ -185,8 +188,8 @@ public class PowerUsageSummary extends PowerUsageBase {
@Override @Override
protected List<PreferenceController> getPreferenceControllers(Context context) { protected List<PreferenceController> getPreferenceControllers(Context context) {
final List<PreferenceController> controllers = new ArrayList<>(); final List<PreferenceController> controllers = new ArrayList<>();
controllers.add(new AutoBrightnessPreferenceController(context)); controllers.add(new AutoBrightnessPreferenceController(context, KEY_AUTO_BRIGHTNESS));
controllers.add(new TimeoutPreferenceController(context)); controllers.add(new TimeoutPreferenceController(context, KEY_SCREEN_TIMEOUT));
controllers.add(new BatterySaverController(context, getLifecycle())); controllers.add(new BatterySaverController(context, getLifecycle()));
controllers.add(new BatteryPercentagePreferenceController(context)); controllers.add(new BatteryPercentagePreferenceController(context));
return controllers; return controllers;
@@ -712,6 +715,16 @@ public class PowerUsageSummary extends PowerUsageBase {
sir.xmlResId = R.xml.power_usage_summary; sir.xmlResId = R.xml.power_usage_summary;
return Arrays.asList(sir); return Arrays.asList(sir);
} }
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> niks = new ArrayList<>();
// Duplicates in display
niks.add(KEY_AUTO_BRIGHTNESS);
niks.add(KEY_SCREEN_TIMEOUT);
niks.add(KEY_BATTERY_SAVER_SUMMARY);
return niks;
}
}; };
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY

View File

@@ -0,0 +1,12 @@
dashboard_tile_placeholder
gesture_pick_up
add_users_when_locked
additional_system_update_settings
gesture_assist
screen_zoom
gesture_swipe_down_fingerprint
gesture_double_twist
lock_screen_notifications
gesture_double_tap_power
gesture_double_tap_screen
usage_access

View File

@@ -70,7 +70,7 @@ public abstract class CodeInspector {
return true; return true;
} }
protected void initializeGrandfatherList(List<String> grandfather, String filename) { public static void initializeGrandfatherList(List<String> grandfather, String filename) {
try { try {
final InputStream in = ShadowApplication.getInstance().getApplicationContext() final InputStream in = ShadowApplication.getInstance().getApplicationContext()
.getAssets() .getAssets()

View File

@@ -43,12 +43,13 @@ public class AutoBrightnessPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS) @Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext; private Context mContext;
private AutoBrightnessPreferenceController mController; private AutoBrightnessPreferenceController mController;
private final String PREFERENCE_KEY = "auto_brightness";
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mController = new AutoBrightnessPreferenceController(mContext); mController = new AutoBrightnessPreferenceController(mContext, PREFERENCE_KEY);
} }
@Test @Test
@@ -72,7 +73,7 @@ public class AutoBrightnessPreferenceControllerTest {
@Test @Test
public void testPreferenceController_ProperResultPayloadType() { public void testPreferenceController_ProperResultPayloadType() {
final Context context = ShadowApplication.getInstance().getApplicationContext(); final Context context = ShadowApplication.getInstance().getApplicationContext();
mController = new AutoBrightnessPreferenceController(context); mController = new AutoBrightnessPreferenceController(context, PREFERENCE_KEY);
ResultPayload payload = mController.getResultPayload(); ResultPayload payload = mController.getResultPayload();
assertThat(payload).isInstanceOf(InlineSwitchPayload.class); assertThat(payload).isInstanceOf(InlineSwitchPayload.class);
} }
@@ -80,7 +81,7 @@ public class AutoBrightnessPreferenceControllerTest {
@Test @Test
public void testPreferenceController_CorrectPayload() { public void testPreferenceController_CorrectPayload() {
final Context context = ShadowApplication.getInstance().getApplicationContext(); final Context context = ShadowApplication.getInstance().getApplicationContext();
mController = new AutoBrightnessPreferenceController(context); mController = new AutoBrightnessPreferenceController(context, PREFERENCE_KEY);
InlineSwitchPayload payload = (InlineSwitchPayload) mController.getResultPayload(); InlineSwitchPayload payload = (InlineSwitchPayload) mController.getResultPayload();
assertThat(payload.settingsUri).isEqualTo("screen_brightness_mode"); assertThat(payload.settingsUri).isEqualTo("screen_brightness_mode");
assertThat(payload.settingSource).isEqualTo(ResultPayload.SettingsSource.SYSTEM); assertThat(payload.settingSource).isEqualTo(ResultPayload.SettingsSource.SYSTEM);

View File

@@ -42,11 +42,13 @@ public class TimeoutPreferenceControllerTest {
private TimeoutListPreference mPreference; private TimeoutListPreference mPreference;
private TimeoutPreferenceController mController; private TimeoutPreferenceController mController;
private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mController = new TimeoutPreferenceController(mContext); mController = new TimeoutPreferenceController(mContext, KEY_SCREEN_TIMEOUT);
} }
@Test @Test

View File

@@ -36,9 +36,11 @@ import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.applications.LayoutPreference; import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.PreferenceController;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor; import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settingslib.BatteryInfo; import com.android.settingslib.BatteryInfo;
import org.junit.Before; import org.junit.Before;
@@ -423,6 +425,33 @@ public class PowerUsageSummaryTest {
TIME_SINCE_LAST_FULL_CHARGE_MS); TIME_SINCE_LAST_FULL_CHARGE_MS);
} }
@Test
public void testNonIndexableKeys_MatchPreferenceKeys() {
final Context context = RuntimeEnvironment.application;
final List<String> niks = PowerUsageSummary.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(context);
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context,
R.xml.power_usage_summary);
assertThat(keys).containsAllIn(niks);
}
@Test
public void testPreferenceControllers_getPreferenceKeys_existInPreferenceScreen() {
final Context context = RuntimeEnvironment.application;
final PowerUsageSummary fragment = new PowerUsageSummary();
final List<String> preferenceScreenKeys = XmlTestUtils.getKeysFromPreferenceXml(context,
fragment.getPreferenceScreenResId());
final List<String> preferenceKeys = new ArrayList<>();
for (PreferenceController controller : fragment.getPreferenceControllers(context)) {
preferenceKeys.add(controller.getPreferenceKey());
}
assertThat(preferenceScreenKeys).containsAllIn(preferenceKeys);
}
public static class TestFragment extends PowerUsageSummary { public static class TestFragment extends PowerUsageSummary {
private Context mContext; private Context mContext;

View File

@@ -0,0 +1,123 @@
package com.android.settings.search;
import android.content.Context;
import android.provider.SearchIndexableResource;
import android.util.ArraySet;
import com.android.settings.DateTimeSettings;
import com.android.settings.R;
import com.android.settings.SecuritySettings;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.core.codeinspection.CodeInspector;
import com.android.settings.datausage.DataUsageSummary;
import com.android.settings.search2.DatabaseIndexingUtils;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static com.google.common.truth.Truth.assertThat;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
assetDir = "/tests/robotests/assets")
public class DataIntegrityTest {
@Test
@Config(shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
})
public void testIndexableResources_uniqueKeys() {
final Context context = RuntimeEnvironment.application;
// Aggregation of all keys
final Set<String> masterKeys = new ArraySet<>();
// Aggregation of the incorrectly duplicate keys
final Set<String> duplicateKeys = new ArraySet<>();
// Keys for a specific page
final Set<String> pageKeys = new ArraySet<>();
// List of all Xml preferences
final Set<Integer> xmlList = new ArraySet<>();
// Duplicates we know about.
List<String> grandfatheredKeys = new ArrayList<>();
CodeInspector.initializeGrandfatherList(grandfatheredKeys,
"whitelist_duplicate_index_key");
// Get a list of all Xml.
for (SearchIndexableResource val : SearchIndexableResources.values()) {
final int xmlResId = val.xmlResId;
if (xmlResId != 0) {
xmlList.add(xmlResId);
} else {
// Take class and get all keys
final Class clazz = DatabaseIndexingUtils.getIndexableClass(val.className);
// Skip classes that are invalid or cannot be mocked. Add them as special Xml below.
if (clazz == null
|| clazz == DateTimeSettings.class
|| clazz == DataUsageSummary.class
|| clazz == SecuritySettings.class) {
continue;
}
Indexable.SearchIndexProvider provider = DatabaseIndexingUtils
.getSearchIndexProvider(clazz);
if (provider == null) {
continue;
}
List<SearchIndexableResource> subXml =
provider.getXmlResourcesToIndex(context, true);
if (subXml == null) {
continue;
}
for (SearchIndexableResource resource : subXml) {
final int subXmlResId = resource.xmlResId;
if (subXmlResId != 0) {
xmlList.add(subXmlResId);
}
}
}
}
addSpecialXml(xmlList);
// Get keys from all Xml and check for duplicates.
for (Integer xmlResId : xmlList) {
// Get all keys to be indexed
final List<String> prefKeys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlResId);
pageKeys.addAll(prefKeys);
// Remove grandfathered keys.
pageKeys.removeAll(grandfatheredKeys);
// Find all already-existing keys.
pageKeys.retainAll(masterKeys);
// Keep list of offending duplicate keys.
duplicateKeys.addAll(pageKeys);
// Add all keys to master key list.
masterKeys.addAll(prefKeys);
pageKeys.clear();
}
assertThat(duplicateKeys).isEmpty();
}
/**
* Add XML preferences from Fragments which have issues being instantiated in robolectric.
*/
private void addSpecialXml(Set<Integer> xmlList) {
xmlList.add(R.xml.date_time_prefs);
xmlList.add(R.xml.data_usage);
xmlList.add(R.xml.data_usage_cellular);
xmlList.add(R.xml.data_usage_wifi);
xmlList.add(R.xml.security_settings_misc);
}
}

View File

@@ -19,9 +19,7 @@ package com.android.settings.search;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE; import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE;
import static com.android.settings.search.SearchIndexableResources.NO_DATA_RES_ID; import static com.android.settings.search.SearchIndexableResources.NO_DATA_RES_ID;
import static com.android.settings.search.SearchIndexableResources.sResMap;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import android.annotation.DrawableRes; import android.annotation.DrawableRes;
@@ -35,12 +33,14 @@ import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.wifi.WifiSettings; import com.android.settings.wifi.WifiSettings;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
@RunWith(SettingsRobolectricTestRunner.class) @RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -51,6 +51,21 @@ public class SearchIndexableResourcesTest {
@DrawableRes @DrawableRes
private static final int ICON_RES_ID = R.drawable.ic_settings_language; private static final int ICON_RES_ID = R.drawable.ic_settings_language;
Map<String, SearchIndexableResource> sResMapCopy;
@Before
public void setUp() {
sResMapCopy = new HashMap<>(SearchIndexableResources.sResMap);
}
@After
public void cleanUp() {
SearchIndexableResources.sResMap.clear();
for (String key : sResMapCopy.keySet()) {
SearchIndexableResources.sResMap.put(key, sResMapCopy.get(key));
}
}
@Test @Test
public void testAddIndex() { public void testAddIndex() {
// Confirms that String.class isn't contained in SearchIndexableResources. // Confirms that String.class isn't contained in SearchIndexableResources.

View File

@@ -0,0 +1,57 @@
package com.android.settings.testutils;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Xml;
import com.android.settings.search2.XmlParserUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.util.ArrayList;
import java.util.List;
/**
* Util class for parsing XML
*/
public class XmlTestUtils {
/**
* Parses a preference screen's xml, collects and returns all keys used by preferences
* on the screen.
*
* @param context of the preference screen.
* @param xmlId of the Preference Xml to be parsed.
* @return List of all keys in the preference Xml
*/
public static List<String> getKeysFromPreferenceXml(Context context, int xmlId) {
final XmlResourceParser parser = context.getResources().getXml(xmlId);
final AttributeSet attrs = Xml.asAttributeSet(parser);
final List<String> keys = new ArrayList<>();
String key;
try {
while (parser.next() != XmlPullParser.END_DOCUMENT) {
try {
key = XmlParserUtils.getDataKey(context, attrs);
if (!TextUtils.isEmpty(key)) {
keys.add(key);
}
} catch (NullPointerException e) {
continue;
} catch (Resources.NotFoundException e) {
continue;
}
}
} catch (java.io.IOException e) {
return null;
} catch (XmlPullParserException e) {
return null;
}
return keys;
}
}