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:
parent
94cde94fbc
commit
f286df9ecf
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user