From 03dbf7533f09006cd7a802b1c13983e5bb5158ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Wed, 6 Dec 2023 11:17:36 +0000 Subject: [PATCH] Xiaomi: Get canned messages from watch --- .../DeviceSpecificSettingsFragment.java | 23 +++++++- .../devices/AbstractDeviceCoordinator.java | 5 ++ .../devices/DeviceCoordinator.java | 5 ++ .../devices/huami/Huami2021Coordinator.java | 5 ++ .../devices/pebble/PebbleCoordinator.java | 5 ++ .../devices/qhybrid/QHybridCoordinator.java | 9 +++ .../devices/xiaomi/XiaomiCoordinator.java | 9 ++- .../devices/xiaomi/XiaomiPreferences.java | 2 + .../services/XiaomiNotificationService.java | 58 ++++++++++++++++--- .../devicesettings_canned_dismisscall_16.xml | 5 ++ .../xml/devicesettings_canned_reply_16.xml | 5 ++ 11 files changed, 119 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index 32efc921c..849367934 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -772,12 +772,14 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i }); } + final int cannedRepliesSlotCount = coordinator.getCannedRepliesSlotCount(device); + final Preference cannedMessagesDismissCall = findPreference("canned_messages_dismisscall_send"); if (cannedMessagesDismissCall != null) { cannedMessagesDismissCall.setOnPreferenceClickListener(new androidx.preference.Preference.OnPreferenceClickListener() { public boolean onPreferenceClick(androidx.preference.Preference preference) { ArrayList messages = new ArrayList<>(); - for (int i = 1; i <= 16; i++) { + for (int i = 1; i <= cannedRepliesSlotCount; i++) { String message = prefs.getString("canned_message_dismisscall_" + i, null); if (message != null && !message.equals("")) { messages.add(message); @@ -790,14 +792,23 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i return true; } }); + + // TODO we could use this to auto-create preferences for watches with > 16 slots + for (int i = cannedRepliesSlotCount + 1; i <= 16; i++) { + final Preference cannedReplyPref = findPreference("canned_message_dismisscall_" + i); + if (cannedReplyPref != null) { + cannedReplyPref.setVisible(false); + } + } } final Preference cannedMessagesGeneric = findPreference("canned_messages_generic_send"); if (cannedMessagesGeneric != null) { + cannedMessagesGeneric.setOnPreferenceClickListener(new androidx.preference.Preference.OnPreferenceClickListener() { public boolean onPreferenceClick(androidx.preference.Preference preference) { final ArrayList messages = new ArrayList<>(); - for (int i = 1; i <= 16; i++) { + for (int i = 1; i <= cannedRepliesSlotCount; i++) { String message = prefs.getString("canned_reply_" + i, null); if (message != null && !message.equals("")) { messages.add(message); @@ -810,6 +821,14 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i return true; } }); + + // TODO we could use this to auto-create preferences for watches with > 16 slots + for (int i = cannedRepliesSlotCount + 1; i <= 16; i++) { + final Preference cannedReplyPref = findPreference("canned_reply_" + i); + if (cannedReplyPref != null) { + cannedReplyPref.setVisible(false); + } + } } setInputTypeFor(HuamiConst.PREF_BUTTON_ACTION_BROADCAST_DELAY, InputType.TYPE_CLASS_NUMBER); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java index 080df31ad..e5d58e595 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java @@ -432,6 +432,11 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { return 0; } + @Override + public int getCannedRepliesSlotCount(final GBDevice device) { + return 0; + } + @Override public int getWorldClocksSlotCount() { return 0; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java index 913780c60..618e5fa6f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java @@ -451,6 +451,11 @@ public interface DeviceCoordinator { */ int getReminderSlotCount(GBDevice device); + /** + * Indicates the maximum number of canned replies available in the device. + */ + int getCannedRepliesSlotCount(GBDevice device); + /** * Indicates the maximum number of slots available for world clocks in the device. */ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021Coordinator.java index e23cf4725..33e16abc6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021Coordinator.java @@ -283,6 +283,11 @@ public abstract class Huami2021Coordinator extends HuamiCoordinator { return ZeppOsRemindersService.getSlotCount(getPrefs(device)); } + @Override + public int getCannedRepliesSlotCount(final GBDevice device) { + return 16; + } + @Override public int getContactsSlotCount(final GBDevice device) { return getPrefs(device).getInt(ZeppOsContactsService.PREF_CONTACTS_SLOT_COUNT, 0); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java index 4c4493a21..cf72a164d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java @@ -125,6 +125,11 @@ public class PebbleCoordinator extends AbstractBLClassicDeviceCoordinator { return 0; } + @Override + public int getCannedRepliesSlotCount(final GBDevice device) { + return 16; + } + @Override public boolean supportsSmartWakeup(GBDevice device) { return false; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java index 21bbcb88a..5b9d1ac46 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridCoordinator.java @@ -146,6 +146,15 @@ public class QHybridCoordinator extends AbstractBLEDeviceCoordinator { return this.supportsAlarmConfiguration() ? 5 : 0; } + @Override + public int getCannedRepliesSlotCount(final GBDevice device) { + if (isHybridHR()) { + return 16; + } + + return 0; + } + @Override public boolean supportsAlarmDescription(GBDevice device) { return isHybridHR(); 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 0662bb5c9..ec5413ed1 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 @@ -279,6 +279,11 @@ public abstract class XiaomiCoordinator extends AbstractBLEDeviceCoordinator { return getPrefs(device).getInt(XiaomiPreferences.PREF_REMINDER_SLOTS, 0); } + @Override + public int getCannedRepliesSlotCount(final GBDevice device) { + return getPrefs(device).getInt(XiaomiPreferences.PREF_CANNED_MESSAGES_MAX, 0); + } + @Override public int getWorldClocksSlotCount() { // TODO how many? also, map world clocks @@ -387,7 +392,9 @@ public abstract class XiaomiCoordinator extends AbstractBLEDeviceCoordinator { settings.add(R.xml.devicesettings_donotdisturb_withauto_and_always); settings.add(R.xml.devicesettings_screen_on_on_notifications); settings.add(R.xml.devicesettings_autoremove_notifications); - settings.add(R.xml.devicesettings_canned_reply_16); + if (getCannedRepliesSlotCount(device) > 0) { + settings.add(R.xml.devicesettings_canned_dismisscall_16); + } // // Calendar 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 e4d5109dc..721270b86 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 @@ -30,6 +30,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public final class XiaomiPreferences { public static final String PREF_ALARM_SLOTS = "alarm_slots"; public static final String PREF_REMINDER_SLOTS = "reminder_slots"; + public static final String PREF_CANNED_MESSAGES_MIN = "canned_messages_min"; + public static final String PREF_CANNED_MESSAGES_MAX = "canned_messages_max"; private XiaomiPreferences() { // util class 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 b0315c133..91da93302 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 @@ -37,10 +37,12 @@ import java.util.Queue; import nodomain.freeyourgadget.gadgetbridge.BuildConfig; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventNotificationControl; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto; +import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiPreferences; import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSupport; import nodomain.freeyourgadget.gadgetbridge.util.BitmapUtil; import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils; @@ -242,18 +244,36 @@ public class XiaomiNotificationService extends AbstractXiaomiService implements } public void onSetCannedMessages(final CannedMessagesSpec cannedMessagesSpec) { - if (cannedMessagesSpec.type != CannedMessagesSpec.TYPE_GENERIC) { + if (cannedMessagesSpec.type != CannedMessagesSpec.TYPE_REJECTEDCALLS) { LOG.warn("Got unsupported canned messages type: {}", cannedMessagesSpec.type); return; } + final int minReplies = getDevicePrefs().getInt(XiaomiPreferences.PREF_CANNED_MESSAGES_MIN, 0); + final int maxReplies = getDevicePrefs().getInt(XiaomiPreferences.PREF_CANNED_MESSAGES_MAX, 0); + + if (maxReplies == 0) { + LOG.warn("Attempting to set canned messages, but max replies is 0"); + return; + } + final XiaomiProto.CannedMessages.Builder cannedMessagesBuilder = XiaomiProto.CannedMessages.newBuilder() - // TODO get those from wathc - // TODO enforce these - .setMinReplies(1) - .setMaxReplies(10); + .setMinReplies(minReplies) + .setMaxReplies(maxReplies); + int i = 0; for (final String cannedMessage : cannedMessagesSpec.cannedMessages) { + if (i >= maxReplies) { + LOG.warn("Got too many canned messages ({}), limit is {}", cannedMessagesSpec.cannedMessages.length, maxReplies); + break; + } + cannedMessagesBuilder.addReply(cannedMessage); + + i++; + } + + for (; i < minReplies; i++) { + cannedMessagesBuilder.addReply("-"); } final XiaomiProto.Notification.Builder notificationBuilder = XiaomiProto.Notification.newBuilder() @@ -281,10 +301,30 @@ public class XiaomiNotificationService extends AbstractXiaomiService implements } public void handleCannedMessages(final XiaomiProto.CannedMessages cannedMessages) { - // TODO save them - //final GBDeviceEventUpdatePreferences gbDeviceEventUpdatePreferences = new GBDeviceEventUpdatePreferences(); - //gbDeviceEventUpdatePreferences.withPreference("canned_reply_" + i, message); - //getSupport().evaluateGBDeviceEvent(gbDeviceEventUpdatePreferences); + LOG.info("Got {} canned messages", cannedMessages.getReplyCount()); + + final int minReplies = cannedMessages.getMinReplies(); + final int maxReplies = cannedMessages.getMaxReplies(); + final GBDeviceEventUpdatePreferences gbDeviceEventUpdatePreferences = new GBDeviceEventUpdatePreferences() + .withPreference(XiaomiPreferences.PREF_CANNED_MESSAGES_MIN, minReplies) + .withPreference(XiaomiPreferences.PREF_CANNED_MESSAGES_MAX, maxReplies); + + int i = 1; + for (final String reply : cannedMessages.getReplyList()) { + gbDeviceEventUpdatePreferences.withPreference("canned_message_dismisscall_" + i, reply); + i++; + + if (i > maxReplies || i > 16) { + LOG.warn("Got too many canned messages ({})", i); + break; + } + } + + for (int j = i; j <= maxReplies; j++) { + gbDeviceEventUpdatePreferences.withPreference("canned_message_dismisscall_" + j, null); + } + + getSupport().evaluateGBDeviceEvent(gbDeviceEventUpdatePreferences); } public boolean canSendSms() { diff --git a/app/src/main/res/xml/devicesettings_canned_dismisscall_16.xml b/app/src/main/res/xml/devicesettings_canned_dismisscall_16.xml index 8722b5640..5436114d5 100644 --- a/app/src/main/res/xml/devicesettings_canned_dismisscall_16.xml +++ b/app/src/main/res/xml/devicesettings_canned_dismisscall_16.xml @@ -13,6 +13,11 @@ android:summary="@string/pref_summary_canned_messages_set" android:title="@string/pref_title_canned_messages_set" /> + + diff --git a/app/src/main/res/xml/devicesettings_canned_reply_16.xml b/app/src/main/res/xml/devicesettings_canned_reply_16.xml index 50e2455d8..5d1790f78 100644 --- a/app/src/main/res/xml/devicesettings_canned_reply_16.xml +++ b/app/src/main/res/xml/devicesettings_canned_reply_16.xml @@ -20,6 +20,11 @@ android:title="@string/pref_title_canned_reply_suffix" app:useSimpleSummaryProvider="true" /> + +