Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8bb7bf3 authored by Hawkwood Glazier's avatar Hawkwood Glazier Committed by Android (Google) Code Review
Browse files

Merge "Smooth discontinuous height changes to KeyguardStatusViewController" into main

parents e3c62a0d dd156197
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -384,6 +384,11 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
        }
    }

    @Nullable
    View getAodNotifIconContainer() {
        return mAodIconContainer;
    }

    @Override
    protected void onViewDetached() {
        mClockRegistry.unregisterClockChangeListener(mClockChangedListener);
@@ -639,6 +644,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
                }
            } else {
                mNotificationIconAreaController.setupAodIcons(nic);
                mAodIconContainer = nic;
            }
        }
    }
+56 −1
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
        Dumpable {
    private static final boolean DEBUG = KeyguardConstants.DEBUG;
    @VisibleForTesting static final String TAG = "KeyguardStatusViewController";
    private static final long STATUS_AREA_HEIGHT_ANIMATION_MILLIS = 133;

    /**
     * Duration to use for the animator when the keyguard status view alignment changes, and a
@@ -104,6 +105,10 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
    private final KeyguardInteractor mKeyguardInteractor;
    private final PowerInteractor mPowerInteractor;
    private final KeyguardTransitionInteractor mKeyguardTransitionInteractor;
    private final DozeParameters mDozeParameters;

    private View mStatusArea = null;
    private ValueAnimator mStatusAreaHeightAnimator = null;

    private Boolean mSplitShadeEnabled = false;
    private Boolean mStatusViewCentered = true;
@@ -123,6 +128,46 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
                }
            };

    private final View.OnLayoutChangeListener mStatusAreaLayoutChangeListener =
            new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View v,
                        int left, int top, int right, int bottom,
                        int oldLeft, int oldTop, int oldRight, int oldBottom
                ) {
                    if (!mDozeParameters.getAlwaysOn()) {
                        return;
                    }

                    int oldHeight = oldBottom - oldTop;
                    int diff = v.getHeight() - oldHeight;
                    if (diff == 0) {
                        return;
                    }

                    int startValue = -1 * diff;
                    long duration = STATUS_AREA_HEIGHT_ANIMATION_MILLIS;
                    if (mStatusAreaHeightAnimator != null
                            && mStatusAreaHeightAnimator.isRunning()) {
                        duration += mStatusAreaHeightAnimator.getDuration()
                                - mStatusAreaHeightAnimator.getCurrentPlayTime();
                        startValue += (int) mStatusAreaHeightAnimator.getAnimatedValue();
                        mStatusAreaHeightAnimator.cancel();
                        mStatusAreaHeightAnimator = null;
                    }

                    mStatusAreaHeightAnimator = ValueAnimator.ofInt(startValue, 0);
                    mStatusAreaHeightAnimator.setDuration(duration);
                    final View nic = mKeyguardClockSwitchController.getAodNotifIconContainer();
                    if (nic != null) {
                        mStatusAreaHeightAnimator.addUpdateListener(anim -> {
                            nic.setTranslationY((int) anim.getAnimatedValue());
                        });
                    }
                    mStatusAreaHeightAnimator.start();
                }
            };

    @Inject
    public KeyguardStatusViewController(
            KeyguardStatusView keyguardStatusView,
@@ -144,6 +189,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
        mKeyguardClockSwitchController = keyguardClockSwitchController;
        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
        mConfigurationController = configurationController;
        mDozeParameters = dozeParameters;
        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
                dozeParameters, screenOffAnimationController, /* animateYPos= */ true,
                logger.getBuffer());
@@ -218,12 +264,15 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV

    @Override
    protected void onViewAttached() {
        mStatusArea = mView.findViewById(R.id.keyguard_status_area);
        mStatusArea.addOnLayoutChangeListener(mStatusAreaLayoutChangeListener);
        mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
        mConfigurationController.addCallback(mConfigurationListener);
    }

    @Override
    protected void onViewDetached() {
        mStatusArea.removeOnLayoutChangeListener(mStatusAreaLayoutChangeListener);
        mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
        mConfigurationController.removeCallback(mConfigurationListener);
    }
@@ -293,9 +342,15 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
    /**
     * Get the height of the keyguard status view without the notification icon area, as that's
     * only visible on AOD.
     *
     * We internally animate height changes to the status area to prevent discontinuities in the
     * doze animation introduced by the height suddenly changing due to smartpace.
     */
    public int getLockscreenHeight() {
        return mView.getHeight() - mKeyguardClockSwitchController.getNotificationIconAreaHeight();
        int heightAnimValue = mStatusAreaHeightAnimator == null ? 0 :
                (int) mStatusAreaHeightAnimator.getAnimatedValue();
        return mView.getHeight() + heightAnimValue
                - mKeyguardClockSwitchController.getNotificationIconAreaHeight();
    }

    /**
+4 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.power.data.repository.FakePowerRepository;
import com.android.systemui.power.domain.interactor.PowerInteractorFactory;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
@@ -70,6 +71,7 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase {

    @Mock protected KeyguardClockSwitch mKeyguardClockSwitch;
    @Mock protected FrameLayout mMediaHostContainer;
    @Mock protected KeyguardStatusAreaView mKeyguardStatusAreaView;

    @Before
    public void setup() {
@@ -109,6 +111,8 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase {
        when(mKeyguardStatusView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
        when(mKeyguardClockSwitchController.getView()).thenReturn(mKeyguardClockSwitch);
        when(mKeyguardTransitionInteractor.getGoneToAodTransition()).thenReturn(emptyFlow());
        when(mKeyguardStatusView.findViewById(R.id.keyguard_status_area))
                .thenReturn(mKeyguardStatusAreaView);
    }

    protected void givenViewAttached() {
+37 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.keyguard;

import static junit.framework.Assert.assertEquals;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -27,6 +29,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.animation.AnimatorTestRule;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -40,6 +43,7 @@ import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -51,6 +55,9 @@ import java.lang.reflect.Field;
@RunWith(AndroidTestingRunner.class)
public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControllerBaseTest {

    @Rule
    public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule();

    @Test
    public void dozeTimeTick_updatesSlice() {
        mController.dozeTimeTick();
@@ -230,4 +237,34 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll
            throw new RuntimeException(e);
        }
    }

    @Test
    public void statusAreaHeightChange_animatesHeightOutputChange() {
        // Init & Capture Layout Listener
        mController.onInit();
        mController.onViewAttached();

        when(mDozeParameters.getAlwaysOn()).thenReturn(true);
        ArgumentCaptor<View.OnLayoutChangeListener> captor =
                ArgumentCaptor.forClass(View.OnLayoutChangeListener.class);
        verify(mKeyguardStatusAreaView).addOnLayoutChangeListener(captor.capture());
        View.OnLayoutChangeListener listener = captor.getValue();

        // Setup and validate initial height
        when(mKeyguardStatusView.getHeight()).thenReturn(200);
        when(mKeyguardClockSwitchController.getNotificationIconAreaHeight()).thenReturn(10);
        assertEquals(190, mController.getLockscreenHeight());

        // Trigger Change and validate value unchanged immediately
        when(mKeyguardStatusAreaView.getHeight()).thenReturn(100);
        when(mKeyguardStatusView.getHeight()).thenReturn(300);      // Include child height
        listener.onLayoutChange(mKeyguardStatusAreaView,
            /* new layout */ 100, 300, 200, 400,
            /* old layout */ 100, 300, 200, 300);
        assertEquals(190, mController.getLockscreenHeight());

        // Complete animation, validate height increased
        mAnimatorTestRule.advanceTimeBy(200);
        assertEquals(290, mController.getLockscreenHeight());
    }
}