mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Huawei: fix voip calls notifications support. Basic support.
This commit is contained in:
+18
@@ -840,6 +840,24 @@ public class HuaweiCoordinator {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsVoipType1() {
|
||||
if (supportsExpandCapability())
|
||||
return supportsExpandCapability(249);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsVoipType2() {
|
||||
if (supportsExpandCapability())
|
||||
return supportsExpandCapability(185);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsVoipType3() {
|
||||
if (supportsExpandCapability())
|
||||
return supportsExpandCapability(152);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsCannedReplies() {
|
||||
if (supportsExpandCapability())
|
||||
return supportsExpandCapability(82);
|
||||
|
||||
+9
-7
@@ -64,6 +64,8 @@ public class Notifications {
|
||||
public byte subscriptionId = 0;
|
||||
public String address = "";
|
||||
public String category = "";
|
||||
public int voipType = 0;
|
||||
public long when = 0;
|
||||
}
|
||||
|
||||
// TODO: support other types of notifications
|
||||
@@ -90,12 +92,6 @@ public class Notifications {
|
||||
short msgId,
|
||||
byte notificationType,
|
||||
ArrayList<TextElement> content,
|
||||
// int encoding,
|
||||
// String titleContent,
|
||||
// String senderContent,
|
||||
// String bodyContent,
|
||||
// int numberFormat,
|
||||
// String numberContent,
|
||||
String sourceAppId,
|
||||
AdditionalParams addParams
|
||||
) {
|
||||
@@ -132,7 +128,6 @@ public class Notifications {
|
||||
this.tlv.put(0x11, sourceAppId.length() > 127?sourceAppId.substring(0, 127): sourceAppId);
|
||||
|
||||
if(addParams != null) {
|
||||
|
||||
if(!TextUtils.isEmpty(addParams.category)) { // type >= 34
|
||||
this.tlv.put(0x12, addParams.category); // "imcall" also possible value, not standard for android
|
||||
}
|
||||
@@ -151,6 +146,13 @@ public class Notifications {
|
||||
this.tlv.put(0x1a, addParams.notificationId);
|
||||
this.tlv.put(0x1b, (addParams.channelId != null) ? addParams.channelId : "");
|
||||
}
|
||||
if(addParams.voipType != 0) {
|
||||
this.tlv.put(0x29, (byte)addParams.voipType);
|
||||
}
|
||||
|
||||
if(addParams.when != 0) {
|
||||
this.tlv.put(0x32, addParams.when);
|
||||
}
|
||||
}
|
||||
|
||||
this.complete = true;
|
||||
|
||||
+9
@@ -761,6 +761,15 @@ public class NotificationListener extends NotificationListenerService {
|
||||
if (appName != null) {
|
||||
callSpec.sourceName = appName;
|
||||
}
|
||||
|
||||
callSpec.isVoip = true;
|
||||
|
||||
callSpec.key = sbn.getKey();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
callSpec.channelId = noti.getChannelId();
|
||||
}
|
||||
callSpec.category = noti.category;
|
||||
|
||||
callSpec.command = callStarted ? CallSpec.CALL_START : CallSpec.CALL_INCOMING;
|
||||
mLastCallCommand = callSpec.command;
|
||||
GBApplication.deviceService().onSetCallState(callSpec);
|
||||
|
||||
@@ -230,6 +230,10 @@ public class GBDeviceService implements DeviceService {
|
||||
.putExtra(EXTRA_CALL_DISPLAYNAME, callSpec.name)
|
||||
.putExtra(EXTRA_CALL_SOURCENAME, callSpec.sourceName)
|
||||
.putExtra(EXTRA_CALL_SOURCEAPPID, callSpec.sourceAppId)
|
||||
.putExtra(EXTRA_CALL_KEY, callSpec.key)
|
||||
.putExtra(EXTRA_CALL_CHANNELID, callSpec.channelId)
|
||||
.putExtra(EXTRA_CALL_CATEGORY, callSpec.category)
|
||||
.putExtra(EXTRA_CALL_ISVOIP, callSpec.isVoip)
|
||||
.putExtra(EXTRA_CALL_COMMAND, callSpec.command)
|
||||
.putExtra(EXTRA_CALL_DNDSUPPRESSED, callSpec.dndSuppressed);
|
||||
invokeService(intent);
|
||||
|
||||
@@ -36,6 +36,12 @@ public class CallSpec {
|
||||
*/
|
||||
public String sourceAppId;
|
||||
|
||||
public String key;
|
||||
public String channelId;
|
||||
public String category;
|
||||
|
||||
public boolean isVoip = false;
|
||||
|
||||
public int command;
|
||||
public int dndSuppressed;
|
||||
}
|
||||
|
||||
@@ -109,6 +109,10 @@ public interface DeviceService extends EventHandler {
|
||||
String EXTRA_CALL_DISPLAYNAME = "call_displayname";
|
||||
String EXTRA_CALL_SOURCENAME = "call_sourcename";
|
||||
String EXTRA_CALL_SOURCEAPPID = "call_sourceappid";
|
||||
String EXTRA_CALL_KEY = "call_key";
|
||||
String EXTRA_CALL_CHANNELID = "call_channel_id";
|
||||
String EXTRA_CALL_CATEGORY = "call_category";
|
||||
String EXTRA_CALL_ISVOIP = "call_is_voip";
|
||||
String EXTRA_CALL_DNDSUPPRESSED = "call_dndsuppressed";
|
||||
String EXTRA_CANNEDMESSAGES = "cannedmessages";
|
||||
String EXTRA_CANNEDMESSAGES_TYPE = "cannedmessages_type";
|
||||
|
||||
+4
@@ -1010,6 +1010,10 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
||||
callSpec.name = intentCopy.getStringExtra(EXTRA_CALL_DISPLAYNAME);
|
||||
callSpec.sourceName = intentCopy.getStringExtra(EXTRA_CALL_SOURCENAME);
|
||||
callSpec.sourceAppId = intentCopy.getStringExtra(EXTRA_CALL_SOURCEAPPID);
|
||||
callSpec.key = intentCopy.getStringExtra(EXTRA_CALL_KEY);
|
||||
callSpec.channelId = intentCopy.getStringExtra(EXTRA_CALL_CHANNELID);
|
||||
callSpec.category = intentCopy.getStringExtra(EXTRA_CALL_CATEGORY);
|
||||
callSpec.isVoip = intentCopy.getBooleanExtra(EXTRA_CALL_ISVOIP, false);
|
||||
callSpec.dndSuppressed = intentCopy.getIntExtra(EXTRA_CALL_DNDSUPPRESSED, 0);
|
||||
deviceSupport.onSetCallState(callSpec);
|
||||
break;
|
||||
|
||||
+8
@@ -28,6 +28,7 @@ import java.util.Queue;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventNotificationControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Notifications;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotificationRequest;
|
||||
@@ -66,6 +67,13 @@ public class HuaweiNotificationsManager {
|
||||
return "0|" + notificationSpec.sourceAppId + "|" + notificationSpec.getId() + "||0";
|
||||
}
|
||||
|
||||
public static String getCallSpecKey(CallSpec callSpec, int id) {
|
||||
if(!TextUtils.isEmpty(callSpec.key)) {
|
||||
return callSpec.key;
|
||||
}
|
||||
return "0|" + callSpec.sourceAppId + "|" + id + "||0";
|
||||
}
|
||||
|
||||
public void onNotification(NotificationSpec notificationSpec) {
|
||||
|
||||
addNotificationToCache(notificationSpec);
|
||||
|
||||
+59
-3
@@ -16,6 +16,7 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiNotificationsManager.getCallSpecKey;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiNotificationsManager.getNotificationKey;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -23,6 +24,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Notifications;
|
||||
@@ -95,6 +97,7 @@ public class SendNotificationRequest extends Request {
|
||||
params.channelId = notificationSpec.channelId;
|
||||
params.category = notificationSpec.category;
|
||||
params.address = notificationSpec.phoneNumber;
|
||||
params.when = notificationSpec.when;
|
||||
|
||||
ArrayList<Notifications.NotificationActionRequest.TextElement> content = new ArrayList<>();
|
||||
content.add(
|
||||
@@ -127,6 +130,11 @@ public class SendNotificationRequest extends Request {
|
||||
}
|
||||
|
||||
public void buildNotificationTLVFromCallSpec(CallSpec callSpec) {
|
||||
byte notificationType = callSpec.command == CallSpec.CALL_OUTGOING?Notifications.NotificationType.outgoingCall:Notifications.NotificationType.call;
|
||||
|
||||
Notifications.NotificationActionRequest.AdditionalParams params = null;
|
||||
String sourceAppId = null;
|
||||
|
||||
ArrayList<Notifications.NotificationActionRequest.TextElement> content = new ArrayList<>();
|
||||
content.add(
|
||||
new Notifications.NotificationActionRequest.TextElement(
|
||||
@@ -134,6 +142,54 @@ public class SendNotificationRequest extends Request {
|
||||
(byte)supportProvider.getHuaweiCoordinator().getContentFormat(),
|
||||
callSpec.name)
|
||||
);
|
||||
|
||||
if(callSpec.isVoip && callSpec.command == CallSpec.CALL_INCOMING) {
|
||||
sourceAppId = callSpec.sourceAppId;
|
||||
params = new Notifications.NotificationActionRequest.AdditionalParams();
|
||||
|
||||
params.supportsReply = supportProvider.getHuaweiCoordinator().supportsNotificationsReply();
|
||||
params.supportsRepeatedNotify = supportProvider.getHuaweiCoordinator().supportsNotificationsRepeatedNotify();
|
||||
params.supportsRemoveSingle = supportProvider.getHuaweiCoordinator().supportsNotificationsRemoveSingle();
|
||||
params.supportsReplyActions = supportProvider.getHuaweiCoordinator().supportsNotificationsReplyActions();
|
||||
params.supportsTimestamp = supportProvider.getHuaweiCoordinator().supportsNotificationsAddIconTimestamp();
|
||||
|
||||
params.notificationId = new Random().nextInt(Integer.MAX_VALUE - 1);
|
||||
params.notificationKey = getCallSpecKey(callSpec, params.notificationId);
|
||||
params.channelId = callSpec.channelId;
|
||||
if(supportProvider.getHuaweiCoordinator().supportsVoipType3()) {
|
||||
params.category = "imcall";
|
||||
} else {
|
||||
params.category = callSpec.category;
|
||||
}
|
||||
params.address = null;
|
||||
if(supportProvider.getHuaweiCoordinator().supportsVoipType2()) {
|
||||
params.voipType = 1;
|
||||
}
|
||||
if (supportProvider.getHuaweiCoordinator().supportsVoipType1() || supportProvider.getHuaweiCoordinator().supportsVoipType2()) {
|
||||
notificationType = Notifications.NotificationType.generic;
|
||||
|
||||
content.add(
|
||||
new Notifications.NotificationActionRequest.TextElement(
|
||||
(byte) Notifications.TextType.title,
|
||||
(byte) supportProvider.getHuaweiCoordinator().getContentFormat(),
|
||||
callSpec.name)
|
||||
);
|
||||
content.add(
|
||||
new Notifications.NotificationActionRequest.TextElement(
|
||||
(byte) Notifications.TextType.sender,
|
||||
(byte) supportProvider.getHuaweiCoordinator().getContentFormat(),
|
||||
callSpec.name)
|
||||
);
|
||||
// TODO: Reject action, need to be parsed from the notification and added here. Then the watch send it back in the service id: 0x2 Command id: 0x11
|
||||
// content.add(
|
||||
// new Notifications.NotificationActionRequest.TextElement(
|
||||
// (byte) 8,
|
||||
// (byte) supportProvider.getHuaweiCoordinator().getContentFormat(),
|
||||
// "REJECT_CALL")
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
if(supportProvider.getHuaweiCoordinator().supportsIncomingNumber()) {
|
||||
content.add(
|
||||
new Notifications.NotificationActionRequest.TextElement(
|
||||
@@ -142,14 +198,14 @@ public class SendNotificationRequest extends Request {
|
||||
callSpec.number)
|
||||
);
|
||||
}
|
||||
final byte notificationType = callSpec.command == CallSpec.CALL_OUTGOING?Notifications.NotificationType.outgoingCall:Notifications.NotificationType.call;
|
||||
|
||||
this.packet = new Notifications.NotificationActionRequest(
|
||||
paramsProvider,
|
||||
supportProvider.getNotificationId(),
|
||||
notificationType,
|
||||
content,
|
||||
null,
|
||||
null
|
||||
sourceAppId,
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user