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 7fbef5bf6..c9ec83a46 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
@@ -16,16 +16,18 @@
along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services;
+import android.Manifest;
+import android.content.pm.PackageManager;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
-import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences;
+import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
@@ -42,8 +44,10 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
public static final int COMMAND_TYPE = 7;
public static final int CMD_NOTIFICATION_SEND = 0;
+ public static final int CMD_CALL_REJECT = 2;
+ public static final int CMD_CALL_IGNORE = 5;
public static final int CMD_CANNED_MESSAGES_GET = 9;
- public static final int CMD_CANNED_MESSAGES_SET = 12;
+ public static final int CMD_CANNED_MESSAGES_SET = 12; // also canned message reply
public XiaomiNotificationService(final XiaomiSupport support) {
super(support);
@@ -56,10 +60,22 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
@Override
public void handleCommand(final XiaomiProto.Command cmd) {
+ final GBDeviceEventCallControl deviceEvtCallControl = new GBDeviceEventCallControl();
+
switch (cmd.getSubtype()) {
+ case CMD_CALL_REJECT:
+ LOG.debug("Reject call");
+ deviceEvtCallControl.event = GBDeviceEventCallControl.Event.REJECT;
+ getSupport().evaluateGBDeviceEvent(deviceEvtCallControl);
+ return;
+ case CMD_CALL_IGNORE:
+ LOG.debug("Ignore call");
+ deviceEvtCallControl.event = GBDeviceEventCallControl.Event.IGNORE;
+ getSupport().evaluateGBDeviceEvent(deviceEvtCallControl);
+ return;
case CMD_CANNED_MESSAGES_GET:
handleCannedMessages(cmd.getNotification().getCannedMessages());
- break;
+ return;
}
// TODO
@@ -68,14 +84,9 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
}
public void onNotification(final NotificationSpec notificationSpec) {
- // TODO this is not working
- if (true) {
- LOG.warn("Notifications disabled, they're not working");
- return;
- }
-
final XiaomiProto.Notification3.Builder notification3 = XiaomiProto.Notification3.newBuilder()
.setId(notificationSpec.getId())
+ .setUnknown4("") // ?
.setTimestamp(TIMESTAMP_SDF.format(new Date(notificationSpec.when)));
if (notificationSpec.sourceAppId != null) {
@@ -97,14 +108,15 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
notification3.setAppName(notificationSpec.sourceName);
}
- // TODO what is this?
- final String unknown12 = String.format(
- Locale.ROOT,
- "0|%s|%d|null|12345",
- notification3.getPackage(),
- notification3.getId() // i think this needs to be converted to unsigned
- );
- notification3.setUnknown12(unknown12);
+ // TODO Open on phone
+ //final String unknown12 = String.format(
+ // Locale.ROOT,
+ // "0|%s|%d|null|12345",
+ // notification3.getPackage(),
+ // notification3.getId() // i think this needs to be converted to unsigned
+ //);
+ //notification3.setUnknown12(unknown12);
+ //notification3.setOpenOnPhone(1);
final XiaomiProto.Notification2 notification2 = XiaomiProto.Notification2.newBuilder()
.setNotification3(notification3)
@@ -129,7 +141,50 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
}
public void onSetCallState(final CallSpec callSpec) {
- // TODO
+ // TODO handle callSpec.command
+ if (callSpec.command != CallSpec.CALL_INCOMING) {
+ return;
+ }
+
+ final XiaomiProto.Notification3.Builder notification3 = XiaomiProto.Notification3.newBuilder()
+ .setId(12345) // ?
+ .setUnknown4("") // ?
+ .setIsCall(true)
+ .setRepliesAllowed(canSendSms())
+ .setTimestamp(TIMESTAMP_SDF.format(new Date()));
+
+ notification3.setPackage(BuildConfig.APPLICATION_ID);
+ notification3.setAppName("Phone");
+
+ if (callSpec.name != null) {
+ notification3.setTitle(callSpec.name);
+ } else {
+ notification3.setTitle("?");
+ }
+ if (callSpec.number != null) {
+ notification3.setBody(callSpec.number);
+ } else {
+ notification3.setBody("?");
+ }
+
+ // TODO unknown caller i18n
+
+ final XiaomiProto.Notification2 notification2 = XiaomiProto.Notification2.newBuilder()
+ .setNotification3(notification3)
+ .build();
+
+ final XiaomiProto.Notification notification = XiaomiProto.Notification.newBuilder()
+ .setNotification2(notification2)
+ .build();
+
+ getSupport().sendCommand(
+ "send call",
+ XiaomiProto.Command.newBuilder()
+ .setType(COMMAND_TYPE)
+ .setSubtype(CMD_NOTIFICATION_SEND)
+ .setNotification(notification)
+ .build()
+ );
}
public void onSetCannedMessages(final CannedMessagesSpec cannedMessagesSpec) {
@@ -177,4 +232,12 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
//gbDeviceEventUpdatePreferences.withPreference("canned_reply_" + i, message);
//getSupport().evaluateGBDeviceEvent(gbDeviceEventUpdatePreferences);
}
+
+ public boolean canSendSms() {
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
+ return getSupport().getContext().checkSelfPermission(Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED;
+ } else {
+ return true;
+ }
+ }
}
diff --git a/app/src/main/proto/xiaomi.proto b/app/src/main/proto/xiaomi.proto
index 97df3c54d..b9f5bd2f1 100644
--- a/app/src/main/proto/xiaomi.proto
+++ b/app/src/main/proto/xiaomi.proto
@@ -442,7 +442,7 @@ message MediaKey {
message Notification {
optional Notification2 notification2 = 3;
- optional Notification4 notification4 = 4;
+ optional NotificationDismiss notification4 = 4;
optional uint32 unknown8 = 8; // 1 on canned replies request?
// 7, 9 get | 7, 12 set
@@ -457,18 +457,24 @@ message Notification3 {
optional string package = 1;
optional string appName = 2;
optional string title = 3;
- optional string timestamp = 6;
optional string unknown4 = 4;
optional string body = 5;
+ optional string timestamp = 6;
optional uint32 id = 7;
- optional string unknown8 = 8;
- optional string unknown11 = 11;
- optional string unknown12 = 12;
- optional uint32 hasReply = 13;
+ optional bool isCall = 8;
+ optional bool repliesAllowed = 11; // only for calls?
+ optional string unknown12 = 12; // "0|||null|12345"
+ optional uint32 openOnPhone = 13; // 1 to show "Open on phone", needs unknown12
}
-message Notification4 {
- optional Notification5 notification5 = 1;
+message NotificationDismiss {
+ optional NotificationId notificationId = 1;
+}
+
+message NotificationId {
+ optional uint32 id = 1;
+ optional string package = 2; // truncated
+ optional string unknown4 = 4; // ""
}
message CannedMessages {
@@ -477,12 +483,6 @@ message CannedMessages {
optional uint32 maxReplies = 3;
}
-message Notification5 {
- optional uint32 id = 1;
- optional string package = 2;
- optional string unknown4 = 4;
-}
-
//
// Weather
//