Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d65d1745 authored by Selim Cinek's avatar Selim Cinek Committed by Android (Google) Code Review
Browse files

Merge "Fixed an issue where the user could be stuck with pulse expanding"

parents 3f1705f0 a7617fc8
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
/*
 * 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.log.dagger;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import com.android.systemui.log.LogBuffer;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;

import javax.inject.Qualifier;

/** A {@link LogBuffer} for lockscreen to shade transition events. */
@Qualifier
@Documented
@Retention(RUNTIME)
public @interface LSShadeTransitionLog {
}
+8 −0
Original line number Diff line number Diff line
@@ -61,6 +61,14 @@ public class LogModule {
        return factory.create("NotifHeadsUpLog", 1000);
    }

    /** Provides a logging buffer for all logs for lockscreen to shade transition events. */
    @Provides
    @SysUISingleton
    @LSShadeTransitionLog
    public static LogBuffer provideLSShadeTransitionControllerBuffer(LogBufferFactory factory) {
        return factory.create("LSShadeTransitionLog", 50);
    }

    /** Provides a logging buffer for all logs related to managing notification sections. */
    @Provides
    @SysUISingleton
+85 −24
Original line number Diff line number Diff line
@@ -8,12 +8,13 @@ import android.content.Context
import android.content.res.Configuration
import android.os.SystemClock
import android.util.DisplayMetrics
import android.util.IndentingPrintWriter
import android.util.MathUtils
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import androidx.annotation.VisibleForTesting
import com.android.internal.logging.nano.MetricsProto.MetricsEvent
import com.android.systemui.Dumpable
import com.android.systemui.ExpandHelper
import com.android.systemui.Gefingerpoken
import com.android.systemui.R
@@ -22,23 +23,26 @@ import com.android.systemui.biometrics.UdfpsKeyguardViewController
import com.android.systemui.classifier.Classifier
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.media.MediaHierarchyManager
import com.android.systemui.plugins.ActivityStarter.OnDismissAction
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.qs.QS
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.LockscreenGestureLogger
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent
import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
import com.android.systemui.statusbar.phone.NotificationPanelViewController
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.phone.StatusBar
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.Utils
import java.io.FileDescriptor
import java.io.PrintWriter
import javax.inject.Inject

private const val SPRING_BACK_ANIMATION_LENGTH_MS = 375L
@@ -51,19 +55,19 @@ private const val RUBBERBAND_FACTOR_EXPANDABLE = 0.5f
@SysUISingleton
class LockscreenShadeTransitionController @Inject constructor(
    private val statusBarStateController: SysuiStatusBarStateController,
    private val lockscreenGestureLogger: LockscreenGestureLogger,
    private val logger: LSShadeTransitionLogger,
    private val keyguardBypassController: KeyguardBypassController,
    private val lockScreenUserManager: NotificationLockscreenUserManager,
    private val falsingCollector: FalsingCollector,
    private val ambientState: AmbientState,
    private val displayMetrics: DisplayMetrics,
    private val mediaHierarchyManager: MediaHierarchyManager,
    private val scrimController: ScrimController,
    private val depthController: NotificationShadeDepthController,
    private val context: Context,
    configurationController: ConfigurationController,
    falsingManager: FalsingManager
) {
    falsingManager: FalsingManager,
    dumpManager: DumpManager,
) : Dumpable {
    private var pulseHeight: Float = 0f
    private var useSplitShade: Boolean = false
    private lateinit var nsslController: NotificationStackScrollLayoutController
@@ -139,6 +143,23 @@ class LockscreenShadeTransitionController @Inject constructor(
                touchHelper.updateResources(context)
            }
        })
        dumpManager.registerDumpable(this)
        statusBarStateController.addCallback(object : StatusBarStateController.StateListener {
            override fun onExpandedChanged(isExpanded: Boolean) {
                // safeguard: When the panel is fully collapsed, let's make sure to reset.
                // See b/198098523
                if (!isExpanded) {
                    if (dragDownAmount != 0f && dragDownAnimator?.isRunning != true) {
                        logger.logDragDownAmountResetWhenFullyCollapsed()
                        dragDownAmount = 0f
                    }
                    if (pulseHeight != 0f && pulseHeightAnimator?.isRunning != true) {
                        logger.logPulseHeightNotResetWhenFullyCollapsed()
                        setPulseHeight(0f, animate = false)
                    }
                }
            }
        })
    }

    private fun updateResources() {
@@ -182,19 +203,19 @@ class LockscreenShadeTransitionController @Inject constructor(
     */
    internal fun onDraggedDown(startingChild: View?, dragLengthY: Int) {
        if (canDragDown()) {
            val cancelRunnable = Runnable {
                logger.logGoingToLockedShadeAborted()
                setDragDownAmountAnimated(0f)
            }
            if (nsslController.isInLockedDownShade()) {
                logger.logDraggedDownLockDownShade(startingChild)
                statusBarStateController.setLeaveOpenOnKeyguardHide(true)
                statusbar.dismissKeyguardThenExecute(OnDismissAction {
                    nextHideKeyguardNeedsNoAnimation = true
                    false
                },
                        null /* cancelRunnable */, false /* afterKeyguardGone */)
                }, cancelRunnable, false /* afterKeyguardGone */)
            } else {
                lockscreenGestureLogger.write(
                        MetricsEvent.ACTION_LS_SHADE,
                        (dragLengthY / displayMetrics.density).toInt(),
                        0 /* velocityDp */)
                lockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_PULL_SHADE_OPEN)
                logger.logDraggedDown(startingChild, dragLengthY)
                if (!ambientState.isDozing() || startingChild != null) {
                    // go to locked shade while animating the drag down amount from its current
                    // value
@@ -216,11 +237,11 @@ class LockscreenShadeTransitionController @Inject constructor(
                        dragDownAmount = 0f
                        forceApplyAmount = false
                    }
                    val cancelRunnable = Runnable { setDragDownAmountAnimated(0f) }
                    goToLockedShadeInternal(startingChild, animationHandler, cancelRunnable)
                }
            }
        } else {
            logger.logUnSuccessfulDragDown(startingChild)
            setDragDownAmountAnimated(0f)
        }
    }
@@ -229,6 +250,7 @@ class LockscreenShadeTransitionController @Inject constructor(
     * Called by the touch helper when the drag down was aborted and should be reset.
     */
    internal fun onDragDownReset() {
        logger.logDragDownAborted()
        nsslController.setDimmed(true /* dimmed */, true /* animated */)
        nsslController.resetScrollPosition()
        nsslController.resetCheckSnoozeLeavebehind()
@@ -246,10 +268,16 @@ class LockscreenShadeTransitionController @Inject constructor(
    /**
     * Called by the touch helper when the drag down was started
     */
    internal fun onDragDownStarted() {
    internal fun onDragDownStarted(startingChild: ExpandableView?) {
        logger.logDragDownStarted(startingChild)
        nsslController.cancelLongPress()
        nsslController.checkSnoozeLeavebehind()
        dragDownAnimator?.cancel()
        dragDownAnimator?.apply {
            if (isRunning) {
                logger.logAnimationCancelled(isPulse = false)
                cancel()
            }
        }
    }

    /**
@@ -294,12 +322,12 @@ class LockscreenShadeTransitionController @Inject constructor(
        set(value) {
            if (field != value || forceApplyAmount) {
                field = value
                if (!nsslController.isInLockedDownShade() || forceApplyAmount) {
                if (!nsslController.isInLockedDownShade() || field == 0f || forceApplyAmount) {
                    nsslController.setTransitionToFullShadeAmount(field)
                    notificationPanelController.setTransitionToFullShadeAmount(field,
                            false /* animate */, 0 /* delay */)
                    dragProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
                    qS.setTransitionToFullShadeAmount(field, dragProgress)
                    qSDragProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
                    qS.setTransitionToFullShadeAmount(field, qSDragProgress)
                    // TODO: appear media also in split shade
                    val mediaAmount = if (useSplitShade) 0f else field
                    mediaHierarchyManager.setTransitionToFullShadeAmount(mediaAmount)
@@ -308,7 +336,10 @@ class LockscreenShadeTransitionController @Inject constructor(
            }
        }

    var dragProgress = 0f
    /**
     * The drag progress of the quick settings drag down amount
     */
    var qSDragProgress = 0f
        private set

    private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
@@ -325,6 +356,7 @@ class LockscreenShadeTransitionController @Inject constructor(
        delay: Long = 0,
        endlistener: (() -> Unit)? = null
    ) {
        logger.logDragDownAnimation(target)
        val dragDownAnimator = ValueAnimator.ofFloat(dragDownAmount, target)
        dragDownAnimator.interpolator = Interpolators.FAST_OUT_SLOW_IN
        dragDownAnimator.duration = SPRING_BACK_ANIMATION_LENGTH_MS
@@ -380,7 +412,9 @@ class LockscreenShadeTransitionController @Inject constructor(
     */
    @JvmOverloads
    fun goToLockedShade(expandedView: View?, needsQSAnimation: Boolean = true) {
        if (statusBarStateController.state == StatusBarState.KEYGUARD) {
        val isKeyguard = statusBarStateController.state == StatusBarState.KEYGUARD
        logger.logTryGoToLockedShade(isKeyguard)
        if (isKeyguard) {
            val animationHandler: ((Long) -> Unit)?
            if (needsQSAnimation) {
                // Let's use the default animation
@@ -416,6 +450,7 @@ class LockscreenShadeTransitionController @Inject constructor(
    ) {
        if (statusbar.isShadeDisabled) {
            cancelAction?.run()
            logger.logShadeDisabledOnGoToLockedShade()
            return
        }
        var userId: Int = lockScreenUserManager.getCurrentUserId()
@@ -454,9 +489,11 @@ class LockscreenShadeTransitionController @Inject constructor(
                }
                cancelAction?.run()
            }
            logger.logShowBouncerOnGoToLockedShade()
            statusbar.showBouncerWithDimissAndCancelIfKeyguard(onDismissAction, cancelHandler)
            draggedDownEntry = entry
        } else {
            logger.logGoingToLockedShade(animationHandler != null)
            statusBarStateController.setState(StatusBarState.SHADE_LOCKED)
            // This call needs to be after updating the shade state since otherwise
            // the scrimstate resets too early
@@ -476,6 +513,7 @@ class LockscreenShadeTransitionController @Inject constructor(
     * @param previousState which state were we in when we hid the keyguard?
     */
    fun onHideKeyguard(delay: Long, previousState: Int) {
        logger.logOnHideKeyguard()
        if (animationHandlerOnKeyguardDismiss != null) {
            animationHandlerOnKeyguardDismiss!!.invoke(delay)
            animationHandlerOnKeyguardDismiss = null
@@ -498,6 +536,7 @@ class LockscreenShadeTransitionController @Inject constructor(
     * not triggered by gestures, e.g. when clicking on the shelf or expand button.
     */
    private fun performDefaultGoToFullShadeAnimation(delay: Long) {
        logger.logDefaultGoToFullShadeAnimation(delay)
        notificationPanelController.animateToFullShade(delay)
        animateAppear(delay)
    }
@@ -534,6 +573,7 @@ class LockscreenShadeTransitionController @Inject constructor(
     * @param cancelled was the interaction cancelled and this is a reset?
     */
    fun finishPulseAnimation(cancelled: Boolean) {
        logger.logPulseExpansionFinished(cancelled)
        if (cancelled) {
            setPulseHeight(0f, animate = true)
        } else {
@@ -546,7 +586,28 @@ class LockscreenShadeTransitionController @Inject constructor(
     * Notify this class that a pulse expansion is starting
     */
    fun onPulseExpansionStarted() {
        pulseHeightAnimator?.cancel()
        logger.logPulseExpansionStarted()
        pulseHeightAnimator?.apply {
            if (isRunning) {
                logger.logAnimationCancelled(isPulse = true)
                cancel()
            }
        }
    }

    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
        IndentingPrintWriter(pw, "  ").let {
            it.println("LSShadeTransitionController:")
            it.increaseIndent()
            it.println("pulseHeight: $pulseHeight")
            it.println("useSplitShade: $useSplitShade")
            it.println("dragDownAmount: $dragDownAmount")
            it.println("qSDragProgress: $qSDragProgress")
            it.println("isDragDownAnywhereEnabled: $isDragDownAnywhereEnabled")
            it.println("isFalsingCheckNeeded: $isFalsingCheckNeeded")
            it.println("hasPendingHandlerOnKeyguardDismiss: " +
                "${animationHandlerOnKeyguardDismiss != null}")
        }
    }
}

@@ -626,7 +687,7 @@ class DragDownHelper(
                    captureStartingChild(initialTouchX, initialTouchY)
                    initialTouchY = y
                    initialTouchX = x
                    dragDownCallback.onDragDownStarted()
                    dragDownCallback.onDragDownStarted(startingChild)
                    dragDownAmountOnStart = dragDownCallback.dragDownAmount
                    return startingChild != null || dragDownCallback.isDragDownAnywhereEnabled
                }
+22 −2
Original line number Diff line number Diff line
@@ -24,15 +24,18 @@ import android.content.res.Configuration
import android.os.PowerManager
import android.os.PowerManager.WAKE_REASON_GESTURE
import android.os.SystemClock
import android.util.IndentingPrintWriter
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.ViewConfiguration
import com.android.systemui.Dumpable
import com.android.systemui.Gefingerpoken
import com.android.systemui.R
import com.android.systemui.animation.Interpolators
import com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
@@ -43,6 +46,8 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
import java.io.FileDescriptor
import java.io.PrintWriter
import javax.inject.Inject
import kotlin.math.max

@@ -61,8 +66,9 @@ constructor(
    private val statusBarStateController: StatusBarStateController,
    private val falsingManager: FalsingManager,
    private val lockscreenShadeTransitionController: LockscreenShadeTransitionController,
    private val falsingCollector: FalsingCollector
) : Gefingerpoken {
    private val falsingCollector: FalsingCollector,
    dumpManager: DumpManager
) : Gefingerpoken, Dumpable {
    companion object {
        private val SPRING_BACK_ANIMATION_LENGTH_MS = 375
    }
@@ -120,6 +126,7 @@ constructor(
            }
        })
        mPowerManager = context.getSystemService(PowerManager::class.java)
        dumpManager.registerDumpable(this)
    }

    private fun initResources(context: Context) {
@@ -329,4 +336,17 @@ constructor(
    fun onStartedWakingUp() {
        isWakingToShadeLocked = false
    }

    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
        IndentingPrintWriter(pw, "  ").let {
            it.println("PulseExpansionHandler:")
            it.increaseIndent()
            it.println("isExpanding: $isExpanding")
            it.println("leavingLockscreen: $leavingLockscreen")
            it.println("mPulsing: $mPulsing")
            it.println("isWakingToShadeLocked: $isWakingToShadeLocked")
            it.println("qsExpanded: $qsExpanded")
            it.println("bouncerShowing: $bouncerShowing")
        }
    }
}
+183 −0
Original line number Diff line number Diff line
/*
 * 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.phone

import android.util.DisplayMetrics
import android.view.View
import com.android.internal.logging.nano.MetricsProto.MetricsEvent
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel
import com.android.systemui.log.dagger.LSShadeTransitionLog
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import javax.inject.Inject

private const val TAG = "LockscreenShadeTransitionController"

class LSShadeTransitionLogger @Inject constructor(
    @LSShadeTransitionLog private val buffer: LogBuffer,
    private val lockscreenGestureLogger: LockscreenGestureLogger,
    private val displayMetrics: DisplayMetrics
) {
    fun logUnSuccessfulDragDown(startingChild: View?) {
        val entry = (startingChild as ExpandableNotificationRow?)?.entry
        buffer.log(TAG, LogLevel.INFO, {
            str1 = entry?.key ?: "no entry"
        }, {
            "Tried to drag down but can't drag down on $str1"
        })
    }

    fun logDragDownAborted() {
        buffer.log(TAG, LogLevel.INFO, {}, {
            "The drag down was reset"
        })
    }

    fun logDragDownStarted(startingChild: ExpandableView?) {
        val entry = (startingChild as ExpandableNotificationRow?)?.entry
        buffer.log(TAG, LogLevel.INFO, {
            str1 = entry?.key ?: "no entry"
        }, {
            "The drag down has started on $str1"
        })
    }

    fun logDraggedDownLockDownShade(startingChild: View?) {
        val entry = (startingChild as ExpandableNotificationRow?)?.entry
        buffer.log(TAG, LogLevel.INFO, {
            str1 = entry?.key ?: "no entry"
        }, {
            "Dragged down in locked down shade on $str1"
        })
    }

    fun logDraggedDown(startingChild: View?, dragLengthY: Int) {
        val entry = (startingChild as ExpandableNotificationRow?)?.entry
        buffer.log(TAG, LogLevel.INFO, {
            str1 = entry?.key ?: "no entry"
        }, {
            "Drag down succeeded on $str1"
        })
        // Do logging to event log not just our own buffer
        lockscreenGestureLogger.write(
            MetricsEvent.ACTION_LS_SHADE,
            (dragLengthY / displayMetrics.density).toInt(),
            0 /* velocityDp */)
        lockscreenGestureLogger.log(
            LockscreenGestureLogger.LockscreenUiEvent.LOCKSCREEN_PULL_SHADE_OPEN)
    }

    fun logDefaultGoToFullShadeAnimation(delay: Long) {
        buffer.log(TAG, LogLevel.DEBUG, {
            long1 = delay
        }, {
            "Default animation started to full shade with delay $long1"
        })
    }

    fun logTryGoToLockedShade(keyguard: Boolean) {
        buffer.log(TAG, LogLevel.INFO, {
            bool1 = keyguard
        }, {
            "Trying to go to locked shade " + if (bool1) "from keyguard" else "not from keyguard"
        })
    }

    fun logShadeDisabledOnGoToLockedShade() {
        buffer.log(TAG, LogLevel.WARNING, {}, {
            "The shade was disabled when trying to go to the locked shade"
        })
    }

    fun logShowBouncerOnGoToLockedShade() {
        buffer.log(TAG, LogLevel.INFO, {}, {
            "Showing bouncer when trying to go to the locked shade"
        })
    }

    fun logGoingToLockedShade(customAnimationHandler: Boolean) {
        buffer.log(TAG, LogLevel.INFO, {
            bool1 = customAnimationHandler
        }, {
            "Going to locked shade " + if (customAnimationHandler) "with" else "without" +
                " a custom handler"
        })
    }

    fun logOnHideKeyguard() {
        buffer.log(TAG, LogLevel.INFO, {}, {
            "Notified that the keyguard is being hidden"
        })
    }

    fun logPulseExpansionStarted() {
        buffer.log(TAG, LogLevel.INFO, {}, {
            "Pulse Expansion has started"
        })
    }

    fun logPulseExpansionFinished(cancelled: Boolean) {
        if (cancelled) {
            buffer.log(TAG, LogLevel.INFO, {}, {
                "Pulse Expansion is requested to cancel"
            })
        } else {
            buffer.log(TAG, LogLevel.INFO, {}, {
                "Pulse Expansion is requested to finish"
            })
        }
    }

    fun logDragDownAnimation(target: Float) {
        buffer.log(TAG, LogLevel.DEBUG, {
            double1 = target.toDouble()
        }, {
            "Drag down amount animating to " + double1
        })
    }

    fun logAnimationCancelled(isPulse: Boolean) {
        if (isPulse) {
            buffer.log(TAG, LogLevel.DEBUG, {}, {
                "Pulse animation cancelled"
            })
        } else {
            buffer.log(TAG, LogLevel.DEBUG, {}, {
                "drag down animation cancelled"
            })
        }
    }

    fun logDragDownAmountResetWhenFullyCollapsed() {
        buffer.log(TAG, LogLevel.WARNING, {}, {
            "Drag down amount stuck and reset after shade was fully collapsed"
        })
    }

    fun logPulseHeightNotResetWhenFullyCollapsed() {
        buffer.log(TAG, LogLevel.WARNING, {}, {
            "Pulse height stuck and reset after shade was fully collapsed"
        })
    }

    fun logGoingToLockedShadeAborted() {
        buffer.log(TAG, LogLevel.INFO, {}, {
            "Going to the Locked Shade has been aborted"
        })
    }
}
Loading