That fuck shit the fascists are using
at master 103 lines 3.7 kB view raw
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