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