Use FooterPreference in xml explicitly

We don't rely on FooterPreferenceMixinCompat
to create footer preference in dashboard fragment.

Instead, declare a FooterPreference explicitly in
xml of screen.

It makes more sense for our referenceController design.

Test: visual, robotest
Bug: 124129485
Change-Id: I0b0c0f9e38d85aa89b815ce2b84ddff30a1d206b
This commit is contained in:
tmfang
2019-05-31 18:24:29 +08:00
parent f1c0f23510
commit 24c3324268
10 changed files with 84 additions and 109 deletions

View File

@@ -34,7 +34,7 @@
</PreferenceCategory> </PreferenceCategory>
<com.android.settingslib.widget.FooterPreference <com.android.settingslib.widget.FooterPreference
android:key="footer_preference" android:key="game_driver_footer"
android:title="@string/game_driver_footer_text" android:title="@string/game_driver_footer_text"
android:selectable="false" android:selectable="false"
settings:controller="com.android.settings.development.gamedriver.GameDriverFooterPreferenceController"> settings:controller="com.android.settings.development.gamedriver.GameDriverFooterPreferenceController">

View File

@@ -15,34 +15,34 @@
--> -->
<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" xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/night_display_title" android:title="@string/night_display_title"
android:key="night_display_title" android:key="night_display_title"
settings:keywords="@string/keywords_display_night_display"> settings:keywords="@string/keywords_display_night_display">
<DropDownPreference <DropDownPreference
android:key="night_display_auto_mode" android:key="night_display_auto_mode"
android:title="@string/night_display_auto_mode_title" android:title="@string/night_display_auto_mode_title"
android:summary="%s" android:summary="%s"
settings:controller="com.android.settings.display.NightDisplayAutoModePreferenceController" /> settings:controller="com.android.settings.display.NightDisplayAutoModePreferenceController"/>
<Preference <Preference
android:key="night_display_start_time" android:key="night_display_start_time"
android:title="@string/night_display_start_time_title" android:title="@string/night_display_start_time_title"
settings:controller="com.android.settings.display.NightDisplayCustomStartTimePreferenceController" /> settings:controller="com.android.settings.display.NightDisplayCustomStartTimePreferenceController"/>
<Preference <Preference
android:key="night_display_end_time" android:key="night_display_end_time"
android:title="@string/night_display_end_time_title" android:title="@string/night_display_end_time_title"
settings:controller="com.android.settings.display.NightDisplayCustomEndTimePreferenceController" /> settings:controller="com.android.settings.display.NightDisplayCustomEndTimePreferenceController"/>
<com.android.settings.widget.SeekBarPreference <com.android.settings.widget.SeekBarPreference
android:key="night_display_temperature" android:key="night_display_temperature"
android:title="@string/night_display_temperature_title" android:title="@string/night_display_temperature_title"
settings:keywords="@string/keywords_display_night_display" settings:keywords="@string/keywords_display_night_display"
settings:controller="com.android.settings.display.NightDisplayIntensityPreferenceController" settings:controller="com.android.settings.display.NightDisplayIntensityPreferenceController"
settings:unavailableSliceSubtitle="@string/night_display_not_currently_on" /> settings:unavailableSliceSubtitle="@string/night_display_not_currently_on"/>
<com.android.settingslib.widget.LayoutPreference <com.android.settingslib.widget.LayoutPreference
android:key="night_display_activated" android:key="night_display_activated"
@@ -50,10 +50,14 @@
android:selectable="false" android:selectable="false"
android:layout="@layout/night_display_activation_button" android:layout="@layout/night_display_activation_button"
settings:keywords="@string/keywords_display_night_display" settings:keywords="@string/keywords_display_night_display"
settings:controller="com.android.settings.display.NightDisplayActivationPreferenceController" /> settings:controller="com.android.settings.display.NightDisplayActivationPreferenceController"/>
<PreferenceCategory android:key="night_display_footer_category"> <PreferenceCategory android:key="night_display_footer_category">
<com.android.settingslib.widget.FooterPreference /> <com.android.settingslib.widget.FooterPreference
android:key="night_display_footer"
android:title="@string/night_display_text"
android:selectable="false"
settings:controller="com.android.settings.display.NightDisplayFooterPreferenceController"/>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@@ -31,7 +31,7 @@
android:title="@string/date_time_set_timezone_title" android:title="@string/date_time_set_timezone_title"
android:summary="@string/summary_placeholder" /> android:summary="@string/summary_placeholder" />
<com.android.settingslib.widget.FooterPreference <com.android.settingslib.widget.FooterPreference
android:key="footer_preference" android:key="timezone_footer"
settings:controller="com.android.settings.datetime.timezone.TimeZoneInfoPreferenceController" /> settings:controller="com.android.settings.datetime.timezone.TimeZoneInfoPreferenceController" />
</PreferenceCategory> </PreferenceCategory>

View File

@@ -29,20 +29,19 @@ import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference; import androidx.preference.Preference;
import com.android.settings.R; import com.android.settings.R;
import com.android.settingslib.widget.FooterPreference; import com.android.settings.core.BasePreferenceController;
import java.util.Date; import java.util.Date;
public class TimeZoneInfoPreferenceController extends BaseTimeZonePreferenceController { public class TimeZoneInfoPreferenceController extends BasePreferenceController {
private static final String PREFERENCE_KEY = FooterPreference.KEY_FOOTER;
@VisibleForTesting @VisibleForTesting
Date mDate; Date mDate;
private TimeZoneInfo mTimeZoneInfo; private TimeZoneInfo mTimeZoneInfo;
private final DateFormat mDateFormat; private final DateFormat mDateFormat;
public TimeZoneInfoPreferenceController(Context context) { public TimeZoneInfoPreferenceController(Context context, String key) {
super(context, PREFERENCE_KEY); super(context, key);
mDateFormat = DateFormat.getDateInstance(SimpleDateFormat.LONG); mDateFormat = DateFormat.getDateInstance(SimpleDateFormat.LONG);
mDateFormat.setContext(DisplayContext.CAPITALIZATION_NONE); mDateFormat.setContext(DisplayContext.CAPITALIZATION_NONE);
mDate = new Date(); mDate = new Date();
@@ -50,24 +49,18 @@ public class TimeZoneInfoPreferenceController extends BaseTimeZonePreferenceCont
@Override @Override
public int getAvailabilityStatus() { public int getAvailabilityStatus() {
return AVAILABLE; return mTimeZoneInfo != null ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE;
} }
@Override @Override
public void updateState(Preference preference) { public CharSequence getSummary() {
CharSequence formattedTimeZone = mTimeZoneInfo == null ? "" : formatInfo(mTimeZoneInfo); return mTimeZoneInfo == null ? "" : formatInfo(mTimeZoneInfo);
preference.setTitle(formattedTimeZone);
preference.setVisible(mTimeZoneInfo != null);
} }
public void setTimeZoneInfo(TimeZoneInfo timeZoneInfo) { public void setTimeZoneInfo(TimeZoneInfo timeZoneInfo) {
mTimeZoneInfo = timeZoneInfo; mTimeZoneInfo = timeZoneInfo;
} }
public TimeZoneInfo getTimeZoneInfo() {
return mTimeZoneInfo;
}
private CharSequence formatOffsetAndName(TimeZoneInfo item) { private CharSequence formatOffsetAndName(TimeZoneInfo item) {
String name = item.getGenericName(); String name = item.getGenericName();
if (name == null) { if (name == null) {
@@ -130,5 +123,4 @@ public class TimeZoneInfoPreferenceController extends BaseTimeZonePreferenceCont
} while (transition != null); } while (transition != null);
return transition; return transition;
} }
} }

View File

@@ -26,7 +26,6 @@ import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
@@ -40,7 +39,7 @@ import com.android.settingslib.widget.FooterPreference;
*/ */
public class GameDriverFooterPreferenceController extends BasePreferenceController public class GameDriverFooterPreferenceController extends BasePreferenceController
implements GameDriverContentObserver.OnGameDriverContentChangedListener, LifecycleObserver, implements GameDriverContentObserver.OnGameDriverContentChangedListener, LifecycleObserver,
OnStart, OnStop { OnStart, OnStop {
private final ContentResolver mContentResolver; private final ContentResolver mContentResolver;
@VisibleForTesting @VisibleForTesting
@@ -48,8 +47,8 @@ public class GameDriverFooterPreferenceController extends BasePreferenceControll
private FooterPreference mPreference; private FooterPreference mPreference;
public GameDriverFooterPreferenceController(Context context) { public GameDriverFooterPreferenceController(Context context, String key) {
super(context, FooterPreference.KEY_FOOTER); super(context, key);
mContentResolver = context.getContentResolver(); mContentResolver = context.getContentResolver();
mGameDriverContentObserver = mGameDriverContentObserver =
new GameDriverContentObserver(new Handler(Looper.getMainLooper()), this); new GameDriverContentObserver(new Handler(Looper.getMainLooper()), this);
@@ -58,8 +57,8 @@ public class GameDriverFooterPreferenceController extends BasePreferenceControll
@Override @Override
public int getAvailabilityStatus() { public int getAvailabilityStatus() {
return Settings.Global.getInt( return Settings.Global.getInt(
mContentResolver, Settings.Global.GAME_DRIVER_ALL_APPS, GAME_DRIVER_DEFAULT) mContentResolver, Settings.Global.GAME_DRIVER_ALL_APPS, GAME_DRIVER_DEFAULT)
== GAME_DRIVER_OFF == GAME_DRIVER_OFF
? AVAILABLE_UNSEARCHABLE ? AVAILABLE_UNSEARCHABLE
: CONDITIONALLY_UNAVAILABLE; : CONDITIONALLY_UNAVAILABLE;
} }
@@ -80,11 +79,6 @@ public class GameDriverFooterPreferenceController extends BasePreferenceControll
mGameDriverContentObserver.unregister(mContentResolver); mGameDriverContentObserver.unregister(mContentResolver);
} }
@Override
public void updateState(Preference preference) {
preference.setVisible(isAvailable());
}
@Override @Override
public void onGameDriverContentChanged() { public void onGameDriverContentChanged() {
updateState(mPreference); updateState(mPreference);

View File

@@ -19,26 +19,17 @@ package com.android.settings.display;
import android.content.Context; import android.content.Context;
import android.hardware.display.ColorDisplayManager; import android.hardware.display.ColorDisplayManager;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.widget.FooterPreference;
public class NightDisplayFooterPreferenceController extends BasePreferenceController { public class NightDisplayFooterPreferenceController extends BasePreferenceController {
public NightDisplayFooterPreferenceController(Context context) { public NightDisplayFooterPreferenceController(Context context, String key) {
super(context, FooterPreference.KEY_FOOTER); super(context, key);
} }
@Override @Override
public int getAvailabilityStatus() { public int getAvailabilityStatus() {
return ColorDisplayManager.isNightDisplayAvailable(mContext) ? AVAILABLE return ColorDisplayManager.isNightDisplayAvailable(mContext)
: UNSUPPORTED_ON_DEVICE; ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
public void updateState(Preference preference) {
preference.setTitle(R.string.night_display_text);
} }
} }

View File

@@ -31,7 +31,6 @@ import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable; import com.android.settings.search.Indexable;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexable;
import java.time.LocalTime; import java.time.LocalTime;
@@ -176,17 +175,6 @@ public class NightDisplaySettings extends DashboardFragment
return TAG; return TAG;
} }
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context);
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
final List<AbstractPreferenceController> controllers = new ArrayList<>(1);
controllers.add(new NightDisplayFooterPreferenceController(context));
return controllers;
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() { new BaseSearchIndexProvider() {
@Override @Override
@@ -203,11 +191,5 @@ public class NightDisplaySettings extends DashboardFragment
protected boolean isPageSearchEnabled(Context context) { protected boolean isPageSearchEnabled(Context context) {
return ColorDisplayManager.isNightDisplayAvailable(context); return ColorDisplayManager.isNightDisplayAvailable(context);
} }
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context);
}
}; };
} }

View File

@@ -16,13 +16,16 @@
package com.android.settings.datetime.timezone; package com.android.settings.datetime.timezone;
import static org.junit.Assert.assertEquals; import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static org.mockito.Mockito.spy; import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import androidx.preference.Preference; import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import com.android.settings.datetime.timezone.TimeZoneInfo.Formatter; import com.android.settings.datetime.timezone.TimeZoneInfo.Formatter;
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.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
@@ -34,20 +37,38 @@ import java.util.Locale;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class TimeZoneInfoPreferenceControllerTest { public class TimeZoneInfoPreferenceControllerTest {
@Test private TimeZoneInfo mTimeZoneInfo;
public void updateState_matchExpectedFormattedText() { private TimeZoneInfoPreferenceController mController;
Date now = new Date(0L); // 00:00 1/1/1970
Formatter formatter = new Formatter(Locale.US, now);
TimeZoneInfo timeZoneInfo = formatter.format("America/Los_Angeles"); @Before
TimeZoneInfoPreferenceController controller = public void setUp() {
new TimeZoneInfoPreferenceController(RuntimeEnvironment.application); final Context context = RuntimeEnvironment.application;
controller.mDate = now; final Date now = new Date(0L); // 00:00 1/1/1970
controller.setTimeZoneInfo(timeZoneInfo); final Formatter formatter = new Formatter(Locale.US, now);
Preference preference = spy(new Preference(RuntimeEnvironment.application)); mTimeZoneInfo = formatter.format("America/Los_Angeles");
controller.updateState(preference); mController = new TimeZoneInfoPreferenceController(context, "key");
assertEquals("Uses Pacific Time (GMT-08:00). " mController.mDate = now;
+ "Pacific Daylight Time starts on April 26, 1970.", mController.setTimeZoneInfo(mTimeZoneInfo);
preference.getTitle().toString()); }
@Test
public void getSummary_matchExpectedFormattedText() {
assertThat(mController.getSummary().toString()).isEqualTo(
"Uses Pacific Time (GMT-08:00). "
+ "Pacific Daylight Time starts on April 26, 1970.");
}
@Test
public void getAvailabilityStatus_timeZoneInfoSet_shouldReturnAVAILABLE_UNSEARCHABLE() {
mController.setTimeZoneInfo(mTimeZoneInfo);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Test
public void getAvailabilityStatus_noTimeZoneInfoSet_shouldReturnUNSUPPORTED_ON_DEVICE() {
mController.setTimeZoneInfo(null);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
} }
} }

View File

@@ -21,6 +21,7 @@ import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_U
import static com.android.settings.development.gamedriver.GameDriverEnableForAllAppsPreferenceController.GAME_DRIVER_ALL_APPS; import static com.android.settings.development.gamedriver.GameDriverEnableForAllAppsPreferenceController.GAME_DRIVER_ALL_APPS;
import static com.android.settings.development.gamedriver.GameDriverEnableForAllAppsPreferenceController.GAME_DRIVER_DEFAULT; import static com.android.settings.development.gamedriver.GameDriverEnableForAllAppsPreferenceController.GAME_DRIVER_DEFAULT;
import static com.android.settings.development.gamedriver.GameDriverEnableForAllAppsPreferenceController.GAME_DRIVER_OFF; import static com.android.settings.development.gamedriver.GameDriverEnableForAllAppsPreferenceController.GAME_DRIVER_OFF;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
@@ -62,7 +63,7 @@ public class GameDriverFooterPreferenceControllerTest {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application; mContext = RuntimeEnvironment.application;
mResolver = mContext.getContentResolver(); mResolver = mContext.getContentResolver();
mController = spy(new GameDriverFooterPreferenceController(mContext)); mController = spy(new GameDriverFooterPreferenceController(mContext, "key"));
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
} }
@@ -104,20 +105,4 @@ public class GameDriverFooterPreferenceControllerTest {
verify(mGameDriverContentObserver).unregister(mResolver); verify(mGameDriverContentObserver).unregister(mResolver);
} }
@Test
public void updateState_available_visible() {
when(mController.getAvailabilityStatus()).thenReturn(AVAILABLE_UNSEARCHABLE);
mController.updateState(mPreference);
verify(mPreference).setVisible(true);
}
@Test
public void updateState_unavailable_invisible() {
when(mController.getAvailabilityStatus()).thenReturn(CONDITIONALLY_UNAVAILABLE);
mController.updateState(mPreference);
verify(mPreference).setVisible(false);
}
} }

View File

@@ -14,6 +14,9 @@
package com.android.settings.display; package com.android.settings.display;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.SettingsShadowResources;
@@ -34,7 +37,8 @@ public class NightDisplayFooterPreferenceControllerTest {
@Before @Before
public void setUp() { public void setUp() {
mController = new NightDisplayFooterPreferenceController(RuntimeEnvironment.application); mController =
new NightDisplayFooterPreferenceController(RuntimeEnvironment.application, "key");
} }
@After @After
@@ -43,16 +47,18 @@ public class NightDisplayFooterPreferenceControllerTest {
} }
@Test @Test
public void isAvailable_configuredAvailable() { public void getAvailabilityStatus_configuredAvailable_shouldReturnAVAILABLE_UNSEARCHABLE() {
SettingsShadowResources.overrideResource( SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_nightDisplayAvailable, true); com.android.internal.R.bool.config_nightDisplayAvailable, true);
assertThat(mController.isAvailable()).isTrue();
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
} }
@Test @Test
public void isAvailable_configuredUnavailable() { public void getAvailabilityStatus_configuredUnavailable_shouldReturnUNSUPPORTED_ON_DEVICE() {
SettingsShadowResources.overrideResource( SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_nightDisplayAvailable, false); com.android.internal.R.bool.config_nightDisplayAvailable, false);
assertThat(mController.isAvailable()).isFalse();
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
} }
} }