1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-29 05:16:51 +01:00

Mi Band 8: Notification and calls (working, but wip)

This commit is contained in:
José Rebelo 2023-10-06 15:59:18 +01:00
parent 94cde94fbc
commit f286df9ecf
2 changed files with 96 additions and 33 deletions

View File

@ -16,16 +16,18 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services; package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services;
import android.Manifest;
import android.content.pm.PackageManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.BuildConfig; 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.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; 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 COMMAND_TYPE = 7;
public static final int CMD_NOTIFICATION_SEND = 0; 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_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) { public XiaomiNotificationService(final XiaomiSupport support) {
super(support); super(support);
@ -56,10 +60,22 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
@Override @Override
public void handleCommand(final XiaomiProto.Command cmd) { public void handleCommand(final XiaomiProto.Command cmd) {
final GBDeviceEventCallControl deviceEvtCallControl = new GBDeviceEventCallControl();
switch (cmd.getSubtype()) { 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: case CMD_CANNED_MESSAGES_GET:
handleCannedMessages(cmd.getNotification().getCannedMessages()); handleCannedMessages(cmd.getNotification().getCannedMessages());
break; return;
} }
// TODO // TODO
@ -68,14 +84,9 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
} }
public void onNotification(final NotificationSpec notificationSpec) { 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() final XiaomiProto.Notification3.Builder notification3 = XiaomiProto.Notification3.newBuilder()
.setId(notificationSpec.getId()) .setId(notificationSpec.getId())
.setUnknown4("") // ?
.setTimestamp(TIMESTAMP_SDF.format(new Date(notificationSpec.when))); .setTimestamp(TIMESTAMP_SDF.format(new Date(notificationSpec.when)));
if (notificationSpec.sourceAppId != null) { if (notificationSpec.sourceAppId != null) {
@ -97,14 +108,15 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
notification3.setAppName(notificationSpec.sourceName); notification3.setAppName(notificationSpec.sourceName);
} }
// TODO what is this? // TODO Open on phone
final String unknown12 = String.format( //final String unknown12 = String.format(
Locale.ROOT, // Locale.ROOT,
"0|%s|%d|null|12345", // "0|%s|%d|null|12345",
notification3.getPackage(), // notification3.getPackage(),
notification3.getId() // i think this needs to be converted to unsigned // notification3.getId() // i think this needs to be converted to unsigned
); //);
notification3.setUnknown12(unknown12); //notification3.setUnknown12(unknown12);
//notification3.setOpenOnPhone(1);
final XiaomiProto.Notification2 notification2 = XiaomiProto.Notification2.newBuilder() final XiaomiProto.Notification2 notification2 = XiaomiProto.Notification2.newBuilder()
.setNotification3(notification3) .setNotification3(notification3)
@ -129,7 +141,50 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
} }
public void onSetCallState(final CallSpec callSpec) { 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) { public void onSetCannedMessages(final CannedMessagesSpec cannedMessagesSpec) {
@ -177,4 +232,12 @@ public class XiaomiNotificationService extends AbstractXiaomiService {
//gbDeviceEventUpdatePreferences.withPreference("canned_reply_" + i, message); //gbDeviceEventUpdatePreferences.withPreference("canned_reply_" + i, message);
//getSupport().evaluateGBDeviceEvent(gbDeviceEventUpdatePreferences); //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;
}
}
} }

View File

@ -442,7 +442,7 @@ message MediaKey {
message Notification { message Notification {
optional Notification2 notification2 = 3; optional Notification2 notification2 = 3;
optional Notification4 notification4 = 4; optional NotificationDismiss notification4 = 4;
optional uint32 unknown8 = 8; // 1 on canned replies request? optional uint32 unknown8 = 8; // 1 on canned replies request?
// 7, 9 get | 7, 12 set // 7, 9 get | 7, 12 set
@ -457,18 +457,24 @@ message Notification3 {
optional string package = 1; optional string package = 1;
optional string appName = 2; optional string appName = 2;
optional string title = 3; optional string title = 3;
optional string timestamp = 6;
optional string unknown4 = 4; optional string unknown4 = 4;
optional string body = 5; optional string body = 5;
optional string timestamp = 6;
optional uint32 id = 7; optional uint32 id = 7;
optional string unknown8 = 8; optional bool isCall = 8;
optional string unknown11 = 11; optional bool repliesAllowed = 11; // only for calls?
optional string unknown12 = 12; optional string unknown12 = 12; // "0|<package>|<id 2 complement>|null|12345"
optional uint32 hasReply = 13; optional uint32 openOnPhone = 13; // 1 to show "Open on phone", needs unknown12
} }
message Notification4 { message NotificationDismiss {
optional Notification5 notification5 = 1; optional NotificationId notificationId = 1;
}
message NotificationId {
optional uint32 id = 1;
optional string package = 2; // truncated
optional string unknown4 = 4; // ""
} }
message CannedMessages { message CannedMessages {
@ -477,12 +483,6 @@ message CannedMessages {
optional uint32 maxReplies = 3; optional uint32 maxReplies = 3;
} }
message Notification5 {
optional uint32 id = 1;
optional string package = 2;
optional string unknown4 = 4;
}
// //
// Weather // Weather
// //