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

Commit 8df5acd8 authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Add logging to NPVC

Add logging to track down events on NPVC and events that could be
conducive to QS expansion.

Also, fix wrong X/Y assignment

Test: manual
Test: atest SystemUITests
Bug: 227115380
Fixes: 227447952
Change-Id: I24f6a655f8977f6a9590855744383d52cdbfefec
parent 5ec5a80c
Loading
Loading
Loading
Loading
+143 −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.view.MotionEvent
import com.android.internal.util.RingBuffer
import com.android.systemui.dump.DumpsysTableLogger
import com.android.systemui.dump.Row
import java.text.SimpleDateFormat
import java.util.Locale

/** Container for storing information about [MotionEvent.ACTION_DOWN] on
 * [NotificationPanelViewController].
 *
 * This will be used in a dump to log the latest recorded down events.
 *
 * @see NotificationPanelViewController.initDownStates
 */
class NPVCDownEventState private constructor(
    private var timeStamp: Long = 0,
    private var x: Float = 0f,
    private var y: Float = 0f,
    private var qsTouchAboveFalsingThreshold: Boolean = false,
    private var dozing: Boolean = false,
    private var collapsed: Boolean = false,
    private var canCollapseOnQQS: Boolean = false,
    private var listenForHeadsUp: Boolean = false,
    private var allowExpandForSmallExpansion: Boolean = false,
    private var touchSlopExceededBeforeDown: Boolean = false,
    private var lastEventSynthesized: Boolean = false
) {

    /**
     * List of [String] to be used as a [Row] with [DumpsysTableLogger].
     */
    val asStringList: List<String> by lazy {
        listOf(
            DATE_FORMAT.format(timeStamp),
            x.toString(),
            y.toString(),
            qsTouchAboveFalsingThreshold.toString(),
            dozing.toString(),
            collapsed.toString(),
            canCollapseOnQQS.toString(),
            listenForHeadsUp.toString(),
            allowExpandForSmallExpansion.toString(),
            touchSlopExceededBeforeDown.toString(),
            lastEventSynthesized.toString()
        )
    }

    /**
     * [RingBuffer] to store [NPVCDownEventState]. After the buffer is full, it will recycle old
     * events.
     *
     * Do not use [append] to add new elements. Instead use [insert], as it will recycle if
     * necessary.
     */
    class Buffer(
        capacity: Int
    ) : RingBuffer<NPVCDownEventState>(NPVCDownEventState::class.java, capacity) {
        override fun append(t: NPVCDownEventState?) {
            throw UnsupportedOperationException("Not supported, use insert instead")
        }

        override fun createNewItem(): NPVCDownEventState {
            return NPVCDownEventState()
        }

        /**
         * Insert a new element in the buffer.
         */
        fun insert(
            timeStamp: Long,
            x: Float,
            y: Float,
            qsTouchAboveFalsingThreshold: Boolean,
            dozing: Boolean,
            collapsed: Boolean,
            canCollapseOnQQS: Boolean,
            listenForHeadsUp: Boolean,
            allowExpandForSmallExpansion: Boolean,
            touchSlopExceededBeforeDown: Boolean,
            lastEventSynthesized: Boolean
        ) {
            nextSlot.apply {
                this.timeStamp = timeStamp
                this.x = x
                this.y = y
                this.qsTouchAboveFalsingThreshold = qsTouchAboveFalsingThreshold
                this.dozing = dozing
                this.collapsed = collapsed
                this.canCollapseOnQQS = canCollapseOnQQS
                this.listenForHeadsUp = listenForHeadsUp
                this.allowExpandForSmallExpansion = allowExpandForSmallExpansion
                this.touchSlopExceededBeforeDown = touchSlopExceededBeforeDown
                this.lastEventSynthesized = lastEventSynthesized
            }
        }

        /**
         * Returns the content of the buffer (sorted from latest to newest).
         *
         * @see NPVCDownEventState.asStringList
         */
        fun toList(): List<Row> {
            return toArray().map { it.asStringList }
        }
    }

    companion object {
        /**
         * Headers for dumping a table using [DumpsysTableLogger].
         */
        @JvmField
        val TABLE_HEADERS = listOf(
            "Timestamp",
            "X",
            "Y",
            "QSTouchAboveFalsingThreshold",
            "Dozing",
            "Collapsed",
            "CanCollapseOnQQS",
            "ListenForHeadsUp",
            "AllowExpandForSmallExpansion",
            "TouchSlopExceededBeforeDown",
            "LastEventSynthesized"
        )
    }
}

private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US)
+50 −13
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import static com.android.systemui.statusbar.notification.stack.StackStateAnimat
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_CLOSED;
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_OPEN;
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_OPENING;
import static com.android.systemui.util.DumpUtilsKt.asIndenting;

import static java.lang.Float.isNaN;

@@ -65,13 +66,13 @@ import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.Trace;
import android.os.UserManager;
import android.os.VibrationEffect;
import android.provider.Settings;
import android.transition.ChangeBounds;
import android.transition.TransitionManager;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MathUtils;
import android.view.LayoutInflater;
@@ -120,6 +121,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.dump.DumpsysTableLogger;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
@@ -192,6 +194,7 @@ import com.android.systemui.util.LargeScreenUtils;
import com.android.systemui.util.ListenerSet;
import com.android.systemui.util.Utils;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.SystemClock;
import com.android.systemui.wallet.controller.QuickAccessWalletController;
import com.android.wm.shell.animation.FlingAnimationUtils;

@@ -211,7 +214,7 @@ import javax.inject.Provider;
@CentralSurfacesComponent.CentralSurfacesScope
public class NotificationPanelViewController extends PanelViewController {

    private static final boolean DEBUG = false;
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    /**
     * The parallax amount of the quick settings translation when dragging down the panel
@@ -278,6 +281,8 @@ public class NotificationPanelViewController extends PanelViewController {
     */
    private static final int MAX_TIME_TO_OPEN_WHEN_FLINGING_FROM_LAUNCHER = 300;

    private static final int MAX_DOWN_EVENT_BUFFER_SIZE = 50;

    private static final String COUNTER_PANEL_OPEN = "panel_open";
    private static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
    private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek";
@@ -646,6 +651,8 @@ public class NotificationPanelViewController extends PanelViewController {
    private final NotificationListContainer mNotificationListContainer;
    private final NotificationStackSizeCalculator mNotificationStackSizeCalculator;

    private final NPVCDownEventState.Buffer mLastDownEvents;

    private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
        @Override
        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
@@ -748,7 +755,8 @@ public class NotificationPanelViewController extends PanelViewController {
            PanelEventsEmitter panelEventsEmitter,
            NotificationStackSizeCalculator notificationStackSizeCalculator,
            UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
            ShadeTransitionController shadeTransitionController) {
            ShadeTransitionController shadeTransitionController,
            SystemClock systemClock) {
        super(view,
                falsingManager,
                dozeLog,
@@ -764,7 +772,8 @@ public class NotificationPanelViewController extends PanelViewController {
                panelExpansionStateManager,
                ambientState,
                interactionJankMonitor,
                keyguardUnlockAnimationController);
                keyguardUnlockAnimationController,
                systemClock);
        mView = view;
        mVibratorHelper = vibratorHelper;
        mKeyguardMediaController = keyguardMediaController;
@@ -853,6 +862,7 @@ public class NotificationPanelViewController extends PanelViewController {
        mScreenOffAnimationController = screenOffAnimationController;
        mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
        mRemoteInputManager = remoteInputManager;
        mLastDownEvents = new NPVCDownEventState.Buffer(MAX_DOWN_EVENT_BUFFER_SIZE);

        int currentMode = navigationModeController.addListener(
                mode -> mIsGestureNavigation = QuickStepContract.isGesturalMode(mode));
@@ -1691,6 +1701,7 @@ public class NotificationPanelViewController extends PanelViewController {
    }

    private boolean onQsIntercept(MotionEvent event) {
        if (DEBUG) Log.d(TAG, "onQsIntercept");
        int pointerIndex = event.findPointerIndex(mTrackingPointer);
        if (pointerIndex < 0) {
            pointerIndex = 0;
@@ -1745,6 +1756,7 @@ public class NotificationPanelViewController extends PanelViewController {
                if ((h > getTouchSlop(event) || (h < -getTouchSlop(event) && mQsExpanded))
                        && Math.abs(h) > Math.abs(x - mInitialTouchX)
                        && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, h)) {
                    if (DEBUG) Log.d(TAG, "onQsIntercept - start tracking expansion");
                    mView.getParent().requestDisallowInterceptTouchEvent(true);
                    mQsTracking = true;
                    traceQsJank(true /* startTracing */, false /* wasCancelled */);
@@ -1814,6 +1826,19 @@ public class NotificationPanelViewController extends PanelViewController {
                // down but not synthesized motion event.
                mLastEventSynthesizedDown = false;
            }
            mLastDownEvents.insert(
                    mSystemClock.currentTimeMillis(),
                    mDownX,
                    mDownY,
                    mQsTouchAboveFalsingThreshold,
                    mDozingOnDown,
                    mCollapsedOnDown,
                    mIsPanelCollapseOnQQS,
                    mListenForHeadsUp,
                    mAllowExpandForSmallExpansion,
                    mTouchSlopExceededBeforeDown,
                    mLastEventSynthesizedDown
            );
        } else {
            // not down event at all.
            mLastEventSynthesizedDown = false;
@@ -1907,7 +1932,7 @@ public class NotificationPanelViewController extends PanelViewController {
        if (mAllowExpandForSmallExpansion) {
            // When we get a touch that came over from launcher, the velocity isn't always correct
            // Let's err on expanding if the gesture has been reasonably slow
            long timeSinceDown = SystemClock.uptimeMillis() - mDownTime;
            long timeSinceDown = mSystemClock.uptimeMillis() - mDownTime;
            return timeSinceDown <= MAX_TIME_TO_OPEN_WHEN_FLINGING_FROM_LAUNCHER;
        }
        return false;
@@ -1934,8 +1959,8 @@ public class NotificationPanelViewController extends PanelViewController {
            mConflictingQsExpansionGesture = true;
            onQsExpansionStarted();
            mInitialHeightOnTouch = mQsExpansionHeight;
            mInitialTouchY = event.getX();
            mInitialTouchX = event.getY();
            mInitialTouchY = event.getY();
            mInitialTouchX = event.getX();
        }
        if (!isFullyCollapsed()) {
            handleQsDown(event);
@@ -2008,12 +2033,13 @@ public class NotificationPanelViewController extends PanelViewController {
    private void handleQsDown(MotionEvent event) {
        if (event.getActionMasked() == MotionEvent.ACTION_DOWN && shouldQuickSettingsIntercept(
                event.getX(), event.getY(), -1)) {
            if (DEBUG) Log.d(TAG, "handleQsDown");
            mFalsingCollector.onQsDown();
            mQsTracking = true;
            onQsExpansionStarted();
            mInitialHeightOnTouch = mQsExpansionHeight;
            mInitialTouchY = event.getX();
            mInitialTouchX = event.getY();
            mInitialTouchY = event.getY();
            mInitialTouchX = event.getX();

            // If we interrupt an expansion gesture here, make sure to update the state correctly.
            notifyExpandingFinished();
@@ -2121,6 +2147,7 @@ public class NotificationPanelViewController extends PanelViewController {
                break;

            case MotionEvent.ACTION_MOVE:
                if (DEBUG) Log.d(TAG, "onQSTouch move");
                setQsExpansion(h + mInitialHeightOnTouch);
                if (h >= getFalsingThreshold()) {
                    mQsTouchAboveFalsingThreshold = true;
@@ -3855,10 +3882,18 @@ public class NotificationPanelViewController extends PanelViewController {
    @Override
    public void dump(PrintWriter pw, String[] args) {
        super.dump(pw, args);
        pw.println("    gestureExclusionRect: " + calculateGestureExclusionRect()
                + " applyQSClippingImmediately: top(" + mQsClipTop + ") bottom(" + mQsClipBottom
                + ") qsVisible(" + mQsVisible
        );
        IndentingPrintWriter ipw = asIndenting(pw);
        ipw.increaseIndent();
        ipw.println("gestureExclusionRect:" + calculateGestureExclusionRect());
        ipw.println("applyQSClippingImmediately: top(" + mQsClipTop + ") bottom(" + mQsClipBottom
                + ")");
        ipw.println("qsVisible:" + mQsVisible);
        new DumpsysTableLogger(
                TAG,
                NPVCDownEventState.TABLE_HEADERS,
                mLastDownEvents.toList()
        ).printTableData(ipw);
        ipw.decreaseIndent();
        if (mKeyguardStatusBarViewController != null) {
            mKeyguardStatusBarViewController.dump(pw, args);
        }
@@ -4025,6 +4060,7 @@ public class NotificationPanelViewController extends PanelViewController {
                }

                if (!isFullyCollapsed() && onQsIntercept(event)) {
                    if (DEBUG) Log.d(TAG, "onQsIntercept true");
                    return true;
                }
                return super.onInterceptTouchEvent(event);
@@ -4095,6 +4131,7 @@ public class NotificationPanelViewController extends PanelViewController {
                handled |= mHeadsUpTouchHelper.onTouchEvent(event);

                if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) {
                    if (DEBUG) Log.d(TAG, "handleQsTouch true");
                    return true;
                }
                if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) {
+7 −4
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.SystemClock;
import android.os.VibrationEffect;
import android.util.Log;
import android.util.MathUtils;
@@ -63,6 +62,7 @@ import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.animation.FlingAnimationUtils;

import java.io.PrintWriter;
@@ -194,6 +194,7 @@ public abstract class PanelViewController {
    private final PanelExpansionStateManager mPanelExpansionStateManager;
    private final TouchHandler mTouchHandler;
    private final InteractionJankMonitor mInteractionJankMonitor;
    protected final SystemClock mSystemClock;

    protected abstract void onExpandingFinished();

@@ -237,7 +238,8 @@ public abstract class PanelViewController {
            PanelExpansionStateManager panelExpansionStateManager,
            AmbientState ambientState,
            InteractionJankMonitor interactionJankMonitor,
            KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
            KeyguardUnlockAnimationController keyguardUnlockAnimationController,
            SystemClock systemClock) {
        mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
        keyguardStateController.addCallback(new KeyguardStateController.Callback() {
            @Override
@@ -297,6 +299,7 @@ public abstract class PanelViewController {
        mVibrateOnOpening = mResources.getBoolean(R.bool.config_vibrateOnIconAnimation);
        mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
        mInteractionJankMonitor = interactionJankMonitor;
        mSystemClock = systemClock;
    }

    protected void loadDimens() {
@@ -1228,7 +1231,7 @@ public abstract class PanelViewController {
                    mCentralSurfaces.userActivity();
                    mAnimatingOnDown = mHeightAnimator != null && !mIsSpringBackAnimation;
                    mMinExpandHeight = 0.0f;
                    mDownTime = SystemClock.uptimeMillis();
                    mDownTime = mSystemClock.uptimeMillis();
                    if (mAnimatingOnDown && mClosing && !mHintAnimationRunning) {
                        cancelHeightAnimator();
                        mTouchSlopExceeded = true;
@@ -1341,7 +1344,7 @@ public abstract class PanelViewController {
                    mHasLayoutedSinceDown = false;
                    mUpdateFlingOnLayout = false;
                    mMotionAborted = false;
                    mDownTime = SystemClock.uptimeMillis();
                    mDownTime = mSystemClock.uptimeMillis();
                    mTouchAboveFalsingThreshold = false;
                    mCollapsedAndHeadsUpOnDown =
                            isFullyCollapsed() && mHeadsUpManager.hasPinnedHeadsUp();
+5 −1
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ import com.android.systemui.unfold.SysUIUnfoldComponent;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.time.SystemClock;
import com.android.systemui.wallet.controller.QuickAccessWalletController;
import com.android.wm.shell.animation.FlingAnimationUtils;

@@ -357,10 +358,12 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
    private Handler mMainHandler;
    private final PanelExpansionStateManager mPanelExpansionStateManager =
            new PanelExpansionStateManager();
    private SystemClock mSystemClock;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mSystemClock = new FakeSystemClock();
        mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
                mInteractionJankMonitor);

@@ -533,7 +536,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
                mPanelEventsEmitter,
                mNotificationStackSizeCalculator,
                mUnlockedScreenOffAnimationController,
                mShadeTransitionController);
                mShadeTransitionController,
                mSystemClock);
        mNotificationPanelViewController.initDependencies(
                mCentralSurfaces,
                () -> {},