/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.statusbar import android.content.Context import android.util.IndentingPrintWriter import android.util.MathUtils import androidx.annotation.FloatRange import androidx.annotation.Px import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.qs.QS import com.android.systemui.res.R import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.SplitShadeStateController import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlin.math.max /** Responsible for the QS components during the lockscreen shade transition. */ class LockscreenShadeQsTransitionController @AssistedInject constructor( context: Context, configurationController: ConfigurationController, dumpManager: DumpManager, @Assisted private val qsProvider: () -> QS?, splitShadeStateController: SplitShadeStateController ) : AbstractLockscreenShadeTransitionController( context, configurationController, dumpManager, splitShadeStateController ) { private val qs: QS? get() = qsProvider() /** * The progress fraction of the QS transition during lockscreen shade expansion. * * Note that this value might be 0 for some time when the expansion is already in progress, * since there is a transition start delay for QS on some device configurations. For this * reason, don't use this value to check whether the shade expansion is in progress. */ @FloatRange(from = 0.0, to = 1.0) var qsTransitionFraction = 0f private set /** * The fraction of the QS "squish" transition progress during lockscreen shade expansion. * * Note that in some device configurations (large screens) this value can start at a value * greater than 0. For this reason don't use this value to check whether the QS transition has * started or not. */ @FloatRange(from = 0.0, to = 1.0) var qsSquishTransitionFraction = 0f private set /** * The drag down amount, in pixels __for the QS transition__, also taking into account the * [qsTransitionStartDelay]. * * Since it takes into account the start delay, it is __not__ the same as the raw drag down * amount from the shade expansion. */ @Px private var qsDragDownAmount = 0f /** * Distance it takes for the QS transition to complete during the lockscreen shade expansion. */ @Px private var qsTransitionDistance = 0 /** Distance delay for the QS transition to start during the lockscreen shade expansion. */ @Px private var qsTransitionStartDelay = 0 /** * Distance that it takes to complete the QS "squish" transition during the lockscreen shade * expansion. */ @Px private var qsSquishTransitionDistance = 0 /** * Whether the transition to full shade is in progress. Might be `true` even though * [qsTransitionFraction] is still 0, due to [qsTransitionStartDelay]. */ private var isTransitioningToFullShade = false /** * The fraction at which the QS "squish" transition should start during the lockscreen shade * expansion. * * 0 is fully collapsed, 1 is fully expanded. */ @FloatRange(from = 0.0, to = 1.0) private var qsSquishStartFraction = 0f override fun updateResources() { qsTransitionDistance = context.resources.getDimensionPixelSize(R.dimen.lockscreen_shade_qs_transition_distance) qsTransitionStartDelay = context.resources.getDimensionPixelSize(R.dimen.lockscreen_shade_qs_transition_delay) qsSquishTransitionDistance = context.resources.getDimensionPixelSize( R.dimen.lockscreen_shade_qs_squish_transition_distance ) qsSquishStartFraction = context.resources.getFloat(R.dimen.lockscreen_shade_qs_squish_start_fraction) qsSquishTransitionFraction = max(qsSquishTransitionFraction, qsSquishStartFraction) } override fun onDragDownAmountChanged(dragDownAmount: Float) { qsDragDownAmount = dragDownAmount - qsTransitionStartDelay qsTransitionFraction = MathUtils.saturate(qsDragDownAmount / qsTransitionDistance) qsSquishTransitionFraction = MathUtils.lerp( /* start= */ qsSquishStartFraction, /* stop= */ 1f, /* amount= */ MathUtils.saturate(qsDragDownAmount / qsSquishTransitionDistance) ) isTransitioningToFullShade = dragDownAmount > 0.0f qs?.setTransitionToFullShadeProgress( isTransitioningToFullShade, qsTransitionFraction, qsSquishTransitionFraction ) } override fun dump(pw: IndentingPrintWriter) { pw.println( """ Resources: qsTransitionDistance: $qsTransitionDistance qsTransitionStartDelay: $qsTransitionStartDelay qsSquishTransitionDistance: $qsSquishTransitionDistance qsSquishStartFraction: $qsSquishStartFraction State: dragDownAmount: $dragDownAmount qsDragDownAmount: $qsDragDownAmount qsDragFraction: $qsTransitionFraction qsSquishFraction: $qsSquishTransitionFraction isTransitioningToFullShade: $isTransitioningToFullShade """ .trimIndent() ) } @AssistedFactory fun interface Factory { fun create(qsProvider: () -> QS?): LockscreenShadeQsTransitionController } }