From 8d1c243297e2b37d821ccdc4b145f5efd443be92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sun, 10 Dec 2023 12:24:59 +0000 Subject: [PATCH] Xiaomi: Detect supported preferences --- .../devices/xiaomi/XiaomiCoordinator.java | 43 +++++++++++++------ .../xiaomi/XiaomiSettingsCustomizer.java | 12 ++++++ .../miwatch/MiWatchLiteCoordinator.java | 1 - .../XiaomiWatchS1ActiveCoordinator.java | 5 --- .../devices/xiaomi/XiaomiPreferences.java | 12 ++++++ .../xiaomi/services/XiaomiHealthService.java | 5 +++ .../services/XiaomiNotificationService.java | 3 ++ .../xiaomi/services/XiaomiSystemService.java | 16 +++++++ 8 files changed, 78 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiCoordinator.java index d40cb2ce2..c6f0cd39a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiCoordinator.java @@ -16,6 +16,8 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.xiaomi; +import static nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiPreferences.*; + import android.app.Activity; import android.bluetooth.le.ScanFilter; import android.os.ParcelUuid; @@ -47,7 +49,6 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.XiaomiActivitySampleDao; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.model.AbstractNotificationPattern; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser; import nodomain.freeyourgadget.gadgetbridge.model.HeartRateSample; @@ -361,19 +362,31 @@ public abstract class XiaomiCoordinator extends AbstractBLEDeviceCoordinator { // Display // settings.add(R.xml.devicesettings_header_display); - settings.add(R.xml.devicesettings_xiaomi_displayitems); - settings.add(R.xml.devicesettings_password); + if (supports(device, FEAT_DISPLAY_ITEMS)) { + settings.add(R.xml.devicesettings_xiaomi_displayitems); + } + if (supports(device, FEAT_PASSWORD)) { + settings.add(R.xml.devicesettings_password); + } // // Health // settings.add(R.xml.devicesettings_header_health); settings.add(R.xml.devicesettings_heartrate_sleep_alert_activity_stress_spo2); - settings.add(R.xml.devicesettings_inactivity_dnd_no_threshold); - settings.add(R.xml.devicesettings_sleep_mode_schedule); - settings.add(R.xml.devicesettings_goal_notification); - settings.add(R.xml.devicesettings_goal_secondary); - settings.add(R.xml.devicesettings_vitality_score); + if (supports(device, FEAT_INACTIVITY)) { + settings.add(R.xml.devicesettings_inactivity_dnd_no_threshold); + } + if (supports(device, FEAT_SLEEP_MODE_SCHEDULE)) { + settings.add(R.xml.devicesettings_sleep_mode_schedule); + } + if (supports(device, FEAT_GOAL_NOTIFICATION)) { + settings.add(R.xml.devicesettings_goal_notification); + settings.add(R.xml.devicesettings_goal_secondary); + } + if (supports(device, FEAT_VITALITY_SCORE)) { + settings.add(R.xml.devicesettings_vitality_score); + } // // Workout @@ -389,7 +402,9 @@ public abstract class XiaomiCoordinator extends AbstractBLEDeviceCoordinator { // TODO not implemented settings.add(R.xml.devicesettings_vibrationpatterns); // TODO not implemented settings.add(R.xml.devicesettings_donotdisturb_withauto_and_always); settings.add(R.xml.devicesettings_send_app_notifications); - settings.add(R.xml.devicesettings_screen_on_on_notifications); + if (supports(device, FEAT_SCREEN_ON_ON_NOTIFICATIONS)) { + settings.add(R.xml.devicesettings_screen_on_on_notifications); + } settings.add(R.xml.devicesettings_autoremove_notifications); if (getCannedRepliesSlotCount(device) > 0) { settings.add(R.xml.devicesettings_canned_dismisscall_16); @@ -410,8 +425,10 @@ public abstract class XiaomiCoordinator extends AbstractBLEDeviceCoordinator { if (getContactsSlotCount(device) > 0) { settings.add(R.xml.devicesettings_contacts); } - settings.add(R.xml.devicesettings_camera_remote); - if (supportsWearingAndSleepingDataThroughDeviceState()) { + // TODO not implemented if (supports(device, FEAT_CAMERA_REMOTE)) { + // TODO not implemented settings.add(R.xml.devicesettings_camera_remote); + // TODO not implemented } + if (supports(device, FEAT_DEVICE_ACTIONS)) { settings.add(R.xml.devicesettings_device_actions); } @@ -492,7 +509,7 @@ public abstract class XiaomiCoordinator extends AbstractBLEDeviceCoordinator { return false; } - public boolean supportsWearingAndSleepingDataThroughDeviceState() { - return false; + public boolean supports(final GBDevice device, final String feature) { + return getPrefs(device).getBoolean(feature, false); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiSettingsCustomizer.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiSettingsCustomizer.java index c0c6f1b1b..af198707c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiSettingsCustomizer.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiSettingsCustomizer.java @@ -16,12 +16,14 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.xiaomi; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsUtils.hidePrefIfNoneVisible; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsUtils.populateOrHideListPreference; import android.os.Parcel; import androidx.preference.Preference; +import java.util.Arrays; import java.util.Collections; import java.util.Set; @@ -44,6 +46,16 @@ public class XiaomiSettingsCustomizer implements DeviceSpecificSettingsCustomize } populateOrHideListPreference(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE, handler, prefs); + + hidePrefIfNoneVisible(handler, DeviceSettingsPreferenceConst.PREF_HEADER_DISPLAY, Arrays.asList( + HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE, + DeviceSettingsPreferenceConst.PREF_SCREEN_PASSWORD + )); + hidePrefIfNoneVisible(handler, "pref_header_other", Arrays.asList( + "pref_contacts", + "camera_remote", + "screen_events_forwarding" + )); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/miwatch/MiWatchLiteCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/miwatch/MiWatchLiteCoordinator.java index f7a4ab230..a7ad29601 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/miwatch/MiWatchLiteCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/miwatch/MiWatchLiteCoordinator.java @@ -27,7 +27,6 @@ import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiInstallHandler; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; public class MiWatchLiteCoordinator extends XiaomiCoordinator { @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/watchs1active/XiaomiWatchS1ActiveCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/watchs1active/XiaomiWatchS1ActiveCoordinator.java index 76a957d61..3ed43f298 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/watchs1active/XiaomiWatchS1ActiveCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/watchs1active/XiaomiWatchS1ActiveCoordinator.java @@ -67,9 +67,4 @@ public class XiaomiWatchS1ActiveCoordinator extends XiaomiCoordinator { public boolean supportsMultipleWeatherLocations() { return true; } - - @Override - public boolean supportsWearingAndSleepingDataThroughDeviceState() { - return true; - } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiPreferences.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiPreferences.java index 721270b86..be63f4f24 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiPreferences.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiPreferences.java @@ -33,6 +33,18 @@ public final class XiaomiPreferences { public static final String PREF_CANNED_MESSAGES_MIN = "canned_messages_min"; public static final String PREF_CANNED_MESSAGES_MAX = "canned_messages_max"; + public static final String FEAT_DEVICE_ACTIONS = "feat_device_actions"; + public static final String FEAT_DISPLAY_ITEMS = "feat_display_items"; + public static final String FEAT_STRESS = "feat_stress"; + public static final String FEAT_SPO2 = "feat_spo2"; + public static final String FEAT_PASSWORD = "feat_password"; + public static final String FEAT_INACTIVITY = "feat_inactivity"; + public static final String FEAT_SLEEP_MODE_SCHEDULE = "feat_sleep_mode_schedule"; + public static final String FEAT_GOAL_NOTIFICATION = "feat_goal_notification"; + public static final String FEAT_VITALITY_SCORE = "feat_vitality_score"; + public static final String FEAT_SCREEN_ON_ON_NOTIFICATIONS = "feat_screen_on_on_notifications"; + public static final String FEAT_CAMERA_REMOTE = "feat_camera_remote"; + private XiaomiPreferences() { // util class } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiHealthService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiHealthService.java index 579c58a9c..fb5c20cc5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiHealthService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiHealthService.java @@ -292,6 +292,7 @@ public class XiaomiHealthService extends AbstractXiaomiService { } final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences() + .withPreference(XiaomiPreferences.FEAT_GOAL_NOTIFICATION, true) .withPreference(DeviceSettingsPreferenceConst.PREF_USER_FITNESS_GOAL_NOTIFICATION, achievementReminders.getEnabled()) .withPreference(DeviceSettingsPreferenceConst.PREF_USER_FITNESS_GOAL_SECONDARY, secondaryValue); @@ -332,6 +333,7 @@ public class XiaomiHealthService extends AbstractXiaomiService { LOG.debug("Got vitality score config"); final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences() + .withPreference(XiaomiPreferences.FEAT_VITALITY_SCORE, true) .withPreference(DeviceSettingsPreferenceConst.PREF_VITALITY_SCORE_7_DAY, vitalityScore.getSevenDay()) .withPreference(DeviceSettingsPreferenceConst.PREF_VITALITY_SCORE_DAILY, vitalityScore.getDailyProgress()); @@ -367,6 +369,7 @@ public class XiaomiHealthService extends AbstractXiaomiService { LOG.debug("Got SpO2 config"); final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences() + .withPreference(XiaomiPreferences.FEAT_SPO2, true) .withPreference(DeviceSettingsPreferenceConst.PREF_SPO2_ALL_DAY_MONITORING, spo2.getAllDayTracking()) .withPreference( DeviceSettingsPreferenceConst.PREF_SPO2_LOW_ALERT_THRESHOLD, @@ -492,6 +495,7 @@ public class XiaomiHealthService extends AbstractXiaomiService { final String dndEnd = XiaomiPreferences.prefFromHourMin(standingReminder.getDndEnd()); final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences() + .withPreference(XiaomiPreferences.FEAT_INACTIVITY, true) .withPreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_ENABLE, standingReminder.getEnabled()) .withPreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_START, start) .withPreference(DeviceSettingsPreferenceConst.PREF_INACTIVITY_END, end) @@ -536,6 +540,7 @@ public class XiaomiHealthService extends AbstractXiaomiService { LOG.debug("Got stress config"); final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences() + .withPreference(XiaomiPreferences.FEAT_STRESS, true) .withPreference(DeviceSettingsPreferenceConst.PREF_HEARTRATE_STRESS_MONITORING, stress.getAllDayTracking()) .withPreference(DeviceSettingsPreferenceConst.PREF_HEARTRATE_STRESS_RELAXATION_REMINDER, stress.getRelaxReminder().getEnabled()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiNotificationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiNotificationService.java index d0ee2fb6a..13b2eeceb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiNotificationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiNotificationService.java @@ -121,6 +121,9 @@ public class XiaomiNotificationService extends AbstractXiaomiService implements final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences( DeviceSettingsPreferenceConst.PREF_SCREEN_ON_ON_NOTIFICATIONS, screenOnOnNotifications + ).withPreference( + XiaomiPreferences.FEAT_SCREEN_ON_ON_NOTIFICATIONS, + true ); getSupport().evaluateGBDeviceEvent(eventUpdatePreferences); return; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiSystemService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiSystemService.java index 3c5529027..f42b9e710 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiSystemService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiSystemService.java @@ -50,6 +50,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.WearingState; import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction; +import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiPreferences; import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSupport; import nodomain.freeyourgadget.gadgetbridge.util.CheckSums; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -71,6 +72,8 @@ public class XiaomiSystemService extends AbstractXiaomiService implements Xiaomi public static final int CMD_CLOCK = 3; public static final int CMD_FIRMWARE_INSTALL = 5; public static final int CMD_LANGUAGE = 6; + public static final int CMD_CAMERA_REMOTE_GET = 7; + public static final int CMD_CAMERA_REMOTE_SET = 8; public static final int CMD_PASSWORD_GET = 9; public static final int CMD_FIND_PHONE = 17; public static final int CMD_FIND_WATCH = 18; @@ -329,6 +332,11 @@ public class XiaomiSystemService extends AbstractXiaomiService implements Xiaomi password.getPassword() ); } + eventUpdatePreferences.withPreference( + XiaomiPreferences.FEAT_PASSWORD, + true + ); + getSupport().evaluateGBDeviceEvent(eventUpdatePreferences); } @@ -453,6 +461,7 @@ public class XiaomiSystemService extends AbstractXiaomiService implements Xiaomi final String prefValue = StringUtils.join(",", enabledScreens.toArray(new String[0])).toString(); final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences() + .withPreference(XiaomiPreferences.FEAT_DISPLAY_ITEMS, displayItems.getDisplayItemCount() > 0) .withPreference(DeviceSettingsUtils.getPrefPossibleValuesKey(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE), allScreensPrefValue) .withPreference(DeviceSettingsUtils.getPrefPossibleValueLabelsKey(HuamiConst.PREF_DISPLAY_ITEMS_SORTABLE), allScreensLabelsPrefValue) .withPreference(PREF_SETTINGS_DISPLAY_ITEM_CODE, settingsCode) @@ -522,6 +531,13 @@ public class XiaomiSystemService extends AbstractXiaomiService implements Xiaomi return; } + // If we got basic device state, we support device actions + final GBDeviceEventUpdatePreferences eventUpdatePreferences = new GBDeviceEventUpdatePreferences( + XiaomiPreferences.FEAT_DEVICE_ACTIONS, + true + ); + getSupport().evaluateGBDeviceEvent(eventUpdatePreferences); + // handle battery info from message { BatteryState newBatteryState = deviceState.getIsCharging() ? BatteryState.BATTERY_CHARGING : BatteryState.BATTERY_NORMAL;