blob: 1b8afb9ddc1d89b414cc49168ea05f1f5ec3d520 [file] [log] [blame]
package com.android.systemui.statusbar.phone.shade.transition
import android.content.res.Configuration
import android.content.res.Resources
import android.util.MathUtils.constrain
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
import com.android.systemui.statusbar.phone.panelstate.PanelState
import com.android.systemui.statusbar.phone.panelstate.STATE_OPENING
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.LargeScreenUtils
import java.io.PrintWriter
import javax.inject.Inject
/** Controls the scrim properties during the shade expansion transition on non-lockscreen. */
@SysUISingleton
class ScrimShadeTransitionController
@Inject
constructor(
configurationController: ConfigurationController,
dumpManager: DumpManager,
private val scrimController: ScrimController,
@Main private val resources: Resources,
private val statusBarStateController: SysuiStatusBarStateController,
) {
private var inSplitShade = false
private var splitShadeScrimTransitionDistance = 0
private var lastExpansionFraction: Float? = null
private var lastExpansionEvent: PanelExpansionChangeEvent? = null
private var currentPanelState: Int? = null
init {
updateResources()
configurationController.addCallback(
object : ConfigurationController.ConfigurationListener {
override fun onConfigChanged(newConfig: Configuration?) {
updateResources()
}
})
dumpManager.registerDumpable(
ScrimShadeTransitionController::class.java.simpleName, this::dump)
}
private fun updateResources() {
inSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(resources)
splitShadeScrimTransitionDistance =
resources.getDimensionPixelSize(R.dimen.split_shade_scrim_transition_distance)
}
fun onPanelStateChanged(@PanelState state: Int) {
currentPanelState = state
onStateChanged()
}
fun onPanelExpansionChanged(panelExpansionChangeEvent: PanelExpansionChangeEvent) {
lastExpansionEvent = panelExpansionChangeEvent
onStateChanged()
}
private fun onStateChanged() {
val expansionEvent = lastExpansionEvent ?: return
val panelState = currentPanelState
val expansionFraction = calculateScrimExpansionFraction(expansionEvent, panelState)
scrimController.setRawPanelExpansionFraction(expansionFraction)
lastExpansionFraction = expansionFraction
}
private fun calculateScrimExpansionFraction(
expansionEvent: PanelExpansionChangeEvent,
@PanelState panelState: Int?
): Float {
return if (canUseCustomFraction(panelState)) {
constrain(expansionEvent.dragDownPxAmount / splitShadeScrimTransitionDistance, 0f, 1f)
} else {
expansionEvent.fraction
}
}
private fun canUseCustomFraction(panelState: Int?) =
inSplitShade && isScreenUnlocked() && panelState == STATE_OPENING
private fun isScreenUnlocked() =
statusBarStateController.currentOrUpcomingState == StatusBarState.SHADE
private fun dump(printWriter: PrintWriter, args: Array<String>) {
printWriter.println(
"""
ScrimShadeTransitionController:
Resources:
inSplitShade: $inSplitShade
isScreenUnlocked: ${isScreenUnlocked()}
splitShadeScrimTransitionDistance: $splitShadeScrimTransitionDistance
State:
currentPanelState: $currentPanelState
lastExpansionFraction: $lastExpansionFraction
lastExpansionEvent: $lastExpansionEvent
""".trimIndent())
}
}