1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-26 02:25:50 +01:00

Garmin: Send notification pictures

This commit is contained in:
José Rebelo 2024-11-24 18:28:05 +00:00
parent ef3509446e
commit c687496cc5
5 changed files with 90 additions and 5 deletions

View File

@ -240,8 +240,7 @@ public class GarminSupport extends AbstractBTLEDeviceSupport implements ICommuni
} }
protected Bitmap getNotificationAttachmentBitmap(int notificationId) { protected Bitmap getNotificationAttachmentBitmap(int notificationId) {
Bitmap pippo = BitmapFactory.decodeFile(getNotificationAttachmentPath(notificationId)); return BitmapFactory.decodeFile(getNotificationAttachmentPath(notificationId));
return pippo;
} }
@Override @Override

View File

@ -117,7 +117,7 @@ public class NotificationsHandler implements MessageHandler {
} }
} }
final boolean hasPicture = !nodomain.freeyourgadget.gadgetbridge.util.StringUtils.isEmpty(notificationSpec.picturePath); final boolean hasPicture = !StringUtils.isEmpty(notificationSpec.picturePath);
return new NotificationUpdateMessage(notificationUpdateType, notificationSpec.type, getNotificationsCount(notificationSpec.type), notificationSpec.getId(), hasActions, hasPicture); return new NotificationUpdateMessage(notificationUpdateType, notificationSpec.type, getNotificationsCount(notificationSpec.type), notificationSpec.getId(), hasActions, hasPicture);
} }
@ -349,8 +349,8 @@ public class NotificationsHandler implements MessageHandler {
toReturn = encodeNotificationActionsString(notificationSpec); toReturn = encodeNotificationActionsString(notificationSpec);
break; break;
case ATTACHMENTS: case ATTACHMENTS:
LOG.debug("NOTIFICATION ATTACHMENTS REQUESTED. Notification Id: {}", notificationSpec.getId()); LOG.debug("Notification attachments requested for notification id {}", notificationSpec.getId());
toReturn = "1"; //TODO: possibly the number of attachments, or is it a progressive ID of the attachment to be requested? toReturn = "1"; // the number of attachments
break; break;
} }
if (maxLength == 0) if (maxLength == 0)

View File

@ -1,6 +1,7 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin; package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap;
import android.location.Location; import android.location.Location;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@ -11,6 +12,7 @@ import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -32,6 +34,7 @@ import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiDataTransferService;
import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiDeviceStatus; import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiDeviceStatus;
import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiFindMyWatch; import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiFindMyWatch;
import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiHttpService; import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiHttpService;
import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiNotificationsService;
import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiSettingsService; import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiSettingsService;
import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiSmartProto; import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiSmartProto;
import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiSmsNotification; import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiSmsNotification;
@ -129,6 +132,9 @@ public class ProtocolBufferHandler implements MessageHandler {
processed = true; processed = true;
processProtobufSettingsService(smart.getSettingsService()); processProtobufSettingsService(smart.getSettingsService());
} }
if (smart.hasNotificationsService()) {
return prepareProtobufResponse(processProtobufNotificationsServiceMessage(smart.getNotificationsService()), message.getRequestId());
}
if (processed) { if (processed) {
message.setStatusMessage(new ProtobufStatusMessage( message.setStatusMessage(new ProtobufStatusMessage(
message.getMessageType(), message.getMessageType(),
@ -358,6 +364,47 @@ public class ProtocolBufferHandler implements MessageHandler {
return null; return null;
} }
private GdiSmartProto.Smart processProtobufNotificationsServiceMessage(final GdiNotificationsService.NotificationsService notificationsService) {
if (notificationsService.hasPictureRequest()) {
final GdiNotificationsService.PictureRequest pictureRequest = notificationsService.getPictureRequest();
final int notificationId = pictureRequest.getNotificationId();
final Bitmap bmp = deviceSupport.getNotificationAttachmentBitmap(notificationId);
if (bmp == null) {
LOG.warn("Failed to find bitmap for notification id {}", notificationId);
return null;
}
final GdiNotificationsService.PictureParameters parameters = pictureRequest.getParameters();
final int targetHeight = (int) Math.round(bmp.getHeight() * ((double) parameters.getWidth() / bmp.getWidth()));
final Bitmap scaledBmp = Bitmap.createScaledBitmap(bmp, parameters.getWidth(), targetHeight, true);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
scaledBmp.compress(Bitmap.CompressFormat.JPEG, parameters.getQuality(), baos);
final byte[] imageBytes = baos.toByteArray();
final int transferId = DataTransferHandler.registerData(imageBytes);
final GdiNotificationsService.PictureResponse response = GdiNotificationsService.PictureResponse.newBuilder()
.setUnk1(1)
.setNotificationId(notificationId)
.setUnk3(0)
.setUnk4(1)
.setDataTransferItem(
GdiNotificationsService.DataTransferItem.newBuilder()
.setId(transferId)
.setSize(imageBytes.length)
.build()
)
.build();
return GdiSmartProto.Smart.newBuilder().setNotificationsService(
GdiNotificationsService.NotificationsService.newBuilder().setPictureResponse(response)
).build();
}
LOG.warn("Protobuf notificationsService request not implemented: {}", notificationsService);
return null;
}
private GdiSmartProto.Smart processProtobufSmsNotificationMessage(GdiSmsNotification.SmsNotificationService smsNotificationService) { private GdiSmartProto.Smart processProtobufSmsNotificationMessage(GdiSmsNotification.SmsNotificationService smsNotificationService) {
if (smsNotificationService.hasSmsCannedListRequest()) { if (smsNotificationService.hasSmsCannedListRequest()) {
LOG.debug("Got request for sms canned list"); LOG.debug("Got request for sms canned list");

View File

@ -0,0 +1,37 @@
syntax = "proto2";
package garmin_vivomovehr;
option java_package = "nodomain.freeyourgadget.gadgetbridge.proto.garmin";
message NotificationsService {
optional PictureRequest pictureRequest = 1;
optional PictureResponse pictureResponse = 2;
}
message PictureRequest {
optional uint32 notification_id = 1;
optional uint32 unk2 = 2; // 0
optional PictureParameters parameters = 3;
// unk4 "\001"
}
message PictureParameters {
optional uint32 width = 1;
optional uint32 height = 2;
optional uint32 unk3 = 3; // 204800 max size?
optional uint32 quality = 4; // 80
}
message PictureResponse {
optional uint32 unk1 = 1; // 1
optional uint32 notification_id = 2;
optional uint32 unk3 = 3; // 0
optional uint32 unk4 = 4; // 1
optional DataTransferItem dataTransferItem = 5;
}
message DataTransferItem {
optional uint32 id = 1;
optional uint32 size = 2;
}

View File

@ -12,6 +12,7 @@ import "garmin/gdi_data_transfer_service.proto";
import "garmin/gdi_sms_notification.proto"; import "garmin/gdi_sms_notification.proto";
import "garmin/gdi_calendar_service.proto"; import "garmin/gdi_calendar_service.proto";
import "garmin/gdi_settings_service.proto"; import "garmin/gdi_settings_service.proto";
import "garmin/gdi_notifications_service.proto";
message Smart { message Smart {
optional CalendarService calendar_service = 1; optional CalendarService calendar_service = 1;
@ -22,6 +23,7 @@ message Smart {
optional CoreService core_service = 13; optional CoreService core_service = 13;
optional SmsNotificationService sms_notification_service = 16; optional SmsNotificationService sms_notification_service = 16;
optional SettingsService settings_service = 42; optional SettingsService settings_service = 42;
optional NotificationsService notifications_service = 49;
} }
/* /*