Merge "Add LogBuffer that passively tracks touch handling in the shade" into udc-d1-dev

This commit is contained in:
Treehugger Robot
2023-08-17 20:17:34 +00:00
committed by Android (Google) Code Review
20 changed files with 279 additions and 32 deletions

View File

@@ -100,6 +100,7 @@ import com.android.systemui.Gefingerpoken;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.classifier.FalsingA11yDelegate; import com.android.systemui.classifier.FalsingA11yDelegate;
import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.shade.TouchLogger;
import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.policy.BaseUserSwitcherAdapter; import com.android.systemui.statusbar.policy.BaseUserSwitcherAdapter;
import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -658,6 +659,11 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
return insets.inset(0, 0, 0, inset); return insets.inset(0, 0, 0, inset);
} }
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return TouchLogger.logDispatchTouch(TAG, ev, super.dispatchTouchEvent(ev));
}
@Override @Override
protected void dispatchDraw(Canvas canvas) { protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas); super.dispatchDraw(canvas);

View File

@@ -23,12 +23,14 @@ import android.graphics.Canvas;
import android.os.Build; import android.os.Build;
import android.os.Trace; import android.os.Trace;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewPropertyAnimator; import android.view.ViewPropertyAnimator;
import android.widget.GridLayout; import android.widget.GridLayout;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.shade.TouchLogger;
import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.CrossFadeHelper;
import java.io.PrintWriter; import java.io.PrintWriter;
@@ -110,6 +112,11 @@ public class KeyguardStatusView extends GridLayout {
} }
} }
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return TouchLogger.logDispatchTouch(TAG, ev, super.dispatchTouchEvent(ev));
}
public void dump(PrintWriter pw, String[] args) { public void dump(PrintWriter pw, String[] args) {
pw.println("KeyguardStatusView:"); pw.println("KeyguardStatusView:");
pw.println(" mDarkAmount: " + mDarkAmount); pw.println(" mDarkAmount: " + mDarkAmount);

View File

@@ -22,6 +22,7 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import com.android.systemui.shade.TouchLogger
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.sqrt import kotlin.math.sqrt
import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.DisposableHandle
@@ -83,6 +84,10 @@ class LongPressHandlingView(
interactionHandler.isLongPressHandlingEnabled = isEnabled interactionHandler.isLongPressHandlingEnabled = isEnabled
} }
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
return TouchLogger.logDispatchTouch("long_press", event, super.dispatchTouchEvent(event))
}
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent?): Boolean { override fun onTouchEvent(event: MotionEvent?): Boolean {
return interactionHandler.onTouchEvent(event?.toModel()) return interactionHandler.onTouchEvent(event?.toModel())

View File

@@ -120,6 +120,14 @@ public class LogModule {
return factory.create("ShadeLog", 500, false); return factory.create("ShadeLog", 500, false);
} }
/** Provides a logging buffer for Shade messages. */
@Provides
@SysUISingleton
@ShadeTouchLog
public static LogBuffer provideShadeTouchLogBuffer(LogBufferFactory factory) {
return factory.create("ShadeTouchLog", 500, false);
}
/** Provides a logging buffer for all logs related to managing notification sections. */ /** Provides a logging buffer for all logs related to managing notification sections. */
@Provides @Provides
@SysUISingleton @SysUISingleton

View File

@@ -0,0 +1,33 @@
/*
* 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 tracking touches in various shade child views. */
@Qualifier
@Documented
@Retention(RUNTIME)
public @interface ShadeTouchLog {
}

View File

@@ -23,12 +23,14 @@ import android.graphics.Canvas;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.PointF; import android.graphics.PointF;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import com.android.systemui.Dumpable; import com.android.systemui.Dumpable;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.qs.customize.QSCustomizer; import com.android.systemui.qs.customize.QSCustomizer;
import com.android.systemui.shade.TouchLogger;
import com.android.systemui.util.LargeScreenUtils; import com.android.systemui.util.LargeScreenUtils;
import java.io.PrintWriter; import java.io.PrintWriter;
@@ -128,6 +130,11 @@ public class QSContainerImpl extends FrameLayout implements Dumpable {
} }
} }
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return TouchLogger.logDispatchTouch("QS", ev, super.dispatchTouchEvent(ev));
}
@Override @Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom); super.onLayout(changed, left, top, right, bottom);

View File

@@ -30,6 +30,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Looper; import android.os.Looper;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -38,6 +39,7 @@ import androidx.core.graphics.ColorUtils;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.ColorExtractor;
import com.android.systemui.shade.TouchLogger;
import com.android.systemui.util.LargeScreenUtils; import com.android.systemui.util.LargeScreenUtils;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -59,6 +61,7 @@ public class ScrimView extends View {
private float mViewAlpha = 1.0f; private float mViewAlpha = 1.0f;
private Drawable mDrawable; private Drawable mDrawable;
private PorterDuffColorFilter mColorFilter; private PorterDuffColorFilter mColorFilter;
private String mScrimName;
private int mTintColor; private int mTintColor;
private boolean mBlendWithMainColor = true; private boolean mBlendWithMainColor = true;
private Runnable mChangeRunnable; private Runnable mChangeRunnable;
@@ -336,6 +339,15 @@ public class ScrimView extends View {
} }
} }
public void setScrimName(String scrimName) {
mScrimName = scrimName;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return TouchLogger.logDispatchTouch(mScrimName, ev, super.dispatchTouchEvent(ev));
}
/** /**
* The position of the bottom of the scrim, used for clipping. * The position of the bottom of the scrim, used for clipping.
* @see #enableBottomEdgeConcave(boolean) * @see #enableBottomEdgeConcave(boolean)

View File

@@ -105,6 +105,11 @@ public final class NotificationPanelView extends FrameLayout {
return mTouchHandler.onInterceptTouchEvent(event); return mTouchHandler.onInterceptTouchEvent(event);
} }
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return TouchLogger.logDispatchTouch("NPV", ev, super.dispatchTouchEvent(ev));
}
@Override @Override
public void dispatchConfigurationChanged(Configuration newConfig) { public void dispatchConfigurationChanged(Configuration newConfig) {
super.dispatchConfigurationChanged(newConfig); super.dispatchConfigurationChanged(newConfig);

View File

@@ -192,6 +192,8 @@ public class NotificationShadeWindowView extends FrameLayout {
result = result != null ? result : super.dispatchTouchEvent(ev); result = result != null ? result : super.dispatchTouchEvent(ev);
TouchLogger.logDispatchTouch(TAG, ev, result);
mInteractionEventHandler.dispatchTouchEventComplete(); mInteractionEventHandler.dispatchTouchEventComplete();
return result; return result;

View File

@@ -92,6 +92,7 @@ public class NotificationShadeWindowViewController {
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController; private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
private final LockIconViewController mLockIconViewController; private final LockIconViewController mLockIconViewController;
private final ShadeLogger mShadeLogger;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final StatusBarWindowStateController mStatusBarWindowStateController; private final StatusBarWindowStateController mStatusBarWindowStateController;
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@@ -146,6 +147,7 @@ public class NotificationShadeWindowViewController {
KeyguardUnlockAnimationController keyguardUnlockAnimationController, KeyguardUnlockAnimationController keyguardUnlockAnimationController,
NotificationInsetsController notificationInsetsController, NotificationInsetsController notificationInsetsController,
AmbientState ambientState, AmbientState ambientState,
ShadeLogger shadeLogger,
PulsingGestureListener pulsingGestureListener, PulsingGestureListener pulsingGestureListener,
KeyguardBouncerViewModel keyguardBouncerViewModel, KeyguardBouncerViewModel keyguardBouncerViewModel,
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory, KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory,
@@ -168,6 +170,7 @@ public class NotificationShadeWindowViewController {
mStatusBarWindowStateController = statusBarWindowStateController; mStatusBarWindowStateController = statusBarWindowStateController;
mLockIconViewController = lockIconViewController; mLockIconViewController = lockIconViewController;
mLockIconViewController.init(); mLockIconViewController.init();
mShadeLogger = shadeLogger;
mService = centralSurfaces; mService = centralSurfaces;
mNotificationShadeWindowController = controller; mNotificationShadeWindowController = controller;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController; mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
@@ -214,6 +217,13 @@ public class NotificationShadeWindowViewController {
return mView.findViewById(R.id.keyguard_message_area); return mView.findViewById(R.id.keyguard_message_area);
} }
private Boolean logDownDispatch(MotionEvent ev, String msg, Boolean result) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mShadeLogger.logShadeWindowDispatch(ev, msg, result);
}
return result;
}
/** Inflates the {@link R.layout#status_bar_expanded} layout and sets it up. */ /** Inflates the {@link R.layout#status_bar_expanded} layout and sets it up. */
public void setupExpandedStatusBar() { public void setupExpandedStatusBar() {
mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller); mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller);
@@ -225,8 +235,8 @@ public class NotificationShadeWindowViewController {
@Override @Override
public Boolean handleDispatchTouchEvent(MotionEvent ev) { public Boolean handleDispatchTouchEvent(MotionEvent ev) {
if (mStatusBarViewController == null) { // Fix for b/192490822 if (mStatusBarViewController == null) { // Fix for b/192490822
Log.w(TAG, "Ignoring touch while statusBarView not yet set."); return logDownDispatch(ev,
return false; "Ignoring touch while statusBarView not yet set", false);
} }
boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN; boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP; boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
@@ -238,10 +248,9 @@ public class NotificationShadeWindowViewController {
} }
// Reset manual touch dispatch state here but make sure the UP/CANCEL event still // Reset manual touch dispatch state here but make sure the UP/CANCEL event still
// gets // gets delivered.
// delivered.
if (!isCancel && mService.shouldIgnoreTouch()) { if (!isCancel && mService.shouldIgnoreTouch()) {
return false; return logDownDispatch(ev, "touch ignored by CS", false);
} }
if (isDown) { if (isDown) {
@@ -253,8 +262,11 @@ public class NotificationShadeWindowViewController {
mTouchActive = false; mTouchActive = false;
mDownEvent = null; mDownEvent = null;
} }
if (mTouchCancelled || mExpandAnimationRunning) { if (mTouchCancelled) {
return false; return logDownDispatch(ev, "touch cancelled", false);
}
if (mExpandAnimationRunning) {
return logDownDispatch(ev, "expand animation running", false);
} }
if (mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) { if (mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
@@ -268,13 +280,13 @@ public class NotificationShadeWindowViewController {
} }
if (mIsOcclusionTransitionRunning) { if (mIsOcclusionTransitionRunning) {
return false; return logDownDispatch(ev, "occlusion transition running", false);
} }
mFalsingCollector.onTouchEvent(ev); mFalsingCollector.onTouchEvent(ev);
mPulsingWakeupGestureHandler.onTouchEvent(ev); mPulsingWakeupGestureHandler.onTouchEvent(ev);
if (mStatusBarKeyguardViewManager.dispatchTouchEvent(ev)) { if (mStatusBarKeyguardViewManager.dispatchTouchEvent(ev)) {
return true; return logDownDispatch(ev, "dispatched to Keyguard", true);
} }
if (mBrightnessMirror != null if (mBrightnessMirror != null
&& mBrightnessMirror.getVisibility() == View.VISIBLE) { && mBrightnessMirror.getVisibility() == View.VISIBLE) {
@@ -282,7 +294,7 @@ public class NotificationShadeWindowViewController {
// you can't touch anything other than the brightness slider while the mirror is // you can't touch anything other than the brightness slider while the mirror is
// showing and the rest of the panel is transparent. // showing and the rest of the panel is transparent.
if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
return false; return logDownDispatch(ev, "disallowed new pointer", false);
} }
} }
if (isDown) { if (isDown) {
@@ -314,7 +326,9 @@ public class NotificationShadeWindowViewController {
expandingBelowNotch = true; expandingBelowNotch = true;
} }
if (expandingBelowNotch) { if (expandingBelowNotch) {
return mStatusBarViewController.sendTouchToView(ev); return logDownDispatch(ev,
"expand below notch. sending touch to status bar",
mStatusBarViewController.sendTouchToView(ev));
} }
if (!mIsTrackingBarGesture && isDown if (!mIsTrackingBarGesture && isDown
@@ -324,9 +338,10 @@ public class NotificationShadeWindowViewController {
if (mStatusBarViewController.touchIsWithinView(x, y)) { if (mStatusBarViewController.touchIsWithinView(x, y)) {
if (mStatusBarWindowStateController.windowIsShowing()) { if (mStatusBarWindowStateController.windowIsShowing()) {
mIsTrackingBarGesture = true; mIsTrackingBarGesture = true;
return mStatusBarViewController.sendTouchToView(ev); return logDownDispatch(ev, "sending touch to status bar",
} else { // it's hidden or hiding, don't send to notification shade. mStatusBarViewController.sendTouchToView(ev));
return true; } else {
return logDownDispatch(ev, "hidden or hiding", true);
} }
} }
} else if (mIsTrackingBarGesture) { } else if (mIsTrackingBarGesture) {
@@ -334,10 +349,10 @@ public class NotificationShadeWindowViewController {
if (isUp || isCancel) { if (isUp || isCancel) {
mIsTrackingBarGesture = false; mIsTrackingBarGesture = false;
} }
return sendToStatusBar; return logDownDispatch(ev, "sending bar gesture to status bar",
sendToStatusBar);
} }
return logDownDispatch(ev, "no custom touch dispatch of down event", null);
return null;
} }
@Override @Override
@@ -349,18 +364,26 @@ public class NotificationShadeWindowViewController {
public boolean shouldInterceptTouchEvent(MotionEvent ev) { public boolean shouldInterceptTouchEvent(MotionEvent ev) {
if (mStatusBarStateController.isDozing() && !mService.isPulsing() if (mStatusBarStateController.isDozing() && !mService.isPulsing()
&& !mDockManager.isDocked()) { && !mDockManager.isDocked()) {
// Capture all touch events in always-on. if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mShadeLogger.d("NSWVC: capture all touch events in always-on");
}
return true; return true;
} }
if (mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(ev)) { if (mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(ev)) {
// Don't allow touches to proceed to underlying views if alternate // Don't allow touches to proceed to underlying views if alternate
// bouncer is showing // bouncer is showing
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mShadeLogger.d("NSWVC: alt bouncer showing");
}
return true; return true;
} }
if (mLockIconViewController.onInterceptTouchEvent(ev)) { if (mLockIconViewController.onInterceptTouchEvent(ev)) {
// immediately return true; don't send the touch to the drag down helper // immediately return true; don't send the touch to the drag down helper
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mShadeLogger.d("NSWVC: don't send touch to drag down helper");
}
return true; return true;
} }
@@ -371,7 +394,13 @@ public class NotificationShadeWindowViewController {
&& mDragDownHelper.isDragDownEnabled() && mDragDownHelper.isDragDownEnabled()
&& !mService.isBouncerShowing() && !mService.isBouncerShowing()
&& !mStatusBarStateController.isDozing()) { && !mStatusBarStateController.isDozing()) {
return mDragDownHelper.onInterceptTouchEvent(ev); boolean result = mDragDownHelper.onInterceptTouchEvent(ev);
if (result) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mShadeLogger.d("NSWVC: drag down helper intercepted");
}
}
return result;
} else { } else {
return false; return false;
} }
@@ -486,6 +515,7 @@ public class NotificationShadeWindowViewController {
} }
public void cancelCurrentTouch() { public void cancelCurrentTouch() {
mShadeLogger.d("NSWVC: cancelling current touch");
if (mTouchActive) { if (mTouchActive) {
final long now = mClock.uptimeMillis(); final long now = mClock.uptimeMillis();
final MotionEvent event; final MotionEvent event;

View File

@@ -22,6 +22,7 @@ import android.content.res.Configuration;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.WindowInsets; import android.view.WindowInsets;
@@ -173,6 +174,12 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
super.dispatchDraw(canvas); super.dispatchDraw(canvas);
} }
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return TouchLogger.logDispatchTouch("NotificationsQuickSettingsContainer", ev,
super.dispatchTouchEvent(ev));
}
@Override @Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) { protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
int layoutIndex = mLayoutDrawingOrder.indexOf(child); int layoutIndex = mLayoutDrawingOrder.indexOf(child);

View File

@@ -25,6 +25,8 @@ import android.view.WindowManagerGlobal;
import com.android.systemui.assist.AssistManager; import com.android.systemui.assist.AssistManager;
import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.dagger.ShadeTouchLog;
import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationPresenter;
@@ -72,6 +74,7 @@ public final class ShadeControllerImpl implements ShadeController {
@Inject @Inject
public ShadeControllerImpl( public ShadeControllerImpl(
CommandQueue commandQueue, CommandQueue commandQueue,
@ShadeTouchLog LogBuffer touchLog,
KeyguardStateController keyguardStateController, KeyguardStateController keyguardStateController,
StatusBarStateController statusBarStateController, StatusBarStateController statusBarStateController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager, StatusBarKeyguardViewManager statusBarKeyguardViewManager,
@@ -82,6 +85,7 @@ public final class ShadeControllerImpl implements ShadeController {
Lazy<NotificationGutsManager> gutsManager Lazy<NotificationGutsManager> gutsManager
) { ) {
mCommandQueue = commandQueue; mCommandQueue = commandQueue;
TouchLogger.logTouchesTo(touchLog);
mStatusBarStateController = statusBarStateController; mStatusBarStateController = statusBarStateController;
mStatusBarWindowController = statusBarWindowController; mStatusBarWindowController = statusBarWindowController;
mGutsManager = gutsManager; mGutsManager = gutsManager;

View File

@@ -79,19 +79,39 @@ class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) {
fun logMotionEvent(event: MotionEvent, message: String) { fun logMotionEvent(event: MotionEvent, message: String) {
buffer.log( buffer.log(
TAG, TAG,
LogLevel.VERBOSE, LogLevel.VERBOSE,
{ {
str1 = message str1 = message
long1 = event.eventTime long1 = event.eventTime
long2 = event.downTime long2 = event.downTime
int1 = event.action int1 = event.action
int2 = event.classification int2 = event.classification
double1 = event.y.toDouble() },
}, {
{ "$str1: eventTime=$long1,downTime=$long2,action=$int1,class=$int2"
"$str1: eventTime=$long1,downTime=$long2,y=$double1,action=$int1,class=$int2" }
} )
}
/** Logs motion event dispatch results from NotificationShadeWindowViewController. */
fun logShadeWindowDispatch(event: MotionEvent, message: String, result: Boolean?) {
buffer.log(
TAG,
LogLevel.VERBOSE,
{
str1 = message
long1 = event.eventTime
long2 = event.downTime
},
{
val prefix = when (result) {
true -> "SHADE TOUCH REROUTED"
false -> "SHADE TOUCH BLOCKED"
null -> "SHADE TOUCH DISPATCHED"
}
"$prefix: eventTime=$long1,downTime=$long2, reason=$str1"
}
) )
} }

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2023 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.shade
import android.view.MotionEvent
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel
private const val TAG = "systemui.shade.touch"
/**
* A logger for tracking touch dispatching in the shade view hierarchy. The purpose of this logger
* is to passively observe dispatchTouchEvent calls in order to see which subtrees of the shade are
* handling touches. Additionally, some touches may be passively observed for views near the top of
* the shade hierarchy that cannot intercept touches, i.e. scrims. The usage of static methods for
* logging is sub-optimal in many ways, but it was selected in this case to make usage of this
* non-function diagnostic code as low friction as possible.
*/
class TouchLogger {
companion object {
private var touchLogger: DispatchTouchLogger? = null
@JvmStatic
fun logTouchesTo(buffer: LogBuffer) {
touchLogger = DispatchTouchLogger(buffer)
}
@JvmStatic
fun logDispatchTouch(viewTag: String, ev: MotionEvent, result: Boolean): Boolean {
touchLogger?.logDispatchTouch(viewTag, ev, result)
return result
}
}
}
/** Logs touches. */
private class DispatchTouchLogger(private val buffer: LogBuffer) {
fun logDispatchTouch(viewTag: String, ev: MotionEvent, result: Boolean) {
// NOTE: never log position of touches for security purposes
buffer.log(
TAG,
LogLevel.DEBUG,
{
str1 = viewTag
int1 = ev.action
long1 = ev.downTime
bool1 = result
},
{ "Touch: view=$str1, type=${typeToString(int1)}, downtime=$long1, result=$bool1" }
)
}
private fun typeToString(type: Int): String {
return when (type) {
MotionEvent.ACTION_DOWN -> "DOWN"
MotionEvent.ACTION_UP -> "UP"
MotionEvent.ACTION_MOVE -> "MOVE"
MotionEvent.ACTION_CANCEL -> "CANCEL"
MotionEvent.ACTION_POINTER_DOWN -> "POINTER_DOWN"
MotionEvent.ACTION_POINTER_UP -> "POINTER_UP"
else -> "OTHER"
}
}
}

View File

@@ -14,9 +14,11 @@ import android.graphics.Shader
import android.os.Trace import android.os.Trace
import android.util.AttributeSet import android.util.AttributeSet
import android.util.MathUtils.lerp import android.util.MathUtils.lerp
import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.animation.PathInterpolator import android.view.animation.PathInterpolator
import com.android.app.animation.Interpolators import com.android.app.animation.Interpolators
import com.android.systemui.shade.TouchLogger
import com.android.systemui.statusbar.LightRevealEffect.Companion.getPercentPastThreshold import com.android.systemui.statusbar.LightRevealEffect.Companion.getPercentPastThreshold
import com.android.systemui.util.getColorWithAlpha import com.android.systemui.util.getColorWithAlpha
import com.android.systemui.util.leak.RotationUtils import com.android.systemui.util.leak.RotationUtils
@@ -234,6 +236,8 @@ class PowerButtonReveal(
} }
} }
private const val TAG = "LightRevealScrim"
/** /**
* Scrim view that partially reveals the content underneath it using a [RadialGradient] with a * Scrim view that partially reveals the content underneath it using a [RadialGradient] with a
* transparent center. The center position, size, and stops of the gradient can be manipulated to * transparent center. The center position, size, and stops of the gradient can be manipulated to
@@ -447,6 +451,10 @@ constructor(
canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), gradientPaint) canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), gradientPaint)
} }
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
return TouchLogger.logDispatchTouch(TAG, event, super.dispatchTouchEvent(event))
}
private fun setPaintColorFilter() { private fun setPaintColorFilter() {
gradientPaint.colorFilter = gradientPaint.colorFilter =
PorterDuffColorFilter( PorterDuffColorFilter(

View File

@@ -92,6 +92,7 @@ import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.TouchLogger;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.NotificationShelf;
@@ -3457,6 +3458,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
return super.onTouchEvent(ev); return super.onTouchEvent(ev);
} }
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return TouchLogger.logDispatchTouch(TAG, ev, super.dispatchTouchEvent(ev));
}
void dispatchDownEventToScroller(MotionEvent ev) { void dispatchDownEventToScroller(MotionEvent ev) {
MotionEvent downEvent = MotionEvent.obtain(ev); MotionEvent downEvent = MotionEvent.obtain(ev);
downEvent.setAction(MotionEvent.ACTION_DOWN); downEvent.setAction(MotionEvent.ACTION_DOWN);

View File

@@ -360,6 +360,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mScrimBehind = behindScrim; mScrimBehind = behindScrim;
mScrimInFront = scrimInFront; mScrimInFront = scrimInFront;
updateThemeColors(); updateThemeColors();
mNotificationsScrim.setScrimName(getScrimName(mNotificationsScrim));
mScrimBehind.setScrimName(getScrimName(mScrimBehind));
mScrimInFront.setScrimName(getScrimName(mScrimInFront));
behindScrim.enableBottomEdgeConcave(mClipsQsScrim); behindScrim.enableBottomEdgeConcave(mClipsQsScrim);
mNotificationsScrim.enableRoundedCorners(true); mNotificationsScrim.enableRoundedCorners(true);

View File

@@ -89,6 +89,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
@Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
@Mock private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController @Mock private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
@Mock private lateinit var shadeController: ShadeController @Mock private lateinit var shadeController: ShadeController
@Mock private lateinit var shadeLogger: ShadeLogger
@Mock private lateinit var ambientState: AmbientState @Mock private lateinit var ambientState: AmbientState
@Mock private lateinit var keyguardBouncerViewModel: KeyguardBouncerViewModel @Mock private lateinit var keyguardBouncerViewModel: KeyguardBouncerViewModel
@Mock private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController @Mock private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController
@@ -167,6 +168,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
keyguardUnlockAnimationController, keyguardUnlockAnimationController,
notificationInsetsController, notificationInsetsController,
ambientState, ambientState,
shadeLogger,
pulsingGestureListener, pulsingGestureListener,
keyguardBouncerViewModel, keyguardBouncerViewModel,
keyguardBouncerComponentFactory, keyguardBouncerComponentFactory,

View File

@@ -99,6 +99,7 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
@Mock private lateinit var lockIconViewController: LockIconViewController @Mock private lateinit var lockIconViewController: LockIconViewController
@Mock private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController @Mock private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
@Mock private lateinit var ambientState: AmbientState @Mock private lateinit var ambientState: AmbientState
@Mock private lateinit var shadeLogger: ShadeLogger
@Mock private lateinit var pulsingGestureListener: PulsingGestureListener @Mock private lateinit var pulsingGestureListener: PulsingGestureListener
@Mock private lateinit var keyguardBouncerViewModel: KeyguardBouncerViewModel @Mock private lateinit var keyguardBouncerViewModel: KeyguardBouncerViewModel
@Mock private lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory @Mock private lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
@@ -179,6 +180,7 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
keyguardUnlockAnimationController, keyguardUnlockAnimationController,
notificationInsetsController, notificationInsetsController,
ambientState, ambientState,
shadeLogger,
pulsingGestureListener, pulsingGestureListener,
keyguardBouncerViewModel, keyguardBouncerViewModel,
keyguardBouncerComponentFactory, keyguardBouncerComponentFactory,

View File

@@ -115,6 +115,7 @@ import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel; import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.notetask.NoteTaskController; import com.android.systemui.notetask.NoteTaskController;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
@@ -435,6 +436,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mShadeController = spy(new ShadeControllerImpl( mShadeController = spy(new ShadeControllerImpl(
mCommandQueue, mCommandQueue,
mock(LogBuffer.class),
mKeyguardStateController, mKeyguardStateController,
mStatusBarStateController, mStatusBarStateController,
mStatusBarKeyguardViewManager, mStatusBarKeyguardViewManager,