1 package com.android.systemui.shade 2 3 import android.content.Context 4 import android.view.DisplayCutout 5 import com.android.systemui.res.R 6 import com.android.systemui.battery.BatteryMeterView 7 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider 8 import javax.inject.Inject 9 10 /** 11 * Controls [BatteryMeterView.BatteryPercentMode]. It takes into account cutout and qs-qqs 12 * transition fraction when determining the mode. 13 */ 14 class QsBatteryModeController 15 @Inject 16 constructor( 17 private val context: Context, 18 private val insetsProvider: StatusBarContentInsetsProvider, 19 ) { 20 21 private companion object { 22 // MotionLayout frames are in [0, 100]. Where 0 and 100 are reserved for start and end 23 // frames. 24 const val MOTION_LAYOUT_MAX_FRAME = 100 25 // We add a single buffer frame to ensure that battery view faded out completely when we are 26 // about to change it's state 27 const val BUFFER_FRAME_COUNT = 1 28 } 29 30 private var fadeInStartFraction: Float = 0f 31 private var fadeOutCompleteFraction: Float = 0f 32 33 init { 34 updateResources() 35 } 36 37 /** 38 * Returns an appropriate [BatteryMeterView.BatteryPercentMode] for the [qsExpandedFraction] and 39 * [cutout]. We don't show battery estimation in qqs header on the devices with center cutout. 40 * The result might be null when the battery icon is invisible during the qs-qqs transition 41 * animation. 42 */ 43 @BatteryMeterView.BatteryPercentMode getBatteryModenull44 fun getBatteryMode(cutout: DisplayCutout?, qsExpandedFraction: Float): Int? = 45 when { 46 qsExpandedFraction > fadeInStartFraction -> BatteryMeterView.MODE_ESTIMATE 47 qsExpandedFraction < fadeOutCompleteFraction -> 48 if (hasCenterCutout(cutout)) { 49 BatteryMeterView.MODE_ON 50 } else { 51 BatteryMeterView.MODE_ESTIMATE 52 } 53 else -> null 54 } 55 updateResourcesnull56 fun updateResources() { 57 fadeInStartFraction = 58 (context.resources.getInteger(R.integer.fade_in_start_frame) - BUFFER_FRAME_COUNT) / 59 MOTION_LAYOUT_MAX_FRAME.toFloat() 60 fadeOutCompleteFraction = 61 (context.resources.getInteger(R.integer.fade_out_complete_frame) + BUFFER_FRAME_COUNT) / 62 MOTION_LAYOUT_MAX_FRAME.toFloat() 63 } 64 hasCenterCutoutnull65 private fun hasCenterCutout(cutout: DisplayCutout?): Boolean = 66 cutout?.let { 67 !insetsProvider.currentRotationHasCornerCutout() && !it.boundingRectTop.isEmpty 68 } 69 ?: false 70 } 71