1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-08-25 00:30:37 +02:00

Xiaomi: Use display items labels from watch

This commit is contained in:
José Rebelo 2023-12-05 13:23:18 +00:00
parent 3ab1ac26db
commit 9ddbcc0c8a
7 changed files with 83 additions and 128 deletions

View File

@ -28,9 +28,10 @@ import androidx.preference.Preference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
@ -49,6 +50,13 @@ public final class DeviceSettingsUtils {
return String.format(Locale.ROOT, "%s_possible_values", key);
}
/**
* Returns the preference key where to save the list of entry labels for a preference, comma-separated.
*/
public static String getPrefPossibleValueLabelsKey(final String key) {
return String.format(Locale.ROOT, "%s_possible_value_labels", key);
}
/**
* Returns the preference key where to that a config was reported as supported (boolean).
*/
@ -57,12 +65,11 @@ public final class DeviceSettingsUtils {
}
/**
* Removes all unsupported elements from a list preference. If they are not known, the preference
* is hidden.
* Populates a list preference, or hides it if no known supported values are known.
*/
public static void removeUnsupportedElementsFromListPreference(final String prefKey,
final DeviceSpecificSettingsHandler handler,
final Prefs prefs) {
public static void populateOrHideListPreference(final String prefKey,
final DeviceSpecificSettingsHandler handler,
final Prefs prefs) {
final Preference pref = handler.findPreference(prefKey);
if (pref == null) {
return;
@ -92,19 +99,40 @@ public final class DeviceSettingsUtils {
return;
}
final List<String> prefValues = new ArrayList<>(originalValues.length);
for (final CharSequence entryValue : originalValues) {
prefValues.add(entryValue.toString());
final Map<CharSequence, CharSequence> entryNames = new HashMap<>();
final List<String> knownLabels = prefs.getList(getPrefPossibleValueLabelsKey(prefKey), null);
if (knownLabels != null) {
// We got some known labels from the watch
if (knownLabels.size() != possibleValues.size()) {
LOG.warn(
"Number of possible values ({}) and labels ({}) for {} differs - this should never happen",
possibleValues.size(),
knownLabels.size(),
prefKey
);
// Abort and hide preference - we can't safely recover from this
pref.setVisible(false);
return;
}
for (int i = 0; i < knownLabels.size(); i++) {
entryNames.put(possibleValues.get(i), knownLabels.get(i));
}
} else {
for (int i = 0; i < originalEntries.length; i++) {
entryNames.put(originalValues[i], originalEntries[i]);
}
}
final CharSequence[] entries = new CharSequence[possibleValues.size()];
final CharSequence[] values = new CharSequence[possibleValues.size()];
for (int i = 0; i < possibleValues.size(); i++) {
final String possibleValue = possibleValues.get(i);
final int idxPrefValue = prefValues.indexOf(possibleValue);
final CharSequence knownLabel = entryNames.get(possibleValue);
if (idxPrefValue >= 0) {
entries[i] = originalEntries[idxPrefValue];
if (knownLabel != null) {
entries[i] = knownLabel;
} else {
entries[i] = handler.getContext().getString(R.string.menuitem_unknown_app, possibleValue);
}

View File

@ -17,16 +17,12 @@
package nodomain.freeyourgadget.gadgetbridge.devices.huami;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsUtils.hidePrefIfNoneVisible;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsUtils.removeUnsupportedElementsFromListPreference;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsUtils.populateOrHideListPreference;
import android.os.Parcel;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.MultiSelectListPreference;
import androidx.preference.Preference;
import org.slf4j.Logger;
@ -65,13 +61,13 @@ public class Huami2021SettingsCustomizer extends HuamiSettingsCustomizer {
super.customizeSettings(handler, prefs);
// These are not reported by the normal configs
removeUnsupportedElementsFromListPreference(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE, handler, prefs);
removeUnsupportedElementsFromListPreference(HuamiConst.PREF_SHORTCUTS_SORTABLE, handler, prefs);
removeUnsupportedElementsFromListPreference(HuamiConst.PREF_CONTROL_CENTER_SORTABLE, handler, prefs);
removeUnsupportedElementsFromListPreference(DeviceSettingsPreferenceConst.SHORTCUT_CARDS_SORTABLE, handler, prefs);
removeUnsupportedElementsFromListPreference(DeviceSettingsPreferenceConst.PREF_WATCHFACE, handler, prefs);
removeUnsupportedElementsFromListPreference(DeviceSettingsPreferenceConst.MORNING_UPDATES_CATEGORIES_SORTABLE, handler, prefs);
removeUnsupportedElementsFromListPreference(DeviceSettingsPreferenceConst.PREF_VOICE_SERVICE_LANGUAGE, handler, prefs);
populateOrHideListPreference(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE, handler, prefs);
populateOrHideListPreference(HuamiConst.PREF_SHORTCUTS_SORTABLE, handler, prefs);
populateOrHideListPreference(HuamiConst.PREF_CONTROL_CENTER_SORTABLE, handler, prefs);
populateOrHideListPreference(DeviceSettingsPreferenceConst.SHORTCUT_CARDS_SORTABLE, handler, prefs);
populateOrHideListPreference(DeviceSettingsPreferenceConst.PREF_WATCHFACE, handler, prefs);
populateOrHideListPreference(DeviceSettingsPreferenceConst.MORNING_UPDATES_CATEGORIES_SORTABLE, handler, prefs);
populateOrHideListPreference(DeviceSettingsPreferenceConst.PREF_VOICE_SERVICE_LANGUAGE, handler, prefs);
for (final ZeppOsConfigService.ConfigArg config : ZeppOsConfigService.ConfigArg.values()) {
if (config.getPrefKey() == null) {
@ -88,7 +84,7 @@ public class Huami2021SettingsCustomizer extends HuamiSettingsCustomizer {
case BYTE_LIST:
case STRING_LIST:
// For list preferences, remove the unsupported items
removeUnsupportedElementsFromListPreference(config.getPrefKey(), handler, prefs);
populateOrHideListPreference(config.getPrefKey(), handler, prefs);
break;
case SHORT:
case INT:

View File

@ -16,6 +16,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.devices.xiaomi;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsUtils.populateOrHideListPreference;
import android.os.Parcel;
import androidx.preference.Preference;
@ -26,6 +28,7 @@ import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
public class XiaomiSettingsCustomizer implements DeviceSpecificSettingsCustomizer {
@ -39,6 +42,8 @@ public class XiaomiSettingsCustomizer implements DeviceSpecificSettingsCustomize
if (activityMonitoringPref != null) {
activityMonitoringPref.setVisible(false);
}
populateOrHideListPreference(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE, handler, prefs);
}
@Override

View File

@ -61,13 +61,6 @@ public final class XiaomiPreferences {
return calendar.getTime();
}
/**
* Returns the preference key where to save the list of possible value for a preference, comma-separated.
*/
public static String getPrefPossibleValuesKey(final String key) {
return String.format(Locale.ROOT, "%s_possible_values", key);
}
public static boolean keepActivityDataOnDevice(final GBDevice gbDevice) {
final Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()));
return prefs.getBoolean("keep_activity_data_on_device", false);

View File

@ -32,6 +32,7 @@ import java.util.TimeZone;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsUtils;
import nodomain.freeyourgadget.gadgetbridge.capabilities.password.PasswordCapabilityImpl;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone;
@ -321,13 +322,28 @@ public class XiaomiSystemService extends AbstractXiaomiService implements Xiaomi
private void setDisplayItems() {
final Prefs prefs = getDevicePrefs();
final List<String> allScreens = new ArrayList<>(prefs.getList(XiaomiPreferences.getPrefPossibleValuesKey(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE), Collections.emptyList()));
final List<String> allScreens = new ArrayList<>(prefs.getList(DeviceSettingsUtils.getPrefPossibleValuesKey(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE), Collections.emptyList()));
final List<String> allLabels = new ArrayList<>(prefs.getList(DeviceSettingsUtils.getPrefPossibleValueLabelsKey(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE), Collections.emptyList()));
final List<String> enabledScreens = new ArrayList<>(prefs.getList(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE, Collections.emptyList()));
if (allScreens.isEmpty()) {
LOG.warn("No list of all screens");
return;
}
if (allScreens.size() != allLabels.size()) {
LOG.warn(
"Mismatched allScreens ({}) and allLabels ({}) sizes - this should never happen",
allScreens.size(),
allLabels.size()
);
return;
}
final Map<String, String> labelsMap = new HashMap<>();
for (int i = 0; i < allScreens.size(); i++) {
labelsMap.put(allScreens.get(i), allLabels.get(i));
}
LOG.debug("Setting display items: {}", enabledScreens);
if (!enabledScreens.contains("setting")) {
@ -344,7 +360,7 @@ public class XiaomiSystemService extends AbstractXiaomiService implements Xiaomi
final XiaomiProto.DisplayItem.Builder displayItem = XiaomiProto.DisplayItem.newBuilder()
.setCode(enabledScreen)
.setName(DISPLAY_ITEM_NAMES.get(enabledScreen))
.setName(labelsMap.get(enabledScreen))
.setUnknown5(1);
if (inMoreSection) {
@ -365,7 +381,7 @@ public class XiaomiSystemService extends AbstractXiaomiService implements Xiaomi
final XiaomiProto.DisplayItem.Builder displayItem = XiaomiProto.DisplayItem.newBuilder()
.setCode(screen)
.setName(DISPLAY_ITEM_NAMES.get(screen))
.setName(labelsMap.get(screen))
.setDisabled(true)
.setUnknown5(1);
@ -386,10 +402,12 @@ public class XiaomiSystemService extends AbstractXiaomiService implements Xiaomi
LOG.debug("Got {} display items", displayItems.getDisplayItemCount());
final List<String> allScreens = new ArrayList<>();
final List<String> allScreensLabels = new ArrayList<>();
final List<String> mainScreens = new ArrayList<>();
final List<String> moreScreens = new ArrayList<>();
for (final XiaomiProto.DisplayItem displayItem : displayItems.getDisplayItemList()) {
allScreens.add(displayItem.getCode());
allScreensLabels.add(displayItem.getName().replace(",", ""));
if (!displayItem.getDisabled()) {
if (displayItem.getInMoreSection()) {
moreScreens.add(displayItem.getCode());
@ -405,11 +423,16 @@ public class XiaomiSystemService extends AbstractXiaomiService implements Xiaomi
enabledScreens.addAll(moreScreens);
}
allScreens.add("more");
allScreensLabels.add(getSupport().getContext().getString(R.string.menuitem_more));
final String allScreensPrefValue = StringUtils.join(",", allScreens.toArray(new String[0])).toString();
final String allScreensLabelsPrefValue = StringUtils.join(",", allScreensLabels.toArray(new String[0])).toString();
final String prefValue = StringUtils.join(",", enabledScreens.toArray(new String[0])).toString();
final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences()
.withPreference(XiaomiPreferences.getPrefPossibleValuesKey(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE), allScreensPrefValue)
.withPreference(DeviceSettingsUtils.getPrefPossibleValuesKey(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE), allScreensPrefValue)
.withPreference(DeviceSettingsUtils.getPrefPossibleValueLabelsKey(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE), allScreensLabelsPrefValue)
.withPreference(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE, prefValue);
getSupport().evaluateGBDeviceEvent(eventUpdatePreferences);
@ -515,34 +538,4 @@ public class XiaomiSystemService extends AbstractXiaomiService implements Xiaomi
LOG.error("Failed to update progress notification", e);
}
}
// TODO do we even need this? also prevent NPE when unknown
private static final Map<String, String> DISPLAY_ITEM_NAMES = new HashMap<String, String>() {{
put("today_act", "Stats");
put("sport", "Workout");
put("sport_record", "Activity");
put("sport_course", "Running");
put("sport_state", "Status");
put("heart", "Heart rate");
put("pai", "Vitality");
put("blood_ox", "SpO₂");
put("sleep", "Sleep");
put("press", "Stress");
put("weather", "Weather");
put("alarm", "Alarm");
put("setting", "Settings");
put("event_reminder", "Alerts");
put("schedule", "Events");
put("breath", "Breathing");
put("stopwatch", "Stopwatch");
put("music", "Music");
put("find_phone", "Find phone");
put("world_clock", "World clock");
put("phone_mute", "Silence phone");
put("phone_remote", "Camera");
put("count_down", "Timer");
put("focus", "Focus");
put("flash_light", "Flashlight");
put("fm_health", "Cycles");
}};
}

View File

@ -1022,66 +1022,6 @@
<item>headphone</item>
</string-array>
<string-array name="pref_xiaomi_apps">
<item>@string/menuitem_stats</item>
<item>@string/menuitem_workout</item>
<item>@string/menuitem_activity</item>
<item>@string/menuitem_running</item>
<item>@string/menuitem_status</item>
<item>@string/menuitem_hr</item>
<item>@string/menuitem_pai</item>
<item>@string/menuitem_spo2</item>
<item>@string/menuitem_sleep</item>
<item>@string/menuitem_stress</item>
<item>@string/menuitem_weather</item>
<item>@string/menuitem_alarm</item>
<item>@string/menuitem_settings</item>
<item>@string/menuitem_more</item> <!-- dummy item -->
<item>@string/menuitem_alerts</item>
<item>@string/menuitem_events</item>
<item>@string/menuitem_breathing</item>
<item>@string/menuitem_female_health</item>
<item>@string/menuitem_stopwatch</item>
<item>@string/menuitem_music</item>
<item>@string/menuitem_findphone</item>
<item>@string/menuitem_worldclock</item>
<item>@string/menuitem_mutephone</item>
<item>@string/menuitem_takephoto</item>
<item>@string/menuitem_timer</item>
<item>@string/menuitem_flashlight</item>
<item>@string/menuitem_pomodoro</item>
</string-array>
<string-array name="pref_xiaomi_apps_values">
<item>today_act</item>
<item>sport</item>
<item>sport_record</item>
<item>sport_course</item>
<item>sport_state</item>
<item>heart</item>
<item>pai</item>
<item>blood_ox</item>
<item>sleep</item>
<item>press</item>
<item>weather</item>
<item>alarm</item>
<item>setting</item>
<item>more</item> <!-- dummy item -->
<item>schedule</item>
<item>event_reminder</item>
<item>breath</item>
<item>fm_health</item>
<item>stopwatch</item>
<item>music</item>
<item>find_phone</item>
<item>world_clock</item>
<item>phone_mute</item>
<item>phone_remote</item>
<item>count_down</item>
<item>flash_light</item>
<item>focus</item>
</string-array>
<string-array name="pref_miband5_workout_activity_types">
<item>@string/activity_type_outdoor_running</item>
<item>@string/activity_type_walking</item>

View File

@ -3,8 +3,8 @@
<com.mobeta.android.dslv.DragSortListPreference
android:defaultValue="@array/pref_huami2021_empty_array"
android:dialogTitle="@string/mi2_prefs_display_items"
android:entries="@array/pref_xiaomi_apps"
android:entryValues="@array/pref_xiaomi_apps_values"
android:entries="@array/pref_huami2021_empty_array"
android:entryValues="@array/pref_huami2021_empty_array"
android:icon="@drawable/ic_widgets"
android:key="display_items_sortable"
android:persistent="true"