Group window relayout requests

Various places in sysui might call into
NotificationShadeWindowController. Some of these calls can lead to
relayoutWindow(), which is quite expensive.

We should group these calls, and execute them in batch.

Test: manual
Test: perfetto trace
Test: atest NotificationPanelViewControllerTest
Test: atest NotificationShadeWindowControllerImplTest
Fixes: 190382751
Bug: 210432290
Change-Id: Ib08f7ba66048eb023ee2d5e9c09461381c390f0d
This commit is contained in:
Lucas Dupin
2022-01-21 11:38:20 -08:00
parent c5900ec571
commit 593266739f
10 changed files with 139 additions and 60 deletions

View File

@@ -113,6 +113,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.DozeParameters;
@@ -318,6 +319,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
// the properties of the keyguard // the properties of the keyguard
private final KeyguardUpdateMonitor mUpdateMonitor; private final KeyguardUpdateMonitor mUpdateMonitor;
private final Lazy<NotificationShadeWindowController> mNotificationShadeWindowControllerLazy;
/** /**
* Last SIM state reported by the telephony system. * Last SIM state reported by the telephony system.
@@ -833,7 +835,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
ScreenOffAnimationController screenOffAnimationController, ScreenOffAnimationController screenOffAnimationController,
Lazy<NotificationShadeDepthController> notificationShadeDepthController, Lazy<NotificationShadeDepthController> notificationShadeDepthController,
ScreenOnCoordinator screenOnCoordinator, ScreenOnCoordinator screenOnCoordinator,
InteractionJankMonitor interactionJankMonitor) { InteractionJankMonitor interactionJankMonitor,
Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy) {
super(context); super(context);
mFalsingCollector = falsingCollector; mFalsingCollector = falsingCollector;
mLockPatternUtils = lockPatternUtils; mLockPatternUtils = lockPatternUtils;
@@ -850,6 +853,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
dumpManager.registerDumpable(getClass().getName(), this); dumpManager.registerDumpable(getClass().getName(), this);
mDeviceConfig = deviceConfig; mDeviceConfig = deviceConfig;
mScreenOnCoordinator = screenOnCoordinator; mScreenOnCoordinator = screenOnCoordinator;
mNotificationShadeWindowControllerLazy = notificationShadeWindowControllerLazy;
mShowHomeOverLockscreen = mDeviceConfig.getBoolean( mShowHomeOverLockscreen = mDeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_SYSTEMUI, DeviceConfig.NAMESPACE_SYSTEMUI,
NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN, NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN,
@@ -1837,10 +1841,14 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
Trace.beginSection( Trace.beginSection(
"KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM"); "KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM");
StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj; StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj;
handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration, mNotificationShadeWindowControllerLazy.get().batchApplyWindowLayoutParams(
params.mApps, params.mWallpapers, params.mNonApps, () -> {
params.mFinishedCallback); handleStartKeyguardExitAnimation(params.startTime,
mFalsingCollector.onSuccessfulUnlock(); params.fadeoutDuration,
params.mApps, params.mWallpapers, params.mNonApps,
params.mFinishedCallback);
mFalsingCollector.onSuccessfulUnlock();
});
Trace.endSection(); Trace.endSection();
break; break;
case CANCEL_KEYGUARD_EXIT_ANIM: case CANCEL_KEYGUARD_EXIT_ANIM:
@@ -2139,10 +2147,12 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
mKeyguardGoingAwayRunnable.run(); mKeyguardGoingAwayRunnable.run();
} else { } else {
// TODO(bc-unlock): Fill parameters // TODO(bc-unlock): Fill parameters
handleStartKeyguardExitAnimation( mNotificationShadeWindowControllerLazy.get().batchApplyWindowLayoutParams(() -> {
SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(), handleStartKeyguardExitAnimation(
mHideAnimation.getDuration(), null /* apps */, null /* wallpapers */, SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
null /* nonApps */, null /* finishedCallback */); mHideAnimation.getDuration(), null /* apps */, null /* wallpapers */,
null /* nonApps */, null /* finishedCallback */);
});
} }
} }
Trace.endSection(); Trace.endSection();

View File

@@ -44,6 +44,7 @@ import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardLiftController; import com.android.systemui.statusbar.phone.KeyguardLiftController;
@@ -98,7 +99,8 @@ public class KeyguardModule {
ScreenOffAnimationController screenOffAnimationController, ScreenOffAnimationController screenOffAnimationController,
Lazy<NotificationShadeDepthController> notificationShadeDepthController, Lazy<NotificationShadeDepthController> notificationShadeDepthController,
ScreenOnCoordinator screenOnCoordinator, ScreenOnCoordinator screenOnCoordinator,
InteractionJankMonitor interactionJankMonitor) { InteractionJankMonitor interactionJankMonitor,
Lazy<NotificationShadeWindowController> notificationShadeWindowController) {
return new KeyguardViewMediator( return new KeyguardViewMediator(
context, context,
falsingCollector, falsingCollector,
@@ -122,7 +124,8 @@ public class KeyguardModule {
screenOffAnimationController, screenOffAnimationController,
notificationShadeDepthController, notificationShadeDepthController,
screenOnCoordinator, screenOnCoordinator,
interactionJankMonitor interactionJankMonitor,
notificationShadeWindowController
); );
} }

View File

@@ -19,6 +19,7 @@ package com.android.systemui.statusbar;
import android.graphics.Region; import android.graphics.Region;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.android.systemui.statusbar.phone.StatusBarWindowCallback; import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
@@ -191,6 +192,14 @@ public interface NotificationShadeWindowController extends RemoteInputController
*/ */
default void setLightRevealScrimOpaque(boolean opaque) {} default void setLightRevealScrimOpaque(boolean opaque) {}
/**
* Defer any application of window {@link WindowManager.LayoutParams} until {@code scope} is
* fully applied.
*/
default void batchApplyWindowLayoutParams(@NonNull Runnable scope) {
scope.run();
}
/** /**
* Custom listener to pipe data back to plugins about whether or not the status bar would be * Custom listener to pipe data back to plugins about whether or not the status bar would be
* collapsed if not for the plugin. * collapsed if not for the plugin.

View File

@@ -162,6 +162,7 @@ import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.NotificationShelfController; import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.QsFrameTranslateController; import com.android.systemui.statusbar.QsFrameTranslateController;
@@ -741,6 +742,7 @@ public class NotificationPanelViewController extends PanelViewController {
KeyguardStateController keyguardStateController, KeyguardStateController keyguardStateController,
StatusBarStateController statusBarStateController, StatusBarStateController statusBarStateController,
StatusBarWindowStateController statusBarWindowStateController, StatusBarWindowStateController statusBarWindowStateController,
NotificationShadeWindowController notificationShadeWindowController,
DozeLog dozeLog, DozeLog dozeLog,
DozeParameters dozeParameters, CommandQueue commandQueue, VibratorHelper vibratorHelper, DozeParameters dozeParameters, CommandQueue commandQueue, VibratorHelper vibratorHelper,
LatencyTracker latencyTracker, PowerManager powerManager, LatencyTracker latencyTracker, PowerManager powerManager,
@@ -800,6 +802,7 @@ public class NotificationPanelViewController extends PanelViewController {
dozeLog, dozeLog,
keyguardStateController, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, (SysuiStatusBarStateController) statusBarStateController,
notificationShadeWindowController,
vibratorHelper, vibratorHelper,
statusBarKeyguardViewManager, statusBarKeyguardViewManager,
latencyTracker, latencyTracker,

View File

@@ -111,6 +111,12 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
private final SysuiColorExtractor mColorExtractor; private final SysuiColorExtractor mColorExtractor;
private final ScreenOffAnimationController mScreenOffAnimationController; private final ScreenOffAnimationController mScreenOffAnimationController;
private float mFaceAuthDisplayBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE; private float mFaceAuthDisplayBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
/**
* Layout params would be aggregated and dispatched all at once if this is > 0.
*
* @see #batchApplyWindowLayoutParams(Runnable)
*/
private int mDeferWindowLayoutParams;
@Inject @Inject
public NotificationShadeWindowControllerImpl(Context context, WindowManager windowManager, public NotificationShadeWindowControllerImpl(Context context, WindowManager windowManager,
@@ -437,6 +443,20 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
} }
} }
private void applyWindowLayoutParams() {
if (mDeferWindowLayoutParams == 0 && mLp != null && mLp.copyFrom(mLpChanged) != 0) {
mWindowManager.updateViewLayout(mNotificationShadeView, mLp);
}
}
@Override
public void batchApplyWindowLayoutParams(Runnable scope) {
mDeferWindowLayoutParams++;
scope.run();
mDeferWindowLayoutParams--;
applyWindowLayoutParams();
}
private void apply(State state) { private void apply(State state) {
applyKeyguardFlags(state); applyKeyguardFlags(state);
applyFocusableFlag(state); applyFocusableFlag(state);
@@ -451,9 +471,8 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
applyHasTopUi(state); applyHasTopUi(state);
applyNotTouchable(state); applyNotTouchable(state);
applyStatusBarColorSpaceAgnosticFlag(state); applyStatusBarColorSpaceAgnosticFlag(state);
if (mLp != null && mLp.copyFrom(mLpChanged) != 0) { applyWindowLayoutParams();
mWindowManager.updateViewLayout(mNotificationShadeView, mLp);
}
if (mHasTopUi != mHasTopUiChanged) { if (mHasTopUi != mHasTopUiChanged) {
whitelistIpcs(() -> { whitelistIpcs(() -> {
try { try {
@@ -739,6 +758,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
pw.println(TAG + ":"); pw.println(TAG + ":");
pw.println(" mKeyguardMaxRefreshRate=" + mKeyguardMaxRefreshRate); pw.println(" mKeyguardMaxRefreshRate=" + mKeyguardMaxRefreshRate);
pw.println(" mKeyguardPreferredRefreshRate=" + mKeyguardPreferredRefreshRate); pw.println(" mKeyguardPreferredRefreshRate=" + mKeyguardPreferredRefreshRate);
pw.println(" mDeferWindowLayoutParams=" + mDeferWindowLayoutParams);
pw.println(mCurrentState); pw.println(mCurrentState);
if (mNotificationShadeView != null && mNotificationShadeView.getViewRootImpl() != null) { if (mNotificationShadeView != null && mNotificationShadeView.getViewRootImpl() != null) {
mNotificationShadeView.getViewRootImpl().dump(" ", pw); mNotificationShadeView.getViewRootImpl().dump(" ", pw);

View File

@@ -57,6 +57,7 @@ import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags; import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.VibratorHelper;
@@ -180,6 +181,7 @@ public abstract class PanelViewController {
private boolean mExpandLatencyTracking; private boolean mExpandLatencyTracking;
private final PanelView mView; private final PanelView mView;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final NotificationShadeWindowController mNotificationShadeWindowController;
protected final Resources mResources; protected final Resources mResources;
protected final KeyguardStateController mKeyguardStateController; protected final KeyguardStateController mKeyguardStateController;
protected final SysuiStatusBarStateController mStatusBarStateController; protected final SysuiStatusBarStateController mStatusBarStateController;
@@ -222,6 +224,7 @@ public abstract class PanelViewController {
DozeLog dozeLog, DozeLog dozeLog,
KeyguardStateController keyguardStateController, KeyguardStateController keyguardStateController,
SysuiStatusBarStateController statusBarStateController, SysuiStatusBarStateController statusBarStateController,
NotificationShadeWindowController notificationShadeWindowController,
VibratorHelper vibratorHelper, VibratorHelper vibratorHelper,
StatusBarKeyguardViewManager statusBarKeyguardViewManager, StatusBarKeyguardViewManager statusBarKeyguardViewManager,
LatencyTracker latencyTracker, LatencyTracker latencyTracker,
@@ -263,6 +266,7 @@ public abstract class PanelViewController {
mResources = mView.getResources(); mResources = mView.getResources();
mKeyguardStateController = keyguardStateController; mKeyguardStateController = keyguardStateController;
mStatusBarStateController = statusBarStateController; mStatusBarStateController = statusBarStateController;
mNotificationShadeWindowController = notificationShadeWindowController;
mFlingAnimationUtils = flingAnimationUtilsBuilder mFlingAnimationUtils = flingAnimationUtilsBuilder
.reset() .reset()
.setMaxLengthSeconds(0.6f) .setMaxLengthSeconds(0.6f)
@@ -760,34 +764,36 @@ public abstract class PanelViewController {
if (isNaN(h)) { if (isNaN(h)) {
Log.wtf(TAG, "ExpandedHeight set to NaN"); Log.wtf(TAG, "ExpandedHeight set to NaN");
} }
if (mExpandLatencyTracking && h != 0f) { mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
DejankUtils.postAfterTraversal( if (mExpandLatencyTracking && h != 0f) {
() -> mLatencyTracker.onActionEnd(LatencyTracker.ACTION_EXPAND_PANEL)); DejankUtils.postAfterTraversal(
mExpandLatencyTracking = false; () -> mLatencyTracker.onActionEnd(LatencyTracker.ACTION_EXPAND_PANEL));
} mExpandLatencyTracking = false;
float maxPanelHeight = getMaxPanelHeight(); }
if (mHeightAnimator == null) { float maxPanelHeight = getMaxPanelHeight();
if (mTracking) { if (mHeightAnimator == null) {
float overExpansionPixels = Math.max(0, h - maxPanelHeight); if (mTracking) {
setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */); float overExpansionPixels = Math.max(0, h - maxPanelHeight);
setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */);
}
mExpandedHeight = Math.min(h, maxPanelHeight);
} else {
mExpandedHeight = h;
} }
mExpandedHeight = Math.min(h, maxPanelHeight);
} else {
mExpandedHeight = h;
}
// If we are closing the panel and we are almost there due to a slow decelerating // If we are closing the panel and we are almost there due to a slow decelerating
// interpolator, abort the animation. // interpolator, abort the animation.
if (mExpandedHeight < 1f && mExpandedHeight != 0f && mClosing) { if (mExpandedHeight < 1f && mExpandedHeight != 0f && mClosing) {
mExpandedHeight = 0f; mExpandedHeight = 0f;
if (mHeightAnimator != null) { if (mHeightAnimator != null) {
mHeightAnimator.end(); mHeightAnimator.end();
}
} }
} mExpandedFraction = Math.min(1f,
mExpandedFraction = Math.min(1f, maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight); onHeightUpdated(mExpandedHeight);
onHeightUpdated(mExpandedHeight); updatePanelExpansionAndVisibility();
updatePanelExpansionAndVisibility(); });
} }
/** /**

View File

@@ -3597,26 +3597,28 @@ public class StatusBar extends CoreStartable implements
public void onStartedWakingUp() { public void onStartedWakingUp() {
String tag = "StatusBar#onStartedWakingUp"; String tag = "StatusBar#onStartedWakingUp";
DejankUtils.startDetectingBlockingIpcs(tag); DejankUtils.startDetectingBlockingIpcs(tag);
mDeviceInteractive = true; mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
mWakeUpCoordinator.setWakingUp(true); mDeviceInteractive = true;
if (!mKeyguardBypassController.getBypassEnabled()) { mWakeUpCoordinator.setWakingUp(true);
mHeadsUpManager.releaseAllImmediately(); if (!mKeyguardBypassController.getBypassEnabled()) {
} mHeadsUpManager.releaseAllImmediately();
updateVisibleToUser(); }
updateIsKeyguard(); updateVisibleToUser();
mDozeServiceHost.stopDozing(); updateIsKeyguard();
// This is intentionally below the stopDozing call above, since it avoids that we're mDozeServiceHost.stopDozing();
// unnecessarily animating the wakeUp transition. Animations should only be enabled // This is intentionally below the stopDozing call above, since it avoids that we're
// once we fully woke up. // unnecessarily animating the wakeUp transition. Animations should only be enabled
updateRevealEffect(true /* wakingUp */); // once we fully woke up.
updateNotificationPanelTouchState(); updateRevealEffect(true /* wakingUp */);
updateNotificationPanelTouchState();
// If we are waking up during the screen off animation, we should undo making the // If we are waking up during the screen off animation, we should undo making the
// expanded visible (we did that so the LightRevealScrim would be visible). // expanded visible (we did that so the LightRevealScrim would be visible).
if (mScreenOffAnimationController.shouldHideLightRevealScrimOnWakeUp()) { if (mScreenOffAnimationController.shouldHideLightRevealScrimOnWakeUp()) {
makeExpandedInvisible(); makeExpandedInvisible();
} }
});
DejankUtils.stopDetectingBlockingIpcs(tag); DejankUtils.stopDetectingBlockingIpcs(tag);
} }

View File

@@ -51,6 +51,7 @@ import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpManager;
import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController; import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
@@ -68,6 +69,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import dagger.Lazy;
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper @TestableLooper.RunWithLooper
@SmallTest @SmallTest
@@ -94,6 +97,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock ScreenOffAnimationController mScreenOffAnimationController; private @Mock ScreenOffAnimationController mScreenOffAnimationController;
private @Mock InteractionJankMonitor mInteractionJankMonitor; private @Mock InteractionJankMonitor mInteractionJankMonitor;
private @Mock ScreenOnCoordinator mScreenOnCoordinator; private @Mock ScreenOnCoordinator mScreenOnCoordinator;
private @Mock Lazy<NotificationShadeWindowController> mNotificationShadeWindowControllerLazy;
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake(); private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -197,7 +201,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mScreenOffAnimationController, mScreenOffAnimationController,
() -> mNotificationShadeDepthController, () -> mNotificationShadeDepthController,
mScreenOnCoordinator, mScreenOnCoordinator,
mInteractionJankMonitor); mInteractionJankMonitor,
mNotificationShadeWindowControllerLazy);
mViewMediator.start(); mViewMediator.start();
} }
} }

View File

@@ -23,7 +23,6 @@ import static com.android.keyguard.KeyguardClockSwitch.SMALL;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.StatusBarState.SHADE; import static com.android.systemui.statusbar.StatusBarState.SHADE;
import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED; import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
import static com.android.systemui.statusbar.notification.ViewGroupFadeHelper.reset;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
@@ -38,6 +37,7 @@ import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -120,6 +120,7 @@ import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.NotificationShelfController; import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.QsFrameTranslateController; import com.android.systemui.statusbar.QsFrameTranslateController;
@@ -365,6 +366,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
private StatusBarWindowStateController mStatusBarWindowStateController; private StatusBarWindowStateController mStatusBarWindowStateController;
@Mock @Mock
private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@Mock
private NotificationShadeWindowController mNotificationShadeWindowController;
private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty(); private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
private SysuiStatusBarStateController mStatusBarStateController; private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController; private NotificationPanelViewController mNotificationPanelViewController;
@@ -490,7 +493,10 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
.thenReturn(true); .thenReturn(true);
when(mInteractionJankMonitor.end(anyInt())) when(mInteractionJankMonitor.end(anyInt()))
.thenReturn(true); .thenReturn(true);
reset(mView); doAnswer(invocation -> {
((Runnable) invocation.getArgument(0)).run();
return null;
}).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
mMainHandler = new Handler(Looper.getMainLooper()); mMainHandler = new Handler(Looper.getMainLooper());
@@ -505,6 +511,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
mCommunalStateController, mKeyguardStateController, mCommunalStateController, mKeyguardStateController,
mStatusBarStateController, mStatusBarStateController,
mStatusBarWindowStateController, mStatusBarWindowStateController,
mNotificationShadeWindowController,
mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper, mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper,
mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor, mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor,
mCommunalSourceMonitor, mMetricsLogger, mActivityManager, mConfigurationController, mCommunalSourceMonitor, mMetricsLogger, mActivityManager, mConfigurationController,

View File

@@ -26,6 +26,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset; import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -225,4 +226,17 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
assertThat((mLayoutParameters.getValue().flags & FLAG_NOT_FOCUSABLE) != 0).isTrue(); assertThat((mLayoutParameters.getValue().flags & FLAG_NOT_FOCUSABLE) != 0).isTrue();
assertThat((mLayoutParameters.getValue().flags & FLAG_ALT_FOCUSABLE_IM) == 0).isTrue(); assertThat((mLayoutParameters.getValue().flags & FLAG_ALT_FOCUSABLE_IM) == 0).isTrue();
} }
@Test
public void batchApplyWindowLayoutParams_doesNotDispatchEvents() {
mNotificationShadeWindowController.setForceDozeBrightness(true);
verify(mWindowManager).updateViewLayout(any(), any());
clearInvocations(mWindowManager);
mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
mNotificationShadeWindowController.setForceDozeBrightness(false);
verify(mWindowManager, never()).updateViewLayout(any(), any());
});
verify(mWindowManager).updateViewLayout(any(), any());
}
} }