That fuck shit the fascists are using
1package org.tm.archive.util;
2
3import android.app.AlarmManager;
4import android.app.PendingIntent;
5import android.content.BroadcastReceiver;
6import android.content.Context;
7import android.content.Intent;
8import android.content.IntentFilter;
9import android.os.Build;
10import android.os.SystemClock;
11
12import androidx.core.app.AlarmManagerCompat;
13
14import org.signal.core.util.PendingIntentFlags;
15import org.signal.core.util.logging.Log;
16import org.whispersystems.signalservice.api.util.SleepTimer;
17
18import java.util.concurrent.ConcurrentSkipListSet;
19
20/**
21 * A sleep timer that is based on elapsed realtime, so that it works properly, even in low-power sleep modes.
22 */
23public class AlarmSleepTimer implements SleepTimer {
24 private static final String TAG = Log.tag(AlarmSleepTimer.class);
25
26 private static final ConcurrentSkipListSet<Integer> actionIdList = new ConcurrentSkipListSet<>();
27
28 private final Context context;
29
30 public AlarmSleepTimer(Context context) {
31 this.context = context;
32 }
33
34 @Override
35 public void sleep(long sleepDuration) {
36 AlarmReceiver alarmReceiver = new AlarmSleepTimer.AlarmReceiver();
37 int actionId = 0;
38
39 while (!actionIdList.add(actionId)){
40 actionId++;
41 }
42
43 try {
44 String actionName = buildActionName(actionId);
45 context.registerReceiver(alarmReceiver, new IntentFilter(actionName));
46
47 long startTime = System.currentTimeMillis();
48 alarmReceiver.setAlarm(sleepDuration, actionName);
49
50 while (System.currentTimeMillis() - startTime < sleepDuration) {
51 try {
52 synchronized (this) {
53 wait(sleepDuration - (System.currentTimeMillis() - startTime));
54 }
55 } catch (InterruptedException e) {
56 Log.w(TAG, e);
57 }
58 }
59 context.unregisterReceiver(alarmReceiver);
60 } catch(Exception e) {
61 Log.w(TAG, "Exception during sleep ...",e);
62 } finally {
63 actionIdList.remove(actionId);
64 }
65 }
66
67 private static String buildActionName(int actionId) {
68 return AlarmReceiver.WAKE_UP_THREAD_ACTION + "." + actionId;
69 }
70
71 private class AlarmReceiver extends BroadcastReceiver {
72 private static final String WAKE_UP_THREAD_ACTION = "org.tm.archive.util.AlarmSleepTimer.AlarmReceiver.WAKE_UP_THREAD";
73
74 private void setAlarm(long millis, String action) {
75 final Intent intent = new Intent(action);
76 final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntentFlags.mutable());
77 final AlarmManager alarmManager = ServiceUtil.getAlarmManager(context);
78
79 if (Build.VERSION.SDK_INT < 31 || alarmManager.canScheduleExactAlarms()) {
80 Log.d(TAG, "Setting an exact alarm to wake up in " + millis + "ms.");
81 AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager,
82 AlarmManager.ELAPSED_REALTIME_WAKEUP,
83 SystemClock.elapsedRealtime() + millis,
84 pendingIntent);
85 } else {
86 Log.w(TAG, "Setting an inexact alarm to wake up in " + millis + "ms. CanScheduleAlarms: " + alarmManager.canScheduleExactAlarms());
87 alarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
88 SystemClock.elapsedRealtime() + millis,
89 pendingIntent);
90 }
91 }
92
93 @Override
94 public void onReceive(Context context, Intent intent) {
95 Log.w(TAG, "Waking up.");
96
97 synchronized (AlarmSleepTimer.this) {
98 AlarmSleepTimer.this.notifyAll();
99 }
100 }
101 }
102}
103