Some preparations for interactive notifications

live-activity-data
Andreas Shimokawa 2015-08-31 22:27:25 +02:00
parent 2da717ea4c
commit 46171e4ab8
13 changed files with 107 additions and 42 deletions

View File

@ -1,5 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.deviceevents;
public class GBDeviceEventDismissNotification extends GBDeviceEvent {
public int notificationID;
}

View File

@ -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
}
}

View File

@ -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();

View File

@ -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
}
}

View File

@ -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);
}

View File

@ -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";

View File

@ -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) {

View File

@ -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: {

View File

@ -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

View File

@ -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);
}

View File

@ -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};

View File

@ -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);
}

View File

@ -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;
}