diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java index f0f94547e1..51ce4189f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java @@ -804,6 +804,12 @@ public class HuaweiCoordinator { return false; } + public boolean supportsNotificationsStartCall() { + if (supportsExpandCapability()) + return supportsExpandCapability(74); + return false; + } + public boolean supportsNotificationsAddIconTimestamp() { if (supportsExpandCapability()) return supportsExpandCapability(77); @@ -996,7 +1002,7 @@ public class HuaweiCoordinator { return (((notificationCapabilities >> 1) & 1) == 0); } - public boolean supportsOutgoingCall () { + public boolean supportsOutgoingCall() { return (((notificationCapabilities >> 2) & 1) == 0); } @@ -1004,7 +1010,7 @@ public class HuaweiCoordinator { return supportsNotificationConstraint(NotificationConstraintsType.yellowPagesSupport); } - public boolean supportsContentSIgn() { + public boolean supportsContentSign() { return supportsNotificationConstraint(NotificationConstraintsType.contentSignSupport); } @@ -1024,7 +1030,7 @@ public class HuaweiCoordinator { return getNotificationConstraint(NotificationConstraintsType.contentSignFormat); } - public int getIncomingFormatFormat() { + public int getIncomingNumberFormat() { return getNotificationConstraint(NotificationConstraintsType.incomingNumberFormat); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Notifications.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Notifications.java index 2c70715c88..d350065770 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Notifications.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Notifications.java @@ -20,6 +20,7 @@ import android.text.TextUtils; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTLV; @@ -36,6 +37,18 @@ public class Notifications { public static class NotificationActionRequest extends HuaweiPacket { public static final byte id = 0x01; + public static class TextElement { + public byte textType; + public byte encoding; + public String value; + + public TextElement(byte textType, byte encoding, String value) { + this.textType = textType; + this.value = value; + this.encoding = encoding; + } + } + public static class AdditionalParams { public boolean supportsReply = false; @@ -76,10 +89,13 @@ public class Notifications { ParamsProvider paramsProvider, short msgId, byte notificationType, - int encoding, - String titleContent, - String senderContent, - String bodyContent, + ArrayList content, +// int encoding, +// String titleContent, +// String senderContent, +// String bodyContent, +// int numberFormat, +// String numberContent, String sourceAppId, AdditionalParams addParams ) { @@ -96,26 +112,15 @@ public class Notifications { .put(0x03, true); // This used to be vibrate, but doesn't work HuaweiTLV subTlv = new HuaweiTLV(); - if (titleContent != null && !titleContent.isEmpty()) - subTlv.put(0x8D, new HuaweiTLV() - .put(0x0E, (byte) TextType.title) - .put(0x0F, (byte) encoding) - .put(0x10, titleContent) - ); - if (senderContent != null && !senderContent.isEmpty()) - subTlv.put(0x8D, new HuaweiTLV() - .put(0x0E, (byte) TextType.sender) - .put(0x0F, (byte) encoding) - .put(0x10, senderContent) - ); - - if (bodyContent != null && !bodyContent.isEmpty()) - subTlv.put(0x8D, new HuaweiTLV() - .put(0x0E, (byte) TextType.text) - .put(0x0F, (byte) encoding) - .put(0x10, bodyContent) - ); + for(TextElement el: content) { + HuaweiTLV elTlv = new HuaweiTLV() + .put(0x0E, el.textType) + .put(0x0F, el.encoding); + if(el.value != null && !el.value.isEmpty()) + elTlv.put(0x10, el.value); // TODO: truncate text by capability. + subTlv.put(0x8D, elTlv); + } if (subTlv.length() != 0) { this.tlv.put(0x84, new HuaweiTLV().put(0x8C, subTlv)); @@ -247,8 +252,10 @@ public class Notifications { public static final byte weChat = 0x03; public static final byte qq = 0x0B; public static final byte stopNotification = 0x0C; // To stop showing a (call) notification + public static final byte startCall = 0x0D; public static final byte missedCall = 0x0E; public static final byte email = 0x0F; + public static final byte outgoingCall = 0x32; public static final byte generic = 0x7F; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java index 5ab1270e85..d94bab65cb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java @@ -87,6 +87,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTrueSleepSequen import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiUtil; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.CameraRemote; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.GpsAndTime; +import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Notifications; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Workout; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.ui.HuaweiStressCalibrationFragment; @@ -1911,7 +1912,7 @@ public class HuaweiSupportProvider { } public void onSetCallState(CallSpec callSpec) { - if (callSpec.command == CallSpec.CALL_INCOMING) { + if (callSpec.command == CallSpec.CALL_INCOMING || (callSpec.command == CallSpec.CALL_OUTGOING && getHuaweiCoordinator().supportsOutgoingCall())) { SendNotificationRequest sendNotificationReq = new SendNotificationRequest(this); try { sendNotificationReq.buildNotificationTLVFromCallSpec(callSpec); @@ -1921,11 +1922,19 @@ public class HuaweiSupportProvider { } } else if ( callSpec.command == CallSpec.CALL_ACCEPT || - callSpec.command == CallSpec.CALL_START || + callSpec.command == CallSpec.CALL_START) { + byte type = getHuaweiCoordinator().supportsNotificationsStartCall()?Notifications.NotificationType.startCall:Notifications.NotificationType.stopNotification; + StopNotificationRequest stopNotificationRequest = new StopNotificationRequest(this, type); + try { + stopNotificationRequest.doPerform(); + } catch (IOException e) { + LOG.error("Failed to send stop call notification", e); + } + }else if ( callSpec.command == CallSpec.CALL_REJECT || callSpec.command == CallSpec.CALL_END ) { - StopNotificationRequest stopNotificationRequest = new StopNotificationRequest(this); + StopNotificationRequest stopNotificationRequest = new StopNotificationRequest(this, Notifications.NotificationType.stopNotification); try { stopNotificationRequest.doPerform(); } catch (IOException e) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendNotificationRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendNotificationRequest.java index e492484606..203c68a88e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendNotificationRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendNotificationRequest.java @@ -21,6 +21,7 @@ import static nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.Huawei import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; import java.util.List; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket; @@ -95,29 +96,58 @@ public class SendNotificationRequest extends Request { params.category = notificationSpec.category; params.address = notificationSpec.phoneNumber; + ArrayList content = new ArrayList<>(); + content.add( + new Notifications.NotificationActionRequest.TextElement( + (byte)Notifications.TextType.title, + (byte)supportProvider.getHuaweiCoordinator().getContentFormat(), + title) + ); + content.add( + new Notifications.NotificationActionRequest.TextElement( + (byte) Notifications.TextType.sender, + (byte)supportProvider.getHuaweiCoordinator().getContentFormat(), + notificationSpec.sender) + ); + content.add( + new Notifications.NotificationActionRequest.TextElement( + (byte) Notifications.TextType.text, + (byte)supportProvider.getHuaweiCoordinator().getContentFormat(), + body) + ); this.packet = new Notifications.NotificationActionRequest( paramsProvider, supportProvider.getNotificationId(), getNotificationType(notificationSpec.type), - supportProvider.getHuaweiCoordinator().getContentFormat(), - title, - notificationSpec.sender, - body, + content, notificationSpec.sourceAppId, params ); } public void buildNotificationTLVFromCallSpec(CallSpec callSpec) { + ArrayList content = new ArrayList<>(); + content.add( + new Notifications.NotificationActionRequest.TextElement( + (byte) Notifications.TextType.text, + (byte)supportProvider.getHuaweiCoordinator().getContentFormat(), + callSpec.name) + ); + if(supportProvider.getHuaweiCoordinator().supportsIncomingNumber()) { + content.add( + new Notifications.NotificationActionRequest.TextElement( + (byte) Notifications.TextType.flight, + (byte) supportProvider.getHuaweiCoordinator().getIncomingNumberFormat(), + callSpec.number) + ); + } + final byte notificationType = callSpec.command == CallSpec.CALL_OUTGOING?Notifications.NotificationType.outgoingCall:Notifications.NotificationType.call; this.packet = new Notifications.NotificationActionRequest( paramsProvider, supportProvider.getNotificationId(), - Notifications.NotificationType.call, - supportProvider.getHuaweiCoordinator().getContentFormat(), - callSpec.name, - callSpec.name, - callSpec.name, + notificationType, + content, null, null ); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/StopNotificationRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/StopNotificationRequest.java index 72d522c719..0cdae81f76 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/StopNotificationRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/StopNotificationRequest.java @@ -16,6 +16,7 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; +import java.util.ArrayList; import java.util.List; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket; @@ -23,24 +24,30 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Notifications import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider; public class StopNotificationRequest extends Request { - public StopNotificationRequest(HuaweiSupportProvider support) { + final byte type; + public StopNotificationRequest(HuaweiSupportProvider support, byte type) { super(support); this.serviceId = Notifications.id; this.commandId = Notifications.NotificationActionRequest.id; this.addToResponse = false; + this.type = type; } @Override protected List createRequest() throws RequestCreationException { try { + ArrayList content = new ArrayList<>(); + content.add( + new Notifications.NotificationActionRequest.TextElement( + (byte) Notifications.TextType.text, + (byte)supportProvider.getHuaweiCoordinator().getContentFormat(), + "") + ); return new Notifications.NotificationActionRequest( paramsProvider, supportProvider.getNotificationId(), - Notifications.NotificationType.stopNotification, - supportProvider.getHuaweiCoordinator().getContentFormat(), - null, - null, - null, + type, + content, null, null ).serialize(); diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/TestNotifications.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/TestNotifications.java index 6f65f640bf..57b901b139 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/TestNotifications.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/TestNotifications.java @@ -21,6 +21,7 @@ import org.junit.Ignore; import org.junit.Test; import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.List; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket; @@ -98,14 +99,33 @@ public class TestNotifications { ) .put(0x11, sourceAppId); + + ArrayList content = new ArrayList<>(); + content.add( + new Notifications.NotificationActionRequest.TextElement( + (byte)Notifications.TextType.title, + (byte)encoding, + titleContent) + ); + content.add( + new Notifications.NotificationActionRequest.TextElement( + (byte) Notifications.TextType.sender, + (byte)encoding, + senderContent) + ); + content.add( + new Notifications.NotificationActionRequest.TextElement( + (byte) Notifications.TextType.text, + (byte)encoding, + bodyContent) + ); + + Notifications.NotificationActionRequest request = new Notifications.NotificationActionRequest( secretsProvider, notificationId, notificationType, - encoding, - titleContent, - senderContent, - bodyContent, + content, sourceAppId, null );