1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-27 12:26:48 +01:00

Cache notifications while devices are out of range (opt-in)

This commit is contained in:
Arjan Schrijver 2023-03-31 21:07:56 +02:00
parent 340db0ca15
commit b892748b15
5 changed files with 58 additions and 1 deletions

View File

@ -17,6 +17,7 @@
* Zepp OS: Fix setting of unknown configuration values * Zepp OS: Fix setting of unknown configuration values
* Add Croatian transliterator * Add Croatian transliterator
* Fix restoring app notification/pebble blacklist preferences on import * Fix restoring app notification/pebble blacklist preferences on import
* Cache notifications while devices are out of range (opt-in)
#### 0.73.0 #### 0.73.0
* Initial support for Amazfit T-Rex 2 * Initial support for Amazfit T-Rex 2

View File

@ -772,7 +772,7 @@ public class NotificationListener extends NotificationListenerService {
notificationsActive.removeAll(notificationsToRemove); notificationsActive.removeAll(notificationsToRemove);
// Send notification remove request to device // Send notification remove request to device
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices(); List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
for(GBDevice device : devices){ for(GBDevice device : devices){
Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress())); Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()));
if (devicePrefs.getBoolean("autoremove_notifications", true)) { if (devicePrefs.getBoolean("autoremove_notifications", true)) {

View File

@ -45,6 +45,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -310,6 +311,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
private DeviceSupportFactory mFactory; private DeviceSupportFactory mFactory;
private final ArrayList<DeviceStruct> deviceStructs = new ArrayList<>(1); private final ArrayList<DeviceStruct> deviceStructs = new ArrayList<>(1);
private final HashMap<String, ArrayList<Intent>> cachedNotifications = new HashMap<>();
private PhoneCallReceiver mPhoneCallReceiver = null; private PhoneCallReceiver mPhoneCallReceiver = null;
private SMSReceiver mSMSReceiver = null; private SMSReceiver mSMSReceiver = null;
@ -347,6 +349,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
private final String COMMAND_BLUETOOTH_CONNECT = "nodomain.freeyourgadget.gadgetbridge.BLUETOOTH_CONNECT"; private final String COMMAND_BLUETOOTH_CONNECT = "nodomain.freeyourgadget.gadgetbridge.BLUETOOTH_CONNECT";
private final String ACTION_DEVICE_CONNECTED = "nodomain.freeyourgadget.gadgetbridge.BLUETOOTH_CONNECTED"; private final String ACTION_DEVICE_CONNECTED = "nodomain.freeyourgadget.gadgetbridge.BLUETOOTH_CONNECTED";
private final int NOTIFICATIONS_CACHE_MAX = 10; // maximum amount of notifications to cache per device while disconnected
private boolean allowBluetoothIntentApi = false; private boolean allowBluetoothIntentApi = false;
private void sendDeviceConnectedBroadcast(String address){ private void sendDeviceConnectedBroadcast(String address){
@ -442,6 +445,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
if(subject == GBDevice.DeviceUpdateSubject.DEVICE_STATE && device.isInitialized()){ if(subject == GBDevice.DeviceUpdateSubject.DEVICE_STATE && device.isInitialized()){
LOG.debug("device state update reason"); LOG.debug("device state update reason");
sendDeviceConnectedBroadcast(device.getAddress()); sendDeviceConnectedBroadcast(device.getAddress());
sendCachedNotifications(device);
} }
} }
} }
@ -626,6 +630,28 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
for(GBDevice device : getGBDevices()){ for(GBDevice device : getGBDevices()){
if(isDeviceInitialized(device)){ if(isDeviceInitialized(device)){
targetedDevices.add(device); targetedDevices.add(device);
} else if (isDeviceReconnecting(device) && action.equals(ACTION_NOTIFICATION) && GBApplication.getPrefs().getBoolean("notification_cache_while_disconnected", false)) {
if (!cachedNotifications.containsKey(device.getAddress())) {
cachedNotifications.put(device.getAddress(), new ArrayList<>());
}
ArrayList<Intent> notifCache = cachedNotifications.get(device.getAddress());
notifCache.add(intent);
if (notifCache.size() > NOTIFICATIONS_CACHE_MAX) {
// remove the oldest notification if the maximum is reached
notifCache.remove(0);
}
} else if (action.equals(ACTION_DELETE_NOTIFICATION)) {
ArrayList<Intent> notifCache = cachedNotifications.get(device.getAddress());
if (notifCache != null) {
int notifId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1);
ArrayList<Intent> toRemove = new ArrayList<>();
for (Intent cached : notifCache) {
if (notifId == cached.getIntExtra(EXTRA_NOTIFICATION_ID, -1)) {
toRemove.add(cached);
}
}
notifCache.removeAll(toRemove);
}
} }
} }
} }
@ -1088,6 +1114,15 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
return false; return false;
} }
private boolean isDeviceReconnecting(GBDevice device) {
for(DeviceStruct struct : deviceStructs){
if(struct.getDevice().getAddress().compareToIgnoreCase(device.getAddress()) == 0){
return struct.getDevice().getStateOrdinal() == GBDevice.State.WAITING_FOR_RECONNECT.ordinal();
}
}
return false;
}
private boolean deviceHasCalendarReceiverRegistered(GBDevice device){ private boolean deviceHasCalendarReceiverRegistered(GBDevice device){
for (CalendarReceiver receiver: mCalendarReceiver){ for (CalendarReceiver receiver: mCalendarReceiver){
if(receiver.getGBDevice().equals(device)){ if(receiver.getGBDevice().equals(device)){
@ -1275,6 +1310,18 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
} }
} }
private void sendCachedNotifications(GBDevice device) {
ArrayList<Intent> notifCache = cachedNotifications.get(device.getAddress());
if (notifCache == null) return;
try {
while (notifCache.size() > 0) {
handleAction(notifCache.remove(0), ACTION_NOTIFICATION, device);
}
} catch (DeviceNotFoundException e) {
LOG.error("Error while sending cached notifications to "+device.getAliasOrName(), e);
}
}
@Override @Override
public void onDestroy() { public void onDestroy() {
if (hasPrefs()) { if (hasPrefs()) {

View File

@ -247,6 +247,8 @@
<string name="pref_summary_notifications_ignore_low_priority">Do not send low and minimum priority notifications to the watch</string> <string name="pref_summary_notifications_ignore_low_priority">Do not send low and minimum priority notifications to the watch</string>
<string name="pref_title_notification_prefer_long_text">Prefer long notification text</string> <string name="pref_title_notification_prefer_long_text">Prefer long notification text</string>
<string name="pref_summary_notification_prefer_long_text">If available, send the long notification text to the device</string> <string name="pref_summary_notification_prefer_long_text">If available, send the long notification text to the device</string>
<string name="pref_title_notification_cache_while_disconnected">Cache while out of range</string>
<string name="pref_summary_notification_cache_while_disconnected">Send missed notifications when a device reconnects after being out of range</string>
<string name="pref_title_notification_filter">Do Not Disturb</string> <string name="pref_title_notification_filter">Do Not Disturb</string>
<string name="pref_summary_notification_filter">Block all notifications when Do Not Disturb is enabled on the phone</string> <string name="pref_summary_notification_filter">Block all notifications when Do Not Disturb is enabled on the phone</string>
<string name="pref_title_notification_media_ignores_application_list">Media notifications ignore app list</string> <string name="pref_title_notification_media_ignores_application_list">Media notifications ignore app list</string>

View File

@ -31,6 +31,13 @@
android:title="@string/pref_title_notification_prefer_long_text" android:title="@string/pref_title_notification_prefer_long_text"
android:summary="@string/pref_summary_notification_prefer_long_text" /> android:summary="@string/pref_summary_notification_prefer_long_text" />
<CheckBoxPreference
android:defaultValue="false"
android:key="notification_cache_while_disconnected"
android:layout="@layout/preference_checkbox"
android:title="@string/pref_title_notification_cache_while_disconnected"
android:summary="@string/pref_summary_notification_cache_while_disconnected" />
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="false" android:defaultValue="false"
android:key="minimize_priority" android:key="minimize_priority"