Merge "Group window relayout requests"

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

View File

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

View File

@@ -19,6 +19,7 @@ package com.android.systemui.statusbar;
import android.graphics.Region;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
@@ -191,6 +192,14 @@ public interface NotificationShadeWindowController extends RemoteInputController
*/
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
* 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.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.QsFrameTranslateController;
@@ -741,6 +742,7 @@ public class NotificationPanelViewController extends PanelViewController {
KeyguardStateController keyguardStateController,
StatusBarStateController statusBarStateController,
StatusBarWindowStateController statusBarWindowStateController,
NotificationShadeWindowController notificationShadeWindowController,
DozeLog dozeLog,
DozeParameters dozeParameters, CommandQueue commandQueue, VibratorHelper vibratorHelper,
LatencyTracker latencyTracker, PowerManager powerManager,
@@ -800,6 +802,7 @@ public class NotificationPanelViewController extends PanelViewController {
dozeLog,
keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController,
notificationShadeWindowController,
vibratorHelper,
statusBarKeyguardViewManager,
latencyTracker,

View File

@@ -111,6 +111,12 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
private final SysuiColorExtractor mColorExtractor;
private final ScreenOffAnimationController mScreenOffAnimationController;
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
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) {
applyKeyguardFlags(state);
applyFocusableFlag(state);
@@ -451,9 +471,8 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
applyHasTopUi(state);
applyNotTouchable(state);
applyStatusBarColorSpaceAgnosticFlag(state);
if (mLp != null && mLp.copyFrom(mLpChanged) != 0) {
mWindowManager.updateViewLayout(mNotificationShadeView, mLp);
}
applyWindowLayoutParams();
if (mHasTopUi != mHasTopUiChanged) {
whitelistIpcs(() -> {
try {
@@ -739,6 +758,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
pw.println(TAG + ":");
pw.println(" mKeyguardMaxRefreshRate=" + mKeyguardMaxRefreshRate);
pw.println(" mKeyguardPreferredRefreshRate=" + mKeyguardPreferredRefreshRate);
pw.println(" mDeferWindowLayoutParams=" + mDeferWindowLayoutParams);
pw.println(mCurrentState);
if (mNotificationShadeView != null && mNotificationShadeView.getViewRootImpl() != null) {
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.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
@@ -180,6 +181,7 @@ public abstract class PanelViewController {
private boolean mExpandLatencyTracking;
private final PanelView mView;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final NotificationShadeWindowController mNotificationShadeWindowController;
protected final Resources mResources;
protected final KeyguardStateController mKeyguardStateController;
protected final SysuiStatusBarStateController mStatusBarStateController;
@@ -222,6 +224,7 @@ public abstract class PanelViewController {
DozeLog dozeLog,
KeyguardStateController keyguardStateController,
SysuiStatusBarStateController statusBarStateController,
NotificationShadeWindowController notificationShadeWindowController,
VibratorHelper vibratorHelper,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
LatencyTracker latencyTracker,
@@ -263,6 +266,7 @@ public abstract class PanelViewController {
mResources = mView.getResources();
mKeyguardStateController = keyguardStateController;
mStatusBarStateController = statusBarStateController;
mNotificationShadeWindowController = notificationShadeWindowController;
mFlingAnimationUtils = flingAnimationUtilsBuilder
.reset()
.setMaxLengthSeconds(0.6f)
@@ -760,34 +764,36 @@ public abstract class PanelViewController {
if (isNaN(h)) {
Log.wtf(TAG, "ExpandedHeight set to NaN");
}
if (mExpandLatencyTracking && h != 0f) {
DejankUtils.postAfterTraversal(
() -> mLatencyTracker.onActionEnd(LatencyTracker.ACTION_EXPAND_PANEL));
mExpandLatencyTracking = false;
}
float maxPanelHeight = getMaxPanelHeight();
if (mHeightAnimator == null) {
if (mTracking) {
float overExpansionPixels = Math.max(0, h - maxPanelHeight);
setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */);
mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
if (mExpandLatencyTracking && h != 0f) {
DejankUtils.postAfterTraversal(
() -> mLatencyTracker.onActionEnd(LatencyTracker.ACTION_EXPAND_PANEL));
mExpandLatencyTracking = false;
}
float maxPanelHeight = getMaxPanelHeight();
if (mHeightAnimator == null) {
if (mTracking) {
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
// interpolator, abort the animation.
if (mExpandedHeight < 1f && mExpandedHeight != 0f && mClosing) {
mExpandedHeight = 0f;
if (mHeightAnimator != null) {
mHeightAnimator.end();
// If we are closing the panel and we are almost there due to a slow decelerating
// interpolator, abort the animation.
if (mExpandedHeight < 1f && mExpandedHeight != 0f && mClosing) {
mExpandedHeight = 0f;
if (mHeightAnimator != null) {
mHeightAnimator.end();
}
}
}
mExpandedFraction = Math.min(1f,
maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
onHeightUpdated(mExpandedHeight);
updatePanelExpansionAndVisibility();
mExpandedFraction = Math.min(1f,
maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
onHeightUpdated(mExpandedHeight);
updatePanelExpansionAndVisibility();
});
}
/**

View File

@@ -3591,26 +3591,28 @@ public class StatusBar extends CoreStartable implements
public void onStartedWakingUp() {
String tag = "StatusBar#onStartedWakingUp";
DejankUtils.startDetectingBlockingIpcs(tag);
mDeviceInteractive = true;
mWakeUpCoordinator.setWakingUp(true);
if (!mKeyguardBypassController.getBypassEnabled()) {
mHeadsUpManager.releaseAllImmediately();
}
updateVisibleToUser();
updateIsKeyguard();
mDozeServiceHost.stopDozing();
// This is intentionally below the stopDozing call above, since it avoids that we're
// unnecessarily animating the wakeUp transition. Animations should only be enabled
// once we fully woke up.
updateRevealEffect(true /* wakingUp */);
updateNotificationPanelTouchState();
mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
mDeviceInteractive = true;
mWakeUpCoordinator.setWakingUp(true);
if (!mKeyguardBypassController.getBypassEnabled()) {
mHeadsUpManager.releaseAllImmediately();
}
updateVisibleToUser();
updateIsKeyguard();
mDozeServiceHost.stopDozing();
// This is intentionally below the stopDozing call above, since it avoids that we're
// unnecessarily animating the wakeUp transition. Animations should only be enabled
// once we fully woke up.
updateRevealEffect(true /* wakingUp */);
updateNotificationPanelTouchState();
// 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).
if (mScreenOffAnimationController.shouldHideLightRevealScrimOnWakeUp()) {
makeExpandedInvisible();
}
// 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).
if (mScreenOffAnimationController.shouldHideLightRevealScrimOnWakeUp()) {
makeExpandedInvisible();
}
});
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.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
@@ -68,6 +69,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import dagger.Lazy;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
@@ -94,6 +97,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock ScreenOffAnimationController mScreenOffAnimationController;
private @Mock InteractionJankMonitor mInteractionJankMonitor;
private @Mock ScreenOnCoordinator mScreenOnCoordinator;
private @Mock Lazy<NotificationShadeWindowController> mNotificationShadeWindowControllerLazy;
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -197,7 +201,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mScreenOffAnimationController,
() -> mNotificationShadeDepthController,
mScreenOnCoordinator,
mInteractionJankMonitor);
mInteractionJankMonitor,
mNotificationShadeWindowControllerLazy);
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.SHADE;
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;
@@ -38,6 +37,7 @@ import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
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.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.QsFrameTranslateController;
@@ -365,6 +366,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
private StatusBarWindowStateController mStatusBarWindowStateController;
@Mock
private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@Mock
private NotificationShadeWindowController mNotificationShadeWindowController;
private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
@@ -490,7 +493,10 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
.thenReturn(true);
when(mInteractionJankMonitor.end(anyInt()))
.thenReturn(true);
reset(mView);
doAnswer(invocation -> {
((Runnable) invocation.getArgument(0)).run();
return null;
}).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
mMainHandler = new Handler(Looper.getMainLooper());
@@ -505,6 +511,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
mCommunalStateController, mKeyguardStateController,
mStatusBarStateController,
mStatusBarWindowStateController,
mNotificationShadeWindowController,
mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper,
mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor,
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.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
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_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());
}
}