Skip to content

Commit

Permalink
Make weather monitor state receiver more generic
Browse files Browse the repository at this point in the history
  • Loading branch information
kylecorry31 committed Jun 29, 2024
1 parent 9cc5069 commit 9916f57
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 37 deletions.
48 changes: 42 additions & 6 deletions app/src/main/java/com/kylecorry/trail_sense/main/Automations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,41 @@ import android.content.Context
import android.content.IntentFilter
import androidx.core.os.bundleOf
import com.kylecorry.andromeda.core.system.BroadcastReceiverTopic
import com.kylecorry.trail_sense.shared.UserPreferences
import com.kylecorry.trail_sense.shared.automations.Automation
import com.kylecorry.trail_sense.shared.automations.AutomationReceiver
import com.kylecorry.trail_sense.tools.battery.BatteryToolRegistration
import com.kylecorry.trail_sense.tools.tools.infrastructure.Tools
import com.kylecorry.trail_sense.tools.weather.WeatherToolRegistration
import com.kylecorry.trail_sense.tools.weather.receivers.SetWeatherMonitorStateReceiver

object Automations {
fun setup(context: Context) {
val tools = Tools.getTools(context, false)
val actions = tools.flatMap { it.broadcasts.map { it.action } }
val prefs = UserPreferences(context)

// TODO: This should be loaded from the disk and kept up to date
val automations = mapOf(
BatteryToolRegistration.ACTION_POWER_SAVING_MODE_CHANGED to listOf(
WeatherToolRegistration.RECEIVER_WEATHER_MONITOR_POWER_SAVING_MODE
val automations = listOf(
Automation(
BatteryToolRegistration.ACTION_POWER_SAVING_MODE_CHANGED,
listOfNotNull(
if (prefs.lowPowerModeDisablesWeather) {
AutomationReceiver(
WeatherToolRegistration.RECEIVER_SET_WEATHER_MONITOR_STATE
) {
bundleOf(
SetWeatherMonitorStateReceiver.PARAM_WEATHER_MONITOR_STATE to !it.getBoolean(
BatteryToolRegistration.PARAM_POWER_SAVING_MODE_ENABLED,
false
)
)
}
} else {
null
}
)

)
)

Expand All @@ -25,10 +47,24 @@ object Automations {
// TODO: Should there be a way to unregister? Maybe only register when something is listening?
receiver.subscribe { intent ->
// TODO: This should be run in the background
Tools.getTools(context)
val automationsToRun = automations.filter { it.broadcast == action }
val receiversToRun = automationsToRun.flatMap { it.receivers.map { it.receiverId } }

val availableReceivers = tools
.flatMap { it.receivers }
.filter { automations.getOrDefault(action, emptyList()).contains(it.id) && it.isEnabled(context) }
.forEach { it.receiver.onReceive(context, intent.extras ?: bundleOf()) }
.filter { receiversToRun.contains(it.id) && it.isEnabled(context) }

automationsToRun.forEach {
it.receivers.forEach { receiver ->
val toolReceiver =
availableReceivers.firstOrNull { it.id == receiver.receiverId }
?: return@forEach
toolReceiver.receiver.onReceive(
context,
receiver.parameterTransform(intent.extras ?: bundleOf())
)
}
}
true
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.kylecorry.trail_sense.shared.automations

import android.os.Bundle

data class Automation(
val broadcast: String,
val receivers: List<AutomationReceiver>
)

data class AutomationReceiver(
val receiverId: String,
// TODO: Make this more generic / easier to store in the DB
val parameterTransform: (Bundle) -> Bundle = { it },
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import android.content.Context
import android.os.Bundle

// TODO: Should receivers return a bundle that can be passed to the next receiver?
interface AutomationReceiver {
interface Receiver {
fun onReceive(context: Context, data: Bundle)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ import android.content.Context
data class ToolReceiver(
val id: String,
val name: String,
val isEnabled: (context: Context) -> Boolean,
val receiver: AutomationReceiver
val receiver: Receiver,
val isEnabled: (context: Context) -> Boolean = { true }
)
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import com.kylecorry.trail_sense.tools.weather.infrastructure.alerts.CurrentWeat
import com.kylecorry.trail_sense.tools.weather.infrastructure.alerts.DailyWeatherAlerter
import com.kylecorry.trail_sense.tools.weather.infrastructure.alerts.StormAlerter
import com.kylecorry.trail_sense.tools.weather.quickactions.QuickActionWeatherMonitor
import com.kylecorry.trail_sense.tools.weather.receivers.WeatherMonitorPowerSavingModeReceiver
import com.kylecorry.trail_sense.tools.weather.receivers.SetWeatherMonitorStateReceiver

object WeatherToolRegistration : ToolRegistration {
override fun getTool(context: Context): Tool {
Expand Down Expand Up @@ -120,14 +120,14 @@ object WeatherToolRegistration : ToolRegistration {
).distinctBy { it.id },
receivers = listOf(
ToolReceiver(
RECEIVER_WEATHER_MONITOR_POWER_SAVING_MODE,
context.getString(R.string.pref_low_power_mode_title),
{ UserPreferences(it).lowPowerModeDisablesWeather },
WeatherMonitorPowerSavingModeReceiver()
RECEIVER_SET_WEATHER_MONITOR_STATE,
context.getString(R.string.weather_monitor),
SetWeatherMonitorStateReceiver()
)
)
)
}

const val RECEIVER_WEATHER_MONITOR_POWER_SAVING_MODE = "weather-monitor-power-saving-mode"
const val RECEIVER_SET_WEATHER_MONITOR_STATE =
"com.kylecorry.trail_sense.tools.weather.RECEIVER_SET_WEATHER_MONITOR_STATE"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.kylecorry.trail_sense.tools.weather.receivers

import android.content.Context
import android.os.Bundle
import com.kylecorry.trail_sense.tools.tools.infrastructure.Receiver
import com.kylecorry.trail_sense.tools.weather.infrastructure.WeatherMonitorIsEnabled
import com.kylecorry.trail_sense.tools.weather.infrastructure.WeatherUpdateScheduler

// TODO: Add support for enable/disable weather monitor
class SetWeatherMonitorStateReceiver : Receiver {
override fun onReceive(context: Context, data: Bundle) {
val desiredState = data.getBoolean(PARAM_WEATHER_MONITOR_STATE, false)

if (desiredState && WeatherMonitorIsEnabled().isSatisfiedBy(context)) {
WeatherUpdateScheduler.start(context)
} else if (!desiredState) {
WeatherUpdateScheduler.stop(context)
}
}

companion object {
const val PARAM_WEATHER_MONITOR_STATE = "state"
}
}

This file was deleted.

0 comments on commit 9916f57

Please sign in to comment.