Allows for system navigation settings to be added dynamically.

This allows for controller-backed preferences to be added or
overridden via xml.

Similarly, if the controllers cause all of the preferences for
2 or 3 button nav to be unavailable, we hide the settings button.

Bug: 324036308
Test: Manual and unit tests
Flag: NA
Change-Id: I2371f3173076172489966728ac69c8767570cd56
Merged-In: I2371f3173076172489966728ac69c8767570cd56
This commit is contained in:
Andy Wickham
2024-03-08 03:26:35 +00:00
parent 4115a9a278
commit 9aa1c402ae
6 changed files with 133 additions and 5 deletions

View File

@@ -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<BasePreferenceController> 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.

View File

@@ -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<BasePreferenceController> preferenceControllers = PreferenceControllerListHelper
.getPreferenceControllersFromXml(getContext(), getPreferenceScreenResId());
preferenceControllers.forEach(controller -> {
controller.updateState(findPreference(controller.getPreferenceKey()));
controller.displayPreference(screen);
});
final List<? extends CandidateInfo> 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())