added music info (controls WIP)

This commit is contained in:
dakhnod
2019-12-31 15:25:30 +01:00
parent 2acac2146e
commit 19d68c62c6
5 changed files with 212 additions and 4 deletions

View File

@@ -61,6 +61,8 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem; import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes; import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCallback; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCallback;
@@ -314,6 +316,20 @@ public class QHybridSupport extends QHybridBaseSupport {
return builder; return builder;
} }
@Override
public void onSetMusicInfo(MusicSpec musicSpec) {
super.onSetMusicInfo(musicSpec);
watchAdapter.setMusicInfo(musicSpec);
}
@Override
public void onSetMusicState(MusicStateSpec stateSpec) {
super.onSetMusicState(stateSpec);
watchAdapter.setMusicState(stateSpec);
}
@Override @Override
public void onFetchRecordedData(int dataTypes) { public void onFetchRecordedData(int dataTypes) {
if ((dataTypes & RecordedDataTypes.TYPE_ACTIVITY) != 0) { if ((dataTypes & RecordedDataTypes.TYPE_ACTIVITY) != 0) {

View File

@@ -24,6 +24,8 @@ import java.util.ArrayList;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
@@ -97,4 +99,10 @@ public abstract class WatchAdapter {
public void setCommuteMenuMessage(String message, boolean finished) { public void setCommuteMenuMessage(String message, boolean finished) {
} }
public void setMusicInfo(MusicSpec musicSpec) {
}
public void setMusicState(MusicStateSpec stateSpec) {
}
} }

View File

@@ -21,6 +21,8 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HRConfigActivity; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HRConfigActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationHRConfiguration; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationHRConfiguration;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
@@ -35,14 +37,20 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.Image; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.Image;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.ImagesPutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.ImagesPutRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.menu.SetCommuteMenuMessage; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.menu.SetCommuteMenuMessage;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicInfoSetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification.NotificationFilterPutHRRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification.NotificationFilterPutHRRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification.NotificationImagePutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification.NotificationImagePutRequest;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest.*;
public class FossilHRWatchAdapter extends FossilWatchAdapter { public class FossilHRWatchAdapter extends FossilWatchAdapter {
private byte[] secretKey = new byte[]{(byte) 0x60, (byte) 0x26, (byte) 0xB7, (byte) 0xFD, (byte) 0xB2, (byte) 0x6D, (byte) 0x05, (byte) 0x5E, (byte) 0xDA, (byte) 0xF7, (byte) 0x4B, (byte) 0x49, (byte) 0x98, (byte) 0x78, (byte) 0x02, (byte) 0x38}; private byte[] secretKey = new byte[]{(byte) 0x60, (byte) 0x26, (byte) 0xB7, (byte) 0xFD, (byte) 0xB2, (byte) 0x6D, (byte) 0x05, (byte) 0x5E, (byte) 0xDA, (byte) 0xF7, (byte) 0x4B, (byte) 0x49, (byte) 0x98, (byte) 0x78, (byte) 0x02, (byte) 0x38};
private byte[] phoneRandomNumber; private byte[] phoneRandomNumber;
private byte[] watchRandomNumber; private byte[] watchRandomNumber;
MusicSpec currentSpec = null;
public FossilHRWatchAdapter(QHybridSupport deviceSupport) { public FossilHRWatchAdapter(QHybridSupport deviceSupport) {
super(deviceSupport); super(deviceSupport);
} }
@@ -93,7 +101,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
setTime(); setTime();
overwriteButtons(null); // overwriteButtons(null);
// negotiateSymmetricKey(); // negotiateSymmetricKey();
// queueWrite( // queueWrite(
@@ -103,6 +111,13 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
// ) // )
// ); // );
queueWrite(new MusicInfoSetRequest(
"This is an artist",
"Some stupid album",
"What the Track!",
this
));
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED)); queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED));
} }
@@ -131,6 +146,32 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
); );
} }
@Override
public void setMusicInfo(MusicSpec musicSpec) {
if (
currentSpec != null
&& currentSpec.album.equals(musicSpec.album)
&& currentSpec.artist.equals(musicSpec.artist)
&& currentSpec.track.equals(musicSpec.track)
) return;
currentSpec = musicSpec;
queueWrite(new MusicInfoSetRequest(
musicSpec.artist,
musicSpec.album,
musicSpec.track,
this
));
}
@Override
public void setMusicState(MusicStateSpec stateSpec) {
super.setMusicState(stateSpec);
queueWrite(new MusicControlRequest(
stateSpec.state == MusicStateSpec.STATE_PLAYING ? MUSIC_PHONE_REQUEST.MUSIC_REQUEST_SET_PLAYING : MUSIC_PHONE_REQUEST.MUSIC_REQUEST_SET_PAUSED
));
}
private void setBackgroundImages(Image background, Image[] complications) { private void setBackgroundImages(Image background, Image[] complications) {
background.setAngle(0); background.setAngle(0);
background.setDistance(0); background.setDistance(0);
@@ -210,6 +251,13 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
byte[] value = characteristic.getValue(); byte[] value = characteristic.getValue();
byte requestType = value[1];
if (requestType == (byte) 0x05) {
handleMusicRequest(value);
return;
}
int eventId = value[2]; int eventId = value[2];
try { try {
@@ -236,6 +284,29 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
} }
} }
private void handleMusicRequest(byte[] value) {
byte command = value[3];
MUSIC_WATCH_REQUEST request = MUSIC_WATCH_REQUEST.fromCommandByte(command);
MusicControlRequest r = new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_PLAY_PAUSE);
switch (request) {
case MUSIC_REQUEST_PLAY_PAUSE: {
queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_PLAY_PAUSE));
break;
}
case MUSIC_REQUEST_LOUDER: {
queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_LOUDER));
break;
}
case MUSIC_REQUEST_QUITER: {
queueWrite(new MusicControlRequest(MUSIC_PHONE_REQUEST.MUSIC_REQUEST_QUITER));
break;
}
}
}
@Override @Override
public void setCommuteMenuMessage(String message, boolean finished) { public void setCommuteMenuMessage(String message, boolean finished) {
queueWrite(new SetCommuteMenuMessage(message, finished, this)); queueWrite(new SetCommuteMenuMessage(message, finished, this));

View File

@@ -0,0 +1,72 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
public class MusicControlRequest extends FossilRequest {
private MUSIC_PHONE_REQUEST request;
public MusicControlRequest(MUSIC_PHONE_REQUEST request) {
this.request = request;
this.data = new byte[]{
(byte) 0x02,
(byte) 0x05,
this.request.getCommandByte(),
(byte) 0x00
};
}
@Override
public boolean isFinished() {
return true;
}
@Override
public byte[] getStartSequence() {
return null;
}
@Override
public UUID getRequestUUID() {
return UUID.fromString("3dda0006-957f-7d4a-34a6-74696673696d");
}
public static enum MUSIC_WATCH_REQUEST{
MUSIC_REQUEST_PLAY_PAUSE((byte) 0x02),
MUSIC_REQUEST_LOUDER((byte) 0x05),
MUSIC_REQUEST_QUITER((byte) 0x06),
;
private byte commandByte;
MUSIC_WATCH_REQUEST(byte commandByte) {
this.commandByte = commandByte;
}
public static MUSIC_WATCH_REQUEST fromCommandByte(byte commandByte){
for(MUSIC_WATCH_REQUEST request : MUSIC_WATCH_REQUEST.values()){
if(request.commandByte == commandByte) return request;
}
return null;
}
}
public static enum MUSIC_PHONE_REQUEST{
MUSIC_REQUEST_SET_PLAYING((byte) 0x00),
MUSIC_REQUEST_SET_PAUSED((byte) 0x01),
MUSIC_REQUEST_PLAY_PAUSE((byte) 0x02),
MUSIC_REQUEST_LOUDER((byte) 0x05),
MUSIC_REQUEST_QUITER((byte) 0x06),
;
private byte commandByte;
public byte getCommandByte() {
return commandByte;
}
private MUSIC_PHONE_REQUEST(byte commandByte) {
this.commandByte = commandByte;
}
}
}

View File

@@ -0,0 +1,41 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
public class MusicInfoSetRequest extends FilePutRequest {
public MusicInfoSetRequest(String artist, String album, String title, FossilWatchAdapter adapter) {
super((short) 0x0400, createFile(artist, album, title), adapter);
}
private static byte[] createFile(String artist, String album, String title){
int length = artist.length() + album.length() + title.length()
+ 3 // null terminators
+ 8; // length and header
ByteBuffer buffer = ByteBuffer.allocate(length);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putShort((short) length);
buffer.put((byte) 0x01); // dunno
buffer.put((byte) (title.length() + 1));
buffer.put((byte) (artist.length() + 1));
buffer.put((byte) (album.length() + 1));
buffer.put((byte) 0x0C); // dunno
buffer.put((byte) 0x00); // dunno
buffer.put(title.getBytes())
.put((byte) 0x00); // null terminator
buffer.put(artist.getBytes())
.put((byte) 0x00); // null terminator
buffer.put(album.getBytes())
.put((byte) 0x00); // null terminator
return buffer.array();
}
}