Merge "Move KeyguardStatusView alignment animation out of NPVC" into udc-dev

This commit is contained in:
Hawkwood Glazier
2023-04-07 19:56:38 +00:00
committed by Android (Google) Code Review
5 changed files with 243 additions and 203 deletions

View File

@@ -16,12 +16,37 @@
package com.android.keyguard;
import static androidx.constraintlayout.widget.ConstraintSet.END;
import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.graphics.Rect;
import android.transition.ChangeBounds;
import android.transition.Transition;
import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.transition.TransitionValues;
import android.util.Slog;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.VisibleForTesting;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.keyguard.KeyguardClockSwitch.ClockSize;
import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.ClockController;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -42,6 +67,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
private static final boolean DEBUG = KeyguardConstants.DEBUG;
private static final String TAG = "KeyguardStatusViewController";
/**
* Duration to use for the animator when the keyguard status view alignment changes, and a
* custom clock animation is in use.
*/
private static final int KEYGUARD_STATUS_VIEW_CUSTOM_CLOCK_MOVE_DURATION = 1000;
private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES =
new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
@@ -50,8 +81,25 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final ConfigurationController mConfigurationController;
private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
private final FeatureFlags mFeatureFlags;
private final InteractionJankMonitor mInteractionJankMonitor;
private final Rect mClipBounds = new Rect();
private Boolean mStatusViewCentered = true;
private final TransitionListenerAdapter mKeyguardStatusAlignmentTransitionListener =
new TransitionListenerAdapter() {
@Override
public void onTransitionCancel(Transition transition) {
mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION);
}
@Override
public void onTransitionEnd(Transition transition) {
mInteractionJankMonitor.end(CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION);
}
};
@Inject
public KeyguardStatusViewController(
KeyguardStatusView keyguardStatusView,
@@ -62,7 +110,9 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
ConfigurationController configurationController,
DozeParameters dozeParameters,
ScreenOffAnimationController screenOffAnimationController,
KeyguardLogger logger) {
KeyguardLogger logger,
FeatureFlags featureFlags,
InteractionJankMonitor interactionJankMonitor) {
super(keyguardStatusView);
mKeyguardSliceViewController = keyguardSliceViewController;
mKeyguardClockSwitchController = keyguardClockSwitchController;
@@ -71,6 +121,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
dozeParameters, screenOffAnimationController, /* animateYPos= */ true,
logger.getBuffer());
mInteractionJankMonitor = interactionJankMonitor;
mFeatureFlags = featureFlags;
}
@Override
@@ -242,9 +294,141 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
}
}
/** Gets the current clock controller. */
@Nullable
public ClockController getClockController() {
return mKeyguardClockSwitchController.getClock();
/**
* Updates the alignment of the KeyguardStatusView and animates the transition if requested.
*/
public void updateAlignment(
ConstraintLayout notifContainerParent,
boolean splitShadeEnabled,
boolean shouldBeCentered,
boolean animate) {
if (mStatusViewCentered == shouldBeCentered) {
return;
}
mStatusViewCentered = shouldBeCentered;
if (notifContainerParent == null) {
return;
}
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(notifContainerParent);
int statusConstraint = shouldBeCentered ? PARENT_ID : R.id.qs_edge_guideline;
constraintSet.connect(R.id.keyguard_status_view, END, statusConstraint, END);
if (!animate) {
constraintSet.applyTo(notifContainerParent);
return;
}
mInteractionJankMonitor.begin(mView, CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION);
ChangeBounds transition = new ChangeBounds();
if (splitShadeEnabled) {
// Excluding media from the transition on split-shade, as it doesn't transition
// horizontally properly.
transition.excludeTarget(R.id.status_view_media_container, true);
}
transition.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
transition.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
ClockController clock = mKeyguardClockSwitchController.getClock();
boolean customClockAnimation = clock != null
&& clock.getConfig().getHasCustomPositionUpdatedAnimation();
if (mFeatureFlags.isEnabled(Flags.STEP_CLOCK_ANIMATION) && customClockAnimation) {
// Find the clock, so we can exclude it from this transition.
FrameLayout clockContainerView = mView.findViewById(R.id.lockscreen_clock_view_large);
// The clock container can sometimes be null. If it is, just fall back to the
// old animation rather than setting up the custom animations.
if (clockContainerView == null || clockContainerView.getChildCount() == 0) {
transition.addListener(mKeyguardStatusAlignmentTransitionListener);
TransitionManager.beginDelayedTransition(notifContainerParent, transition);
} else {
View clockView = clockContainerView.getChildAt(0);
transition.excludeTarget(clockView, /* exclude= */ true);
TransitionSet set = new TransitionSet();
set.addTransition(transition);
SplitShadeTransitionAdapter adapter =
new SplitShadeTransitionAdapter(mKeyguardClockSwitchController);
// Use linear here, so the actual clock can pick its own interpolator.
adapter.setInterpolator(Interpolators.LINEAR);
adapter.setDuration(KEYGUARD_STATUS_VIEW_CUSTOM_CLOCK_MOVE_DURATION);
adapter.addTarget(clockView);
set.addTransition(adapter);
set.addListener(mKeyguardStatusAlignmentTransitionListener);
TransitionManager.beginDelayedTransition(notifContainerParent, set);
}
} else {
transition.addListener(mKeyguardStatusAlignmentTransitionListener);
TransitionManager.beginDelayedTransition(notifContainerParent, transition);
}
constraintSet.applyTo(notifContainerParent);
}
@VisibleForTesting
static class SplitShadeTransitionAdapter extends Transition {
private static final String PROP_BOUNDS = "splitShadeTransitionAdapter:bounds";
private static final String[] TRANSITION_PROPERTIES = { PROP_BOUNDS };
private final KeyguardClockSwitchController mController;
@VisibleForTesting
SplitShadeTransitionAdapter(KeyguardClockSwitchController controller) {
mController = controller;
}
private void captureValues(TransitionValues transitionValues) {
Rect boundsRect = new Rect();
boundsRect.left = transitionValues.view.getLeft();
boundsRect.top = transitionValues.view.getTop();
boundsRect.right = transitionValues.view.getRight();
boundsRect.bottom = transitionValues.view.getBottom();
transitionValues.values.put(PROP_BOUNDS, boundsRect);
}
@Override
public void captureEndValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
@Override
public void captureStartValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
@Nullable
@Override
public Animator createAnimator(ViewGroup sceneRoot, @Nullable TransitionValues startValues,
@Nullable TransitionValues endValues) {
if (startValues == null || endValues == null) {
return null;
}
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
Rect from = (Rect) startValues.values.get(PROP_BOUNDS);
Rect to = (Rect) endValues.values.get(PROP_BOUNDS);
anim.addUpdateListener(animation -> {
ClockController clock = mController.getClock();
if (clock == null) {
return;
}
clock.getAnimations().onPositionUpdated(from, to, animation.getAnimatedFraction());
});
return anim;
}
@Override
public String[] getTransitionProperties() {
return TRANSITION_PROPERTIES;
}
}
}

View File

@@ -22,10 +22,6 @@ import static android.view.MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static androidx.constraintlayout.widget.ConstraintSet.END;
import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION;
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
import static com.android.keyguard.KeyguardClockSwitch.SMALL;
import static com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE;
@@ -73,12 +69,6 @@ import android.os.Trace;
import android.os.UserManager;
import android.os.VibrationEffect;
import android.provider.Settings;
import android.transition.ChangeBounds;
import android.transition.Transition;
import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.transition.TransitionValues;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MathUtils;
@@ -100,8 +90,6 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
@@ -163,8 +151,6 @@ import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ClockAnimations;
import com.android.systemui.plugins.ClockController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.FalsingManager.FalsingTapListener;
import com.android.systemui.plugins.qs.QS;
@@ -300,11 +286,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek";
private static final Rect M_DUMMY_DIRTY_RECT = new Rect(0, 0, 1, 1);
private static final Rect EMPTY_RECT = new Rect();
/**
* Duration to use for the animator when the keyguard status view alignment changes, and a
* custom clock animation is in use.
*/
private static final int KEYGUARD_STATUS_VIEW_CUSTOM_CLOCK_MOVE_DURATION = 1000;
/**
* Whether the Shade should animate to reflect Back gesture progress.
* To minimize latency at runtime, we cache this, else we'd be reading it every time
@@ -552,8 +533,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private final KeyguardMediaController mKeyguardMediaController;
private boolean mStatusViewCentered = true;
private final Optional<KeyguardUnfoldTransition> mKeyguardUnfoldTransition;
private final Optional<NotificationPanelUnfoldAnimationController>
mNotificationPanelUnfoldAnimationController;
@@ -684,18 +663,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
step.getTransitionState() == TransitionState.RUNNING;
};
private final TransitionListenerAdapter mKeyguardStatusAlignmentTransitionListener =
new TransitionListenerAdapter() {
@Override
public void onTransitionCancel(Transition transition) {
mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION);
}
@Override
public void onTransitionEnd(Transition transition) {
mInteractionJankMonitor.end(CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION);
}
};
private final ActivityStarter mActivityStarter;
@Inject
@@ -1323,9 +1290,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
keyguardStatusView = (KeyguardStatusView) mLayoutInflater.inflate(
R.layout.keyguard_status_view, mNotificationContainerParent, false);
mNotificationContainerParent.addView(keyguardStatusView, statusIndex);
// When it's reinflated, this is centered by default. If it shouldn't be, this will update
// below when resources are updated.
mStatusViewCentered = true;
attachSplitShadeMediaPlayerContainer(
keyguardStatusView.findViewById(R.id.status_view_media_container));
@@ -1620,68 +1584,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private void updateKeyguardStatusViewAlignment(boolean animate) {
boolean shouldBeCentered = shouldKeyguardStatusViewBeCentered();
if (mStatusViewCentered != shouldBeCentered) {
mStatusViewCentered = shouldBeCentered;
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(mNotificationContainerParent);
int statusConstraint = shouldBeCentered ? PARENT_ID : R.id.qs_edge_guideline;
constraintSet.connect(R.id.keyguard_status_view, END, statusConstraint, END);
if (animate) {
mInteractionJankMonitor.begin(mView, CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION);
ChangeBounds transition = new ChangeBounds();
if (mSplitShadeEnabled) {
// Excluding media from the transition on split-shade, as it doesn't transition
// horizontally properly.
transition.excludeTarget(R.id.status_view_media_container, true);
}
transition.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
transition.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
ClockController clock = mKeyguardStatusViewController.getClockController();
boolean customClockAnimation = clock != null
&& clock.getConfig().getHasCustomPositionUpdatedAnimation();
if (mFeatureFlags.isEnabled(Flags.STEP_CLOCK_ANIMATION) && customClockAnimation) {
// Find the clock, so we can exclude it from this transition.
FrameLayout clockContainerView =
mView.findViewById(R.id.lockscreen_clock_view_large);
// The clock container can sometimes be null. If it is, just fall back to the
// old animation rather than setting up the custom animations.
if (clockContainerView == null || clockContainerView.getChildCount() == 0) {
transition.addListener(mKeyguardStatusAlignmentTransitionListener);
TransitionManager.beginDelayedTransition(
mNotificationContainerParent, transition);
} else {
View clockView = clockContainerView.getChildAt(0);
transition.excludeTarget(clockView, /* exclude= */ true);
TransitionSet set = new TransitionSet();
set.addTransition(transition);
SplitShadeTransitionAdapter adapter =
new SplitShadeTransitionAdapter(mKeyguardStatusViewController);
// Use linear here, so the actual clock can pick its own interpolator.
adapter.setInterpolator(Interpolators.LINEAR);
adapter.setDuration(KEYGUARD_STATUS_VIEW_CUSTOM_CLOCK_MOVE_DURATION);
adapter.addTarget(clockView);
set.addTransition(adapter);
set.addListener(mKeyguardStatusAlignmentTransitionListener);
TransitionManager.beginDelayedTransition(mNotificationContainerParent, set);
}
} else {
transition.addListener(mKeyguardStatusAlignmentTransitionListener);
TransitionManager.beginDelayedTransition(
mNotificationContainerParent, transition);
}
}
constraintSet.applyTo(mNotificationContainerParent);
}
mKeyguardUnfoldTransition.ifPresent(t -> t.setStatusViewCentered(mStatusViewCentered));
mKeyguardStatusViewController.updateAlignment(
mNotificationContainerParent, mSplitShadeEnabled, shouldBeCentered, animate);
mKeyguardUnfoldTransition.ifPresent(t -> t.setStatusViewCentered(shouldBeCentered));
}
private boolean shouldKeyguardStatusViewBeCentered() {
@@ -3335,7 +3240,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
ipw.print("mIsGestureNavigation="); ipw.println(mIsGestureNavigation);
ipw.print("mOldLayoutDirection="); ipw.println(mOldLayoutDirection);
ipw.print("mMinFraction="); ipw.println(mMinFraction);
ipw.print("mStatusViewCentered="); ipw.println(mStatusViewCentered);
ipw.print("mSplitShadeFullTransitionDistance=");
ipw.println(mSplitShadeFullTransitionDistance);
ipw.print("mSplitShadeScrimTransitionDistance=");
@@ -5130,65 +5034,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
}
static class SplitShadeTransitionAdapter extends Transition {
private static final String PROP_BOUNDS = "splitShadeTransitionAdapter:bounds";
private static final String[] TRANSITION_PROPERTIES = { PROP_BOUNDS };
private final KeyguardStatusViewController mController;
SplitShadeTransitionAdapter(KeyguardStatusViewController controller) {
mController = controller;
}
private void captureValues(TransitionValues transitionValues) {
Rect boundsRect = new Rect();
boundsRect.left = transitionValues.view.getLeft();
boundsRect.top = transitionValues.view.getTop();
boundsRect.right = transitionValues.view.getRight();
boundsRect.bottom = transitionValues.view.getBottom();
transitionValues.values.put(PROP_BOUNDS, boundsRect);
}
@Override
public void captureEndValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
@Override
public void captureStartValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
@Nullable
@Override
public Animator createAnimator(ViewGroup sceneRoot, @Nullable TransitionValues startValues,
@Nullable TransitionValues endValues) {
if (startValues == null || endValues == null) {
return null;
}
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
Rect from = (Rect) startValues.values.get(PROP_BOUNDS);
Rect to = (Rect) endValues.values.get(PROP_BOUNDS);
anim.addUpdateListener(animation -> {
ClockController clock = mController.getClockController();
if (clock == null) {
return;
}
clock.getAnimations().onPositionUpdated(from, to, animation.getAnimatedFraction());
});
return anim;
}
@Override
public String[] getTransitionProperties() {
return TRANSITION_PROPERTIES;
}
}
private final class HeadsUpNotificationViewControllerImpl implements
HeadsUpTouchHelper.HeadsUpNotificationViewController {
@Override

View File

@@ -16,17 +16,15 @@
package com.android.keyguard;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ClockController;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -45,26 +43,21 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidTestingRunner.class)
public class KeyguardStatusViewControllerTest extends SysuiTestCase {
@Mock
private KeyguardStatusView mKeyguardStatusView;
@Mock
private KeyguardSliceViewController mKeyguardSliceViewController;
@Mock
private KeyguardClockSwitchController mKeyguardClockSwitchController;
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
ConfigurationController mConfigurationController;
@Mock
DozeParameters mDozeParameters;
@Mock
ScreenOffAnimationController mScreenOffAnimationController;
@Mock private KeyguardStatusView mKeyguardStatusView;
@Mock private KeyguardSliceViewController mKeyguardSliceViewController;
@Mock private KeyguardClockSwitchController mKeyguardClockSwitchController;
@Mock private KeyguardStateController mKeyguardStateController;
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock private ConfigurationController mConfigurationController;
@Mock private DozeParameters mDozeParameters;
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
@Mock private KeyguardLogger mKeyguardLogger;
@Mock private KeyguardStatusViewController mControllerMock;
@Mock private FeatureFlags mFeatureFlags;
@Mock private InteractionJankMonitor mInteractionJankMonitor;
@Captor
private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
@Mock
KeyguardLogger mKeyguardLogger;
private KeyguardStatusViewController mController;
@@ -81,7 +74,9 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
mConfigurationController,
mDozeParameters,
mScreenOffAnimationController,
mKeyguardLogger);
mKeyguardLogger,
mFeatureFlags,
mInteractionJankMonitor);
}
@Test
@@ -116,12 +111,4 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
configurationListenerArgumentCaptor.getValue().onLocaleListChanged();
verify(mKeyguardClockSwitchController).onLocaleListChanged();
}
@Test
public void getClock_forwardsToClockSwitch() {
ClockController mockClock = mock(ClockController.class);
when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock);
assertEquals(mockClock, mController.getClockController());
}
}

View File

@@ -13,15 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.shade
package com.android.keyguard
import android.animation.Animator
import android.testing.AndroidTestingRunner
import android.transition.TransitionValues
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardStatusViewController
import com.android.keyguard.KeyguardStatusViewController.SplitShadeTransitionAdapter
import com.android.systemui.SysuiTestCase
import com.android.systemui.shade.NotificationPanelViewController.SplitShadeTransitionAdapter
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
@@ -33,14 +32,14 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
class SplitShadeTransitionAdapterTest : SysuiTestCase() {
@Mock private lateinit var keyguardStatusViewController: KeyguardStatusViewController
@Mock private lateinit var KeyguardClockSwitchController: KeyguardClockSwitchController
private lateinit var adapter: SplitShadeTransitionAdapter
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
adapter = SplitShadeTransitionAdapter(keyguardStatusViewController)
adapter = SplitShadeTransitionAdapter(KeyguardClockSwitchController)
}
@Test

View File

@@ -32,6 +32,7 @@ import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -66,6 +67,7 @@ import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardClockSwitch;
import com.android.keyguard.KeyguardClockSwitchController;
import com.android.keyguard.KeyguardSliceViewController;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardStatusViewController;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -74,6 +76,7 @@ import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
@@ -233,7 +236,6 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
@Mock protected KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
@Mock protected KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
@Mock protected KeyguardClockSwitchController mKeyguardClockSwitchController;
@Mock protected KeyguardStatusViewController mKeyguardStatusViewController;
@Mock protected KeyguardStatusBarViewController mKeyguardStatusBarViewController;
@Mock protected NotificationStackScrollLayoutController
mNotificationStackScrollLayoutController;
@@ -293,6 +295,9 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
@Mock protected AlternateBouncerInteractor mAlternateBouncerInteractor;
@Mock protected MotionEvent mDownMotionEvent;
@Mock protected CoroutineDispatcher mMainDispatcher;
@Mock protected KeyguardSliceViewController mKeyguardSliceViewController;
@Mock protected KeyguardLogger mKeyguardLogger;
@Mock protected KeyguardStatusView mKeyguardStatusView;
@Captor
protected ArgumentCaptor<NotificationStackScrollLayout.OnEmptySpaceClickListener>
mEmptySpaceClickListenerCaptor;
@@ -309,6 +314,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
protected List<View.OnAttachStateChangeListener> mOnAttachStateChangeListeners;
protected Handler mMainHandler;
protected View.OnLayoutChangeListener mLayoutChangeListener;
protected KeyguardStatusViewController mKeyguardStatusViewController;
protected final FalsingManagerFake mFalsingManager = new FalsingManagerFake();
protected final Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
@@ -335,6 +341,18 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
keyguardStatusView.setId(R.id.keyguard_status_view);
mKeyguardStatusViewController = spy(new KeyguardStatusViewController(
mKeyguardStatusView,
mKeyguardSliceViewController,
mKeyguardClockSwitchController,
mKeyguardStateController,
mUpdateMonitor,
mConfigurationController,
mDozeParameters,
mScreenOffAnimationController,
mKeyguardLogger,
mFeatureFlags,
mInteractionJankMonitor));
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
when(mHeadsUpCallback.getContext()).thenReturn(mContext);
@@ -366,12 +384,15 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea);
when(mKeyguardBottomArea.animate()).thenReturn(mViewPropertyAnimator);
when(mView.animate()).thenReturn(mViewPropertyAnimator);
when(mKeyguardStatusView.animate()).thenReturn(mViewPropertyAnimator);
when(mViewPropertyAnimator.translationX(anyFloat())).thenReturn(mViewPropertyAnimator);
when(mViewPropertyAnimator.alpha(anyFloat())).thenReturn(mViewPropertyAnimator);
when(mViewPropertyAnimator.setDuration(anyLong())).thenReturn(mViewPropertyAnimator);
when(mViewPropertyAnimator.setStartDelay(anyLong())).thenReturn(mViewPropertyAnimator);
when(mViewPropertyAnimator.setInterpolator(any())).thenReturn(mViewPropertyAnimator);
when(mViewPropertyAnimator.setListener(any())).thenReturn(mViewPropertyAnimator);
when(mViewPropertyAnimator.setUpdateListener(any())).thenReturn(mViewPropertyAnimator);
when(mViewPropertyAnimator.withEndAction(any())).thenReturn(mViewPropertyAnimator);
when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
when(mView.findViewById(R.id.keyguard_status_view))
.thenReturn(mock(KeyguardStatusView.class));
@@ -650,9 +671,13 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
@After
public void tearDown() {
mNotificationPanelViewController.mBottomAreaShadeAlphaAnimator.cancel();
mNotificationPanelViewController.cancelHeightAnimator();
mMainHandler.removeCallbacksAndMessages(null);
if (mNotificationPanelViewController != null) {
mNotificationPanelViewController.mBottomAreaShadeAlphaAnimator.cancel();
mNotificationPanelViewController.cancelHeightAnimator();
}
if (mMainHandler != null) {
mMainHandler.removeCallbacksAndMessages(null);
}
}
protected void setBottomPadding(int stackBottom, int lockIconPadding, int indicationPadding,