added logic for call notification (WIP)

This commit is contained in:
Daniel Dakhno 2020-02-02 03:16:48 +01:00
parent a90cf2bfc3
commit 829a306c64
8 changed files with 57 additions and 106 deletions

View File

@ -55,6 +55,7 @@ import nodomain.freeyourgadget.gadgetbridge.externalevents.NotificationListener;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
@ -304,6 +305,12 @@ public class QHybridSupport extends QHybridBaseSupport {
GBApplication.getContext().registerReceiver(globalCommandReceiver, globalFilter);
}
@Override
public void onSetCallState(CallSpec callSpec) {
super.onSetCallState(callSpec);
watchAdapter.onSetCallState(callSpec);
}
@Override
public void dispose() {
LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(commandReceiver);

View File

@ -24,6 +24,7 @@ import java.util.ArrayList;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
@ -117,4 +118,7 @@ public abstract class WatchAdapter {
public void updateWidgets() {
}
public void onSetCallState(CallSpec callSpec) {
}
}

View File

@ -55,6 +55,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.NotificationFilterPutRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayNotificationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.VerifyPrivateKeyRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.MoveHandsRequest;
@ -140,6 +141,7 @@ public class FossilWatchAdapter extends WatchAdapter {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
log("status " + status + " newState: " + newState);
if(newState != BluetoothGatt.STATE_CONNECTED){
log("status " + newState + " clearing queue...");
requestQueue.clear();
@ -190,7 +192,7 @@ public class FossilWatchAdapter extends WatchAdapter {
log("package name in notification not set");
return;
}
queueWrite(new PlayNotificationRequest(config.getPackageName(), this), false);
queueWrite(new PlayTextNotificationRequest(config.getPackageName(), this), false);
}
@Override

View File

@ -31,6 +31,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicContr
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HRConfigActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationHRConfiguration;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
@ -39,7 +40,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.foss
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.TimeConfigItem;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayCallNotificationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayNotificationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.VerifyPrivateKeyRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfigurationPutRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration.ConfigurationGetRequest;
@ -452,17 +455,23 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
try {
for (NotificationHRConfiguration configuration : this.notificationConfigurations){
if(configuration.getPackageName().equals(notificationSpec.sourceAppId)){
queueWrite(new PlayNotificationRequest(notificationSpec.sourceAppId, senderOrTitle, notificationSpec.body, this));
queueWrite(new PlayTextNotificationRequest(notificationSpec.sourceAppId, senderOrTitle, notificationSpec.body, this));
return true;
}
}
queueWrite(new PlayNotificationRequest("generic", senderOrTitle, notificationSpec.body, this));
queueWrite(new PlayTextNotificationRequest("generic", senderOrTitle, notificationSpec.body, this));
}catch (Exception e){
e.printStackTrace();
}
return true;
}
@Override
public void onSetCallState(CallSpec callSpec) {
super.onSetCallState(callSpec);
queueWrite(new PlayCallNotificationRequest(callSpec.number, callSpec.command == CallSpec.CALL_INCOMING, this));
}
public byte[] getSecretKey() {
byte[] authKeyBytes = new byte[16];

View File

@ -0,0 +1,9 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
public class PlayCallNotificationRequest extends PlayNotificationRequest {
public PlayCallNotificationRequest(String number, boolean callStart, FossilWatchAdapter adapter) {
super(callStart ? 1 : 7, callStart ? 8 : 2, "generic", number, "Incoming Call", adapter);
}
}

View File

@ -25,29 +25,26 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.foss
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
public class PlayNotificationRequest extends FilePutRequest {
public abstract class PlayNotificationRequest extends FilePutRequest {
static int id = 0;
public PlayNotificationRequest(String packageName, FossilWatchAdapter adapter) {
super((short) 0x0900, createFile(packageName, packageName, packageName), adapter);
public PlayNotificationRequest(int notificationType, int flags, String packageName, FossilWatchAdapter adapter) {
super((short) 0x0900, createFile(notificationType, flags, packageName, packageName, packageName), adapter);
}
public PlayNotificationRequest(String packageName, String sender, String message, FossilWatchAdapter adapter) {
super((short) 0x0900, createFile(packageName, sender, message), adapter);
public PlayNotificationRequest(int notificationType, int flags, String packageName, String sender, String message, FossilWatchAdapter adapter) {
super((short) 0x0900, createFile(notificationType, flags, packageName, sender, message), adapter);
}
private static byte[] createFile(String packageName, String sender, String message){
private static byte[] createFile(int notificationType, int flags, String packageName, String sender, String message){
CRC32 crc = new CRC32();
crc.update(packageName.getBytes());
return createFile(packageName, sender, message, (int)crc.getValue());
return createFile(notificationType, flags, packageName, sender, message, (int)crc.getValue());
}
private static byte[] createFile(String title, String sender, String message, int packageCrc) {
private static byte[] createFile(int notificationType, int flags, String title, String sender, String message, int packageCrc) {
byte lengthBufferLength = (byte) 10;
byte typeId = 3;
byte flags = getFlags();
byte uidLength = (byte) 4;
byte appBundleCRCLength = (byte) 4;
@ -68,8 +65,8 @@ public class PlayNotificationRequest extends FilePutRequest {
mainBuffer.putShort(mainBufferLength);
mainBuffer.put(lengthBufferLength);
mainBuffer.put(typeId);
mainBuffer.put(flags);
mainBuffer.put((byte) notificationType);
mainBuffer.put((byte) flags);
mainBuffer.put(uidLength);
mainBuffer.put(appBundleCRCLength);
mainBuffer.put((byte) titleBytes.length);
@ -84,8 +81,4 @@ public class PlayNotificationRequest extends FilePutRequest {
return mainBuffer.array();
}
private static byte getFlags(){
return (byte) 2;
}
}

View File

@ -0,0 +1,13 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
public class PlayTextNotificationRequest extends PlayNotificationRequest {
public PlayTextNotificationRequest(String packageName, String sender, String message, FossilWatchAdapter adapter) {
super(3, 2, packageName, sender, message, adapter);
}
public PlayTextNotificationRequest(String packageName, FossilWatchAdapter adapter) {
super(3, 2, packageName, adapter);
}
}

View File

@ -1,86 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.notification;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.util.zip.CRC32;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
public class PlayNotificationHRRequest extends FilePutRequest {
public PlayNotificationHRRequest(NotificationSpec spec, FossilWatchAdapter adapter) {
this(spec.sourceAppId, spec.sender, spec.body, adapter);
}
public PlayNotificationHRRequest(String packageName, String sender, String message, FossilWatchAdapter adapter){
super((short) 0x0900, createFile(packageName, sender, message), adapter);
}
private static byte[] createFile(String packageName, String sender, String message) {
byte lengthBufferLength = (byte) 10;
byte typeId = 3;
byte flags = getFlags();
byte uidLength = (byte) 4;
byte appBundleCRCLength = (byte) 4;
String nullTerminatedTitle = StringUtils.terminateNull(packageName);
Charset charsetUTF8 = Charset.forName("UTF-8");
byte[] titleBytes = nullTerminatedTitle.getBytes(charsetUTF8);
String nullTerminatedSender = StringUtils.terminateNull(sender);
byte[] senderBytes = nullTerminatedSender.getBytes(charsetUTF8);
String nullTerminatedMessage = StringUtils.terminateNull(message);
byte[] messageBytes = nullTerminatedMessage.getBytes(charsetUTF8);
short mainBufferLength = (short) (lengthBufferLength + uidLength + appBundleCRCLength + titleBytes.length + senderBytes.length + messageBytes.length);
ByteBuffer lengthBuffer = ByteBuffer.allocate(lengthBufferLength);
lengthBuffer.order(ByteOrder.LITTLE_ENDIAN);
lengthBuffer.putShort(mainBufferLength);
lengthBuffer.put(lengthBufferLength);
lengthBuffer.put(typeId);
lengthBuffer.put(flags);
lengthBuffer.put(uidLength);
lengthBuffer.put(appBundleCRCLength);
lengthBuffer.put((byte) titleBytes.length);
lengthBuffer.put((byte) senderBytes.length);
lengthBuffer.put((byte) messageBytes.length);
ByteBuffer mainBuffer = ByteBuffer.allocate(mainBufferLength);
mainBuffer.order(ByteOrder.LITTLE_ENDIAN);
mainBuffer.put(lengthBuffer.array());
lengthBuffer = ByteBuffer.allocate(mainBufferLength - lengthBufferLength);
lengthBuffer.order(ByteOrder.LITTLE_ENDIAN);
// lengthBuffer.putInt(0);
lengthBuffer.put((byte) 0x00);
lengthBuffer.put((byte) 0x00);
lengthBuffer.put((byte) 0x00);
lengthBuffer.put((byte) 0x00);
CRC32 packageNameCrc = new CRC32();
packageNameCrc.update(packageName.getBytes());
// lengthBuffer.putInt((int) packageNameCrc.getValue());
lengthBuffer.putInt((int) 0);
// lengthBuffer.put((byte) 0x19);
// lengthBuffer.put((byte) 0x38);
// lengthBuffer.put((byte) 0xE0);
// lengthBuffer.put((byte) 0xDA);
lengthBuffer.put(titleBytes);
lengthBuffer.put(senderBytes);
lengthBuffer.put(messageBytes);
mainBuffer.put(lengthBuffer.array());
return mainBuffer.array();
}
private static byte getFlags(){
return (byte) 2;
}
}