mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-25 18:15:49 +01:00
added call notification support (doesnt work on all phones)
This commit is contained in:
parent
17ade7e591
commit
f9a4c1ad35
@ -1,18 +1,33 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
public class NotificationHRConfiguration implements Serializable {
|
||||
private String packageName;
|
||||
private long id = -1;
|
||||
private byte[] packageCrc;
|
||||
|
||||
public NotificationHRConfiguration(String packageName, long id) {
|
||||
this.packageName = packageName;
|
||||
this.id = id;
|
||||
|
||||
CRC32 crc = new CRC32();
|
||||
crc.update(packageName.getBytes());
|
||||
|
||||
this.packageCrc = ByteBuffer
|
||||
.allocate(4)
|
||||
.order(ByteOrder.LITTLE_ENDIAN)
|
||||
.putInt((int) crc.getValue())
|
||||
.array();
|
||||
}
|
||||
|
||||
public NotificationHRConfiguration(String packageName, byte[] packageCrc, long id) {
|
||||
this.id = id;
|
||||
this.packageCrc = packageCrc;
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
@ -22,4 +37,8 @@ public class NotificationHRConfiguration implements Serializable {
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public byte[] getPackageCrc() {
|
||||
return packageCrc;
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import java.util.Iterator;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HRConfigActivity;
|
||||
@ -37,9 +38,11 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
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.requests.fossil.FossilRequest;
|
||||
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.file.FilePutRequest;
|
||||
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;
|
||||
@ -99,46 +102,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
|
||||
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZING));
|
||||
|
||||
// icons
|
||||
|
||||
loadNotificationConfigurations();
|
||||
queueWrite(new NotificationFilterPutHRRequest(this.notificationConfigurations, this));
|
||||
// queueWrite(new NotificationFilterPutHRRequest(this.notificationConfigurations,this));
|
||||
|
||||
/*try {
|
||||
final String[] appNames = {"instagram", "snapchat", "line", "whatsapp"};
|
||||
final String[] paths = {
|
||||
"/storage/emulated/0/Q/images/icInstagram.icon",
|
||||
"/storage/emulated/0/Q/images/icSnapchat.icon",
|
||||
"/storage/emulated/0/Q/images/icLine.icon",
|
||||
"/storage/emulated/0/Q/images/icWhatsapp.icon"
|
||||
};
|
||||
|
||||
NotificationHRConfiguration[] configs = new NotificationHRConfiguration[4];
|
||||
NotificationImage[] images = new NotificationImage[4];
|
||||
for(int i = 0; i < 4; i++){
|
||||
FileInputStream fis = new FileInputStream(paths[i]);
|
||||
byte[] imageData = new byte[fis.available()];
|
||||
fis.read(imageData);
|
||||
fis.close();
|
||||
configs[i] = new NotificationHRConfiguration(appNames[i], i);
|
||||
images[i] = new NotificationImage(appNames[i], imageData);
|
||||
}
|
||||
queueWrite(new NotificationImagePutRequest(images, this));
|
||||
queueWrite(new NotificationFilterPutHRRequest(configs, this));
|
||||
|
||||
for(String appName : appNames){
|
||||
queueWrite(new PlayNotificationHRRequest(
|
||||
appName,
|
||||
appName.toUpperCase(),
|
||||
"this is some strange message",
|
||||
this
|
||||
));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
|
||||
setVibrationStrength((short) 75);
|
||||
|
||||
syncSettings();
|
||||
@ -165,6 +130,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
private void loadNotificationConfigurations(){
|
||||
this.notificationConfigurations = new NotificationHRConfiguration[]{
|
||||
new NotificationHRConfiguration("generic", 0),
|
||||
new NotificationHRConfiguration("call", new byte[]{(byte)0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}, 0)
|
||||
};
|
||||
}
|
||||
|
||||
@ -539,7 +505,9 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
|
||||
byte requestType = value[1];
|
||||
|
||||
if (requestType == (byte) 0x05) {
|
||||
if(requestType == (byte) 0x04){
|
||||
handleCallRequest(value);
|
||||
}else if (requestType == (byte) 0x05) {
|
||||
handleMusicRequest(value);
|
||||
} else if (requestType == (byte) 0x01) {
|
||||
int eventId = value[2];
|
||||
@ -608,6 +576,16 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCallRequest(byte[] value) {
|
||||
boolean acceptCall = value[7] == (byte) 0x00;
|
||||
queueWrite(new PlayCallNotificationRequest("", false, this));
|
||||
|
||||
GBDeviceEventCallControl callControlEvent = new GBDeviceEventCallControl();
|
||||
callControlEvent.event = acceptCall ? GBDeviceEventCallControl.Event.START : GBDeviceEventCallControl.Event.REJECT;
|
||||
|
||||
getDeviceSupport().evaluateGBDeviceEvent(callControlEvent);
|
||||
}
|
||||
|
||||
private void handleMusicRequest(byte[] value) {
|
||||
byte command = value[3];
|
||||
logger.info("got music command: " + command);
|
||||
|
@ -1,9 +1,14 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
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);
|
||||
super(callStart ? 1 : 7, callStart ? 8 : 2,
|
||||
ByteBuffer.wrap(new byte[]{(byte) 0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}).order(ByteOrder.LITTLE_ENDIAN).getInt(),
|
||||
number, "Incoming Call", adapter);
|
||||
}
|
||||
}
|
||||
|
@ -26,8 +26,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||
|
||||
public abstract class PlayNotificationRequest extends FilePutRequest {
|
||||
static int id = 0;
|
||||
|
||||
public PlayNotificationRequest(int notificationType, int flags, String packageName, FossilWatchAdapter adapter) {
|
||||
super((short) 0x0900, createFile(notificationType, flags, packageName, packageName, packageName), adapter);
|
||||
}
|
||||
@ -36,6 +34,9 @@ public abstract class PlayNotificationRequest extends FilePutRequest {
|
||||
super((short) 0x0900, createFile(notificationType, flags, packageName, sender, message), adapter);
|
||||
}
|
||||
|
||||
public PlayNotificationRequest(int notificationType, int flags, int packageCRC, String sender, String message, FossilWatchAdapter adapter) {
|
||||
super((short) 0x0900, createFile(notificationType, flags, "whatever", sender, message, packageCRC), adapter);
|
||||
}
|
||||
|
||||
private static byte[] createFile(int notificationType, int flags, String packageName, String sender, String message){
|
||||
CRC32 crc = new CRC32();
|
||||
@ -73,7 +74,7 @@ public abstract class PlayNotificationRequest extends FilePutRequest {
|
||||
mainBuffer.put((byte) senderBytes.length);
|
||||
mainBuffer.put((byte) messageBytes.length);
|
||||
|
||||
mainBuffer.putInt(id++); // messageId
|
||||
mainBuffer.putInt(0); // messageId
|
||||
mainBuffer.putInt(packageCrc);
|
||||
mainBuffer.put(titleBytes);
|
||||
mainBuffer.put(senderBytes);
|
||||
|
@ -3,7 +3,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fo
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationHRConfiguration;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||
@ -21,20 +20,16 @@ public class NotificationFilterPutHRRequest extends FilePutRequest {
|
||||
}
|
||||
|
||||
private static byte[] createFile(NotificationHRConfiguration[] configs) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(configs.length * 28);
|
||||
int payloadLength = configs.length * 28;
|
||||
ByteBuffer buffer = ByteBuffer.allocate(payloadLength);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
for (NotificationHRConfiguration config : configs) {
|
||||
buffer.putShort((short) 28); //packet length
|
||||
payloadLength = 26;
|
||||
|
||||
CRC32 crc = new CRC32();
|
||||
crc.update(config.getPackageName().getBytes());
|
||||
buffer.putShort((short) payloadLength); //packet length
|
||||
|
||||
byte[] crcBytes = ByteBuffer
|
||||
.allocate(4)
|
||||
.order(ByteOrder.LITTLE_ENDIAN)
|
||||
.putInt((int) crc.getValue())
|
||||
.array();
|
||||
byte[] crcBytes = config.getPackageCrc();
|
||||
|
||||
// 6 bytes
|
||||
buffer.put(PacketID.PACKAGE_NAME_CRC.id)
|
||||
@ -44,7 +39,7 @@ public class NotificationFilterPutHRRequest extends FilePutRequest {
|
||||
// 3 bytes
|
||||
buffer.put(PacketID.GROUP_ID.id)
|
||||
.put((byte) 1)
|
||||
.put((byte) 2);
|
||||
.put((byte) 0);
|
||||
|
||||
// 3 bytes
|
||||
buffer.put(PacketID.PRIORITY.id)
|
||||
|
@ -53,7 +53,7 @@ public class GBCallControlReceiver extends BroadcastReceiver {
|
||||
telephonyService.answerRingingCall();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("could not start or hangup call");
|
||||
LOG.warn("could not start or hangup call", e);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user