diff options
5 files changed, 104 insertions, 3 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 500de2d29d03..93204995c5b0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.notification.stack; +import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING; import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_SILENT; import static com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.ANCHOR_SCROLLING; @@ -73,6 +74,7 @@ import android.widget.ScrollView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.ColorUtils; +import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.KeyguardSliceView; import com.android.settingslib.Utils; @@ -97,7 +99,6 @@ import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.ShadeViewRefactor; import com.android.systemui.statusbar.notification.ShadeViewRefactor.RefactorComponent; import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.logging.NotificationLogger; @@ -260,6 +261,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private boolean mDismissAllInProgress; private boolean mFadeNotificationsOnDismiss; private FooterDismissListener mFooterDismissListener; + private boolean mFlingAfterUpEvent; /** * Was the scroller scrolled to the top when the down motion was observed? @@ -3789,6 +3791,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if ((Math.abs(initialVelocity) > mMinimumVelocity)) { float currentOverScrollTop = getCurrentOverScrollAmount(true); if (currentOverScrollTop == 0.0f || initialVelocity > 0) { + mFlingAfterUpEvent = true; + setFinishScrollingCallback(() -> { + mFlingAfterUpEvent = false; + InteractionJankMonitor.getInstance() + .end(CUJ_NOTIFICATION_SHADE_SCROLL_FLING); + setFinishScrollingCallback(null); + }); fling(-initialVelocity); } else { onOverScrollFling(false, initialVelocity); @@ -3840,6 +3849,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable return true; } + boolean isFlingAfterUpEvent() { + return mFlingAfterUpEvent; + } + @ShadeViewRefactor(RefactorComponent.INPUT) protected boolean isInsideQsContainer(MotionEvent ev) { return ev.getY() < mQsContainer.getBottom(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 703c214ed3ac..68208198da68 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.stack; import static android.service.notification.NotificationStats.DISMISSAL_SHADE; import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; +import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING; import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnEmptySpaceClickListener; @@ -47,6 +48,7 @@ import android.view.WindowInsets; import android.widget.FrameLayout; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; @@ -1556,6 +1558,14 @@ public class NotificationStackScrollLayoutController { if (ev.getActionMasked() == MotionEvent.ACTION_UP) { mView.setCheckForLeaveBehind(true); } + + // When swiping directly on the NSSL, this would only get an onTouchEvent. + // We log any touches other than down, which will be captured by onTouchEvent. + // In the intercept we only start tracing when it's not a down (otherwise that down + // would be duplicated when intercepted). + if (scrollWantsIt && ev.getActionMasked() != MotionEvent.ACTION_DOWN) { + InteractionJankMonitor.getInstance().begin(CUJ_NOTIFICATION_SHADE_SCROLL_FLING); + } return swipeWantsIt || scrollWantsIt || expandWantsIt; } @@ -1611,7 +1621,32 @@ public class NotificationStackScrollLayoutController { if (ev.getActionMasked() == MotionEvent.ACTION_UP) { mView.setCheckForLeaveBehind(true); } + traceJankOnTouchEvent(ev.getActionMasked(), scrollerWantsIt); return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt; } + + private void traceJankOnTouchEvent(int action, boolean scrollerWantsIt) { + // Handle interaction jank monitor cases. + switch (action) { + case MotionEvent.ACTION_DOWN: + if (scrollerWantsIt) { + InteractionJankMonitor.getInstance() + .begin(CUJ_NOTIFICATION_SHADE_SCROLL_FLING); + } + break; + case MotionEvent.ACTION_UP: + if (scrollerWantsIt && !mView.isFlingAfterUpEvent()) { + InteractionJankMonitor.getInstance() + .end(CUJ_NOTIFICATION_SHADE_SCROLL_FLING); + } + break; + case MotionEvent.ACTION_CANCEL: + if (scrollerWantsIt) { + InteractionJankMonitor.getInstance() + .cancel(CUJ_NOTIFICATION_SHADE_SCROLL_FLING); + } + break; + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index cd9cc0775c66..3f636ffe3a2f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -18,6 +18,8 @@ package com.android.systemui.statusbar.phone; import static android.view.View.GONE; +import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE; +import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE; import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters; @@ -62,6 +64,7 @@ import android.widget.FrameLayout; import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; @@ -1139,6 +1142,7 @@ public class NotificationPanelViewController extends PanelViewController { onQsExpansionStarted(); mInitialHeightOnTouch = mQsExpansionHeight; mQsTracking = true; + traceQsJank(true /* startTracing */, false /* wasCancelled */); mNotificationStackScrollLayoutController.cancelLongPress(); } break; @@ -1170,6 +1174,7 @@ public class NotificationPanelViewController extends PanelViewController { && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, h)) { mView.getParent().requestDisallowInterceptTouchEvent(true); mQsTracking = true; + traceQsJank(true /* startTracing */, false /* wasCancelled */); onQsExpansionStarted(); notifyExpandingFinished(); mInitialHeightOnTouch = mQsExpansionHeight; @@ -1202,6 +1207,19 @@ public class NotificationPanelViewController extends PanelViewController { && x < stackScrollerX + mNotificationStackScrollLayoutController.getWidth(); } + private void traceQsJank(boolean startTracing, boolean wasCancelled) { + InteractionJankMonitor monitor = InteractionJankMonitor.getInstance(); + if (startTracing) { + monitor.begin(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE); + } else { + if (wasCancelled) { + monitor.cancel(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE); + } else { + monitor.end(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE); + } + } + } + private void initDownStates(MotionEvent event) { if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { mOnlyAffordanceInThisMotion = false; @@ -1315,9 +1333,9 @@ public class NotificationPanelViewController extends PanelViewController { final int action = event.getActionMasked(); if (action == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f && mBarState != KEYGUARD && !mQsExpanded && mQsExpansionEnabled) { - // Down in the empty area while fully expanded - go to QS. mQsTracking = true; + traceQsJank(true /* startTracing */, false /* wasCancelled */); mConflictingQsExpansionGesture = true; onQsExpansionStarted(); mInitialHeightOnTouch = mQsExpansionHeight; @@ -1405,6 +1423,7 @@ public class NotificationPanelViewController extends PanelViewController { return; } mExpectingSynthesizedDown = true; + InteractionJankMonitor.getInstance().begin(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); onTrackingStarted(); updatePanelExpanded(); } @@ -1474,6 +1493,7 @@ public class NotificationPanelViewController extends PanelViewController { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: mQsTracking = true; + traceQsJank(true /* startTracing */, false /* wasCancelled */); mInitialTouchY = y; mInitialTouchX = x; onQsExpansionStarted(); @@ -1513,6 +1533,9 @@ public class NotificationPanelViewController extends PanelViewController { if (fraction != 0f || y >= mInitialTouchY) { flingQsWithCurrentVelocity(y, event.getActionMasked() == MotionEvent.ACTION_CANCEL); + } else { + traceQsJank(false /* startTracing */, + event.getActionMasked() == MotionEvent.ACTION_CANCEL); } if (mQsVelocityTracker != null) { mQsVelocityTracker.recycle(); @@ -1893,7 +1916,7 @@ public class NotificationPanelViewController extends PanelViewController { * @see #flingSettings(float, int, Runnable, boolean) */ public void flingSettings(float vel, int type) { - flingSettings(vel, type, null, false /* isClick */); + flingSettings(vel, type, null /* onFinishRunnable */, false /* isClick */); } /** @@ -1923,6 +1946,7 @@ public class NotificationPanelViewController extends PanelViewController { if (onFinishRunnable != null) { onFinishRunnable.run(); } + traceQsJank(false /* startTracing */, type != FLING_EXPAND /* wasCancelled */); return; } @@ -1947,12 +1971,18 @@ public class NotificationPanelViewController extends PanelViewController { setQsExpansion((Float) animation.getAnimatedValue()); }); animator.addListener(new AnimatorListenerAdapter() { + private boolean mIsCanceled; @Override public void onAnimationStart(Animator animation) { notifyExpandingStarted(); } @Override + public void onAnimationCancel(Animator animation) { + mIsCanceled = true; + } + + @Override public void onAnimationEnd(Animator animation) { mAnimatingQS = false; notifyExpandingFinished(); @@ -1961,6 +1991,7 @@ public class NotificationPanelViewController extends PanelViewController { if (onFinishRunnable != null) { onFinishRunnable.run(); } + traceQsJank(false /* startTracing */, mIsCanceled /* wasCancelled */); } }); // Let's note that we're animating QS. Moving the animator here will cancel it immediately, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java index bc80a1a5137d..a4fc3a39c706 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java @@ -49,6 +49,7 @@ import android.view.WindowInsets; import android.view.WindowInsetsController; import android.widget.FrameLayout; +import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.view.FloatingActionMode; import com.android.internal.widget.FloatingToolbar; import com.android.systemui.R; @@ -145,6 +146,7 @@ public class NotificationShadeWindowView extends FrameLayout { protected void onAttachedToWindow() { super.onAttachedToWindow(); setWillNotDraw(!DEBUG); + InteractionJankMonitor.getInstance().init(this); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java index 6fa99ba41006..5a01f471d0cd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; +import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE; import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK; import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS; import static com.android.systemui.classifier.Classifier.UNLOCK; @@ -40,6 +41,7 @@ import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.animation.Interpolator; +import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; import com.android.systemui.DejankUtils; @@ -109,6 +111,7 @@ public abstract class PanelViewController { private boolean mMotionAborted; private boolean mUpwardsWhenThresholdReached; private boolean mAnimatingOnDown; + private boolean mHandlingPointerUp; private ValueAnimator mHeightAnimator; private ObjectAnimator mPeekAnimator; @@ -356,6 +359,9 @@ public abstract class PanelViewController { protected void startExpandMotion(float newX, float newY, boolean startTracking, float expandedHeight) { + if (!mHandlingPointerUp) { + InteractionJankMonitor.getInstance().begin(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); + } mInitialOffsetOnTouch = expandedHeight; mInitialTouchY = newY; mInitialTouchX = newX; @@ -571,6 +577,7 @@ public abstract class PanelViewController { target = getMaxPanelHeight() - getClearAllHeightWithPadding(); } if (target == mExpandedHeight || getOverExpansionAmount() > 0f && expand) { + InteractionJankMonitor.getInstance().end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); notifyExpandingFinished(); return; } @@ -622,7 +629,12 @@ public abstract class PanelViewController { } setAnimator(null); if (!mCancelled) { + InteractionJankMonitor.getInstance() + .end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); notifyExpandingFinished(); + } else { + InteractionJankMonitor.getInstance() + .cancel(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); } notifyBarPanelExpansionChanged(); } @@ -1272,7 +1284,9 @@ public abstract class PanelViewController { final float newY = event.getY(newIndex); final float newX = event.getX(newIndex); mTrackingPointer = event.getPointerId(newIndex); + mHandlingPointerUp = true; startExpandMotion(newX, newY, true /* startTracking */, mExpandedHeight); + mHandlingPointerUp = false; } break; case MotionEvent.ACTION_POINTER_DOWN: @@ -1330,6 +1344,12 @@ public abstract class PanelViewController { case MotionEvent.ACTION_CANCEL: addMovement(event); endMotionEvent(event, x, y, false /* forceCancel */); + InteractionJankMonitor monitor = InteractionJankMonitor.getInstance(); + if (event.getActionMasked() == MotionEvent.ACTION_UP) { + monitor.end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); + } else { + monitor.cancel(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); + } break; } return !mGestureWaitForTouchSlop || mTracking; |