Add Toggle Controllers to XML
Autobrightness preference controller was accidentally removed from display_settings.xml. Given that no tests were broken and this would be a disaster for phone buddy & inline actions, I have added another test which keeps a list of valid controllers that should exist in xml. When more inline controllers types are added, they will be included in this test. Fixes: 72564979 Test: robotests Change-Id: I40fe18f9118af9cec1c201632742d2949ff64be5
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||||
android:title="@string/battery_saver"
|
android:title="@string/battery_saver"
|
||||||
android:key="battery_saver">
|
android:key="battery_saver">
|
||||||
|
|
||||||
@@ -23,12 +24,15 @@
|
|||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="auto_battery_saver"
|
android:key="auto_battery_saver"
|
||||||
android:title="@string/battery_saver_auto_title"
|
android:title="@string/battery_saver_auto_title"
|
||||||
android:summary="@string/battery_saver_auto_summary"/>
|
android:summary="@string/battery_saver_auto_summary"
|
||||||
|
settings:controller="com.android.settings.fuelgauge.batterysaver.AutoBatterySaverPreferenceController"/>
|
||||||
|
|
||||||
<com.android.settings.widget.SeekBarPreference
|
<com.android.settings.widget.SeekBarPreference
|
||||||
android:key="battery_saver_seek_bar"
|
android:key="battery_saver_seek_bar"
|
||||||
android:title="@string/battery_saver_seekbar_title"
|
android:title="@string/battery_saver_seekbar_title"
|
||||||
android:max="75"
|
android:max="75"
|
||||||
android:min="5"/>
|
android:min="5"/>
|
||||||
|
|
||||||
<com.android.settings.applications.LayoutPreference
|
<com.android.settings.applications.LayoutPreference
|
||||||
android:key="battery_saver_button_container"
|
android:key="battery_saver_button_container"
|
||||||
android:selectable="false"
|
android:selectable="false"
|
||||||
|
@@ -25,8 +25,8 @@
|
|||||||
android:title="@string/bluetooth_settings_title"
|
android:title="@string/bluetooth_settings_title"
|
||||||
android:icon="@drawable/ic_settings_bluetooth"
|
android:icon="@drawable/ic_settings_bluetooth"
|
||||||
android:summary="@string/bluetooth_pref_summary"
|
android:summary="@string/bluetooth_pref_summary"
|
||||||
settings:controller="com.android.settings.bluetooth.BluetoothSwitchPreferenceController"
|
android:order="-7"
|
||||||
android:order="-7"/>
|
settings:controller="com.android.settings.bluetooth.BluetoothSwitchPreferenceController"/>
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="toggle_nfc"
|
android:key="toggle_nfc"
|
||||||
@@ -54,6 +54,7 @@
|
|||||||
android:title="@string/bluetooth_on_while_driving_pref"
|
android:title="@string/bluetooth_on_while_driving_pref"
|
||||||
android:icon="@drawable/ic_settings_bluetooth"
|
android:icon="@drawable/ic_settings_bluetooth"
|
||||||
android:summary="@string/bluetooth_on_while_driving_summary"
|
android:summary="@string/bluetooth_on_while_driving_summary"
|
||||||
|
settings:controller="com.android.settings.connecteddevice.BluetoothOnWhileDrivingPreferenceController"
|
||||||
android:order="-2"/>
|
android:order="-2"/>
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
|
@@ -43,8 +43,9 @@
|
|||||||
<com.android.settingslib.RestrictedSwitchPreference
|
<com.android.settingslib.RestrictedSwitchPreference
|
||||||
android:key="auto_brightness"
|
android:key="auto_brightness"
|
||||||
android:title="@string/auto_brightness_title"
|
android:title="@string/auto_brightness_title"
|
||||||
settings:keywords="@string/keywords_display_auto_brightness"
|
|
||||||
android:summary="@string/auto_brightness_summary"
|
android:summary="@string/auto_brightness_summary"
|
||||||
|
settings:keywords="@string/keywords_display_auto_brightness"
|
||||||
|
settings:controller="com.android.settings.display.AutoBrightnessPreferenceController"
|
||||||
settings:useAdminDisabledSummary="true"
|
settings:useAdminDisabledSummary="true"
|
||||||
settings:userRestriction="no_config_brightness" />
|
settings:userRestriction="no_config_brightness" />
|
||||||
|
|
||||||
|
@@ -79,7 +79,8 @@
|
|||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="visiblepattern_profile"
|
android:key="visiblepattern_profile"
|
||||||
android:summary="@string/summary_placeholder"
|
android:summary="@string/summary_placeholder"
|
||||||
android:title="@string/lockpattern_settings_enable_visible_pattern_title_profile" />
|
android:title="@string/lockpattern_settings_enable_visible_pattern_title_profile"
|
||||||
|
settings:controller="com.android.settings.security.VisiblePatternProfilePreferenceController"/>
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="fingerprint_settings_profile"
|
android:key="fingerprint_settings_profile"
|
||||||
@@ -103,7 +104,8 @@
|
|||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="show_password"
|
android:key="show_password"
|
||||||
android:title="@string/show_password"
|
android:title="@string/show_password"
|
||||||
android:summary="@string/show_password_summary" />
|
android:summary="@string/show_password_summary"
|
||||||
|
settings:controller="com.android.settings.security.ShowPasswordPreferenceController"/>
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||||
android:key="security_lockscreen_settings_screen"
|
android:key="security_lockscreen_settings_screen"
|
||||||
android:title="@string/lockscreen_settings_title">
|
android:title="@string/lockscreen_settings_title">
|
||||||
|
|
||||||
@@ -36,7 +37,8 @@
|
|||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="security_setting_lockdown_enabled"
|
android:key="security_setting_lockdown_enabled"
|
||||||
android:title="@string/lockdown_settings_title"
|
android:title="@string/lockdown_settings_title"
|
||||||
android:summary="@string/lockdown_settings_summary" />
|
android:summary="@string/lockdown_settings_summary"
|
||||||
|
settings:controller="com.android.settings.security.LockdownButtonPreferenceController"/>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:key="security_setting_lock_screen_notif_work_header"
|
android:key="security_setting_lock_screen_notif_work_header"
|
||||||
|
@@ -30,6 +30,8 @@ import java.util.List;
|
|||||||
* Abstract class to consolidate utility between preference controllers and act as an interface
|
* 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 Slices. The abstract classes that inherit from this class will act as the direct interfaces
|
||||||
* for each type when plugging into Slices.
|
* for each type when plugging into Slices.
|
||||||
|
*
|
||||||
|
* TODO (b/73074893) Add Lifecycle Setting method.
|
||||||
*/
|
*/
|
||||||
public abstract class BasePreferenceController extends AbstractPreferenceController {
|
public abstract class BasePreferenceController extends AbstractPreferenceController {
|
||||||
|
|
||||||
|
@@ -44,6 +44,11 @@ public class VisiblePatternProfilePreferenceController extends TogglePreferenceC
|
|||||||
|
|
||||||
private Preference mPreference;
|
private Preference mPreference;
|
||||||
|
|
||||||
|
public VisiblePatternProfilePreferenceController(Context context) {
|
||||||
|
this(context, null /* lifecycle */);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO (b/73074893) Replace this constructor without Lifecycle using setter method instead.
|
||||||
public VisiblePatternProfilePreferenceController(Context context, Lifecycle lifecycle) {
|
public VisiblePatternProfilePreferenceController(Context context, Lifecycle lifecycle) {
|
||||||
super(context, KEY_VISIBLE_PATTERN_PROFILE);
|
super(context, KEY_VISIBLE_PATTERN_PROFILE);
|
||||||
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
com.android.settings.testutils.FakeToggleController
|
@@ -31,6 +31,7 @@ import android.net.Uri;
|
|||||||
|
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.testutils.DatabaseTestUtils;
|
import com.android.settings.testutils.DatabaseTestUtils;
|
||||||
|
import com.android.settings.testutils.FakeToggleController;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
@@ -31,6 +31,7 @@ import com.android.settings.search.FakeIndexProvider;
|
|||||||
import com.android.settings.search.SearchFeatureProvider;
|
import com.android.settings.search.SearchFeatureProvider;
|
||||||
import com.android.settings.search.SearchFeatureProviderImpl;
|
import com.android.settings.search.SearchFeatureProviderImpl;
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
|
import com.android.settings.testutils.FakeToggleController;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
@@ -29,6 +29,7 @@ import android.net.Uri;
|
|||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
import com.android.settings.testutils.FakeToggleController;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 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.slices;
|
||||||
|
|
||||||
|
import static com.android.settings.TestConfig.SDK_VERSION;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertWithMessage;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.XmlResourceParser;
|
||||||
|
import android.provider.SearchIndexableResource;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Xml;
|
||||||
|
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settings.core.TogglePreferenceController;
|
||||||
|
import com.android.settings.core.codeinspection.ClassScanner;
|
||||||
|
import com.android.settings.core.codeinspection.CodeInspector;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settings.search.DatabaseIndexingUtils;
|
||||||
|
import com.android.settings.search.Indexable;
|
||||||
|
import com.android.settings.search.SearchFeatureProvider;
|
||||||
|
import com.android.settings.search.SearchFeatureProviderImpl;
|
||||||
|
import com.android.settings.search.XmlParserUtils;
|
||||||
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = SDK_VERSION)
|
||||||
|
public class SliceControllerInXmlTest {
|
||||||
|
|
||||||
|
private static final List<Class> mSliceControllerClasses = new ArrayList<>(Arrays.asList(
|
||||||
|
TogglePreferenceController.class
|
||||||
|
));
|
||||||
|
|
||||||
|
private final List<String> mXmlDeclaredControllers = new ArrayList<>();
|
||||||
|
private final List<String> mGrandfatheredClasses = new ArrayList<>();
|
||||||
|
|
||||||
|
private final String ERROR_MISSING_CONTROLLER =
|
||||||
|
"The following controllers were expected to be declared by "
|
||||||
|
+ "'settings:controller=Controller_Class_Name' in their corresponding Xml. "
|
||||||
|
+ "If it should not appear in XML, add the controller's classname to "
|
||||||
|
+ "grandfather_slice_controller_not_in_xml. Controllers:\n";
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
SearchFeatureProvider mSearchProvider;
|
||||||
|
private FakeFeatureFactory mFakeFeatureFactory;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
|
|
||||||
|
mSearchProvider = new SearchFeatureProviderImpl();
|
||||||
|
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||||
|
mFakeFeatureFactory.searchFeatureProvider = mSearchProvider;
|
||||||
|
|
||||||
|
CodeInspector.initializeGrandfatherList(mGrandfatheredClasses,
|
||||||
|
"grandfather_slice_controller_not_in_xml");
|
||||||
|
initDeclaredControllers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initDeclaredControllers() {
|
||||||
|
final List<Integer> xmlResources = getIndexableXml();
|
||||||
|
XmlResourceParser parser;
|
||||||
|
|
||||||
|
for (int xmlResId : xmlResources) {
|
||||||
|
try {
|
||||||
|
parser = mContext.getResources().getXml(xmlResId);
|
||||||
|
|
||||||
|
int type;
|
||||||
|
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||||
|
&& type != XmlPullParser.START_TAG) {
|
||||||
|
// Parse next until start tag is found
|
||||||
|
}
|
||||||
|
|
||||||
|
final int outerDepth = parser.getDepth();
|
||||||
|
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||||
|
String controllerClassName;
|
||||||
|
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||||
|
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
|
||||||
|
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
controllerClassName = XmlParserUtils.getController(mContext, attrs);
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(controllerClassName)) {
|
||||||
|
mXmlDeclaredControllers.add(controllerClassName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Assume an issue with robolectric resources
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllControllersDeclaredInXml() throws Exception {
|
||||||
|
final List<Class<?>> classes = new ClassScanner().getClassesForPackage(
|
||||||
|
mContext.getPackageName());
|
||||||
|
final List<String> missingControllersInXml = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Class<?> clazz : classes) {
|
||||||
|
if (!isInlineSliceClass(clazz)) {
|
||||||
|
// Only care about inline-slice controller classes.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mXmlDeclaredControllers.contains(clazz.getName())) {
|
||||||
|
// Class clazz should have been declared in XML (unless whitelisted).
|
||||||
|
missingControllersInXml.add(clazz.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removed whitelisted classes
|
||||||
|
missingControllersInXml.removeAll(mGrandfatheredClasses);
|
||||||
|
|
||||||
|
final String missingControllerError = buildErrorMessage(ERROR_MISSING_CONTROLLER,
|
||||||
|
missingControllersInXml);
|
||||||
|
|
||||||
|
assertWithMessage(missingControllerError).that(missingControllersInXml).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInlineSliceClass(Class clazz) {
|
||||||
|
while (clazz != null) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
if (mSliceControllerClasses.contains(clazz)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildErrorMessage(String errorSummary, List<String> errorClasses) {
|
||||||
|
final StringBuilder error = new StringBuilder(errorSummary);
|
||||||
|
for (String c : errorClasses) {
|
||||||
|
error.append(c).append("\n");
|
||||||
|
}
|
||||||
|
return error.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Integer> getIndexableXml() {
|
||||||
|
final List<Integer> xmlResSet = new ArrayList<>();
|
||||||
|
|
||||||
|
final Collection<Class> indexableClasses = FeatureFactory.getFactory(
|
||||||
|
mContext).getSearchFeatureProvider().getSearchIndexableResources()
|
||||||
|
.getProviderValues();
|
||||||
|
|
||||||
|
for (Class clazz : indexableClasses) {
|
||||||
|
|
||||||
|
Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(
|
||||||
|
clazz);
|
||||||
|
|
||||||
|
if (provider == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<SearchIndexableResource> resources = provider.getXmlResourcesToIndex(mContext,
|
||||||
|
true);
|
||||||
|
|
||||||
|
if (resources == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SearchIndexableResource resource : resources) {
|
||||||
|
// Add '0's anyway. It won't break the test.
|
||||||
|
xmlResSet.add(resource.xmlResId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return xmlResSet;
|
||||||
|
}
|
||||||
|
}
|
@@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.slices;
|
package com.android.settings.testutils;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
Reference in New Issue
Block a user