Rules.kt raw

   1  package io.github.domi04151309.alwayson.helpers
   2  
   3  import android.app.NotificationManager
   4  import android.content.Context
   5  import android.content.Intent
   6  import android.content.IntentFilter
   7  import android.icu.util.Calendar
   8  import android.os.BatteryManager
   9  import io.github.domi04151309.alwayson.R
  10  
  11  class Rules(context: Context) {
  12      private var start = 0L
  13      private var end = 0L
  14  
  15      init {
  16          val startString = P.getPreferences(context).getString("rules_time_start", "0:00") ?: "0:00"
  17          val endString = P.getPreferences(context).getString("rules_time_end", "0:00") ?: "0:00"
  18          val startCalendar =
  19              Calendar.getInstance().apply {
  20                  set(Calendar.MILLISECOND, 0)
  21                  set(Calendar.MILLISECOND, 0)
  22                  set(Calendar.SECOND, 0)
  23                  set(Calendar.MINUTE, startString.substringAfter(":").toInt())
  24                  set(Calendar.HOUR_OF_DAY, startString.substringBefore(":").toInt())
  25              }
  26          val endCalendar =
  27              Calendar.getInstance().apply {
  28                  set(Calendar.MILLISECOND, 0)
  29                  set(Calendar.MILLISECOND, 0)
  30                  set(Calendar.SECOND, 0)
  31                  set(Calendar.MINUTE, endString.substringAfter(":").toInt())
  32                  set(Calendar.HOUR_OF_DAY, endString.substringBefore(":").toInt())
  33              }
  34          if (startCalendar.after(endCalendar)) endCalendar.add(Calendar.DATE, 1)
  35          start = startCalendar.timeInMillis
  36          end = endCalendar.timeInMillis
  37      }
  38  
  39      private fun isInTimePeriod(): Boolean =
  40          if (start == end) {
  41              true
  42          } else {
  43              System.currentTimeMillis() in start + 1 until end
  44          }
  45  
  46      fun millisTillEnd(): Long =
  47          if (start == end) {
  48              -1
  49          } else {
  50              end - System.currentTimeMillis()
  51          }
  52  
  53      fun canShow(context: Context): Boolean =
  54          isAlwaysOnDisplayEnabled(context) &&
  55              matchesDoNotDisturbState(context) &&
  56              matchesChargingState(context) &&
  57              matchesBatteryPercentage(context) &&
  58              isInTimePeriod()
  59  
  60      companion object {
  61          const val BATTERY_FULL: Int = 100
  62  
  63          private fun getBatteryStatus(c: Context): Intent? =
  64              IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { filter ->
  65                  c.registerReceiver(
  66                      null,
  67                      filter,
  68                  )
  69              }
  70  
  71          private fun isCharging(context: Context): Boolean {
  72              val chargingState: Int =
  73                  getBatteryStatus(context)
  74                      ?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
  75                      ?: return true
  76              return if (chargingState > 0) {
  77                  P.getPreferences(context).getStringSet(
  78                      "rules_charger_type",
  79                      context.resources.getStringArray(R.array.pref_look_and_feel_rules_charger_values)
  80                          .toSet(),
  81                  )?.contains(
  82                      when (chargingState) {
  83                          BatteryManager.BATTERY_PLUGGED_AC -> "ac"
  84                          BatteryManager.BATTERY_PLUGGED_USB -> "usb"
  85                          BatteryManager.BATTERY_PLUGGED_WIRELESS -> "wireless"
  86                          else -> ""
  87                      },
  88                  ) == true
  89              } else {
  90                  false
  91              }
  92          }
  93  
  94          fun matchesDoNotDisturbState(context: Context): Boolean {
  95              val ruleDisableInDoNotDisturb =
  96                  P.getPreferences(context).getBoolean(
  97                      P.RULES_DISABLE_IN_DO_NOT_DISTURB,
  98                      P.RULES_DISABLE_IN_DO_NOT_DISTURB_DEFAULT,
  99                  )
 100              if (!ruleDisableInDoNotDisturb) return true
 101              val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
 102              return notificationManager.currentInterruptionFilter == NotificationManager.INTERRUPTION_FILTER_ALL
 103          }
 104  
 105          fun matchesChargingState(context: Context): Boolean {
 106              val ruleChargingState =
 107                  P.getPreferences(context).getString(
 108                      P.RULES_CHARGING_STATE,
 109                      P.RULES_CHARGING_STATE_DEFAULT,
 110                  )
 111              if (ruleChargingState == P.RULES_CHARGING_STATE_DEFAULT) return true
 112              val charging = isCharging(context)
 113              return (ruleChargingState == P.RULES_CHARGING_STATE_CHARGING && charging) ||
 114                  (ruleChargingState == P.RULES_CHARGING_STATE_DISCHARGING && !charging)
 115          }
 116  
 117          fun isAlwaysOnDisplayEnabled(context: Context): Boolean =
 118              P.getPreferences(context).getBoolean(
 119                  P.ALWAYS_ON,
 120                  P.ALWAYS_ON_DEFAULT,
 121              )
 122  
 123          fun isAmbientMode(context: Context): Boolean =
 124              P.getPreferences(context).getBoolean(
 125                  "rules_ambient_mode",
 126                  false,
 127              )
 128  
 129          fun matchesBatteryPercentage(context: Context): Boolean =
 130              (
 131                  getBatteryStatus(context)?.getIntExtra(
 132                      BatteryManager.EXTRA_LEVEL,
 133                      0,
 134                  ) ?: BATTERY_FULL
 135              ) > P.getPreferences(context).getInt(P.RULES_BATTERY, P.RULES_BATTERY_DEFAULT)
 136      }
 137  }
 138