From 46171e4ab87c115a872f973b473a5916681f0ae4 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Mon, 31 Aug 2015 22:27:25 +0200 Subject: [PATCH] Some preparations for interactive notifications --- .../GBDeviceEventDismissNotification.java | 5 -- .../GBDeviceEventNotificationControl.java | 13 +++++ .../gadgetbridge/devices/EventHandler.java | 2 +- .../externalevents/NotificationListener.java | 23 +++++++- .../gadgetbridge/impl/GBDeviceService.java | 5 +- .../gadgetbridge/model/DeviceService.java | 1 + .../service/AbstractDeviceSupport.java | 27 ++++++--- .../service/DeviceCommunicationService.java | 5 +- .../service/ServiceDeviceSupport.java | 4 +- .../service/devices/miband/MiBandSupport.java | 2 +- .../devices/pebble/PebbleProtocol.java | 56 +++++++++++++------ .../serial/AbstractSerialDeviceSupport.java | 4 +- .../service/serial/GBDeviceProtocol.java | 2 +- 13 files changed, 107 insertions(+), 42 deletions(-) delete mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDismissNotification.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDismissNotification.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDismissNotification.java deleted file mode 100644 index 3a4111219..000000000 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDismissNotification.java +++ /dev/null @@ -1,5 +0,0 @@ -package nodomain.freeyourgadget.gadgetbridge.deviceevents; - -public class GBDeviceEventDismissNotification extends GBDeviceEvent { - public int notificationID; -} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java new file mode 100644 index 000000000..deab36825 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventNotificationControl.java @@ -0,0 +1,13 @@ +package nodomain.freeyourgadget.gadgetbridge.deviceevents; + +public class GBDeviceEventNotificationControl extends GBDeviceEvent { + public int handle; + + public Event event = Event.UNKNOWN; + + public enum Event { + UNKNOWN, + DISMISS, + OPEN + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java index 915c352eb..b2d6f90d1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java @@ -19,7 +19,7 @@ public interface EventHandler { void onEmail(String from, String subject, String body); - void onGenericNotification(String title, String details); + void onGenericNotification(String title, String details, int handle); void onSetTime(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index d046bd1ca..0b325a05b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -2,6 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.externalevents; import android.app.ActivityManager; import android.app.Notification; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -26,12 +27,29 @@ public class NotificationListener extends NotificationListenerService { public static final String ACTION_DISMISS = "nodomain.freeyourgadget.gadgetbridge.notificationlistener.action.dismiss"; + public static final String ACTION_OPEN + = "nodomain.freeyourgadget.gadgetbridge.notificationlistener.action.open"; private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (action.equals(ACTION_DISMISS)) { + if (action.equals(ACTION_OPEN)) { + StatusBarNotification[] sbns = NotificationListener.this.getActiveNotifications(); + int handle = intent.getIntExtra("handle", -1); + for (StatusBarNotification sbn : sbns) { + if ((int) sbn.getPostTime() == handle) { + try { + PendingIntent pi = sbn.getNotification().contentIntent; + if (pi != null) { + pi.send(); + } + } catch (PendingIntent.CanceledException e) { + e.printStackTrace(); + } + } + } + } else if (action.equals(ACTION_DISMISS)) { NotificationListener.this.cancelAllNotifications(); } } @@ -42,6 +60,7 @@ public class NotificationListener extends NotificationListenerService { super.onCreate(); IntentFilter filterLocal = new IntentFilter(); filterLocal.addAction(ACTION_DISMISS); + filterLocal.addAction(ACTION_OPEN); LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal); } @@ -112,7 +131,7 @@ public class NotificationListener extends NotificationListenerService { } if (content != null) { - GBApplication.deviceService().onGenericNotification(title, content); + GBApplication.deviceService().onGenericNotification(title, content, (int) sbn.getPostTime()); //FIMXE: a truly unique id would be better } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index c410d5f80..72e90bf20 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -96,10 +96,11 @@ public class GBDeviceService implements DeviceService { } @Override - public void onGenericNotification(String title, String details) { + public void onGenericNotification(String title, String details, int handle) { Intent intent = createIntent().setAction(ACTION_NOTIFICATION_GENERIC) .putExtra(EXTRA_NOTIFICATION_TITLE, title) - .putExtra(EXTRA_NOTIFICATION_BODY, details); + .putExtra(EXTRA_NOTIFICATION_BODY, details) + .putExtra(EXTRA_NOTIFICATION_HANDLE, handle); invokeService(intent); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index 05d3281eb..63e651117 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -36,6 +36,7 @@ public interface DeviceService extends EventHandler { static final String EXTRA_NOTIFICATION_BODY = "notification_body"; static final String EXTRA_NOTIFICATION_SENDER = "notification_sender"; static final String EXTRA_NOTIFICATION_SUBJECT = "notification_subject"; + static final String EXTRA_NOTIFICATION_HANDLE = "notification_handle"; static final String EXTRA_FIND_START = "find_start"; static final String EXTRA_CALL_COMMAND = "call_command"; static final String EXTRA_CALL_PHONENUMBER = "call_phonenumber"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java index 8242ddff4..9aaa4d9dd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractDeviceSupport.java @@ -26,8 +26,8 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventAppInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; -import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventDismissNotification; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventNotificationControl; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventScreenshot; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSleepMonitorResult; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; @@ -103,8 +103,8 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { handleGBDeviceEvent((GBDeviceEventSleepMonitorResult) deviceEvent); } else if (deviceEvent instanceof GBDeviceEventScreenshot) { handleGBDeviceEvent((GBDeviceEventScreenshot) deviceEvent); - } else if (deviceEvent instanceof GBDeviceEventDismissNotification) { - handleGBDeviceEvent((GBDeviceEventDismissNotification) deviceEvent); + } else if (deviceEvent instanceof GBDeviceEventNotificationControl) { + handleGBDeviceEvent((GBDeviceEventNotificationControl) deviceEvent); } else if (deviceEvent instanceof GBDeviceEventBatteryInfo) { handleGBDeviceEvent((GBDeviceEventBatteryInfo) deviceEvent); } @@ -206,12 +206,23 @@ public abstract class AbstractDeviceSupport implements DeviceSupport { } } - private void handleGBDeviceEvent(GBDeviceEventDismissNotification deviceEvent) { + private void handleGBDeviceEvent(GBDeviceEventNotificationControl deviceEvent) { Context context = getContext(); - LOG.info("Got DISMISS_NOTIFICATION device event"); - Intent notificationListenerIntent = new Intent(NotificationListener.ACTION_DISMISS); - notificationListenerIntent.putExtra("id", deviceEvent.notificationID); - LocalBroadcastManager.getInstance(context).sendBroadcast(notificationListenerIntent); + LOG.info("Got NOTIFICATION CONTROL device event"); + String action = null; + switch (deviceEvent.event) { + case DISMISS: + action = NotificationListener.ACTION_DISMISS; + break; + case OPEN: + action = NotificationListener.ACTION_OPEN; + break; + } + if (action != null) { + Intent notificationListenerIntent = new Intent(action); + notificationListenerIntent.putExtra("handle", deviceEvent.handle); + LocalBroadcastManager.getInstance(context).sendBroadcast(notificationListenerIntent); + } } public void handleGBDeviceEvent(GBDeviceEventBatteryInfo deviceEvent) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 7fa301c3e..72046b8e5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -26,6 +26,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -58,6 +59,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUS import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_ARTIST; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_TRACK; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_BODY; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_HANDLE; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SENDER; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SUBJECT; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TITLE; @@ -179,7 +181,8 @@ public class DeviceCommunicationService extends Service { case ACTION_NOTIFICATION_GENERIC: { String title = intent.getStringExtra(EXTRA_NOTIFICATION_TITLE); String body = intent.getStringExtra(EXTRA_NOTIFICATION_BODY); - mDeviceSupport.onGenericNotification(title, body); + int handle = intent.getIntExtra(EXTRA_NOTIFICATION_HANDLE,-1); + mDeviceSupport.onGenericNotification(title, body, handle); break; } case ACTION_NOTIFICATION_SMS: { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java index a659dc458..6639b8cce 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java @@ -127,11 +127,11 @@ public class ServiceDeviceSupport implements DeviceSupport { } @Override - public void onGenericNotification(String title, String details) { + public void onGenericNotification(String title, String details, int handle) { if (checkBusy("generic notification") || checkThrottle("generic notification")) { return; } - delegate.onGenericNotification(title, details); + delegate.onGenericNotification(title, details, handle); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java index 9af6ec427..0d695bee2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java @@ -408,7 +408,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { } @Override - public void onGenericNotification(String title, String details) { + public void onGenericNotification(String title, String details, int handle) { performPreferredNotification("generic notification received", ORIGIN_GENERIC, null); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 111a79e66..a26dda7fd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -17,8 +17,8 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventAppInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventAppManagement; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl; -import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventDismissNotification; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventNotificationControl; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventScreenshot; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; @@ -393,8 +393,8 @@ public class PebbleProtocol extends GBDeviceProtocol { } @Override - public byte[] encodeGenericNotification(String title, String details) { - return encodeNotification(mRandom.nextInt(), title, null, details, NOTIFICATION_SMS); + public byte[] encodeGenericNotification(String title, String details, int handle) { + return encodeNotification(handle, title, null, details, NOTIFICATION_SMS); } @Override @@ -437,7 +437,7 @@ public class PebbleProtocol extends GBDeviceProtocol { // Calculate length first byte attributes_count = 0; - int length = 21 + 17; + int length = 21 + 17; //+ 19 if (parts != null) { for (String s : parts) { if (s == null || s.equals("")) { @@ -465,7 +465,7 @@ public class PebbleProtocol extends GBDeviceProtocol { buf.putInt(timestamp); buf.put((byte) 0x01); // layout - ? buf.put(attributes_count); // length attributes - buf.put((byte) 1); // len actions - only dismiss + buf.put((byte) 1); // len actions byte attribute_id = 0; // Encode Pascal-Style Strings @@ -485,13 +485,24 @@ public class PebbleProtocol extends GBDeviceProtocol { } // ACTION - buf.put((byte) 0x01); // id + buf.put((byte) 0x02); // id buf.put((byte) 0x04); // dismiss action buf.put((byte) 0x01); // number attributes buf.put((byte) 0x01); // attribute id (title) String actionstring = "dismiss all"; buf.putShort((short) actionstring.length()); buf.put(actionstring.getBytes()); + + /* + buf.put((byte) 0x01); // id + buf.put((byte) 0x02); // generic action + buf.put((byte) 0x01); // number attributes + buf.put((byte) 0x01); // attribute id (title) + actionstring = "open on phone"; + buf.putShort((short) actionstring.length()); + buf.put(actionstring.getBytes()); + */ + return buf.array(); } @@ -598,7 +609,7 @@ public class PebbleProtocol extends GBDeviceProtocol { buf.putInt(icon_id); // ACTION - buf.put((byte) 0x01); // id + buf.put((byte) 0x02); // id buf.put((byte) 0x02); // generic action, dismiss did not do anything buf.put((byte) 0x01); // number attributes buf.put((byte) 0x01); // attribute id (title) @@ -1077,17 +1088,27 @@ public class PebbleProtocol extends GBDeviceProtocol { return null; } - private GBDeviceEventDismissNotification decodeNotificationAction2x(ByteBuffer buf) { + private GBDeviceEventNotificationControl decodeNotificationAction2x(ByteBuffer buf) { buf.order(ByteOrder.LITTLE_ENDIAN); byte command = buf.get(); - if (command == 0x02) { // dismiss notification ? + if (command == 0x02) { int id = buf.getInt(); - short action = buf.getShort(); // at least the low byte should be the action - or not? - if (action == 0x0001) { - GBDeviceEventDismissNotification devEvtDismissNotification = new GBDeviceEventDismissNotification(); - devEvtDismissNotification.notificationID = id; - return devEvtDismissNotification; + byte action = buf.get(); + if (action == 0x01 || action == 0x02) { + GBDeviceEventNotificationControl devEvtNotificationControl = new GBDeviceEventNotificationControl(); + devEvtNotificationControl.handle = id; + switch (action) { + case 0x01: + devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.OPEN; + break; + case 0x02: + devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.DISMISS; + break; + default: + return null; + } + return devEvtNotificationControl; } LOG.info("unexpected paramerter in dismiss action: " + action); } @@ -1105,9 +1126,10 @@ public class PebbleProtocol extends GBDeviceProtocol { long uuid_low = buf.getLong(); int id = (int) (uuid_low & 0xffff); byte action = buf.get(); - if (action == 0x01) { - GBDeviceEventDismissNotification dismissNotification = new GBDeviceEventDismissNotification(); - dismissNotification.notificationID = id; + if (action == 0x02) { + GBDeviceEventNotificationControl dismissNotification = new GBDeviceEventNotificationControl(); + dismissNotification.handle = id; + dismissNotification.event = GBDeviceEventNotificationControl.Event.DISMISS; GBDeviceEventSendBytes sendBytesAck = new GBDeviceEventSendBytes(); sendBytesAck.encodedBytes = encodeActionResponse(new UUID(uuid_high, uuid_low)); return new GBDeviceEvent[]{sendBytesAck, dismissNotification}; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java index 1772a34d8..448f699f3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java @@ -118,8 +118,8 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport } @Override - public void onGenericNotification(String title, String details) { - byte[] bytes = gbDeviceProtocol.encodeGenericNotification(title, details); + public void onGenericNotification(String title, String details, int handle) { + byte[] bytes = gbDeviceProtocol.encodeGenericNotification(title, details, handle); sendToDevice(bytes); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java index e99e0c250..90cf1d488 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java @@ -15,7 +15,7 @@ public abstract class GBDeviceProtocol { return null; } - public byte[] encodeGenericNotification(String title, String details) { + public byte[] encodeGenericNotification(String title, String details, int handle) { return null; }