Loading packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +6 −0 Original line number Diff line number Diff line Loading @@ -384,6 +384,11 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } } @Nullable View getAodNotifIconContainer() { return mAodIconContainer; } @Override protected void onViewDetached() { mClockRegistry.unregisterClockChangeListener(mClockChangedListener); Loading Loading @@ -639,6 +644,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } } else { mNotificationIconAreaController.setupAodIcons(nic); mAodIconContainer = nic; } } } Loading packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +56 −1 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading @@ -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, Loading @@ -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()); Loading Loading @@ -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); } Loading Loading @@ -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(); } /** Loading packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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() { Loading packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java +37 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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()); } } Loading
packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +6 −0 Original line number Diff line number Diff line Loading @@ -384,6 +384,11 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } } @Nullable View getAodNotifIconContainer() { return mAodIconContainer; } @Override protected void onViewDetached() { mClockRegistry.unregisterClockChangeListener(mClockChangedListener); Loading Loading @@ -639,6 +644,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } } else { mNotificationIconAreaController.setupAodIcons(nic); mAodIconContainer = nic; } } } Loading
packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +56 −1 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading @@ -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, Loading @@ -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()); Loading Loading @@ -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); } Loading Loading @@ -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(); } /** Loading
packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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() { Loading
packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java +37 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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()); } }