diff --git a/res/values/strings.xml b/res/values/strings.xml index 55c48af6ac8..6f4b5945942 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10478,7 +10478,7 @@ Back Sensitivity - Gesture Navigation Sensitivity + Gesture Navigation Button navigation diff --git a/src/com/android/settings/core/PreferenceControllerListHelper.java b/src/com/android/settings/core/PreferenceControllerListHelper.java index f37140eaaf6..dea8c971c49 100644 --- a/src/com/android/settings/core/PreferenceControllerListHelper.java +++ b/src/com/android/settings/core/PreferenceControllerListHelper.java @@ -27,6 +27,8 @@ import android.text.TextUtils; import android.util.Log; import androidx.annotation.NonNull; +import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag; import com.android.settingslib.core.AbstractPreferenceController; @@ -93,6 +95,25 @@ public class PreferenceControllerListHelper { return controllers; } + /** + * Checks if the given PreferenceScreen will be empty due to all preferences being unavailable. + * + * @param xmlResId resource id of the PreferenceScreen to check + * @return {@code true} if none of the preferences in the given screen will appear + */ + public static boolean areAllPreferencesUnavailable(@NonNull Context context, + @NonNull PreferenceManager preferenceManager, @XmlRes int xmlResId) { + PreferenceScreen screen = preferenceManager.inflateFromResource(context, xmlResId, + /* rootPreferences= */ null); + List preferenceControllers = + getPreferenceControllersFromXml(context, xmlResId); + if (screen.getPreferenceCount() != preferenceControllers.size()) { + // There are some preferences without controllers, which will show regardless. + return false; + } + return preferenceControllers.stream().noneMatch(BasePreferenceController::isAvailable); + } + /** * Return a sub list of {@link AbstractPreferenceController} to only contain controller that * doesn't exist in filter. diff --git a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java index c40212b7e01..dd57fbd5710 100644 --- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java +++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java @@ -43,6 +43,8 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.accessibility.AccessibilityGestureNavigationTutorial; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.PreferenceControllerListHelper; import com.android.settings.core.SubSettingLauncher; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.overlay.FeatureFactory; @@ -147,14 +149,20 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment i final PreferenceScreen screen = getPreferenceScreen(); screen.removeAll(); screen.addPreference(mVideoPreference); + addPreferencesFromResource(getPreferenceScreenResId()); + final List preferenceControllers = PreferenceControllerListHelper + .getPreferenceControllersFromXml(getContext(), getPreferenceScreenResId()); + preferenceControllers.forEach(controller -> { + controller.updateState(findPreference(controller.getPreferenceKey())); + controller.displayPreference(screen); + }); final List candidateList = getCandidates(); if (candidateList == null) { return; } for (CandidateInfo info : candidateList) { - SelectorWithWidgetPreference pref = - new SelectorWithWidgetPreference(getPrefContext()); + SelectorWithWidgetPreference pref = new SelectorWithWidgetPreference(getPrefContext()); bindPreference(pref, info.getKey(), info, defaultKey); bindPreferenceExtra(pref, info.getKey(), info, defaultKey, systemDefaultKey); screen.addPreference(pref); @@ -176,8 +184,11 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment i GestureNavigationSettingsFragment.GESTURE_NAVIGATION_SETTINGS))); } - if (KEY_SYSTEM_NAV_2BUTTONS.equals(info.getKey()) || KEY_SYSTEM_NAV_3BUTTONS.equals( - info.getKey())) { + if ((KEY_SYSTEM_NAV_2BUTTONS.equals(info.getKey()) + || KEY_SYSTEM_NAV_3BUTTONS.equals(info.getKey())) + // Don't add the settings button if that page will be blank. + && !PreferenceControllerListHelper.areAllPreferencesUnavailable( + getContext(), getPreferenceManager(), R.xml.button_navigation_settings)) { pref.setExtraWidgetOnClickListener((v) -> new SubSettingLauncher(getContext()) .setDestination(ButtonNavigationSettingsFragment.class.getName()) diff --git a/tests/robotests/res/xml-mcc997/location_settings.xml b/tests/robotests/res/xml-mcc997/location_settings.xml new file mode 100644 index 00000000000..d417d189354 --- /dev/null +++ b/tests/robotests/res/xml-mcc997/location_settings.xml @@ -0,0 +1,36 @@ + + + + + + + + + + \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/core/PreferenceControllerListHelperTest.java b/tests/robotests/src/com/android/settings/core/PreferenceControllerListHelperTest.java index 68dfb7952ce..0cc38574cab 100644 --- a/tests/robotests/src/com/android/settings/core/PreferenceControllerListHelperTest.java +++ b/tests/robotests/src/com/android/settings/core/PreferenceControllerListHelperTest.java @@ -20,6 +20,8 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import androidx.preference.PreferenceManager; + import com.android.settings.R; import com.android.settings.slices.FakePreferenceController; import com.android.settingslib.core.AbstractPreferenceController; @@ -38,10 +40,12 @@ import java.util.List; public class PreferenceControllerListHelperTest { private Context mContext; + private PreferenceManager mPreferenceManager; @Before public void setUp() { mContext = RuntimeEnvironment.application; + mPreferenceManager = new PreferenceManager(mContext); } @Test @@ -68,6 +72,30 @@ public class PreferenceControllerListHelperTest { assertThat(controllers.get(0)).isInstanceOf(FakePreferenceController.class); } + @Test + @Config(qualifiers = "mcc999") + public void areAllPreferencesUnavailable_allAvailable() { + // All preferences have controllers indicating they are available. + assertThat(PreferenceControllerListHelper.areAllPreferencesUnavailable(mContext, + mPreferenceManager, R.xml.location_settings)).isFalse(); + } + + @Test + @Config(qualifiers = "mcc997") + public void areAllPreferencesUnavailable_allUnavailable() { + // All preferences have controllers indicating they are unavailable. (note the qualifier) + assertThat(PreferenceControllerListHelper.areAllPreferencesUnavailable(mContext, + mPreferenceManager, R.xml.location_settings)).isTrue(); + } + + @Test + @Config(qualifiers = "mcc999") + public void areAllPreferencesUnavailable_noControllersShouldAssumeAvailable() { + // None of the preferences have controllers, so they are assumed available. + assertThat(PreferenceControllerListHelper.areAllPreferencesUnavailable(mContext, + mPreferenceManager, R.xml.display_settings)).isFalse(); + } + @Test public void filterControllers_noFilter_shouldReturnSameList() { final List controllers = new ArrayList<>(); diff --git a/tests/robotests/src/com/android/settings/core/UnavailablePreferenceController.java b/tests/robotests/src/com/android/settings/core/UnavailablePreferenceController.java new file mode 100644 index 00000000000..bf6e7e2cb3f --- /dev/null +++ b/tests/robotests/src/com/android/settings/core/UnavailablePreferenceController.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.core; + +import android.content.Context; + +public class UnavailablePreferenceController extends BasePreferenceController { + + public UnavailablePreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + return UNSUPPORTED_ON_DEVICE; + } + +}