Fix missing push notifications

since_ids and last_notifid_reccorded often contained the same id
so fetching notification was aborted. It looks like these variables
were introduced to avoid multiple fetches at the same time.
So this commit adds a reentrantLock with a tryLock to do it
This commit is contained in:
sim 2023-08-28 23:16:13 +02:00
parent ce92f23c50
commit 36b28a4483
1 changed files with 33 additions and 52 deletions

View File

@ -42,6 +42,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import app.fedilab.android.BaseMainActivity; import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R; import app.fedilab.android.R;
@ -62,9 +63,10 @@ import retrofit2.converter.gson.GsonConverterFactory;
public class NotificationsHelper { public class NotificationsHelper {
public static HashMap<String, String> since_ids = new HashMap<>();
public static HashMap<String, List<String>> pushed_notifications = new HashMap<>(); public static HashMap<String, List<String>> pushed_notifications = new HashMap<>();
public static ReentrantLock lock = new ReentrantLock();
public static synchronized void task(Context context, String slug) throws DBException { public static synchronized void task(Context context, String slug) throws DBException {
SharedPreferences prefs = PreferenceManager SharedPreferences prefs = PreferenceManager
@ -74,16 +76,6 @@ public class NotificationsHelper {
if (accountDb == null) { if (accountDb == null) {
return; return;
} }
String last_notifid;
last_notifid = prefs.getString(context.getString(R.string.LAST_NOTIFICATION_ID) + slug, null);
if (since_ids.containsKey(slug)) {
String last_notifid_reccorded = since_ids.get(slug);
if (last_notifid_reccorded != null && last_notifid_reccorded.compareToIgnoreCase(last_notifid) == 0) {
return;
}
} else {
since_ids.put(slug, last_notifid);
}
//Check which notifications the user wants to see //Check which notifications the user wants to see
boolean notif_follow = prefs.getBoolean(context.getString(R.string.SET_NOTIF_FOLLOW), true); boolean notif_follow = prefs.getBoolean(context.getString(R.string.SET_NOTIF_FOLLOW), true);
@ -101,16 +93,15 @@ public class NotificationsHelper {
return; //Nothing is done return; //Nothing is done
} }
MastodonNotificationsService mastodonNotificationsService = init(context, slugArray[1]);
String finalLast_notifid = last_notifid;
new Thread(() -> { new Thread(() -> {
try {
// fetch if we get the lock, or ignore, another thread is doing the job
if (lock.tryLock()) {
MastodonNotificationsService mastodonNotificationsService = init(context, slugArray[1]);
Notifications notifications = new Notifications(); Notifications notifications = new Notifications();
Call<List<Notification>> notificationsCall; Call<List<Notification>> notificationsCall;
if (finalLast_notifid != null) { String last_notif_id = prefs.getString(context.getString(R.string.LAST_NOTIFICATION_ID) + slug, null);
notificationsCall = mastodonNotificationsService.getNotifications(accountDb.token, null, null, null, finalLast_notifid, null, 30); notificationsCall = mastodonNotificationsService.getNotifications(accountDb.token, null, null, null, last_notif_id, null, 30);
} else {
notificationsCall = mastodonNotificationsService.getNotifications(accountDb.token, null, null, null, null, null, 5);
}
if (notificationsCall != null) { if (notificationsCall != null) {
try { try {
Response<List<Notification>> notificationsResponse = notificationsCall.execute(); Response<List<Notification>> notificationsResponse = notificationsCall.execute();
@ -118,7 +109,10 @@ public class NotificationsHelper {
notifications.notifications = notificationsResponse.body(); notifications.notifications = notificationsResponse.body();
if (notifications.notifications != null) { if (notifications.notifications != null) {
if (notifications.notifications.size() > 0) { if (notifications.notifications.size() > 0) {
since_ids.put(slug, notifications.notifications.get(0).id); prefs.edit().putString(
context.getString(R.string.LAST_NOTIFICATION_ID) + slug,
notifications.notifications.get(0).id
).apply();
} }
} }
notifications.pagination = MastodonHelper.getPagination(notificationsResponse.headers()); notifications.pagination = MastodonHelper.getPagination(notificationsResponse.headers());
@ -127,11 +121,14 @@ public class NotificationsHelper {
e.printStackTrace(); e.printStackTrace();
} }
Handler mainHandler = new Handler(Looper.getMainLooper()); Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> onRetrieveNotifications(context, notifications, accountDb); Runnable myRunnable = () -> onRetrieveNotifications(context, notifications, accountDb, last_notif_id);
mainHandler.post(myRunnable); mainHandler.post(myRunnable);
} }
}
} finally {
lock.unlock();
}
}).start(); }).start();
} }
@ -150,7 +147,7 @@ public class NotificationsHelper {
return retrofit.create(MastodonNotificationsService.class); return retrofit.create(MastodonNotificationsService.class);
} }
public static void onRetrieveNotifications(Context context, Notifications newNotifications, final BaseAccount account) { public static void onRetrieveNotifications(Context context, Notifications newNotifications, final BaseAccount account, String max_id) {
if (newNotifications == null || newNotifications.notifications == null || newNotifications.notifications.size() == 0 || account == null) { if (newNotifications == null || newNotifications.notifications == null || newNotifications.notifications.size() == 0 || account == null) {
return; return;
} }
@ -169,8 +166,6 @@ public class NotificationsHelper {
boolean notif_signup = prefs.getBoolean(context.getString(R.string.SET_NOTIF_ADMIN_SIGNUP), true); boolean notif_signup = prefs.getBoolean(context.getString(R.string.SET_NOTIF_ADMIN_SIGNUP), true);
boolean notif_report = prefs.getBoolean(context.getString(R.string.SET_NOTIF_ADMIN_REPORT), true); boolean notif_report = prefs.getBoolean(context.getString(R.string.SET_NOTIF_ADMIN_REPORT), true);
final String max_id = prefs.getString(context.getString(R.string.LAST_NOTIFICATION_ID) + key, null);
final List<Notification> notifications = new ArrayList<>(); final List<Notification> notifications = new ArrayList<>();
int pos = 0; int pos = 0;
for (Notification notif : notificationsReceived) { for (Notification notif : notificationsReceived) {
@ -401,28 +396,14 @@ public class NotificationsHelper {
.into(new CustomTarget<Bitmap>() { .into(new CustomTarget<Bitmap>() {
@Override @Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) { public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
String lastNotif = prefs.getString(context.getString(R.string.LAST_NOTIFICATION_ID) + account.user_id + "@" + account.instance, null);
// if (lastNotif == null || Helper.compareTo(notification.id, lastNotif) > 0) {
SharedPreferences.Editor editor = prefs.edit();
editor.putString(context.getString(R.string.LAST_NOTIFICATION_ID) + account.user_id + "@" + account.instance, notifications.get(0).id);
editor.commit();
since_ids.put(account.user_id + "@" + account.instance, lastNotif);
Helper.notify_user(context, account, intent, resource, finalNotifType, finalTitle, finalMessage); Helper.notify_user(context, account, intent, resource, finalNotifType, finalTitle, finalMessage);
// }
} }
@Override @Override
public void onLoadFailed(@Nullable Drawable errorDrawable) { public void onLoadFailed(@Nullable Drawable errorDrawable) {
super.onLoadFailed(errorDrawable); super.onLoadFailed(errorDrawable);
String lastNotif = prefs.getString(context.getString(R.string.LAST_NOTIFICATION_ID) + account.user_id + "@" + account.instance, null);
// if (lastNotif == null || Helper.compareTo(notification.id, lastNotif) > 0) {
SharedPreferences.Editor editor = prefs.edit();
since_ids.put(account.user_id + "@" + account.instance, lastNotif);
editor.putString(context.getString(R.string.LAST_NOTIFICATION_ID) + account.user_id + "@" + account.instance, notifications.get(0).id);
editor.commit();
Helper.notify_user(context, account, intent, BitmapFactory.decodeResource(context.getResources(), Helper.notify_user(context, account, intent, BitmapFactory.decodeResource(context.getResources(),
getMainLogo(context)), finalNotifType, finalTitle, finalMessage); getMainLogo(context)), finalNotifType, finalTitle, finalMessage);
// }
} }
@Override @Override