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

View File

@@ -23,12 +23,14 @@ import android.graphics.Canvas;
import android.os.Build;
import android.os.Trace;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.widget.GridLayout;
import com.android.systemui.R;
import com.android.systemui.shade.TouchLogger;
import com.android.systemui.statusbar.CrossFadeHelper;
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) {
pw.println("KeyguardStatusView:");
pw.println(" mDarkAmount: " + mDarkAmount);

View File

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

View File

@@ -120,6 +120,14 @@ public class LogModule {
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
@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.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.qs.customize.QSCustomizer;
import com.android.systemui.shade.TouchLogger;
import com.android.systemui.util.LargeScreenUtils;
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
protected void onLayout(boolean changed, int left, int top, int right, int 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.os.Looper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
@@ -38,6 +39,7 @@ import androidx.core.graphics.ColorUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.systemui.shade.TouchLogger;
import com.android.systemui.util.LargeScreenUtils;
import java.util.concurrent.Executor;
@@ -59,6 +61,7 @@ public class ScrimView extends View {
private float mViewAlpha = 1.0f;
private Drawable mDrawable;
private PorterDuffColorFilter mColorFilter;
private String mScrimName;
private int mTintColor;
private boolean mBlendWithMainColor = true;
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.
* @see #enableBottomEdgeConcave(boolean)

View File

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

View File

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

View File

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

View File

@@ -22,6 +22,7 @@ import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowInsets;
@@ -173,6 +174,12 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
super.dispatchDraw(canvas);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return TouchLogger.logDispatchTouch("NotificationsQuickSettingsContainer", ev,
super.dispatchTouchEvent(ev));
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
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.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.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationPresenter;
@@ -72,6 +74,7 @@ public final class ShadeControllerImpl implements ShadeController {
@Inject
public ShadeControllerImpl(
CommandQueue commandQueue,
@ShadeTouchLog LogBuffer touchLog,
KeyguardStateController keyguardStateController,
StatusBarStateController statusBarStateController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
@@ -82,6 +85,7 @@ public final class ShadeControllerImpl implements ShadeController {
Lazy<NotificationGutsManager> gutsManager
) {
mCommandQueue = commandQueue;
TouchLogger.logTouchesTo(touchLog);
mStatusBarStateController = statusBarStateController;
mStatusBarWindowController = statusBarWindowController;
mGutsManager = gutsManager;

View File

@@ -79,19 +79,39 @@ class ShadeLogger @Inject constructor(@ShadeLog private val buffer: LogBuffer) {
fun logMotionEvent(event: MotionEvent, message: String) {
buffer.log(
TAG,
LogLevel.VERBOSE,
{
str1 = message
long1 = event.eventTime
long2 = event.downTime
int1 = event.action
int2 = event.classification
double1 = event.y.toDouble()
},
{
"$str1: eventTime=$long1,downTime=$long2,y=$double1,action=$int1,class=$int2"
}
TAG,
LogLevel.VERBOSE,
{
str1 = message
long1 = event.eventTime
long2 = event.downTime
int1 = event.action
int2 = event.classification
},
{
"$str1: eventTime=$long1,downTime=$long2,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.util.AttributeSet
import android.util.MathUtils.lerp
import android.view.MotionEvent
import android.view.View
import android.view.animation.PathInterpolator
import com.android.app.animation.Interpolators
import com.android.systemui.shade.TouchLogger
import com.android.systemui.statusbar.LightRevealEffect.Companion.getPercentPastThreshold
import com.android.systemui.util.getColorWithAlpha
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
* 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)
}
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
return TouchLogger.logDispatchTouch(TAG, event, super.dispatchTouchEvent(event))
}
private fun setPaintColorFilter() {
gradientPaint.colorFilter =
PorterDuffColorFilter(

View File

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

View File

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

View File

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

View File

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

View File

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