Loading packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt +157 −141 Original line number Original line Diff line number Diff line Loading @@ -18,10 +18,7 @@ import com.android.systemui.navigationbar.gestural.BackPanelController.DelayedOn private const val TAG = "BackPanel" private const val TAG = "BackPanel" private const val DEBUG = false private const val DEBUG = false class BackPanel( class BackPanel(context: Context, private val latencyTracker: LatencyTracker) : View(context) { context: Context, private val latencyTracker: LatencyTracker ) : View(context) { var arrowsPointLeft = false var arrowsPointLeft = false set(value) { set(value) { Loading @@ -42,15 +39,12 @@ class BackPanel( // True if the panel is currently on the left of the screen // True if the panel is currently on the left of the screen var isLeftPanel = false var isLeftPanel = false /** /** Used to track back arrow latency from [android.view.MotionEvent.ACTION_DOWN] to [onDraw] */ * Used to track back arrow latency from [android.view.MotionEvent.ACTION_DOWN] to [onDraw] */ private var trackingBackArrowLatency = false private var trackingBackArrowLatency = false /** /** The length of the arrow measured horizontally. Used for animating [arrowPath] */ * The length of the arrow measured horizontally. Used for animating [arrowPath] private var arrowLength = */ AnimatedFloat( private var arrowLength = AnimatedFloat( name = "arrowLength", name = "arrowLength", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS ) ) Loading @@ -59,18 +53,21 @@ class BackPanel( * The height of the arrow measured vertically from its center to its top (i.e. half the total * The height of the arrow measured vertically from its center to its top (i.e. half the total * height). Used for animating [arrowPath] * height). Used for animating [arrowPath] */ */ var arrowHeight = AnimatedFloat( var arrowHeight = AnimatedFloat( name = "arrowHeight", name = "arrowHeight", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ROTATION_DEGREES minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ROTATION_DEGREES ) ) val backgroundWidth = AnimatedFloat( val backgroundWidth = AnimatedFloat( name = "backgroundWidth", name = "backgroundWidth", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumValue = 0f, minimumValue = 0f, ) ) val backgroundHeight = AnimatedFloat( val backgroundHeight = AnimatedFloat( name = "backgroundHeight", name = "backgroundHeight", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumValue = 0f, minimumValue = 0f, Loading @@ -88,13 +85,15 @@ class BackPanel( */ */ val backgroundFarCornerRadius = AnimatedFloat("backgroundFarCornerRadius") val backgroundFarCornerRadius = AnimatedFloat("backgroundFarCornerRadius") var scale = AnimatedFloat( var scale = AnimatedFloat( name = "scale", name = "scale", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_SCALE, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_SCALE, minimumValue = 0f minimumValue = 0f ) ) val scalePivotX = AnimatedFloat( val scalePivotX = AnimatedFloat( name = "scalePivotX", name = "scalePivotX", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumValue = backgroundWidth.pos / 2, minimumValue = backgroundWidth.pos / 2, Loading @@ -107,21 +106,24 @@ class BackPanel( */ */ var horizontalTranslation = AnimatedFloat(name = "horizontalTranslation") var horizontalTranslation = AnimatedFloat(name = "horizontalTranslation") var arrowAlpha = AnimatedFloat( var arrowAlpha = AnimatedFloat( name = "arrowAlpha", name = "arrowAlpha", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA, minimumValue = 0f, minimumValue = 0f, maximumValue = 1f maximumValue = 1f ) ) val backgroundAlpha = AnimatedFloat( val backgroundAlpha = AnimatedFloat( name = "backgroundAlpha", name = "backgroundAlpha", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA, minimumValue = 0f, minimumValue = 0f, maximumValue = 1f maximumValue = 1f ) ) private val allAnimatedFloat = setOf( private val allAnimatedFloat = setOf( arrowLength, arrowLength, arrowHeight, arrowHeight, backgroundWidth, backgroundWidth, Loading @@ -140,22 +142,22 @@ class BackPanel( */ */ var verticalTranslation = AnimatedFloat("verticalTranslation") var verticalTranslation = AnimatedFloat("verticalTranslation") /** /** Use for drawing debug info. Can only be set if [DEBUG]=true */ * Use for drawing debug info. Can only be set if [DEBUG]=true */ var drawDebugInfo: ((canvas: Canvas) -> Unit)? = null var drawDebugInfo: ((canvas: Canvas) -> Unit)? = null set(value) { set(value) { if (DEBUG) field = value if (DEBUG) field = value } } internal fun updateArrowPaint(arrowThickness: Float) { internal fun updateArrowPaint(arrowThickness: Float) { arrowPaint.strokeWidth = arrowThickness arrowPaint.strokeWidth = arrowThickness val isDeviceInNightTheme = resources.configuration.uiMode and val isDeviceInNightTheme = Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES arrowPaint.color = Utils.getColorAttrDefaultColor(context, arrowPaint.color = Utils.getColorAttrDefaultColor( context, if (isDeviceInNightTheme) { if (isDeviceInNightTheme) { com.android.internal.R.attr.materialColorOnSecondaryContainer com.android.internal.R.attr.materialColorOnSecondaryContainer } else { } else { Loading @@ -163,7 +165,9 @@ class BackPanel( } } ) ) arrowBackgroundPaint.color = Utils.getColorAttrDefaultColor(context, arrowBackgroundPaint.color = Utils.getColorAttrDefaultColor( context, if (isDeviceInNightTheme) { if (isDeviceInNightTheme) { com.android.internal.R.attr.materialColorSecondaryContainer com.android.internal.R.attr.materialColorSecondaryContainer } else { } else { Loading Loading @@ -207,14 +211,16 @@ class BackPanel( } } init { init { val floatProp = object : FloatPropertyCompat<AnimatedFloat>(name) { val floatProp = object : FloatPropertyCompat<AnimatedFloat>(name) { override fun setValue(animatedFloat: AnimatedFloat, value: Float) { override fun setValue(animatedFloat: AnimatedFloat, value: Float) { animatedFloat.pos = value animatedFloat.pos = value } } override fun getValue(animatedFloat: AnimatedFloat): Float = animatedFloat.pos override fun getValue(animatedFloat: AnimatedFloat): Float = animatedFloat.pos } } animation = SpringAnimation(this, floatProp).apply { animation = SpringAnimation(this, floatProp).apply { spring = SpringForce() spring = SpringForce() this@AnimatedFloat.minimumValue?.let { setMinValue(it) } this@AnimatedFloat.minimumValue?.let { setMinValue(it) } this@AnimatedFloat.maximumValue?.let { setMaxValue(it) } this@AnimatedFloat.maximumValue?.let { setMaxValue(it) } Loading @@ -233,7 +239,6 @@ class BackPanel( snapTo(restingPosition) snapTo(restingPosition) } } fun stretchTo( fun stretchTo( stretchAmount: Float, stretchAmount: Float, startingVelocity: Float? = null, startingVelocity: Float? = null, Loading Loading @@ -373,8 +378,11 @@ class BackPanel( } } fun popArrowAlpha(startingVelocity: Float, springForce: SpringForce? = null) { fun popArrowAlpha(startingVelocity: Float, springForce: SpringForce? = null) { arrowAlpha.stretchTo(stretchAmount = 0f, startingVelocity = startingVelocity, arrowAlpha.stretchTo( springForce = springForce) stretchAmount = 0f, startingVelocity = startingVelocity, springForce = springForce ) } } fun resetStretch() { fun resetStretch() { Loading @@ -392,9 +400,7 @@ class BackPanel( backgroundFarCornerRadius.snapToRestingPosition() backgroundFarCornerRadius.snapToRestingPosition() } } /** /** Updates resting arrow and background size not accounting for stretch */ * Updates resting arrow and background size not accounting for stretch */ internal fun setRestingDimens( internal fun setRestingDimens( restingParams: EdgePanelParams.BackIndicatorDimens, restingParams: EdgePanelParams.BackIndicatorDimens, animate: Boolean = true animate: Boolean = true Loading @@ -410,10 +416,12 @@ class BackPanel( backgroundWidth.updateRestingPosition(restingParams.backgroundDimens.width, animate) backgroundWidth.updateRestingPosition(restingParams.backgroundDimens.width, animate) backgroundHeight.updateRestingPosition(restingParams.backgroundDimens.height, animate) backgroundHeight.updateRestingPosition(restingParams.backgroundDimens.height, animate) backgroundEdgeCornerRadius.updateRestingPosition( backgroundEdgeCornerRadius.updateRestingPosition( restingParams.backgroundDimens.edgeCornerRadius, animate restingParams.backgroundDimens.edgeCornerRadius, animate ) ) backgroundFarCornerRadius.updateRestingPosition( backgroundFarCornerRadius.updateRestingPosition( restingParams.backgroundDimens.farCornerRadius, animate restingParams.backgroundDimens.farCornerRadius, animate ) ) } } Loading Loading @@ -459,26 +467,28 @@ class BackPanel( if (!isLeftPanel) canvas.scale(-1f, 1f, canvasWidth / 2.0f, 0f) if (!isLeftPanel) canvas.scale(-1f, 1f, canvasWidth / 2.0f, 0f) canvas.translate( canvas.translate(horizontalTranslation.pos, height * 0.5f + verticalTranslation.pos) horizontalTranslation.pos, height * 0.5f + verticalTranslation.pos ) canvas.scale(scale.pos, scale.pos, scalePivotX, 0f) canvas.scale(scale.pos, scale.pos, scalePivotX, 0f) val arrowBackground = arrowBackgroundRect.apply { val arrowBackground = arrowBackgroundRect .apply { left = 0f left = 0f top = -halfHeight top = -halfHeight right = backgroundWidth right = backgroundWidth bottom = halfHeight bottom = halfHeight }.toPathWithRoundCorners( } .toPathWithRoundCorners( topLeft = edgeCorner, topLeft = edgeCorner, bottomLeft = edgeCorner, bottomLeft = edgeCorner, topRight = farCorner, topRight = farCorner, bottomRight = farCorner bottomRight = farCorner ) ) canvas.drawPath(arrowBackground, canvas.drawPath( arrowBackgroundPaint.apply { alpha = (255 * backgroundAlpha.pos).toInt() }) arrowBackground, arrowBackgroundPaint.apply { alpha = (255 * backgroundAlpha.pos).toInt() } ) val dx = arrowLength.pos val dx = arrowLength.pos val dy = arrowHeight.pos val dy = arrowHeight.pos Loading @@ -500,8 +510,8 @@ class BackPanel( } } val arrowPath = calculateArrowPath(dx = dx, dy = dy) val arrowPath = calculateArrowPath(dx = dx, dy = dy) val arrowPaint = arrowPaint val arrowPaint = .apply { alpha = (255 * min(arrowAlpha.pos, backgroundAlpha.pos)).toInt() } arrowPaint.apply { alpha = (255 * min(arrowAlpha.pos, backgroundAlpha.pos)).toInt() } canvas.drawPath(arrowPath, arrowPaint) canvas.drawPath(arrowPath, arrowPaint) canvas.restore() canvas.restore() Loading @@ -523,12 +533,18 @@ class BackPanel( topRight: Float = 0f, topRight: Float = 0f, bottomRight: Float = 0f, bottomRight: Float = 0f, bottomLeft: Float = 0f bottomLeft: Float = 0f ): Path = Path().apply { ): Path = val corners = floatArrayOf( Path().apply { topLeft, topLeft, val corners = topRight, topRight, floatArrayOf( bottomRight, bottomRight, topLeft, bottomLeft, bottomLeft topLeft, topRight, topRight, bottomRight, bottomRight, bottomLeft, bottomLeft ) ) addRoundRect(this@toPathWithRoundCorners, corners, Path.Direction.CW) addRoundRect(this@toPathWithRoundCorners, corners, Path.Direction.CW) } } Loading packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt +8 −9 Original line number Original line Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.view.Gravity import android.view.HapticFeedbackConstants import android.view.HapticFeedbackConstants import android.view.MotionEvent import android.view.MotionEvent import android.view.VelocityTracker import android.view.VelocityTracker import android.view.View import android.view.ViewConfiguration import android.view.ViewConfiguration import android.view.WindowManager import android.view.WindowManager import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting Loading Loading @@ -164,6 +163,7 @@ internal constructor( private val elapsedTimeSinceInactive private val elapsedTimeSinceInactive get() = systemClock.uptimeMillis() - gestureInactiveTime get() = systemClock.uptimeMillis() - gestureInactiveTime private val elapsedTimeSinceEntry private val elapsedTimeSinceEntry get() = systemClock.uptimeMillis() - gestureEntryTime get() = systemClock.uptimeMillis() - gestureEntryTime Loading Loading @@ -612,6 +612,7 @@ internal constructor( } } private var previousPreThresholdWidthInterpolator = params.entryWidthInterpolator private var previousPreThresholdWidthInterpolator = params.entryWidthInterpolator private fun preThresholdWidthStretchAmount(progress: Float): Float { private fun preThresholdWidthStretchAmount(progress: Float): Float { val interpolator = run { val interpolator = run { val isPastSlop = totalTouchDeltaInactive > viewConfiguration.scaledTouchSlop val isPastSlop = totalTouchDeltaInactive > viewConfiguration.scaledTouchSlop Loading Loading @@ -677,8 +678,7 @@ internal constructor( velocityTracker?.run { velocityTracker?.run { computeCurrentVelocity(PX_PER_SEC) computeCurrentVelocity(PX_PER_SEC) xVelocity.takeIf { mView.isLeftPanel } ?: (xVelocity * -1) xVelocity.takeIf { mView.isLeftPanel } ?: (xVelocity * -1) } } ?: 0f ?: 0f val isPastFlingVelocityThreshold = val isPastFlingVelocityThreshold = flingVelocity > viewConfiguration.scaledMinimumFlingVelocity flingVelocity > viewConfiguration.scaledMinimumFlingVelocity return flingDistance > minFlingDistance && isPastFlingVelocityThreshold return flingDistance > minFlingDistance && isPastFlingVelocityThreshold Loading Loading @@ -1028,8 +1028,7 @@ internal constructor( velocityTracker?.run { velocityTracker?.run { computeCurrentVelocity(PX_PER_MS) computeCurrentVelocity(PX_PER_MS) MathUtils.smoothStep(slowVelocityBound, fastVelocityBound, abs(xVelocity)) MathUtils.smoothStep(slowVelocityBound, fastVelocityBound, abs(xVelocity)) } } ?: valueOnFastVelocity ?: valueOnFastVelocity return MathUtils.lerp(valueOnFastVelocity, valueOnSlowVelocity, 1 - factor) return MathUtils.lerp(valueOnFastVelocity, valueOnSlowVelocity, 1 - factor) } } Loading packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt +132 −86 Original line number Original line Diff line number Diff line Loading @@ -45,57 +45,79 @@ data class EdgePanelParams(private var resources: Resources) { lateinit var entryIndicator: BackIndicatorDimens lateinit var entryIndicator: BackIndicatorDimens private set private set lateinit var activeIndicator: BackIndicatorDimens lateinit var activeIndicator: BackIndicatorDimens private set private set lateinit var cancelledIndicator: BackIndicatorDimens lateinit var cancelledIndicator: BackIndicatorDimens private set private set lateinit var flungIndicator: BackIndicatorDimens lateinit var flungIndicator: BackIndicatorDimens private set private set lateinit var committedIndicator: BackIndicatorDimens lateinit var committedIndicator: BackIndicatorDimens private set private set lateinit var preThresholdIndicator: BackIndicatorDimens lateinit var preThresholdIndicator: BackIndicatorDimens private set private set lateinit var fullyStretchedIndicator: BackIndicatorDimens lateinit var fullyStretchedIndicator: BackIndicatorDimens private set private set // navigation bar edge constants // navigation bar edge constants var arrowPaddingEnd: Int = 0 var arrowPaddingEnd: Int = 0 private set private set var arrowThickness: Float = 0f var arrowThickness: Float = 0f private set private set // The closest to y // The closest to y var minArrowYPosition: Int = 0 var minArrowYPosition: Int = 0 private set private set var fingerOffset: Int = 0 var fingerOffset: Int = 0 private set private set var staticTriggerThreshold: Float = 0f var staticTriggerThreshold: Float = 0f private set private set var reactivationTriggerThreshold: Float = 0f var reactivationTriggerThreshold: Float = 0f private set private set var deactivationTriggerThreshold: Float = 0f var deactivationTriggerThreshold: Float = 0f get() = -field get() = -field private set private set lateinit var dynamicTriggerThresholdRange: ClosedRange<Float> lateinit var dynamicTriggerThresholdRange: ClosedRange<Float> private set private set var swipeProgressThreshold: Float = 0f var swipeProgressThreshold: Float = 0f private set private set lateinit var entryWidthInterpolator: Interpolator lateinit var entryWidthInterpolator: Interpolator private set private set lateinit var entryWidthTowardsEdgeInterpolator: Interpolator lateinit var entryWidthTowardsEdgeInterpolator: Interpolator private set private set lateinit var activeWidthInterpolator: Interpolator lateinit var activeWidthInterpolator: Interpolator private set private set lateinit var arrowAngleInterpolator: Interpolator lateinit var arrowAngleInterpolator: Interpolator private set private set lateinit var horizontalTranslationInterpolator: Interpolator lateinit var horizontalTranslationInterpolator: Interpolator private set private set lateinit var verticalTranslationInterpolator: Interpolator lateinit var verticalTranslationInterpolator: Interpolator private set private set lateinit var farCornerInterpolator: Interpolator lateinit var farCornerInterpolator: Interpolator private set private set lateinit var edgeCornerInterpolator: Interpolator lateinit var edgeCornerInterpolator: Interpolator private set private set lateinit var heightInterpolator: Interpolator lateinit var heightInterpolator: Interpolator private set private set Loading @@ -108,7 +130,10 @@ data class EdgePanelParams(private var resources: Resources) { } } private fun getDimenFloat(id: Int): Float { private fun getDimenFloat(id: Int): Float { return TypedValue().run { resources.getValue(id, this, true); float } return TypedValue().run { resources.getValue(id, this, true) float } } } private fun getPx(id: Int): Int { private fun getPx(id: Int): Int { Loading @@ -126,8 +151,7 @@ data class EdgePanelParams(private var resources: Resources) { getDimen(R.dimen.navigation_edge_action_reactivation_drag_threshold) getDimen(R.dimen.navigation_edge_action_reactivation_drag_threshold) deactivationTriggerThreshold = deactivationTriggerThreshold = getDimen(R.dimen.navigation_edge_action_deactivation_drag_threshold) getDimen(R.dimen.navigation_edge_action_deactivation_drag_threshold) dynamicTriggerThresholdRange = dynamicTriggerThresholdRange = reactivationTriggerThreshold..deactivationTriggerThreshold reactivationTriggerThreshold..deactivationTriggerThreshold swipeProgressThreshold = getDimen(R.dimen.navigation_edge_action_progress_threshold) swipeProgressThreshold = getDimen(R.dimen.navigation_edge_action_progress_threshold) entryWidthInterpolator = PathInterpolator(.19f, 1.27f, .71f, .86f) entryWidthInterpolator = PathInterpolator(.19f, 1.27f, .71f, .86f) Loading @@ -149,27 +173,31 @@ data class EdgePanelParams(private var resources: Resources) { val commonArrowDimensAlphaThreshold = .165f val commonArrowDimensAlphaThreshold = .165f val commonArrowDimensAlphaFactor = 1.05f val commonArrowDimensAlphaFactor = 1.05f val commonArrowDimensAlphaSpring = Step( val commonArrowDimensAlphaSpring = Step( threshold = commonArrowDimensAlphaThreshold, threshold = commonArrowDimensAlphaThreshold, factor = commonArrowDimensAlphaFactor, factor = commonArrowDimensAlphaFactor, postThreshold = createSpring(180f, 0.9f), postThreshold = createSpring(180f, 0.9f), preThreshold = createSpring(2000f, 0.6f) preThreshold = createSpring(2000f, 0.6f) ) ) val commonArrowDimensAlphaSpringInterpolator = Step( val commonArrowDimensAlphaSpringInterpolator = Step( threshold = commonArrowDimensAlphaThreshold, threshold = commonArrowDimensAlphaThreshold, factor = commonArrowDimensAlphaFactor, factor = commonArrowDimensAlphaFactor, postThreshold = 1f, postThreshold = 1f, preThreshold = 0f preThreshold = 0f ) ) entryIndicator = BackIndicatorDimens( entryIndicator = BackIndicatorDimens( horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin), horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin), scale = getDimenFloat(R.dimen.navigation_edge_entry_scale), scale = getDimenFloat(R.dimen.navigation_edge_entry_scale), scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), horizontalTranslationSpring = createSpring(800f, 0.76f), horizontalTranslationSpring = createSpring(800f, 0.76f), verticalTranslationSpring = createSpring(30000f, 1f), verticalTranslationSpring = createSpring(30000f, 1f), scaleSpring = createSpring(120f, 0.8f), scaleSpring = createSpring(120f, 0.8f), arrowDimens = ArrowDimens( arrowDimens = ArrowDimens( length = getDimen(R.dimen.navigation_edge_entry_arrow_length), length = getDimen(R.dimen.navigation_edge_entry_arrow_length), height = getDimen(R.dimen.navigation_edge_entry_arrow_height), height = getDimen(R.dimen.navigation_edge_entry_arrow_height), alpha = 0f, alpha = 0f, Loading @@ -178,7 +206,8 @@ data class EdgePanelParams(private var resources: Resources) { alphaSpring = commonArrowDimensAlphaSpring, alphaSpring = commonArrowDimensAlphaSpring, alphaInterpolator = commonArrowDimensAlphaSpringInterpolator alphaInterpolator = commonArrowDimensAlphaSpringInterpolator ), ), backgroundDimens = BackgroundDimens( backgroundDimens = BackgroundDimens( alpha = 1f, alpha = 1f, width = getDimen(R.dimen.navigation_edge_entry_background_width), width = getDimen(R.dimen.navigation_edge_entry_background_width), height = getDimen(R.dimen.navigation_edge_entry_background_height), height = getDimen(R.dimen.navigation_edge_entry_background_height), Loading @@ -191,13 +220,15 @@ data class EdgePanelParams(private var resources: Resources) { ) ) ) ) activeIndicator = BackIndicatorDimens( activeIndicator = BackIndicatorDimens( horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin), horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin), scale = getDimenFloat(R.dimen.navigation_edge_active_scale), scale = getDimenFloat(R.dimen.navigation_edge_active_scale), horizontalTranslationSpring = createSpring(1000f, 0.8f), horizontalTranslationSpring = createSpring(1000f, 0.8f), scaleSpring = createSpring(325f, 0.55f), scaleSpring = createSpring(325f, 0.55f), scalePivotX = getDimen(R.dimen.navigation_edge_active_background_width), scalePivotX = getDimen(R.dimen.navigation_edge_active_background_width), arrowDimens = ArrowDimens( arrowDimens = ArrowDimens( length = getDimen(R.dimen.navigation_edge_active_arrow_length), length = getDimen(R.dimen.navigation_edge_active_arrow_length), height = getDimen(R.dimen.navigation_edge_active_arrow_height), height = getDimen(R.dimen.navigation_edge_active_arrow_height), alpha = 1f, alpha = 1f, Loading @@ -206,7 +237,8 @@ data class EdgePanelParams(private var resources: Resources) { alphaSpring = commonArrowDimensAlphaSpring, alphaSpring = commonArrowDimensAlphaSpring, alphaInterpolator = commonArrowDimensAlphaSpringInterpolator alphaInterpolator = commonArrowDimensAlphaSpringInterpolator ), ), backgroundDimens = BackgroundDimens( backgroundDimens = BackgroundDimens( alpha = 1f, alpha = 1f, width = getDimen(R.dimen.navigation_edge_active_background_width), width = getDimen(R.dimen.navigation_edge_active_background_width), height = getDimen(R.dimen.navigation_edge_active_background_height), height = getDimen(R.dimen.navigation_edge_active_background_height), Loading @@ -219,13 +251,15 @@ data class EdgePanelParams(private var resources: Resources) { ) ) ) ) preThresholdIndicator = BackIndicatorDimens( preThresholdIndicator = BackIndicatorDimens( horizontalTranslation = getDimen(R.dimen.navigation_edge_pre_threshold_margin), horizontalTranslation = getDimen(R.dimen.navigation_edge_pre_threshold_margin), scale = getDimenFloat(R.dimen.navigation_edge_pre_threshold_scale), scale = getDimenFloat(R.dimen.navigation_edge_pre_threshold_scale), scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), scaleSpring = createSpring(120f, 0.8f), scaleSpring = createSpring(120f, 0.8f), horizontalTranslationSpring = createSpring(6000f, 1f), horizontalTranslationSpring = createSpring(6000f, 1f), arrowDimens = ArrowDimens( arrowDimens = ArrowDimens( length = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_length), length = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_length), height = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_height), height = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_height), alpha = 1f, alpha = 1f, Loading @@ -234,7 +268,8 @@ data class EdgePanelParams(private var resources: Resources) { alphaSpring = commonArrowDimensAlphaSpring, alphaSpring = commonArrowDimensAlphaSpring, alphaInterpolator = commonArrowDimensAlphaSpringInterpolator alphaInterpolator = commonArrowDimensAlphaSpringInterpolator ), ), backgroundDimens = BackgroundDimens( backgroundDimens = BackgroundDimens( alpha = 1f, alpha = 1f, width = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), width = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), height = getDimen(R.dimen.navigation_edge_pre_threshold_background_height), height = getDimen(R.dimen.navigation_edge_pre_threshold_background_height), Loading @@ -249,16 +284,19 @@ data class EdgePanelParams(private var resources: Resources) { ) ) ) ) committedIndicator = activeIndicator.copy( committedIndicator = activeIndicator.copy( horizontalTranslation = null, horizontalTranslation = null, scalePivotX = null, scalePivotX = null, arrowDimens = activeIndicator.arrowDimens.copy( arrowDimens = activeIndicator.arrowDimens.copy( lengthSpring = activeCommittedArrowLengthSpring, lengthSpring = activeCommittedArrowLengthSpring, heightSpring = activeCommittedArrowHeightSpring, heightSpring = activeCommittedArrowHeightSpring, length = null, length = null, height = null, height = null, ), ), backgroundDimens = activeIndicator.backgroundDimens.copy( backgroundDimens = activeIndicator.backgroundDimens.copy( alpha = 0f, alpha = 0f, // explicitly set to null to preserve previous width upon state change // explicitly set to null to preserve previous width upon state change width = null, width = null, Loading @@ -272,14 +310,17 @@ data class EdgePanelParams(private var resources: Resources) { scaleSpring = createSpring(5700f, 1f), scaleSpring = createSpring(5700f, 1f), ) ) flungIndicator = committedIndicator.copy( flungIndicator = arrowDimens = committedIndicator.arrowDimens.copy( committedIndicator.copy( arrowDimens = committedIndicator.arrowDimens.copy( lengthSpring = createSpring(850f, 0.46f), lengthSpring = createSpring(850f, 0.46f), heightSpring = createSpring(850f, 0.46f), heightSpring = createSpring(850f, 0.46f), length = activeIndicator.arrowDimens.length, length = activeIndicator.arrowDimens.length, height = activeIndicator.arrowDimens.height height = activeIndicator.arrowDimens.height ), ), backgroundDimens = committedIndicator.backgroundDimens.copy( backgroundDimens = committedIndicator.backgroundDimens.copy( widthSpring = flungCommittedWidthSpring, widthSpring = flungCommittedWidthSpring, heightSpring = flungCommittedHeightSpring, heightSpring = flungCommittedHeightSpring, edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring, edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring, Loading @@ -287,21 +328,25 @@ data class EdgePanelParams(private var resources: Resources) { ) ) ) ) cancelledIndicator = entryIndicator.copy( cancelledIndicator = backgroundDimens = entryIndicator.backgroundDimens.copy( entryIndicator.copy( backgroundDimens = entryIndicator.backgroundDimens.copy( width = 0f, width = 0f, alpha = 0f, alpha = 0f, alphaSpring = createSpring(450f, 1f) alphaSpring = createSpring(450f, 1f) ) ) ) ) fullyStretchedIndicator = BackIndicatorDimens( fullyStretchedIndicator = BackIndicatorDimens( horizontalTranslation = getDimen(R.dimen.navigation_edge_stretch_margin), horizontalTranslation = getDimen(R.dimen.navigation_edge_stretch_margin), scale = getDimenFloat(R.dimen.navigation_edge_stretch_scale), scale = getDimenFloat(R.dimen.navigation_edge_stretch_scale), horizontalTranslationSpring = null, horizontalTranslationSpring = null, verticalTranslationSpring = null, verticalTranslationSpring = null, scaleSpring = null, scaleSpring = null, arrowDimens = ArrowDimens( arrowDimens = ArrowDimens( length = getDimen(R.dimen.navigation_edge_stretched_arrow_length), length = getDimen(R.dimen.navigation_edge_stretched_arrow_length), height = getDimen(R.dimen.navigation_edge_stretched_arrow_height), height = getDimen(R.dimen.navigation_edge_stretched_arrow_height), alpha = 1f, alpha = 1f, Loading @@ -309,7 +354,8 @@ data class EdgePanelParams(private var resources: Resources) { heightSpring = null, heightSpring = null, lengthSpring = null, lengthSpring = null, ), ), backgroundDimens = BackgroundDimens( backgroundDimens = BackgroundDimens( alpha = 1f, alpha = 1f, width = getDimen(R.dimen.navigation_edge_stretch_background_width), width = getDimen(R.dimen.navigation_edge_stretch_background_width), height = getDimen(R.dimen.navigation_edge_stretch_background_height), height = getDimen(R.dimen.navigation_edge_stretch_background_height), Loading packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt +1 −0 Original line number Original line Diff line number Diff line Loading @@ -55,6 +55,7 @@ class BackPanelControllerTest : SysuiTestCase() { companion object { companion object { private const val START_X: Float = 0f private const val START_X: Float = 0f } } private val kosmos = testKosmos() private val kosmos = testKosmos() private lateinit var mBackPanelController: BackPanelController private lateinit var mBackPanelController: BackPanelController private lateinit var systemClock: FakeSystemClock private lateinit var systemClock: FakeSystemClock Loading Loading
packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt +157 −141 Original line number Original line Diff line number Diff line Loading @@ -18,10 +18,7 @@ import com.android.systemui.navigationbar.gestural.BackPanelController.DelayedOn private const val TAG = "BackPanel" private const val TAG = "BackPanel" private const val DEBUG = false private const val DEBUG = false class BackPanel( class BackPanel(context: Context, private val latencyTracker: LatencyTracker) : View(context) { context: Context, private val latencyTracker: LatencyTracker ) : View(context) { var arrowsPointLeft = false var arrowsPointLeft = false set(value) { set(value) { Loading @@ -42,15 +39,12 @@ class BackPanel( // True if the panel is currently on the left of the screen // True if the panel is currently on the left of the screen var isLeftPanel = false var isLeftPanel = false /** /** Used to track back arrow latency from [android.view.MotionEvent.ACTION_DOWN] to [onDraw] */ * Used to track back arrow latency from [android.view.MotionEvent.ACTION_DOWN] to [onDraw] */ private var trackingBackArrowLatency = false private var trackingBackArrowLatency = false /** /** The length of the arrow measured horizontally. Used for animating [arrowPath] */ * The length of the arrow measured horizontally. Used for animating [arrowPath] private var arrowLength = */ AnimatedFloat( private var arrowLength = AnimatedFloat( name = "arrowLength", name = "arrowLength", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS ) ) Loading @@ -59,18 +53,21 @@ class BackPanel( * The height of the arrow measured vertically from its center to its top (i.e. half the total * The height of the arrow measured vertically from its center to its top (i.e. half the total * height). Used for animating [arrowPath] * height). Used for animating [arrowPath] */ */ var arrowHeight = AnimatedFloat( var arrowHeight = AnimatedFloat( name = "arrowHeight", name = "arrowHeight", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ROTATION_DEGREES minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ROTATION_DEGREES ) ) val backgroundWidth = AnimatedFloat( val backgroundWidth = AnimatedFloat( name = "backgroundWidth", name = "backgroundWidth", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumValue = 0f, minimumValue = 0f, ) ) val backgroundHeight = AnimatedFloat( val backgroundHeight = AnimatedFloat( name = "backgroundHeight", name = "backgroundHeight", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumValue = 0f, minimumValue = 0f, Loading @@ -88,13 +85,15 @@ class BackPanel( */ */ val backgroundFarCornerRadius = AnimatedFloat("backgroundFarCornerRadius") val backgroundFarCornerRadius = AnimatedFloat("backgroundFarCornerRadius") var scale = AnimatedFloat( var scale = AnimatedFloat( name = "scale", name = "scale", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_SCALE, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_SCALE, minimumValue = 0f minimumValue = 0f ) ) val scalePivotX = AnimatedFloat( val scalePivotX = AnimatedFloat( name = "scalePivotX", name = "scalePivotX", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS, minimumValue = backgroundWidth.pos / 2, minimumValue = backgroundWidth.pos / 2, Loading @@ -107,21 +106,24 @@ class BackPanel( */ */ var horizontalTranslation = AnimatedFloat(name = "horizontalTranslation") var horizontalTranslation = AnimatedFloat(name = "horizontalTranslation") var arrowAlpha = AnimatedFloat( var arrowAlpha = AnimatedFloat( name = "arrowAlpha", name = "arrowAlpha", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA, minimumValue = 0f, minimumValue = 0f, maximumValue = 1f maximumValue = 1f ) ) val backgroundAlpha = AnimatedFloat( val backgroundAlpha = AnimatedFloat( name = "backgroundAlpha", name = "backgroundAlpha", minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA, minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA, minimumValue = 0f, minimumValue = 0f, maximumValue = 1f maximumValue = 1f ) ) private val allAnimatedFloat = setOf( private val allAnimatedFloat = setOf( arrowLength, arrowLength, arrowHeight, arrowHeight, backgroundWidth, backgroundWidth, Loading @@ -140,22 +142,22 @@ class BackPanel( */ */ var verticalTranslation = AnimatedFloat("verticalTranslation") var verticalTranslation = AnimatedFloat("verticalTranslation") /** /** Use for drawing debug info. Can only be set if [DEBUG]=true */ * Use for drawing debug info. Can only be set if [DEBUG]=true */ var drawDebugInfo: ((canvas: Canvas) -> Unit)? = null var drawDebugInfo: ((canvas: Canvas) -> Unit)? = null set(value) { set(value) { if (DEBUG) field = value if (DEBUG) field = value } } internal fun updateArrowPaint(arrowThickness: Float) { internal fun updateArrowPaint(arrowThickness: Float) { arrowPaint.strokeWidth = arrowThickness arrowPaint.strokeWidth = arrowThickness val isDeviceInNightTheme = resources.configuration.uiMode and val isDeviceInNightTheme = Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES arrowPaint.color = Utils.getColorAttrDefaultColor(context, arrowPaint.color = Utils.getColorAttrDefaultColor( context, if (isDeviceInNightTheme) { if (isDeviceInNightTheme) { com.android.internal.R.attr.materialColorOnSecondaryContainer com.android.internal.R.attr.materialColorOnSecondaryContainer } else { } else { Loading @@ -163,7 +165,9 @@ class BackPanel( } } ) ) arrowBackgroundPaint.color = Utils.getColorAttrDefaultColor(context, arrowBackgroundPaint.color = Utils.getColorAttrDefaultColor( context, if (isDeviceInNightTheme) { if (isDeviceInNightTheme) { com.android.internal.R.attr.materialColorSecondaryContainer com.android.internal.R.attr.materialColorSecondaryContainer } else { } else { Loading Loading @@ -207,14 +211,16 @@ class BackPanel( } } init { init { val floatProp = object : FloatPropertyCompat<AnimatedFloat>(name) { val floatProp = object : FloatPropertyCompat<AnimatedFloat>(name) { override fun setValue(animatedFloat: AnimatedFloat, value: Float) { override fun setValue(animatedFloat: AnimatedFloat, value: Float) { animatedFloat.pos = value animatedFloat.pos = value } } override fun getValue(animatedFloat: AnimatedFloat): Float = animatedFloat.pos override fun getValue(animatedFloat: AnimatedFloat): Float = animatedFloat.pos } } animation = SpringAnimation(this, floatProp).apply { animation = SpringAnimation(this, floatProp).apply { spring = SpringForce() spring = SpringForce() this@AnimatedFloat.minimumValue?.let { setMinValue(it) } this@AnimatedFloat.minimumValue?.let { setMinValue(it) } this@AnimatedFloat.maximumValue?.let { setMaxValue(it) } this@AnimatedFloat.maximumValue?.let { setMaxValue(it) } Loading @@ -233,7 +239,6 @@ class BackPanel( snapTo(restingPosition) snapTo(restingPosition) } } fun stretchTo( fun stretchTo( stretchAmount: Float, stretchAmount: Float, startingVelocity: Float? = null, startingVelocity: Float? = null, Loading Loading @@ -373,8 +378,11 @@ class BackPanel( } } fun popArrowAlpha(startingVelocity: Float, springForce: SpringForce? = null) { fun popArrowAlpha(startingVelocity: Float, springForce: SpringForce? = null) { arrowAlpha.stretchTo(stretchAmount = 0f, startingVelocity = startingVelocity, arrowAlpha.stretchTo( springForce = springForce) stretchAmount = 0f, startingVelocity = startingVelocity, springForce = springForce ) } } fun resetStretch() { fun resetStretch() { Loading @@ -392,9 +400,7 @@ class BackPanel( backgroundFarCornerRadius.snapToRestingPosition() backgroundFarCornerRadius.snapToRestingPosition() } } /** /** Updates resting arrow and background size not accounting for stretch */ * Updates resting arrow and background size not accounting for stretch */ internal fun setRestingDimens( internal fun setRestingDimens( restingParams: EdgePanelParams.BackIndicatorDimens, restingParams: EdgePanelParams.BackIndicatorDimens, animate: Boolean = true animate: Boolean = true Loading @@ -410,10 +416,12 @@ class BackPanel( backgroundWidth.updateRestingPosition(restingParams.backgroundDimens.width, animate) backgroundWidth.updateRestingPosition(restingParams.backgroundDimens.width, animate) backgroundHeight.updateRestingPosition(restingParams.backgroundDimens.height, animate) backgroundHeight.updateRestingPosition(restingParams.backgroundDimens.height, animate) backgroundEdgeCornerRadius.updateRestingPosition( backgroundEdgeCornerRadius.updateRestingPosition( restingParams.backgroundDimens.edgeCornerRadius, animate restingParams.backgroundDimens.edgeCornerRadius, animate ) ) backgroundFarCornerRadius.updateRestingPosition( backgroundFarCornerRadius.updateRestingPosition( restingParams.backgroundDimens.farCornerRadius, animate restingParams.backgroundDimens.farCornerRadius, animate ) ) } } Loading Loading @@ -459,26 +467,28 @@ class BackPanel( if (!isLeftPanel) canvas.scale(-1f, 1f, canvasWidth / 2.0f, 0f) if (!isLeftPanel) canvas.scale(-1f, 1f, canvasWidth / 2.0f, 0f) canvas.translate( canvas.translate(horizontalTranslation.pos, height * 0.5f + verticalTranslation.pos) horizontalTranslation.pos, height * 0.5f + verticalTranslation.pos ) canvas.scale(scale.pos, scale.pos, scalePivotX, 0f) canvas.scale(scale.pos, scale.pos, scalePivotX, 0f) val arrowBackground = arrowBackgroundRect.apply { val arrowBackground = arrowBackgroundRect .apply { left = 0f left = 0f top = -halfHeight top = -halfHeight right = backgroundWidth right = backgroundWidth bottom = halfHeight bottom = halfHeight }.toPathWithRoundCorners( } .toPathWithRoundCorners( topLeft = edgeCorner, topLeft = edgeCorner, bottomLeft = edgeCorner, bottomLeft = edgeCorner, topRight = farCorner, topRight = farCorner, bottomRight = farCorner bottomRight = farCorner ) ) canvas.drawPath(arrowBackground, canvas.drawPath( arrowBackgroundPaint.apply { alpha = (255 * backgroundAlpha.pos).toInt() }) arrowBackground, arrowBackgroundPaint.apply { alpha = (255 * backgroundAlpha.pos).toInt() } ) val dx = arrowLength.pos val dx = arrowLength.pos val dy = arrowHeight.pos val dy = arrowHeight.pos Loading @@ -500,8 +510,8 @@ class BackPanel( } } val arrowPath = calculateArrowPath(dx = dx, dy = dy) val arrowPath = calculateArrowPath(dx = dx, dy = dy) val arrowPaint = arrowPaint val arrowPaint = .apply { alpha = (255 * min(arrowAlpha.pos, backgroundAlpha.pos)).toInt() } arrowPaint.apply { alpha = (255 * min(arrowAlpha.pos, backgroundAlpha.pos)).toInt() } canvas.drawPath(arrowPath, arrowPaint) canvas.drawPath(arrowPath, arrowPaint) canvas.restore() canvas.restore() Loading @@ -523,12 +533,18 @@ class BackPanel( topRight: Float = 0f, topRight: Float = 0f, bottomRight: Float = 0f, bottomRight: Float = 0f, bottomLeft: Float = 0f bottomLeft: Float = 0f ): Path = Path().apply { ): Path = val corners = floatArrayOf( Path().apply { topLeft, topLeft, val corners = topRight, topRight, floatArrayOf( bottomRight, bottomRight, topLeft, bottomLeft, bottomLeft topLeft, topRight, topRight, bottomRight, bottomRight, bottomLeft, bottomLeft ) ) addRoundRect(this@toPathWithRoundCorners, corners, Path.Direction.CW) addRoundRect(this@toPathWithRoundCorners, corners, Path.Direction.CW) } } Loading
packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt +8 −9 Original line number Original line Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.view.Gravity import android.view.HapticFeedbackConstants import android.view.HapticFeedbackConstants import android.view.MotionEvent import android.view.MotionEvent import android.view.VelocityTracker import android.view.VelocityTracker import android.view.View import android.view.ViewConfiguration import android.view.ViewConfiguration import android.view.WindowManager import android.view.WindowManager import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting Loading Loading @@ -164,6 +163,7 @@ internal constructor( private val elapsedTimeSinceInactive private val elapsedTimeSinceInactive get() = systemClock.uptimeMillis() - gestureInactiveTime get() = systemClock.uptimeMillis() - gestureInactiveTime private val elapsedTimeSinceEntry private val elapsedTimeSinceEntry get() = systemClock.uptimeMillis() - gestureEntryTime get() = systemClock.uptimeMillis() - gestureEntryTime Loading Loading @@ -612,6 +612,7 @@ internal constructor( } } private var previousPreThresholdWidthInterpolator = params.entryWidthInterpolator private var previousPreThresholdWidthInterpolator = params.entryWidthInterpolator private fun preThresholdWidthStretchAmount(progress: Float): Float { private fun preThresholdWidthStretchAmount(progress: Float): Float { val interpolator = run { val interpolator = run { val isPastSlop = totalTouchDeltaInactive > viewConfiguration.scaledTouchSlop val isPastSlop = totalTouchDeltaInactive > viewConfiguration.scaledTouchSlop Loading Loading @@ -677,8 +678,7 @@ internal constructor( velocityTracker?.run { velocityTracker?.run { computeCurrentVelocity(PX_PER_SEC) computeCurrentVelocity(PX_PER_SEC) xVelocity.takeIf { mView.isLeftPanel } ?: (xVelocity * -1) xVelocity.takeIf { mView.isLeftPanel } ?: (xVelocity * -1) } } ?: 0f ?: 0f val isPastFlingVelocityThreshold = val isPastFlingVelocityThreshold = flingVelocity > viewConfiguration.scaledMinimumFlingVelocity flingVelocity > viewConfiguration.scaledMinimumFlingVelocity return flingDistance > minFlingDistance && isPastFlingVelocityThreshold return flingDistance > minFlingDistance && isPastFlingVelocityThreshold Loading Loading @@ -1028,8 +1028,7 @@ internal constructor( velocityTracker?.run { velocityTracker?.run { computeCurrentVelocity(PX_PER_MS) computeCurrentVelocity(PX_PER_MS) MathUtils.smoothStep(slowVelocityBound, fastVelocityBound, abs(xVelocity)) MathUtils.smoothStep(slowVelocityBound, fastVelocityBound, abs(xVelocity)) } } ?: valueOnFastVelocity ?: valueOnFastVelocity return MathUtils.lerp(valueOnFastVelocity, valueOnSlowVelocity, 1 - factor) return MathUtils.lerp(valueOnFastVelocity, valueOnSlowVelocity, 1 - factor) } } Loading
packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt +132 −86 Original line number Original line Diff line number Diff line Loading @@ -45,57 +45,79 @@ data class EdgePanelParams(private var resources: Resources) { lateinit var entryIndicator: BackIndicatorDimens lateinit var entryIndicator: BackIndicatorDimens private set private set lateinit var activeIndicator: BackIndicatorDimens lateinit var activeIndicator: BackIndicatorDimens private set private set lateinit var cancelledIndicator: BackIndicatorDimens lateinit var cancelledIndicator: BackIndicatorDimens private set private set lateinit var flungIndicator: BackIndicatorDimens lateinit var flungIndicator: BackIndicatorDimens private set private set lateinit var committedIndicator: BackIndicatorDimens lateinit var committedIndicator: BackIndicatorDimens private set private set lateinit var preThresholdIndicator: BackIndicatorDimens lateinit var preThresholdIndicator: BackIndicatorDimens private set private set lateinit var fullyStretchedIndicator: BackIndicatorDimens lateinit var fullyStretchedIndicator: BackIndicatorDimens private set private set // navigation bar edge constants // navigation bar edge constants var arrowPaddingEnd: Int = 0 var arrowPaddingEnd: Int = 0 private set private set var arrowThickness: Float = 0f var arrowThickness: Float = 0f private set private set // The closest to y // The closest to y var minArrowYPosition: Int = 0 var minArrowYPosition: Int = 0 private set private set var fingerOffset: Int = 0 var fingerOffset: Int = 0 private set private set var staticTriggerThreshold: Float = 0f var staticTriggerThreshold: Float = 0f private set private set var reactivationTriggerThreshold: Float = 0f var reactivationTriggerThreshold: Float = 0f private set private set var deactivationTriggerThreshold: Float = 0f var deactivationTriggerThreshold: Float = 0f get() = -field get() = -field private set private set lateinit var dynamicTriggerThresholdRange: ClosedRange<Float> lateinit var dynamicTriggerThresholdRange: ClosedRange<Float> private set private set var swipeProgressThreshold: Float = 0f var swipeProgressThreshold: Float = 0f private set private set lateinit var entryWidthInterpolator: Interpolator lateinit var entryWidthInterpolator: Interpolator private set private set lateinit var entryWidthTowardsEdgeInterpolator: Interpolator lateinit var entryWidthTowardsEdgeInterpolator: Interpolator private set private set lateinit var activeWidthInterpolator: Interpolator lateinit var activeWidthInterpolator: Interpolator private set private set lateinit var arrowAngleInterpolator: Interpolator lateinit var arrowAngleInterpolator: Interpolator private set private set lateinit var horizontalTranslationInterpolator: Interpolator lateinit var horizontalTranslationInterpolator: Interpolator private set private set lateinit var verticalTranslationInterpolator: Interpolator lateinit var verticalTranslationInterpolator: Interpolator private set private set lateinit var farCornerInterpolator: Interpolator lateinit var farCornerInterpolator: Interpolator private set private set lateinit var edgeCornerInterpolator: Interpolator lateinit var edgeCornerInterpolator: Interpolator private set private set lateinit var heightInterpolator: Interpolator lateinit var heightInterpolator: Interpolator private set private set Loading @@ -108,7 +130,10 @@ data class EdgePanelParams(private var resources: Resources) { } } private fun getDimenFloat(id: Int): Float { private fun getDimenFloat(id: Int): Float { return TypedValue().run { resources.getValue(id, this, true); float } return TypedValue().run { resources.getValue(id, this, true) float } } } private fun getPx(id: Int): Int { private fun getPx(id: Int): Int { Loading @@ -126,8 +151,7 @@ data class EdgePanelParams(private var resources: Resources) { getDimen(R.dimen.navigation_edge_action_reactivation_drag_threshold) getDimen(R.dimen.navigation_edge_action_reactivation_drag_threshold) deactivationTriggerThreshold = deactivationTriggerThreshold = getDimen(R.dimen.navigation_edge_action_deactivation_drag_threshold) getDimen(R.dimen.navigation_edge_action_deactivation_drag_threshold) dynamicTriggerThresholdRange = dynamicTriggerThresholdRange = reactivationTriggerThreshold..deactivationTriggerThreshold reactivationTriggerThreshold..deactivationTriggerThreshold swipeProgressThreshold = getDimen(R.dimen.navigation_edge_action_progress_threshold) swipeProgressThreshold = getDimen(R.dimen.navigation_edge_action_progress_threshold) entryWidthInterpolator = PathInterpolator(.19f, 1.27f, .71f, .86f) entryWidthInterpolator = PathInterpolator(.19f, 1.27f, .71f, .86f) Loading @@ -149,27 +173,31 @@ data class EdgePanelParams(private var resources: Resources) { val commonArrowDimensAlphaThreshold = .165f val commonArrowDimensAlphaThreshold = .165f val commonArrowDimensAlphaFactor = 1.05f val commonArrowDimensAlphaFactor = 1.05f val commonArrowDimensAlphaSpring = Step( val commonArrowDimensAlphaSpring = Step( threshold = commonArrowDimensAlphaThreshold, threshold = commonArrowDimensAlphaThreshold, factor = commonArrowDimensAlphaFactor, factor = commonArrowDimensAlphaFactor, postThreshold = createSpring(180f, 0.9f), postThreshold = createSpring(180f, 0.9f), preThreshold = createSpring(2000f, 0.6f) preThreshold = createSpring(2000f, 0.6f) ) ) val commonArrowDimensAlphaSpringInterpolator = Step( val commonArrowDimensAlphaSpringInterpolator = Step( threshold = commonArrowDimensAlphaThreshold, threshold = commonArrowDimensAlphaThreshold, factor = commonArrowDimensAlphaFactor, factor = commonArrowDimensAlphaFactor, postThreshold = 1f, postThreshold = 1f, preThreshold = 0f preThreshold = 0f ) ) entryIndicator = BackIndicatorDimens( entryIndicator = BackIndicatorDimens( horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin), horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin), scale = getDimenFloat(R.dimen.navigation_edge_entry_scale), scale = getDimenFloat(R.dimen.navigation_edge_entry_scale), scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), horizontalTranslationSpring = createSpring(800f, 0.76f), horizontalTranslationSpring = createSpring(800f, 0.76f), verticalTranslationSpring = createSpring(30000f, 1f), verticalTranslationSpring = createSpring(30000f, 1f), scaleSpring = createSpring(120f, 0.8f), scaleSpring = createSpring(120f, 0.8f), arrowDimens = ArrowDimens( arrowDimens = ArrowDimens( length = getDimen(R.dimen.navigation_edge_entry_arrow_length), length = getDimen(R.dimen.navigation_edge_entry_arrow_length), height = getDimen(R.dimen.navigation_edge_entry_arrow_height), height = getDimen(R.dimen.navigation_edge_entry_arrow_height), alpha = 0f, alpha = 0f, Loading @@ -178,7 +206,8 @@ data class EdgePanelParams(private var resources: Resources) { alphaSpring = commonArrowDimensAlphaSpring, alphaSpring = commonArrowDimensAlphaSpring, alphaInterpolator = commonArrowDimensAlphaSpringInterpolator alphaInterpolator = commonArrowDimensAlphaSpringInterpolator ), ), backgroundDimens = BackgroundDimens( backgroundDimens = BackgroundDimens( alpha = 1f, alpha = 1f, width = getDimen(R.dimen.navigation_edge_entry_background_width), width = getDimen(R.dimen.navigation_edge_entry_background_width), height = getDimen(R.dimen.navigation_edge_entry_background_height), height = getDimen(R.dimen.navigation_edge_entry_background_height), Loading @@ -191,13 +220,15 @@ data class EdgePanelParams(private var resources: Resources) { ) ) ) ) activeIndicator = BackIndicatorDimens( activeIndicator = BackIndicatorDimens( horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin), horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin), scale = getDimenFloat(R.dimen.navigation_edge_active_scale), scale = getDimenFloat(R.dimen.navigation_edge_active_scale), horizontalTranslationSpring = createSpring(1000f, 0.8f), horizontalTranslationSpring = createSpring(1000f, 0.8f), scaleSpring = createSpring(325f, 0.55f), scaleSpring = createSpring(325f, 0.55f), scalePivotX = getDimen(R.dimen.navigation_edge_active_background_width), scalePivotX = getDimen(R.dimen.navigation_edge_active_background_width), arrowDimens = ArrowDimens( arrowDimens = ArrowDimens( length = getDimen(R.dimen.navigation_edge_active_arrow_length), length = getDimen(R.dimen.navigation_edge_active_arrow_length), height = getDimen(R.dimen.navigation_edge_active_arrow_height), height = getDimen(R.dimen.navigation_edge_active_arrow_height), alpha = 1f, alpha = 1f, Loading @@ -206,7 +237,8 @@ data class EdgePanelParams(private var resources: Resources) { alphaSpring = commonArrowDimensAlphaSpring, alphaSpring = commonArrowDimensAlphaSpring, alphaInterpolator = commonArrowDimensAlphaSpringInterpolator alphaInterpolator = commonArrowDimensAlphaSpringInterpolator ), ), backgroundDimens = BackgroundDimens( backgroundDimens = BackgroundDimens( alpha = 1f, alpha = 1f, width = getDimen(R.dimen.navigation_edge_active_background_width), width = getDimen(R.dimen.navigation_edge_active_background_width), height = getDimen(R.dimen.navigation_edge_active_background_height), height = getDimen(R.dimen.navigation_edge_active_background_height), Loading @@ -219,13 +251,15 @@ data class EdgePanelParams(private var resources: Resources) { ) ) ) ) preThresholdIndicator = BackIndicatorDimens( preThresholdIndicator = BackIndicatorDimens( horizontalTranslation = getDimen(R.dimen.navigation_edge_pre_threshold_margin), horizontalTranslation = getDimen(R.dimen.navigation_edge_pre_threshold_margin), scale = getDimenFloat(R.dimen.navigation_edge_pre_threshold_scale), scale = getDimenFloat(R.dimen.navigation_edge_pre_threshold_scale), scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), scaleSpring = createSpring(120f, 0.8f), scaleSpring = createSpring(120f, 0.8f), horizontalTranslationSpring = createSpring(6000f, 1f), horizontalTranslationSpring = createSpring(6000f, 1f), arrowDimens = ArrowDimens( arrowDimens = ArrowDimens( length = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_length), length = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_length), height = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_height), height = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_height), alpha = 1f, alpha = 1f, Loading @@ -234,7 +268,8 @@ data class EdgePanelParams(private var resources: Resources) { alphaSpring = commonArrowDimensAlphaSpring, alphaSpring = commonArrowDimensAlphaSpring, alphaInterpolator = commonArrowDimensAlphaSpringInterpolator alphaInterpolator = commonArrowDimensAlphaSpringInterpolator ), ), backgroundDimens = BackgroundDimens( backgroundDimens = BackgroundDimens( alpha = 1f, alpha = 1f, width = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), width = getDimen(R.dimen.navigation_edge_pre_threshold_background_width), height = getDimen(R.dimen.navigation_edge_pre_threshold_background_height), height = getDimen(R.dimen.navigation_edge_pre_threshold_background_height), Loading @@ -249,16 +284,19 @@ data class EdgePanelParams(private var resources: Resources) { ) ) ) ) committedIndicator = activeIndicator.copy( committedIndicator = activeIndicator.copy( horizontalTranslation = null, horizontalTranslation = null, scalePivotX = null, scalePivotX = null, arrowDimens = activeIndicator.arrowDimens.copy( arrowDimens = activeIndicator.arrowDimens.copy( lengthSpring = activeCommittedArrowLengthSpring, lengthSpring = activeCommittedArrowLengthSpring, heightSpring = activeCommittedArrowHeightSpring, heightSpring = activeCommittedArrowHeightSpring, length = null, length = null, height = null, height = null, ), ), backgroundDimens = activeIndicator.backgroundDimens.copy( backgroundDimens = activeIndicator.backgroundDimens.copy( alpha = 0f, alpha = 0f, // explicitly set to null to preserve previous width upon state change // explicitly set to null to preserve previous width upon state change width = null, width = null, Loading @@ -272,14 +310,17 @@ data class EdgePanelParams(private var resources: Resources) { scaleSpring = createSpring(5700f, 1f), scaleSpring = createSpring(5700f, 1f), ) ) flungIndicator = committedIndicator.copy( flungIndicator = arrowDimens = committedIndicator.arrowDimens.copy( committedIndicator.copy( arrowDimens = committedIndicator.arrowDimens.copy( lengthSpring = createSpring(850f, 0.46f), lengthSpring = createSpring(850f, 0.46f), heightSpring = createSpring(850f, 0.46f), heightSpring = createSpring(850f, 0.46f), length = activeIndicator.arrowDimens.length, length = activeIndicator.arrowDimens.length, height = activeIndicator.arrowDimens.height height = activeIndicator.arrowDimens.height ), ), backgroundDimens = committedIndicator.backgroundDimens.copy( backgroundDimens = committedIndicator.backgroundDimens.copy( widthSpring = flungCommittedWidthSpring, widthSpring = flungCommittedWidthSpring, heightSpring = flungCommittedHeightSpring, heightSpring = flungCommittedHeightSpring, edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring, edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring, Loading @@ -287,21 +328,25 @@ data class EdgePanelParams(private var resources: Resources) { ) ) ) ) cancelledIndicator = entryIndicator.copy( cancelledIndicator = backgroundDimens = entryIndicator.backgroundDimens.copy( entryIndicator.copy( backgroundDimens = entryIndicator.backgroundDimens.copy( width = 0f, width = 0f, alpha = 0f, alpha = 0f, alphaSpring = createSpring(450f, 1f) alphaSpring = createSpring(450f, 1f) ) ) ) ) fullyStretchedIndicator = BackIndicatorDimens( fullyStretchedIndicator = BackIndicatorDimens( horizontalTranslation = getDimen(R.dimen.navigation_edge_stretch_margin), horizontalTranslation = getDimen(R.dimen.navigation_edge_stretch_margin), scale = getDimenFloat(R.dimen.navigation_edge_stretch_scale), scale = getDimenFloat(R.dimen.navigation_edge_stretch_scale), horizontalTranslationSpring = null, horizontalTranslationSpring = null, verticalTranslationSpring = null, verticalTranslationSpring = null, scaleSpring = null, scaleSpring = null, arrowDimens = ArrowDimens( arrowDimens = ArrowDimens( length = getDimen(R.dimen.navigation_edge_stretched_arrow_length), length = getDimen(R.dimen.navigation_edge_stretched_arrow_length), height = getDimen(R.dimen.navigation_edge_stretched_arrow_height), height = getDimen(R.dimen.navigation_edge_stretched_arrow_height), alpha = 1f, alpha = 1f, Loading @@ -309,7 +354,8 @@ data class EdgePanelParams(private var resources: Resources) { heightSpring = null, heightSpring = null, lengthSpring = null, lengthSpring = null, ), ), backgroundDimens = BackgroundDimens( backgroundDimens = BackgroundDimens( alpha = 1f, alpha = 1f, width = getDimen(R.dimen.navigation_edge_stretch_background_width), width = getDimen(R.dimen.navigation_edge_stretch_background_width), height = getDimen(R.dimen.navigation_edge_stretch_background_height), height = getDimen(R.dimen.navigation_edge_stretch_background_height), Loading
packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt +1 −0 Original line number Original line Diff line number Diff line Loading @@ -55,6 +55,7 @@ class BackPanelControllerTest : SysuiTestCase() { companion object { companion object { private const val START_X: Float = 0f private const val START_X: Float = 0f } } private val kosmos = testKosmos() private val kosmos = testKosmos() private lateinit var mBackPanelController: BackPanelController private lateinit var mBackPanelController: BackPanelController private lateinit var systemClock: FakeSystemClock private lateinit var systemClock: FakeSystemClock Loading