diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java index 8901ebc05..fb945a50b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java @@ -153,10 +153,10 @@ public class BluetoothCommunicationService extends Service { BluetoothDevice btDevice = mBtAdapter.getRemoteDevice(btDeviceAddress); if (btDevice.getName() == null || btDevice.getName().equals("MI")) { //FIXME: workaround for Miband not being paired mGBDevice = new GBDevice(btDeviceAddress, "MI", DeviceType.MIBAND); - mDeviceSupport = new MiBandSupport(); + mDeviceSupport = new ServiceDeviceSupport(new MiBandSupport()); } else if (btDevice.getName().indexOf("Pebble") == 0) { mGBDevice = new GBDevice(btDeviceAddress, btDevice.getName(), DeviceType.PEBBLE); - mDeviceSupport = new PebbleSupport(); + mDeviceSupport = new ServiceDeviceSupport(new PebbleSupport()); } if (mDeviceSupport != null) { mDeviceSupport.initialize(mGBDevice, mBtAdapter, this); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ServiceDeviceSupport.java new file mode 100644 index 000000000..9603151b8 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ServiceDeviceSupport.java @@ -0,0 +1,211 @@ +package nodomain.freeyourgadget.gadgetbridge; + +import android.bluetooth.BluetoothAdapter; +import android.content.Context; +import android.net.Uri; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.UUID; + +/** + * Wraps another device support instance and supports busy-checking and throttling of events. + */ +public class ServiceDeviceSupport implements DeviceSupport { + private static final Logger LOG = LoggerFactory.getLogger(ServiceDeviceSupport.class); + private static final long THROTTLING_THRESHOLD = 1000; // throttle multiple events in between one second + + private final DeviceSupport delegate; + private long lastNoficationTime = 0; + private String lastNotificationType; + + public ServiceDeviceSupport(DeviceSupport delegate) { + this.delegate = delegate; + } + + @Override + public void initialize(GBDevice gbDevice, BluetoothAdapter btAdapter, Context context) { + delegate.initialize(gbDevice, btAdapter, context); + } + + @Override + public boolean isConnected() { + return delegate.isConnected(); + } + + @Override + public boolean connect() { + return delegate.connect(); + } + + @Override + public void dispose() { + delegate.dispose(); + } + + @Override + public GBDevice getDevice() { + return delegate.getDevice(); + } + + @Override + public BluetoothAdapter getBluetoothAdapter() { + return delegate.getBluetoothAdapter(); + } + + @Override + public Context getContext() { + return delegate.getContext(); + } + + @Override + public boolean useAutoConnect() { + return delegate.useAutoConnect(); + } + + @Override + public void pair() { + delegate.pair(); + } + + private boolean checkBusy(String notificationKind) { + if (getDevice().isBusy()) { + LOG.info("Ignoring " + notificationKind + " because we're busy with " + getDevice().getBusyTask()); + } + return false; + } + + private boolean checkThrottle(String notificationKind) { + long currentTime = System.currentTimeMillis(); + if ((currentTime - lastNoficationTime) < THROTTLING_THRESHOLD) { + if (notificationKind != null && notificationKind.equals(lastNotificationType)) { + LOG.info("Ignoring " + notificationKind + " because of throttling threshold reached"); + return true; + } + } + return false; + } + + @Override + public void onSMS(String from, String body) { + if (checkBusy("sms") || checkThrottle("sms")) { + return; + } + delegate.onSMS(from, body); + } + + @Override + public void onEmail(String from, String subject, String body) { + if (checkBusy("email") || checkThrottle("email")) { + return; + } + delegate.onEmail(from, subject, body); + } + + @Override + public void onGenericNotification(String title, String details) { + if (checkBusy("generic notification") || checkThrottle("generic notification")) { + return; + } + delegate.onGenericNotification(title, details); + } + + @Override + public void onSetTime(long ts) { + if (checkBusy("set time") || checkThrottle("set time")) { + return; + } + delegate.onSetTime(ts); + } + + // No throttling for the other events + + @Override + public void onSetCallState(String number, String name, GBCommand command) { + if (checkBusy("set call state")) { + return; + } + delegate.onSetCallState(number, name, command); + } + + @Override + public void onSetMusicInfo(String artist, String album, String track) { + if (checkBusy("set music info")) { + return; + } + delegate.onSetMusicInfo(artist, album, track); + } + + @Override + public void onFirmwareVersionReq() { + if (checkBusy("firmware version request")) { + return; + } + delegate.onFirmwareVersionReq(); + } + + @Override + public void onBatteryInfoReq() { + if (checkBusy("battery info request")) { + return; + } + delegate.onBatteryInfoReq(); + } + + @Override + public void onInstallApp(Uri uri) { + if (checkBusy("install app")) { + return; + } + delegate.onInstallApp(uri); + } + + @Override + public void onAppInfoReq() { + if (checkBusy("app info request")) { + return; + } + delegate.onAppInfoReq(); + } + + @Override + public void onAppStart(UUID uuid) { + if (checkBusy("app start")) { + return; + } + delegate.onAppStart(uuid); + } + + @Override + public void onAppDelete(UUID uuid) { + if (checkBusy("app delete")) { + return; + } + delegate.onAppDelete(uuid); + } + + @Override + public void onPhoneVersion(byte os) { + if (checkBusy("phone version")) { + return; + } + delegate.onPhoneVersion(os); + } + + @Override + public void onFetchActivityData() { + if (checkBusy("fetch activity data")) { + return; + } + delegate.onFetchActivityData(); + } + + @Override + public void onReboot() { + if (checkBusy("reboot")) { + return; + } + delegate.onReboot(); + } +}