@@ -3,49 +3,66 @@ package sncf.connect.tech.flutter_eco_mode
33import android.content.BroadcastReceiver
44import android.content.Context
55import android.content.Intent
6+ import android.content.Intent.ACTION_BATTERY_CHANGED
67import android.content.IntentFilter
78import android.os.BatteryManager
9+ import android.os.BatteryManager.BATTERY_STATUS_CHARGING
10+ import android.os.BatteryManager.BATTERY_STATUS_DISCHARGING
11+ import android.os.BatteryManager.BATTERY_STATUS_FULL
12+ import android.os.BatteryManager.BATTERY_STATUS_NOT_CHARGING
813import android.os.Build
914import android.os.Environment
1015import android.os.PowerManager
16+ import android.os.PowerManager.THERMAL_STATUS_CRITICAL
17+ import android.os.PowerManager.THERMAL_STATUS_EMERGENCY
18+ import android.os.PowerManager.THERMAL_STATUS_LIGHT
19+ import android.os.PowerManager.THERMAL_STATUS_MODERATE
20+ import android.os.PowerManager.THERMAL_STATUS_NONE
21+ import android.os.PowerManager.THERMAL_STATUS_SEVERE
22+ import android.os.PowerManager.THERMAL_STATUS_SHUTDOWN
1123import android.os.StatFs
1224import androidx.annotation.RequiresApi
1325import io.flutter.embedding.engine.plugins.FlutterPlugin
1426import io.flutter.plugin.common.EventChannel
27+ import sncf.connect.tech.flutter_eco_mode.BatteryState.CHARGING
28+ import sncf.connect.tech.flutter_eco_mode.BatteryState.DISCHARGING
29+ import sncf.connect.tech.flutter_eco_mode.BatteryState.FULL
30+ import sncf.connect.tech.flutter_eco_mode.BatteryState.UNKNOWN
31+ import sncf.connect.tech.flutter_eco_mode.ThermalState.CRITICAL
32+ import sncf.connect.tech.flutter_eco_mode.ThermalState.FAIR
33+ import sncf.connect.tech.flutter_eco_mode.ThermalState.SAFE
34+ import sncf.connect.tech.flutter_eco_mode.ThermalState.SERIOUS
1535
16- class FlutterEcoModePlugin : FlutterPlugin , EcoModeApi , EventChannel .StreamHandler {
36+
37+ class FlutterEcoModePlugin : FlutterPlugin , EcoModeApi {
1738 private lateinit var context: Context
1839
1940 private val lowPowerModeEventChannel = " sncf.connect.tech/battery.isLowPowerMode"
20- private var eventSink: EventChannel .EventSink ? = null
21-
22- private var powerSavingReceiver: BroadcastReceiver ? = null
41+ private val batteryStateEventChannel = " sncf.connect.tech/battery.state"
42+ private val batteryLevelEventChannel = " sncf.connect.tech/battery.level"
2343
2444 override fun onAttachedToEngine (flutterPluginBinding : FlutterPlugin .FlutterPluginBinding ) {
2545 EcoModeApi .setUp(flutterPluginBinding.binaryMessenger, this )
2646 context = flutterPluginBinding.applicationContext
2747 EventChannel (
2848 flutterPluginBinding.binaryMessenger,
29- lowPowerModeEventChannel
30- ).setStreamHandler(this )
49+ lowPowerModeEventChannel,
50+ ).setStreamHandler(PowerModeStreamHandler (context))
51+ EventChannel (
52+ flutterPluginBinding.binaryMessenger,
53+ batteryStateEventChannel,
54+ ).setStreamHandler(BatteryStateStreamHandler (context))
55+ EventChannel (
56+ flutterPluginBinding.binaryMessenger,
57+ batteryLevelEventChannel,
58+ ).setStreamHandler(BatteryLevelStreamHandler (context))
3159 }
3260
61+
3362 override fun onDetachedFromEngine (flutterPluginBinding : FlutterPlugin .FlutterPluginBinding ) {
3463 EcoModeApi .setUp(flutterPluginBinding.binaryMessenger, null )
3564 }
3665
37- override fun onListen (arguments : Any? , events : EventChannel .EventSink ? ) {
38- eventSink = events
39- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
40- setupPowerSavingReceiver()
41- }
42- }
43-
44- override fun onCancel (arguments : Any? ) {
45- eventSink = null
46- context.unregisterReceiver(powerSavingReceiver)
47- }
48-
4966 override fun getPlatformInfo (): String {
5067 val release: String = Build .VERSION .RELEASE
5168 val device: String = Build .DEVICE
@@ -55,15 +72,12 @@ class FlutterEcoModePlugin : FlutterPlugin, EcoModeApi, EventChannel.StreamHandl
5572 return " Android - $release - $device - $hardware - $product - $type "
5673 }
5774
58- override fun getBatteryLevel (): Double {
59- val batteryStatus = getBatteryStatus()
60- val batteryLevel: Double? = batteryStatus?.let { intent ->
61- val level: Int = intent.getIntExtra(BatteryManager .EXTRA_LEVEL , - 1 )
62- val scale: Int = intent.getIntExtra(BatteryManager .EXTRA_SCALE , - 1 )
63- level * 100 / scale.toDouble()
64- }
65- return batteryLevel ? : 0.0
66- }
75+ override fun getBatteryLevel (): Double = getBatteryLevel(getBatteryStatus())
76+ private fun getBatteryLevel (intent : Intent ? ): Double = intent?.let {
77+ val level: Int = it.getIntExtra(BatteryManager .EXTRA_LEVEL , - 1 )
78+ val scale: Int = it.getIntExtra(BatteryManager .EXTRA_SCALE , - 1 )
79+ level * 100 / scale.toDouble()
80+ } ? : 0.0
6781
6882 override fun getBatteryState (): BatteryState {
6983 val batteryStatus = getBatteryStatus()
@@ -79,18 +93,6 @@ class FlutterEcoModePlugin : FlutterPlugin, EcoModeApi, EventChannel.StreamHandl
7993 return false // can't return null so we return false for older versions
8094 }
8195
82- @RequiresApi(Build .VERSION_CODES .LOLLIPOP )
83- private fun setupPowerSavingReceiver () {
84- powerSavingReceiver = object : BroadcastReceiver () {
85- override fun onReceive (context : Context , intent : Intent ? ) {
86- val powerManager = context.getSystemService(Context .POWER_SERVICE ) as PowerManager
87- eventSink?.success(powerManager.isPowerSaveMode)
88- }
89- }
90- val filter = IntentFilter (PowerManager .ACTION_POWER_SAVE_MODE_CHANGED )
91- context.registerReceiver(powerSavingReceiver, filter)
92- }
93-
9496 override fun getThermalState (): ThermalState {
9597 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .Q ) {
9698 val powerManager = context.getSystemService(Context .POWER_SERVICE ) as PowerManager
@@ -141,27 +143,138 @@ class FlutterEcoModePlugin : FlutterPlugin, EcoModeApi, EventChannel.StreamHandl
141143 }
142144
143145 private fun getBatteryStatus (): Intent ? {
144- return IntentFilter (Intent . ACTION_BATTERY_CHANGED ).let { intentFilter ->
146+ return IntentFilter (ACTION_BATTERY_CHANGED ).let { intentFilter ->
145147 context.registerReceiver(null , intentFilter)
146148 }
147149 }
148150
149151 private fun convertBatteryState (state : Int ): BatteryState {
150152 return when (state) {
151- BatteryManager . BATTERY_STATUS_CHARGING -> BatteryState . CHARGING
152- BatteryManager . BATTERY_STATUS_FULL -> BatteryState . FULL
153- BatteryManager . BATTERY_STATUS_DISCHARGING , BatteryManager . BATTERY_STATUS_NOT_CHARGING -> BatteryState . DISCHARGING
154- else -> BatteryState . UNKNOWN
153+ BATTERY_STATUS_CHARGING -> CHARGING
154+ BATTERY_STATUS_FULL -> FULL
155+ BATTERY_STATUS_DISCHARGING , BATTERY_STATUS_NOT_CHARGING -> DISCHARGING
156+ else -> UNKNOWN
155157 }
156158 }
157159
158160 private fun convertThermalState (state : Int ): ThermalState {
159161 return when (state) {
160- PowerManager . THERMAL_STATUS_NONE -> ThermalState . SAFE
161- PowerManager . THERMAL_STATUS_MODERATE , PowerManager . THERMAL_STATUS_LIGHT -> ThermalState . FAIR
162- PowerManager . THERMAL_STATUS_SEVERE -> ThermalState . SERIOUS
163- PowerManager . THERMAL_STATUS_CRITICAL , PowerManager . THERMAL_STATUS_EMERGENCY , PowerManager . THERMAL_STATUS_SHUTDOWN -> ThermalState . CRITICAL
162+ THERMAL_STATUS_NONE -> SAFE
163+ THERMAL_STATUS_MODERATE , THERMAL_STATUS_LIGHT -> FAIR
164+ THERMAL_STATUS_SEVERE -> SERIOUS
165+ THERMAL_STATUS_CRITICAL , THERMAL_STATUS_EMERGENCY , THERMAL_STATUS_SHUTDOWN -> CRITICAL
164166 else -> ThermalState .UNKNOWN
165167 }
166168 }
167169}
170+
171+ class PowerModeStreamHandler (private val context : Context ) : EventChannel.StreamHandler {
172+
173+ private var lowPowerModeEventSink: EventChannel .EventSink ? = null
174+ private var powerSavingReceiver: BroadcastReceiver ? = null
175+
176+ override fun onListen (arguments : Any? , events : EventChannel .EventSink ? ) {
177+ lowPowerModeEventSink = events
178+
179+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
180+ setupPowerSavingReceiver()
181+ }
182+ }
183+
184+ override fun onCancel (p0 : Any? ) {
185+ context.unregisterReceiver(powerSavingReceiver)
186+ }
187+
188+ @RequiresApi(Build .VERSION_CODES .LOLLIPOP )
189+ private fun setupPowerSavingReceiver () {
190+ powerSavingReceiver = object : BroadcastReceiver () {
191+ override fun onReceive (context : Context , intent : Intent ? ) {
192+ val powerManager = context.getSystemService(Context .POWER_SERVICE ) as PowerManager
193+ lowPowerModeEventSink?.success(powerManager.isPowerSaveMode)
194+ }
195+ }
196+ val filter = IntentFilter (PowerManager .ACTION_POWER_SAVE_MODE_CHANGED )
197+ context.registerReceiver(powerSavingReceiver, filter)
198+ }
199+
200+ }
201+
202+ class BatteryStateStreamHandler (private val context : Context ) : EventChannel.StreamHandler {
203+
204+ private var batteryStateEventSink: EventChannel .EventSink ? = null
205+ private var batteryStateReceiver: BroadcastReceiver ? = null
206+
207+ override fun onListen (arguments : Any? , events : EventChannel .EventSink ? ) {
208+ batteryStateEventSink = events
209+
210+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .M ) {
211+ setupBatteryStateReceiver()
212+ }
213+ }
214+
215+ override fun onCancel (p0 : Any? ) {
216+ context.unregisterReceiver(batteryStateReceiver)
217+ }
218+
219+ @RequiresApi(Build .VERSION_CODES .M )
220+ private fun setupBatteryStateReceiver () {
221+ batteryStateReceiver = object : BroadcastReceiver () {
222+ override fun onReceive (context : Context , intent : Intent ? ) {
223+ val event = when (intent?.action) {
224+ ACTION_BATTERY_CHANGED ->
225+ when (intent.getIntExtra(BatteryManager .EXTRA_STATUS , - 1 )) {
226+ BATTERY_STATUS_CHARGING -> CHARGING .name
227+ BATTERY_STATUS_FULL -> FULL .name
228+ BATTERY_STATUS_DISCHARGING , BATTERY_STATUS_NOT_CHARGING -> DISCHARGING .name
229+ else -> UNKNOWN .name
230+ }
231+ else -> DISCHARGING .name
232+ }
233+ batteryStateEventSink?.success(event)
234+ }
235+ }
236+ val filterBatteryState = IntentFilter ()
237+ filterBatteryState.addAction(ACTION_BATTERY_CHANGED )
238+ context.registerReceiver(batteryStateReceiver, filterBatteryState)
239+ }
240+
241+ }
242+
243+ class BatteryLevelStreamHandler (private val context : Context ) : EventChannel.StreamHandler {
244+
245+ private var batteryLevelEventSink: EventChannel .EventSink ? = null
246+ private var batteryLevelReceiver: BroadcastReceiver ? = null
247+
248+ override fun onListen (arguments : Any? , events : EventChannel .EventSink ? ) {
249+ batteryLevelEventSink = events
250+
251+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
252+ setupBatteryLevelReceiver()
253+ }
254+ }
255+
256+ override fun onCancel (p0 : Any? ) {
257+ context.unregisterReceiver(batteryLevelReceiver)
258+ }
259+
260+
261+ @RequiresApi(Build .VERSION_CODES .LOLLIPOP )
262+ private fun setupBatteryLevelReceiver () {
263+
264+ batteryLevelReceiver = object : BroadcastReceiver () {
265+
266+ override fun onReceive (context : Context , intent : Intent ? ) {
267+ val batteryPct = intent?.let { i ->
268+ val level: Int = i.getIntExtra(BatteryManager .EXTRA_LEVEL , - 1 )
269+ val scale: Int = i.getIntExtra(BatteryManager .EXTRA_SCALE , - 1 )
270+ level * 100 / scale.toFloat()
271+ }
272+ batteryLevelEventSink?.success(batteryPct?.toDouble())
273+ }
274+ }
275+ val filter = IntentFilter (ACTION_BATTERY_CHANGED )
276+ context.registerReceiver(batteryLevelReceiver, filter)
277+
278+ }
279+
280+ }
0 commit comments