diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java index 54453e67..8073d86f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java @@ -21,6 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -28,8 +29,10 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity; +import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_HEIGHT_CM; import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_SLEEP_DURATION; @@ -155,6 +158,25 @@ public class SettingsActivity extends AbstractSettingsActivity { } }); + pref = findPreference("canned_messages_dismisscall_send"); + pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + Prefs prefs = GBApplication.getPrefs(); + ArrayList messages = new ArrayList<>(); + for (int i = 1; i <= 16; i++) { + String message = prefs.getString("canned_message_dismisscall_" + i, null); + if (message != null && !message.equals("")) { + messages.add(message); + } + } + CannedMessagesSpec cannedMessagesSpec = new CannedMessagesSpec(); + cannedMessagesSpec.type = CannedMessagesSpec.TYPE_MISSEDCALLS; + cannedMessagesSpec.cannedMessages = messages.toArray(new String[messages.size()]); + GBApplication.deviceService().onSetCannedMessages(cannedMessagesSpec); + return true; + } + }); + // Get all receivers of Media Buttons Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); @@ -206,6 +228,22 @@ public class SettingsActivity extends AbstractSettingsActivity { "canned_reply_14", "canned_reply_15", "canned_reply_16", + "canned_message_dismisscall_1", + "canned_message_dismisscall_2", + "canned_message_dismisscall_3", + "canned_message_dismisscall_4", + "canned_message_dismisscall_5", + "canned_message_dismisscall_6", + "canned_message_dismisscall_7", + "canned_message_dismisscall_8", + "canned_message_dismisscall_9", + "canned_message_dismisscall_10", + "canned_message_dismisscall_11", + "canned_message_dismisscall_12", + "canned_message_dismisscall_13", + "canned_message_dismisscall_14", + "canned_message_dismisscall_15", + "canned_message_dismisscall_16", PREF_USER_YEAR_OF_BIRTH, PREF_USER_HEIGHT_CM, PREF_USER_WEIGHT_KG, diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java index 97e0f8f6..8ca1e4a9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java @@ -8,6 +8,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; @@ -26,6 +27,8 @@ public interface EventHandler { void onSetCallState(CallSpec callSpec); + void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec); + void onSetMusicState(MusicStateSpec stateSpec); void onSetMusicInfo(MusicSpec musicSpec); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index 1aa83c9c..bc458c81 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -12,6 +12,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; @@ -30,8 +31,7 @@ public class GBDeviceService implements DeviceService { } protected Intent createIntent() { - Intent startIntent = new Intent(mContext, mServiceClass); - return startIntent; + return new Intent(mContext, mServiceClass); } protected void invokeService(Intent intent) { @@ -128,6 +128,14 @@ public class GBDeviceService implements DeviceService { invokeService(intent); } + @Override + public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) { + Intent intent = createIntent().setAction(ACTION_SETCANNEDMESSAGES) + .putExtra(EXTRA_CANNEDMESSAGES_TYPE, cannedMessagesSpec.type) + .putExtra(EXTRA_CANNEDMESSAGES, cannedMessagesSpec.cannedMessages); + invokeService(intent); + } + @Override public void onSetMusicState(MusicStateSpec stateSpec) { Intent intent = createIntent().setAction(ACTION_SETMUSICSTATE) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index 59518f7a..7c459f42 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -16,6 +16,7 @@ public interface DeviceService extends EventHandler { String ACTION_CONNECT = PREFIX + ".action.connect"; String ACTION_NOTIFICATION = PREFIX + ".action.notification"; String ACTION_CALLSTATE = PREFIX + ".action.callstate"; + String ACTION_SETCANNEDMESSAGES = PREFIX + ".action.setcannedmessages"; String ACTION_SETTIME = PREFIX + ".action.settime"; String ACTION_SETMUSICINFO = PREFIX + ".action.setmusicinfo"; String ACTION_SETMUSICSTATE = PREFIX + ".action.setmusicstate"; @@ -53,6 +54,8 @@ public interface DeviceService extends EventHandler { String EXTRA_FIND_START = "find_start"; String EXTRA_CALL_COMMAND = "call_command"; String EXTRA_CALL_PHONENUMBER = "call_phonenumber"; + String EXTRA_CANNEDMESSAGES = "cannedmessages"; + String EXTRA_CANNEDMESSAGES_TYPE = "cannedmessages_type"; String EXTRA_MUSIC_ARTIST = "music_artist"; String EXTRA_MUSIC_ALBUM = "music_album"; String EXTRA_MUSIC_TRACK = "music_track"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index f66ed504..c604359f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -37,6 +37,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; @@ -66,6 +67,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_RE import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_APPINFO; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_DEVICEINFO; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_SCREENSHOT; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETCANNEDMESSAGES; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETMUSICINFO; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETMUSICSTATE; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETTIME; @@ -85,6 +87,8 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CAL import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_TYPE; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_COMMAND; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_PHONENUMBER; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CANNEDMESSAGES; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CANNEDMESSAGES_TYPE; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_DEVICE_ADDRESS; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_FIND_START; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_ALBUM; @@ -346,6 +350,15 @@ public class DeviceCommunicationService extends Service implements SharedPrefere callSpec.name = callerName; mDeviceSupport.onSetCallState(callSpec); break; + case ACTION_SETCANNEDMESSAGES: + int type = intent.getIntExtra(EXTRA_CANNEDMESSAGES_TYPE, -1); + String[] cannedMessages = intent.getStringArrayExtra(EXTRA_CANNEDMESSAGES); + + CannedMessagesSpec cannedMessagesSpec = new CannedMessagesSpec(); + cannedMessagesSpec.type = type; + cannedMessagesSpec.cannedMessages = cannedMessages; + mDeviceSupport.onSetCannedMessages(cannedMessagesSpec); + break; case ACTION_SETTIME: mDeviceSupport.onSetTime(); break; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java index bf43077b..7c509984 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java @@ -15,6 +15,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; @@ -151,6 +152,14 @@ public class ServiceDeviceSupport implements DeviceSupport { delegate.onSetCallState(callSpec); } + @Override + public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) { + if (checkBusy("set canned messages")) { + return; + } + delegate.onSetCannedMessages(cannedMessagesSpec); + } + @Override public void onSetMusicState(MusicStateSpec stateSpec) { if (checkBusy("set music state")) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java index fbb73cc5..96996834 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java @@ -35,6 +35,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEvents; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; import nodomain.freeyourgadget.gadgetbridge.model.GenericItem; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; @@ -595,6 +596,10 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { } } + @Override + public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) { + } + private boolean isTelephoneRinging() { // don't synchronize, this is not really important return telephoneRinging; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 05c39bf6..23db3475 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -35,6 +35,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp; import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; @@ -85,7 +86,10 @@ public class PebbleProtocol extends GBDeviceProtocol { static final byte BLOBDB_APP = 2; static final byte BLOBDB_REMINDER = 3; static final byte BLOBDB_NOTIFICATION = 4; + static final byte BLOBDB_CANNED_MESSAGES = 6; static final byte BLOBDB_PREFERENCES = 7; + static final byte BLOBDB_APPGLANCE = 11; + static final byte BLOBDB_SUCCESS = 1; static final byte BLOBDB_GENERALFAILURE = 2; static final byte BLOBDB_INVALIDOPERATION = 3; @@ -1318,6 +1322,53 @@ public class PebbleProtocol extends GBDeviceProtocol { return buf.array(); } + @Override + public byte[] encodeSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) { + + if (cannedMessagesSpec.cannedMessages == null || cannedMessagesSpec.cannedMessages.length == 0) { + return null; + } + + String blobDBKey; + switch (cannedMessagesSpec.type) { + case CannedMessagesSpec.TYPE_MISSEDCALLS: + blobDBKey = "com.pebble.android.phone"; + break; + case CannedMessagesSpec.TYPE_NEWSMS: + blobDBKey = "com.pebble.sendText"; + break; + default: + return null; + } + + int replies_length = -1; + + for (String reply : cannedMessagesSpec.cannedMessages) { + replies_length += reply.getBytes().length + 1; + } + + ByteBuffer buf = ByteBuffer.allocate(12 + replies_length); + buf.order(ByteOrder.LITTLE_ENDIAN); + buf.putInt(0x00000000); // unknown + buf.put((byte) 0x00); // atributes count? + buf.put((byte) 0x01); // actions count? + + // action + buf.put((byte) 0x00); // action id + buf.put((byte) 0x03); // action type = reply + buf.put((byte) 0x01); // attributes count + buf.put((byte) 0x08); // canned messages + buf.putShort((short) replies_length); + for (int i = 0; i < cannedMessagesSpec.cannedMessages.length - 1; i++) { + buf.put(cannedMessagesSpec.cannedMessages[i].getBytes()); + buf.put((byte) 0x00); + } + // last one must not be zero terminated, else we get an additional empty reply + buf.put(cannedMessagesSpec.cannedMessages[cannedMessagesSpec.cannedMessages.length - 1].getBytes()); + + return encodeBlobdb(blobDBKey, BLOBDB_INSERT, BLOBDB_CANNED_MESSAGES, buf.array()); + } + /* pebble specific install methods */ public byte[] encodeUploadStart(byte type, int app_id, int size, String filename) { short length; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java index 0e4f5bbf..53e3593e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java @@ -1,8 +1,5 @@ package nodomain.freeyourgadget.gadgetbridge.service.serial; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; @@ -10,6 +7,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes; import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; @@ -29,9 +27,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport; * to create the device specific message for the respective events and sends them to the device via {@link #sendToDevice(byte[])}. */ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport { - - private static final Logger LOG = LoggerFactory.getLogger(AbstractDeviceSupport.class); - protected GBDeviceProtocol gbDeviceProtocol; protected GBDeviceIoThread gbDeviceIOThread; @@ -124,6 +119,12 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport sendToDevice(bytes); } + @Override + public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) { + byte[] bytes = gbDeviceProtocol.encodeSetCannedMessages(cannedMessagesSpec); + sendToDevice(bytes); + } + @Override public void onSetMusicState(MusicStateSpec stateSpec) { byte[] bytes = gbDeviceProtocol.encodeSetMusicState(stateSpec.state, stateSpec.position, stateSpec.playRate, stateSpec.shuffle, stateSpec.repeat); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java index ec641e36..e46c83b8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java @@ -5,6 +5,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; +import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; public abstract class GBDeviceProtocol { @@ -27,6 +28,10 @@ public abstract class GBDeviceProtocol { return null; } + public byte[] encodeSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) { + return null; + } + public byte[] encodeSetMusicInfo(String artist, String album, String track, int duration, int trackCount, int trackNr) { return null; } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3bc390d9..55b266bb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -67,8 +67,11 @@ Blacklist Apps - Canned Replies + Canned Messages + Replies Common suffix + Call Dismissal + Update on Pebble Developer Options Mi Band address diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 7c5723b6..bf34e969 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -94,63 +94,6 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +