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
This commit is contained in:
Fabian Kozynski
2022-04-26 14:50:27 -04:00
parent 5ec5a80c8a
commit 8df5acd8a3
4 changed files with 205 additions and 18 deletions

View File

@@ -0,0 +1,143 @@
/*
* 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)

View File

@@ -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()) {

View File

@@ -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();

View File

@@ -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,
() -> {},