Skip to content

Commit

Permalink
feat(eco mode stream): bump version 0.2, add eco mode stream
Browse files Browse the repository at this point in the history
  • Loading branch information
apoichet authored and Tiska committed Jun 17, 2024
1 parent f7e0ac7 commit 920676d
Show file tree
Hide file tree
Showing 15 changed files with 877 additions and 310 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.2.0

> Add Eco Mode Stream
- **FEAT**: Add eco mode stream `isBatteryEcoModeStream`.

## 0.0.1

> Initial release
Expand Down
31 changes: 16 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,22 @@ also to offer a less energy-consuming app.

## Features

| Feature | Android | iOS | Runtime | Event |
|:---------------------------------------------------------------------------------------------|:---------------------------------------:|:---------------------------------------:|:-------------------------------------:|:-----:|
| getPlatformInfo() | Yes | Yes | | |
| getBatteryLevel() | Yes | Yes | X | |
| getBatteryState() | No | Yes | X | |
| isBatteryInLowPowerMode() | Yes | Yes | X | |
| lowPowerModeEventStream() | Yes | Yes | X | X |
| getThermalState() | Yes | Yes | X | |
| getProcessorCount() | Yes | Yes | | |
| getTotalMemory() | Yes | Yes | | |
| getFreeMemory() | Yes | Yes | X | |
| getTotalStorage() | Yes | Yes | | |
| getFreeStorage() | Yes | Yes | X | |
| <span style="color: #3CB371">**isBatteryEcoMode()**</span> | <span style="color: #3CB371">Yes</span> | <span style="color: #3CB371">Yes</span> | <span style="color: #3CB371">X</span> | |
| <span style="color: #3CB371">**getEcoRange**()</span> | <span style="color: #3CB371">Yes</span> | <span style="color: #3CB371">Yes</span> | <span style="color: #3CB371">X</span> | |
| Feature | Android | iOS | Runtime | Event |
|:---------------------------------------------------------------------------------------------------|:---------------------------------------:|:---------------------------------------:|:-------------------------------------:|:-----:|
| getPlatformInfo() | Yes | Yes | | |
| getBatteryLevel() | Yes | Yes | X | |
| getBatteryState() | No | Yes | X | |
| isBatteryInLowPowerMode() | Yes | Yes | X | |
| lowPowerModeEventStream() | Yes | Yes | X | X |
| getThermalState() | Yes | Yes | X | |
| getProcessorCount() | Yes | Yes | | |
| getTotalMemory() | Yes | Yes | | |
| getFreeMemory() | Yes | Yes | X | |
| getTotalStorage() | Yes | Yes | | |
| getFreeStorage() | Yes | Yes | X | |
| isBatteryEcoModeStream | Yes | No | | X |
| <span style="color: #3CB371">**isBatteryEcoMode()**</span> | <span style="color: #3CB371">Yes</span> | <span style="color: #3CB371">Yes</span> | <span style="color: #3CB371">X</span> | |
| <span style="color: #3CB371">**getEcoRange**()</span> | <span style="color: #3CB371">Yes</span> | <span style="color: #3CB371">Yes</span> | <span style="color: #3CB371">X</span> | |


## Eco Mode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,66 @@ package sncf.connect.tech.flutter_eco_mode
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.Intent.ACTION_BATTERY_CHANGED
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.BatteryManager.BATTERY_STATUS_CHARGING
import android.os.BatteryManager.BATTERY_STATUS_DISCHARGING
import android.os.BatteryManager.BATTERY_STATUS_FULL
import android.os.BatteryManager.BATTERY_STATUS_NOT_CHARGING
import android.os.Build
import android.os.Environment
import android.os.PowerManager
import android.os.PowerManager.THERMAL_STATUS_CRITICAL
import android.os.PowerManager.THERMAL_STATUS_EMERGENCY
import android.os.PowerManager.THERMAL_STATUS_LIGHT
import android.os.PowerManager.THERMAL_STATUS_MODERATE
import android.os.PowerManager.THERMAL_STATUS_NONE
import android.os.PowerManager.THERMAL_STATUS_SEVERE
import android.os.PowerManager.THERMAL_STATUS_SHUTDOWN
import android.os.StatFs
import androidx.annotation.RequiresApi
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.EventChannel
import sncf.connect.tech.flutter_eco_mode.BatteryState.CHARGING
import sncf.connect.tech.flutter_eco_mode.BatteryState.DISCHARGING
import sncf.connect.tech.flutter_eco_mode.BatteryState.FULL
import sncf.connect.tech.flutter_eco_mode.BatteryState.UNKNOWN
import sncf.connect.tech.flutter_eco_mode.ThermalState.CRITICAL
import sncf.connect.tech.flutter_eco_mode.ThermalState.FAIR
import sncf.connect.tech.flutter_eco_mode.ThermalState.SAFE
import sncf.connect.tech.flutter_eco_mode.ThermalState.SERIOUS

class FlutterEcoModePlugin : FlutterPlugin, EcoModeApi, EventChannel.StreamHandler {

class FlutterEcoModePlugin : FlutterPlugin, EcoModeApi {
private lateinit var context: Context

private val lowPowerModeEventChannel = "sncf.connect.tech/battery.isLowPowerMode"
private var eventSink: EventChannel.EventSink? = null

private var powerSavingReceiver: BroadcastReceiver? = null
private val batteryStateEventChannel = "sncf.connect.tech/battery.state"
private val batteryLevelEventChannel = "sncf.connect.tech/battery.level"

override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
EcoModeApi.setUp(flutterPluginBinding.binaryMessenger, this)
context = flutterPluginBinding.applicationContext
EventChannel(
flutterPluginBinding.binaryMessenger,
lowPowerModeEventChannel
).setStreamHandler(this)
lowPowerModeEventChannel,
).setStreamHandler(PowerModeStreamHandler(context))
EventChannel(
flutterPluginBinding.binaryMessenger,
batteryStateEventChannel,
).setStreamHandler(BatteryStateStreamHandler(context))
EventChannel(
flutterPluginBinding.binaryMessenger,
batteryLevelEventChannel,
).setStreamHandler(BatteryLevelStreamHandler(context))
}


override fun onDetachedFromEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
EcoModeApi.setUp(flutterPluginBinding.binaryMessenger, null)
}

override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
eventSink = events
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setupPowerSavingReceiver()
}
}

override fun onCancel(arguments: Any?) {
eventSink = null
context.unregisterReceiver(powerSavingReceiver)
}

override fun getPlatformInfo(): String {
val release: String = Build.VERSION.RELEASE
val device: String = Build.DEVICE
Expand All @@ -55,15 +72,12 @@ class FlutterEcoModePlugin : FlutterPlugin, EcoModeApi, EventChannel.StreamHandl
return "Android - $release - $device - $hardware - $product - $type"
}

override fun getBatteryLevel(): Double {
val batteryStatus = getBatteryStatus()
val batteryLevel: Double? = batteryStatus?.let { intent ->
val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
level * 100 / scale.toDouble()
}
return batteryLevel ?: 0.0
}
override fun getBatteryLevel(): Double = getBatteryLevel(getBatteryStatus())
private fun getBatteryLevel(intent: Intent?): Double = intent?.let {
val level: Int = it.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale: Int = it.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
level * 100 / scale.toDouble()
} ?: 0.0

override fun getBatteryState(): BatteryState {
val batteryStatus = getBatteryStatus()
Expand All @@ -79,18 +93,6 @@ class FlutterEcoModePlugin : FlutterPlugin, EcoModeApi, EventChannel.StreamHandl
return false // can't return null so we return false for older versions
}

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun setupPowerSavingReceiver() {
powerSavingReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
eventSink?.success(powerManager.isPowerSaveMode)
}
}
val filter = IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
context.registerReceiver(powerSavingReceiver, filter)
}

override fun getThermalState(): ThermalState {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
Expand Down Expand Up @@ -141,27 +143,138 @@ class FlutterEcoModePlugin : FlutterPlugin, EcoModeApi, EventChannel.StreamHandl
}

private fun getBatteryStatus(): Intent? {
return IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { intentFilter ->
return IntentFilter(ACTION_BATTERY_CHANGED).let { intentFilter ->
context.registerReceiver(null, intentFilter)
}
}

private fun convertBatteryState(state: Int): BatteryState {
return when (state) {
BatteryManager.BATTERY_STATUS_CHARGING -> BatteryState.CHARGING
BatteryManager.BATTERY_STATUS_FULL -> BatteryState.FULL
BatteryManager.BATTERY_STATUS_DISCHARGING, BatteryManager.BATTERY_STATUS_NOT_CHARGING -> BatteryState.DISCHARGING
else -> BatteryState.UNKNOWN
BATTERY_STATUS_CHARGING -> CHARGING
BATTERY_STATUS_FULL -> FULL
BATTERY_STATUS_DISCHARGING, BATTERY_STATUS_NOT_CHARGING -> DISCHARGING
else -> UNKNOWN
}
}

private fun convertThermalState(state: Int): ThermalState {
return when (state) {
PowerManager.THERMAL_STATUS_NONE -> ThermalState.SAFE
PowerManager.THERMAL_STATUS_MODERATE, PowerManager.THERMAL_STATUS_LIGHT -> ThermalState.FAIR
PowerManager.THERMAL_STATUS_SEVERE -> ThermalState.SERIOUS
PowerManager.THERMAL_STATUS_CRITICAL, PowerManager.THERMAL_STATUS_EMERGENCY, PowerManager.THERMAL_STATUS_SHUTDOWN -> ThermalState.CRITICAL
THERMAL_STATUS_NONE -> SAFE
THERMAL_STATUS_MODERATE, THERMAL_STATUS_LIGHT -> FAIR
THERMAL_STATUS_SEVERE -> SERIOUS
THERMAL_STATUS_CRITICAL, THERMAL_STATUS_EMERGENCY, THERMAL_STATUS_SHUTDOWN -> CRITICAL
else -> ThermalState.UNKNOWN
}
}
}

class PowerModeStreamHandler(private val context: Context) : EventChannel.StreamHandler {

private var lowPowerModeEventSink: EventChannel.EventSink? = null
private var powerSavingReceiver: BroadcastReceiver? = null

override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
lowPowerModeEventSink = events

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setupPowerSavingReceiver()
}
}

override fun onCancel(p0: Any?) {
context.unregisterReceiver(powerSavingReceiver)
}

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun setupPowerSavingReceiver() {
powerSavingReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
lowPowerModeEventSink?.success(powerManager.isPowerSaveMode)
}
}
val filter = IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
context.registerReceiver(powerSavingReceiver, filter)
}

}

class BatteryStateStreamHandler(private val context: Context) : EventChannel.StreamHandler {

private var batteryStateEventSink: EventChannel.EventSink? = null
private var batteryStateReceiver: BroadcastReceiver? = null

override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
batteryStateEventSink = events

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setupBatteryStateReceiver()
}
}

override fun onCancel(p0: Any?) {
context.unregisterReceiver(batteryStateReceiver)
}

@RequiresApi(Build.VERSION_CODES.M)
private fun setupBatteryStateReceiver() {
batteryStateReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
val event = when (intent?.action) {
ACTION_BATTERY_CHANGED ->
when (intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)) {
BATTERY_STATUS_CHARGING -> CHARGING.name
BATTERY_STATUS_FULL -> FULL.name
BATTERY_STATUS_DISCHARGING, BATTERY_STATUS_NOT_CHARGING -> DISCHARGING.name
else -> UNKNOWN.name
}
else -> DISCHARGING.name
}
batteryStateEventSink?.success(event)
}
}
val filterBatteryState = IntentFilter()
filterBatteryState.addAction(ACTION_BATTERY_CHANGED)
context.registerReceiver(batteryStateReceiver, filterBatteryState)
}

}

class BatteryLevelStreamHandler(private val context: Context) : EventChannel.StreamHandler {

private var batteryLevelEventSink: EventChannel.EventSink? = null
private var batteryLevelReceiver: BroadcastReceiver? = null

override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
batteryLevelEventSink = events

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setupBatteryLevelReceiver()
}
}

override fun onCancel(p0: Any?) {
context.unregisterReceiver(batteryLevelReceiver)
}


@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun setupBatteryLevelReceiver() {

batteryLevelReceiver = object : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent?) {
val batteryPct = intent?.let { i ->
val level: Int = i.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale: Int = i.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
level * 100 / scale.toFloat()
}
batteryLevelEventSink?.success(batteryPct?.toDouble())
}
}
val filter = IntentFilter(ACTION_BATTERY_CHANGED)
context.registerReceiver(batteryLevelReceiver, filter)

}

}
Loading

0 comments on commit 920676d

Please sign in to comment.