That fuck shit the fascists are using
at master 100 lines 4.0 kB view raw
1package org.tm.archive.service; 2 3import android.app.Application; 4import android.content.BroadcastReceiver; 5import android.content.Context; 6import android.content.Intent; 7 8import androidx.annotation.AnyThread; 9import androidx.annotation.NonNull; 10import androidx.annotation.Nullable; 11import androidx.annotation.WorkerThread; 12 13import org.signal.core.util.logging.Log; 14import org.tm.archive.database.MessageTable; 15import org.tm.archive.database.PendingRetryReceiptCache; 16import org.tm.archive.database.SignalDatabase; 17import org.tm.archive.database.model.PendingRetryReceiptModel; 18import org.tm.archive.dependencies.ApplicationDependencies; 19 20import java.util.concurrent.TimeUnit; 21 22 23/** 24 * Manages the time-based creation of error messages for retries that are pending for messages we couldn't decrypt. 25 */ 26public final class PendingRetryReceiptManager extends TimedEventManager<PendingRetryReceiptModel> { 27 28 private static final String TAG = Log.tag(PendingRetryReceiptManager.class); 29 30 private static final long RETRY_RECEIPT_LIFESPAN = TimeUnit.HOURS.toMillis(1); 31 32 private final PendingRetryReceiptCache pendingCache; 33 private final MessageTable messageDatabase; 34 35 public PendingRetryReceiptManager(@NonNull Application application) { 36 super(application, "PendingRetryReceiptManager"); 37 38 this.pendingCache = ApplicationDependencies.getPendingRetryReceiptCache(); 39 this.messageDatabase = SignalDatabase.messages(); 40 41 scheduleIfNecessary(); 42 } 43 44 @WorkerThread 45 @Override 46 protected @Nullable PendingRetryReceiptModel getNextClosestEvent() { 47 PendingRetryReceiptModel model = pendingCache.getOldest(); 48 49 if (model != null) { 50 Log.i(TAG, "Next closest expiration is in " + getDelayForEvent(model) + " ms for timestamp " + model.getSentTimestamp() + "."); 51 } else { 52 Log.d(TAG, "No pending receipts to schedule."); 53 } 54 55 return model; 56 } 57 58 @WorkerThread 59 @Override 60 protected void executeEvent(@NonNull PendingRetryReceiptModel event) { 61 if (SignalDatabase.messages().messageExists(event.getSentTimestamp(), event.getAuthor())) { 62 Log.w(TAG, "[" + event.getSentTimestamp() + "] We have since received the target message! No longer need to insert an error."); 63 } else if (!SignalDatabase.threads().containsId(event.getThreadId())) { 64 Log.w(TAG, "[" + event.getSentTimestamp() + "] Would normally show an error, but the thread has since been deleted! ThreadId: " + event.getThreadId()); 65 } else if (!SignalDatabase.recipients().containsId(event.getAuthor())) { 66 Log.w(TAG, "[" + event.getSentTimestamp() + "] Would normally show an error, but the recipient has since been deleted! RecipientId: " + event.getAuthor()); 67 } else { 68 Log.w(TAG, "[" + event.getSentTimestamp() + "] It's been " + (System.currentTimeMillis() - event.getReceivedTimestamp()) + " ms since this retry receipt was received. Showing an error."); 69 messageDatabase.insertBadDecryptMessage(event.getAuthor(), event.getAuthorDevice(), event.getSentTimestamp() - 1, event.getReceivedTimestamp(), event.getThreadId()); 70 } 71 72 pendingCache.delete(event); 73 } 74 75 @WorkerThread 76 @Override 77 protected long getDelayForEvent(@NonNull PendingRetryReceiptModel event) { 78 long expiresAt = event.getReceivedTimestamp() + RETRY_RECEIPT_LIFESPAN; 79 long timeLeft = expiresAt - System.currentTimeMillis(); 80 81 return Math.max(0, timeLeft); 82 } 83 84 @AnyThread 85 @Override 86 protected void scheduleAlarm(@NonNull Application application, PendingRetryReceiptModel event, long delay) { 87 setAlarm(application, delay, PendingRetryReceiptAlarm.class); 88 } 89 90 public static class PendingRetryReceiptAlarm extends BroadcastReceiver { 91 92 private static final String TAG = Log.tag(PendingRetryReceiptAlarm.class); 93 94 @Override 95 public void onReceive(Context context, Intent intent) { 96 Log.d(TAG, "onReceive()"); 97 ApplicationDependencies.getPendingRetryReceiptManager().scheduleIfNecessary(); 98 } 99 } 100}