Loading packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java +3 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.keyguard.dagger; import com.android.keyguard.KeyguardStatusViewController; import com.android.systemui.statusbar.phone.KeyguardStatusBarView; import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController; import com.android.systemui.statusbar.phone.NotificationPanelViewController; import dagger.BindsInstance; import dagger.Subcomponent; Loading @@ -36,8 +37,8 @@ public interface KeyguardStatusBarViewComponent { interface Factory { KeyguardStatusBarViewComponent build( @BindsInstance KeyguardStatusBarView view, @BindsInstance KeyguardStatusBarViewController.ViewStateProvider viewStateProvider); @BindsInstance NotificationPanelViewController.NotificationPanelViewStateProvider notificationPanelViewStateProvider); } /** Builds a {@link KeyguardStatusViewController}. */ Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java +84 −21 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.res.Resources; import android.hardware.biometrics.BiometricSourceType; import android.util.MathUtils; import android.view.View; import androidx.annotation.NonNull; Loading @@ -40,6 +41,9 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.events.SystemStatusAnimationCallback; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.PropertyAnimator; import com.android.systemui.statusbar.notification.stack.AnimationProperties; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; Loading @@ -57,6 +61,21 @@ import javax.inject.Inject; /** View Controller for {@link com.android.systemui.statusbar.phone.KeyguardStatusBarView}. */ public class KeyguardStatusBarViewController extends ViewController<KeyguardStatusBarView> { private static final AnimationProperties KEYGUARD_HUN_PROPERTIES = new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); private float mKeyguardHeadsUpShowingAmount = 0.0f; private final AnimatableProperty mHeadsUpShowingAmountAnimation = AnimatableProperty.from( "KEYGUARD_HEADS_UP_SHOWING_AMOUNT", (view, aFloat) -> { mKeyguardHeadsUpShowingAmount = aFloat; updateViewState(); }, view -> mKeyguardHeadsUpShowingAmount, R.id.keyguard_hun_animator_tag, R.id.keyguard_hun_animator_end_tag, R.id.keyguard_hun_animator_start_tag); private final CarrierTextController mCarrierTextController; private final ConfigurationController mConfigurationController; private final SystemStatusAnimationScheduler mAnimationScheduler; Loading @@ -65,7 +84,8 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat private final StatusBarIconController mStatusBarIconController; private final StatusBarIconController.TintedIconManager.Factory mTintedIconManagerFactory; private final BatteryMeterViewController mBatteryMeterViewController; private final ViewStateProvider mViewStateProvider; private final NotificationPanelViewController.NotificationPanelViewStateProvider mNotificationPanelViewStateProvider; private final KeyguardStateController mKeyguardStateController; private final KeyguardBypassController mKeyguardBypassController; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; Loading Loading @@ -176,6 +196,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat }; private final List<String> mBlockedIcons; private final int mNotificationsHeaderCollideDistance; private boolean mBatteryListening; private StatusBarIconController.TintedIconManager mTintedIconManager; Loading @@ -193,6 +214,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat private boolean mDelayShowingKeyguardStatusBar; private int mStatusBarState; private boolean mDozing; private boolean mShowingKeyguardHeadsUp; @Inject public KeyguardStatusBarViewController( Loading @@ -205,7 +227,8 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat StatusBarIconController statusBarIconController, StatusBarIconController.TintedIconManager.Factory tintedIconManagerFactory, BatteryMeterViewController batteryMeterViewController, ViewStateProvider viewStateProvider, NotificationPanelViewController.NotificationPanelViewStateProvider notificationPanelViewStateProvider, KeyguardStateController keyguardStateController, KeyguardBypassController bypassController, KeyguardUpdateMonitor keyguardUpdateMonitor, Loading @@ -220,7 +243,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat mStatusBarIconController = statusBarIconController; mTintedIconManagerFactory = tintedIconManagerFactory; mBatteryMeterViewController = batteryMeterViewController; mViewStateProvider = viewStateProvider; mNotificationPanelViewStateProvider = notificationPanelViewStateProvider; mKeyguardStateController = keyguardStateController; mKeyguardBypassController = bypassController; mKeyguardUpdateMonitor = keyguardUpdateMonitor; Loading @@ -245,6 +268,8 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat r.getString(com.android.internal.R.string.status_bar_volume), r.getString(com.android.internal.R.string.status_bar_alarm_clock), r.getString(com.android.internal.R.string.status_bar_call_strength))); mNotificationsHeaderCollideDistance = r.getDimensionPixelSize( R.dimen.header_notifications_collide_distance); } @Override Loading Loading @@ -355,16 +380,20 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat } /** * Updates the {@link KeyguardStatusBarView} state based on what the {@link ViewStateProvider} * and other controllers provide. * Updates the {@link KeyguardStatusBarView} state based on what the * {@link NotificationPanelViewController.NotificationPanelViewStateProvider} and other * controllers provide. */ public void updateViewState() { ViewState newViewState = mViewStateProvider.provideViewState(); if (!isKeyguardShowing()) { return; } float newAlpha = newViewState.mAlpha * mKeyguardStatusBarAnimateAlpha; float alphaQsExpansion = 1 - Math.min( 1, mNotificationPanelViewStateProvider.getQsExpansionFraction() * 2); float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion) * mKeyguardStatusBarAnimateAlpha * (1.0f - mKeyguardHeadsUpShowingAmount); boolean hideForBypass = mFirstBypassAttempt && mKeyguardUpdateMonitor.shouldListenForFace() Loading @@ -383,6 +412,54 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat mView.setVisibility(visibility); } /** * @return the alpha to be used to fade out the contents on Keyguard (status bar, bottom area) * during swiping up. */ private float getKeyguardContentsAlpha() { float alpha; if (isKeyguardShowing()) { // When on Keyguard, we hide the header as soon as we expanded close enough to the // header alpha = mNotificationPanelViewStateProvider.getPanelViewExpandedHeight() / (mView.getHeight() + mNotificationsHeaderCollideDistance); } else { // In SHADE_LOCKED, the top card is already really close to the header. Hide it as // soon as we start translating the stack. alpha = mNotificationPanelViewStateProvider.getPanelViewExpandedHeight() / mView.getHeight(); } alpha = MathUtils.saturate(alpha); alpha = (float) Math.pow(alpha, 0.75); return alpha; } /** * Update {@link KeyguardStatusBarView}'s visibility based on whether keyguard is showing and * whether heads up is visible. */ public void updateForHeadsUp() { updateForHeadsUp(true); } void updateForHeadsUp(boolean animate) { boolean showingKeyguardHeadsUp = isKeyguardShowing() && mNotificationPanelViewStateProvider.shouldHeadsUpBeVisible(); if (mShowingKeyguardHeadsUp != showingKeyguardHeadsUp) { mShowingKeyguardHeadsUp = showingKeyguardHeadsUp; if (isKeyguardShowing()) { PropertyAnimator.setProperty( mView, mHeadsUpShowingAmountAnimation, showingKeyguardHeadsUp ? 1.0f : 0.0f, KEYGUARD_HUN_PROPERTIES, animate); } else { PropertyAnimator.applyImmediately(mView, mHeadsUpShowingAmountAnimation, 0.0f); } } } private boolean isKeyguardShowing() { return mStatusBarState == KEYGUARD; } Loading @@ -394,18 +471,4 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat mView.dump(fd, pw, args); } /** An interface that provides the desired state of {@link KeyguardStatusBarView}. */ public interface ViewStateProvider { /** Provides the state. */ ViewState provideViewState(); } /** A POJO for the desired state of {@link KeyguardStatusBarView}. */ static class ViewState { final float mAlpha; ViewState(float alpha) { this.mAlpha = alpha; } } } packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +41 −81 Original line number Diff line number Diff line Loading @@ -180,7 +180,6 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.Executor; import java.util.function.Consumer; import java.util.function.Function; import javax.inject.Inject; import javax.inject.Provider; Loading Loading @@ -261,17 +260,6 @@ public class NotificationPanelViewController extends PanelViewController { private static final Rect M_DUMMY_DIRTY_RECT = new Rect(0, 0, 1, 1); private static final Rect EMPTY_RECT = new Rect(); private final AnimatableProperty KEYGUARD_HEADS_UP_SHOWING_AMOUNT = AnimatableProperty.from( "KEYGUARD_HEADS_UP_SHOWING_AMOUNT", (notificationPanelView, aFloat) -> setKeyguardHeadsUpShowingAmount(aFloat), (Function<NotificationPanelView, Float>) notificationPanelView -> getKeyguardHeadsUpShowingAmount(), R.id.keyguard_hun_animator_tag, R.id.keyguard_hun_animator_end_tag, R.id.keyguard_hun_animator_start_tag); private static final AnimationProperties KEYGUARD_HUN_PROPERTIES = new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); private final LayoutInflater mLayoutInflater; private final PowerManager mPowerManager; private final AccessibilityManager mAccessibilityManager; Loading Loading @@ -360,7 +348,6 @@ public class NotificationPanelViewController extends PanelViewController { private FlingAnimationUtils mFlingAnimationUtils; private int mStatusBarMinHeight; private int mStatusBarHeaderHeightKeyguard; private int mNotificationsHeaderCollideDistance; private float mOverStretchAmount; private float mDownX; private float mDownY; Loading Loading @@ -494,8 +481,6 @@ public class NotificationPanelViewController extends PanelViewController { private int mDarkIconSize; private int mHeadsUpInset; private boolean mHeadsUpPinnedMode; private float mKeyguardHeadsUpShowingAmount = 0.0f; private boolean mShowingKeyguardHeadsUp; private boolean mAllowExpandForSmallExpansion; private Runnable mExpandAfterLayoutRunnable; Loading Loading @@ -638,17 +623,6 @@ public class NotificationPanelViewController extends PanelViewController { } }; private final KeyguardStatusBarViewController.ViewStateProvider mViewStateProvider = new KeyguardStatusBarViewController.ViewStateProvider() { @Override public KeyguardStatusBarViewController.ViewState provideViewState() { float alphaQsExpansion = 1 - Math.min(1, computeQsExpansionFraction() * 2); float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion) * (1.0f - mKeyguardHeadsUpShowingAmount); return new KeyguardStatusBarViewController.ViewState(newAlpha); } }; @Inject public NotificationPanelViewController(NotificationPanelView view, @Main Resources resources, Loading Loading @@ -839,7 +813,7 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardStatusBarViewController = mKeyguardStatusBarViewComponentFactory.build( mKeyguardStatusBar, mViewStateProvider) mNotificationPanelViewStateProvider) .getKeyguardStatusBarViewController(); mKeyguardStatusBarViewController.init(); Loading Loading @@ -873,7 +847,7 @@ public class NotificationPanelViewController extends PanelViewController { mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() { @Override public void onFullyHiddenChanged(boolean isFullyHidden) { updateKeyguardStatusBarForHeadsUp(); mKeyguardStatusBarViewController.updateForHeadsUp(); } @Override Loading Loading @@ -910,8 +884,6 @@ public class NotificationPanelViewController extends PanelViewController { mStatusBarHeaderHeightKeyguard = mResources.getDimensionPixelSize( R.dimen.status_bar_header_height_keyguard); mQsPeekHeight = mResources.getDimensionPixelSize(R.dimen.qs_peek_height); mNotificationsHeaderCollideDistance = mResources.getDimensionPixelSize( R.dimen.header_notifications_collide_distance); mClockPositionAlgorithm.loadDimens(mResources); mQsFalsingThreshold = mResources.getDimensionPixelSize(R.dimen.qs_falsing_threshold); mPositionMinSideMargin = mResources.getDimensionPixelSize( Loading Loading @@ -2922,30 +2894,6 @@ public class NotificationPanelViewController extends PanelViewController { return Math.min(0, translation); } /** * @return the alpha to be used to fade out the contents on Keyguard (status bar, bottom area) * during swiping up */ private float getKeyguardContentsAlpha() { float alpha; if (mBarState == KEYGUARD) { // When on Keyguard, we hide the header as soon as we expanded close enough to the // header alpha = getExpandedHeight() / (mKeyguardStatusBar.getHeight() + mNotificationsHeaderCollideDistance); } else { // In SHADE_LOCKED, the top card is already really close to the header. Hide it as // soon as we start translating the stack. alpha = getExpandedHeight() / mKeyguardStatusBar.getHeight(); } alpha = MathUtils.saturate(alpha); alpha = (float) Math.pow(alpha, 0.75); return alpha; } private void updateKeyguardBottomAreaAlpha() { // There are two possible panel expansion behaviors: // • User dragging up to unlock: we want to fade out as quick as possible Loading Loading @@ -3241,31 +3189,6 @@ public class NotificationPanelViewController extends PanelViewController { mPanelAlphaEndAction = r; } private void updateKeyguardStatusBarForHeadsUp() { boolean showingKeyguardHeadsUp = mKeyguardShowing && mHeadsUpAppearanceController.shouldBeVisible(); if (mShowingKeyguardHeadsUp != showingKeyguardHeadsUp) { mShowingKeyguardHeadsUp = showingKeyguardHeadsUp; if (mKeyguardShowing) { PropertyAnimator.setProperty(mView, KEYGUARD_HEADS_UP_SHOWING_AMOUNT, showingKeyguardHeadsUp ? 1.0f : 0.0f, KEYGUARD_HUN_PROPERTIES, true /* animate */); } else { PropertyAnimator.applyImmediately(mView, KEYGUARD_HEADS_UP_SHOWING_AMOUNT, 0.0f); } } } private void setKeyguardHeadsUpShowingAmount(float amount) { mKeyguardHeadsUpShowingAmount = amount; mKeyguardStatusBarViewController.updateViewState(); } private float getKeyguardHeadsUpShowingAmount() { return mKeyguardHeadsUpShowingAmount; } public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) { mHeadsUpAnimatingAway = headsUpAnimatingAway; mNotificationStackScrollLayoutController.setHeadsUpAnimatingAway(headsUpAnimatingAway); Loading Loading @@ -4245,7 +4168,7 @@ public class NotificationPanelViewController extends PanelViewController { updateGestureExclusionRect(); mHeadsUpPinnedMode = inPinnedMode; updateHeadsUpVisibility(); updateKeyguardStatusBarForHeadsUp(); mKeyguardStatusBarViewController.updateForHeadsUp(); } @Override Loading Loading @@ -4404,7 +4327,7 @@ public class NotificationPanelViewController extends PanelViewController { } } } updateKeyguardStatusBarForHeadsUp(); mKeyguardStatusBarViewController.updateForHeadsUp(); if (keyguardShowing) { updateDozingVisibilities(false /* animate */); } Loading @@ -4429,6 +4352,43 @@ public class NotificationPanelViewController extends PanelViewController { } } /** * An interface that provides the current state of the notification panel and related views, * which is needed to calculate {@link KeyguardStatusBarView}'s state in * {@link KeyguardStatusBarViewController}. */ public interface NotificationPanelViewStateProvider { /** Returns the expanded height of the panel view. */ float getPanelViewExpandedHeight(); /** Returns the fraction of QS that's expanded. */ float getQsExpansionFraction(); /** * Returns true if heads up should be visible. * * TODO(b/138786270): If HeadsUpAppearanceController was injectable, we could inject it into * {@link KeyguardStatusBarViewController} and remove this method. */ boolean shouldHeadsUpBeVisible(); } private final NotificationPanelViewStateProvider mNotificationPanelViewStateProvider = new NotificationPanelViewStateProvider() { @Override public float getPanelViewExpandedHeight() { return getExpandedHeight(); } @Override public float getQsExpansionFraction() { return computeQsExpansionFraction(); } @Override public boolean shouldHeadsUpBeVisible() { return mHeadsUpAppearanceController.shouldBeVisible(); } }; /** * Reconfigures the shade to show the AOD UI (clock, smartspace, etc). This is called by the * screen off animation controller in order to animate in AOD without "actually" fully switching Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java +92 −6 Original line number Diff line number Diff line Loading @@ -86,15 +86,14 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { @Mock private SysuiStatusBarStateController mStatusBarStateController; private TestNotificationPanelViewStateProvider mNotificationPanelViewStateProvider; private KeyguardStatusBarView mKeyguardStatusBarView; private KeyguardStatusBarViewController mController; private float mAlpha = 0.5f; private final KeyguardStatusBarViewController.ViewStateProvider mViewStateProvider = () -> new KeyguardStatusBarViewController.ViewState(mAlpha); @Before public void setup() throws Exception { mNotificationPanelViewStateProvider = new TestNotificationPanelViewStateProvider(); MockitoAnnotations.initMocks(this); allowTestableLooperAsMainThread(); Loading @@ -114,7 +113,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { mStatusBarIconController, new StatusBarIconController.TintedIconManager.Factory(mFeatureFlags), mBatteryMeterViewController, mViewStateProvider, mNotificationPanelViewStateProvider, mKeyguardStateController, mKeyguardBypassController, mKeyguardUpdateMonitor, Loading Loading @@ -210,7 +209,6 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { @Test public void updateViewState_notKeyguardState_nothingUpdated() { mAlpha = 0.255f; mController.onViewAttached(); updateStateToNotKeyguard(); Loading Loading @@ -264,8 +262,59 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE); } @Test public void updateViewState_panelExpandedHeightZero_viewHidden() { mController.onViewAttached(); updateStateToKeyguard(); mNotificationPanelViewStateProvider.setPanelViewExpandedHeight(0); mController.updateViewState(); assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE); } @Test public void updateViewState_qsExpansionOne_viewHidden() { mController.onViewAttached(); updateStateToKeyguard(); mNotificationPanelViewStateProvider.setQsExpansionFraction(1f); mController.updateViewState(); assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE); } // TODO(b/195442899): Add more tests for #updateViewState once CLs are finalized. @Test public void updateForHeadsUp_headsUpShouldBeVisible_viewHidden() { mController.onViewAttached(); updateStateToKeyguard(); mKeyguardStatusBarView.setVisibility(View.VISIBLE); mNotificationPanelViewStateProvider.setShouldHeadsUpBeVisible(true); mController.updateForHeadsUp(/* animate= */ false); assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE); } @Test public void updateForHeadsUp_headsUpShouldNotBeVisible_viewShown() { mController.onViewAttached(); updateStateToKeyguard(); // Start with the opposite state. mNotificationPanelViewStateProvider.setShouldHeadsUpBeVisible(true); mController.updateForHeadsUp(/* animate= */ false); mNotificationPanelViewStateProvider.setShouldHeadsUpBeVisible(false); mController.updateForHeadsUp(/* animate= */ false); assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE); } private void updateStateToNotKeyguard() { updateStatusBarState(SHADE); } Loading Loading @@ -295,4 +344,41 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { callback.onFinishedGoingToSleep(0); } private static class TestNotificationPanelViewStateProvider implements NotificationPanelViewController.NotificationPanelViewStateProvider { TestNotificationPanelViewStateProvider() {} private float mPanelViewExpandedHeight = 100f; private float mQsExpansionFraction = 0f; private boolean mShouldHeadsUpBeVisible = false; @Override public float getPanelViewExpandedHeight() { return mPanelViewExpandedHeight; } @Override public float getQsExpansionFraction() { return mQsExpansionFraction; } @Override public boolean shouldHeadsUpBeVisible() { return mShouldHeadsUpBeVisible; } public void setPanelViewExpandedHeight(float panelViewExpandedHeight) { this.mPanelViewExpandedHeight = panelViewExpandedHeight; } public void setQsExpansionFraction(float qsExpansionFraction) { this.mQsExpansionFraction = qsExpansionFraction; } public void setShouldHeadsUpBeVisible(boolean shouldHeadsUpBeVisible) { this.mShouldHeadsUpBeVisible = shouldHeadsUpBeVisible; } } } Loading
packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java +3 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.keyguard.dagger; import com.android.keyguard.KeyguardStatusViewController; import com.android.systemui.statusbar.phone.KeyguardStatusBarView; import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController; import com.android.systemui.statusbar.phone.NotificationPanelViewController; import dagger.BindsInstance; import dagger.Subcomponent; Loading @@ -36,8 +37,8 @@ public interface KeyguardStatusBarViewComponent { interface Factory { KeyguardStatusBarViewComponent build( @BindsInstance KeyguardStatusBarView view, @BindsInstance KeyguardStatusBarViewController.ViewStateProvider viewStateProvider); @BindsInstance NotificationPanelViewController.NotificationPanelViewStateProvider notificationPanelViewStateProvider); } /** Builds a {@link KeyguardStatusViewController}. */ Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java +84 −21 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.res.Resources; import android.hardware.biometrics.BiometricSourceType; import android.util.MathUtils; import android.view.View; import androidx.annotation.NonNull; Loading @@ -40,6 +41,9 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.events.SystemStatusAnimationCallback; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.PropertyAnimator; import com.android.systemui.statusbar.notification.stack.AnimationProperties; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; Loading @@ -57,6 +61,21 @@ import javax.inject.Inject; /** View Controller for {@link com.android.systemui.statusbar.phone.KeyguardStatusBarView}. */ public class KeyguardStatusBarViewController extends ViewController<KeyguardStatusBarView> { private static final AnimationProperties KEYGUARD_HUN_PROPERTIES = new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); private float mKeyguardHeadsUpShowingAmount = 0.0f; private final AnimatableProperty mHeadsUpShowingAmountAnimation = AnimatableProperty.from( "KEYGUARD_HEADS_UP_SHOWING_AMOUNT", (view, aFloat) -> { mKeyguardHeadsUpShowingAmount = aFloat; updateViewState(); }, view -> mKeyguardHeadsUpShowingAmount, R.id.keyguard_hun_animator_tag, R.id.keyguard_hun_animator_end_tag, R.id.keyguard_hun_animator_start_tag); private final CarrierTextController mCarrierTextController; private final ConfigurationController mConfigurationController; private final SystemStatusAnimationScheduler mAnimationScheduler; Loading @@ -65,7 +84,8 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat private final StatusBarIconController mStatusBarIconController; private final StatusBarIconController.TintedIconManager.Factory mTintedIconManagerFactory; private final BatteryMeterViewController mBatteryMeterViewController; private final ViewStateProvider mViewStateProvider; private final NotificationPanelViewController.NotificationPanelViewStateProvider mNotificationPanelViewStateProvider; private final KeyguardStateController mKeyguardStateController; private final KeyguardBypassController mKeyguardBypassController; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; Loading Loading @@ -176,6 +196,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat }; private final List<String> mBlockedIcons; private final int mNotificationsHeaderCollideDistance; private boolean mBatteryListening; private StatusBarIconController.TintedIconManager mTintedIconManager; Loading @@ -193,6 +214,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat private boolean mDelayShowingKeyguardStatusBar; private int mStatusBarState; private boolean mDozing; private boolean mShowingKeyguardHeadsUp; @Inject public KeyguardStatusBarViewController( Loading @@ -205,7 +227,8 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat StatusBarIconController statusBarIconController, StatusBarIconController.TintedIconManager.Factory tintedIconManagerFactory, BatteryMeterViewController batteryMeterViewController, ViewStateProvider viewStateProvider, NotificationPanelViewController.NotificationPanelViewStateProvider notificationPanelViewStateProvider, KeyguardStateController keyguardStateController, KeyguardBypassController bypassController, KeyguardUpdateMonitor keyguardUpdateMonitor, Loading @@ -220,7 +243,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat mStatusBarIconController = statusBarIconController; mTintedIconManagerFactory = tintedIconManagerFactory; mBatteryMeterViewController = batteryMeterViewController; mViewStateProvider = viewStateProvider; mNotificationPanelViewStateProvider = notificationPanelViewStateProvider; mKeyguardStateController = keyguardStateController; mKeyguardBypassController = bypassController; mKeyguardUpdateMonitor = keyguardUpdateMonitor; Loading @@ -245,6 +268,8 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat r.getString(com.android.internal.R.string.status_bar_volume), r.getString(com.android.internal.R.string.status_bar_alarm_clock), r.getString(com.android.internal.R.string.status_bar_call_strength))); mNotificationsHeaderCollideDistance = r.getDimensionPixelSize( R.dimen.header_notifications_collide_distance); } @Override Loading Loading @@ -355,16 +380,20 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat } /** * Updates the {@link KeyguardStatusBarView} state based on what the {@link ViewStateProvider} * and other controllers provide. * Updates the {@link KeyguardStatusBarView} state based on what the * {@link NotificationPanelViewController.NotificationPanelViewStateProvider} and other * controllers provide. */ public void updateViewState() { ViewState newViewState = mViewStateProvider.provideViewState(); if (!isKeyguardShowing()) { return; } float newAlpha = newViewState.mAlpha * mKeyguardStatusBarAnimateAlpha; float alphaQsExpansion = 1 - Math.min( 1, mNotificationPanelViewStateProvider.getQsExpansionFraction() * 2); float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion) * mKeyguardStatusBarAnimateAlpha * (1.0f - mKeyguardHeadsUpShowingAmount); boolean hideForBypass = mFirstBypassAttempt && mKeyguardUpdateMonitor.shouldListenForFace() Loading @@ -383,6 +412,54 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat mView.setVisibility(visibility); } /** * @return the alpha to be used to fade out the contents on Keyguard (status bar, bottom area) * during swiping up. */ private float getKeyguardContentsAlpha() { float alpha; if (isKeyguardShowing()) { // When on Keyguard, we hide the header as soon as we expanded close enough to the // header alpha = mNotificationPanelViewStateProvider.getPanelViewExpandedHeight() / (mView.getHeight() + mNotificationsHeaderCollideDistance); } else { // In SHADE_LOCKED, the top card is already really close to the header. Hide it as // soon as we start translating the stack. alpha = mNotificationPanelViewStateProvider.getPanelViewExpandedHeight() / mView.getHeight(); } alpha = MathUtils.saturate(alpha); alpha = (float) Math.pow(alpha, 0.75); return alpha; } /** * Update {@link KeyguardStatusBarView}'s visibility based on whether keyguard is showing and * whether heads up is visible. */ public void updateForHeadsUp() { updateForHeadsUp(true); } void updateForHeadsUp(boolean animate) { boolean showingKeyguardHeadsUp = isKeyguardShowing() && mNotificationPanelViewStateProvider.shouldHeadsUpBeVisible(); if (mShowingKeyguardHeadsUp != showingKeyguardHeadsUp) { mShowingKeyguardHeadsUp = showingKeyguardHeadsUp; if (isKeyguardShowing()) { PropertyAnimator.setProperty( mView, mHeadsUpShowingAmountAnimation, showingKeyguardHeadsUp ? 1.0f : 0.0f, KEYGUARD_HUN_PROPERTIES, animate); } else { PropertyAnimator.applyImmediately(mView, mHeadsUpShowingAmountAnimation, 0.0f); } } } private boolean isKeyguardShowing() { return mStatusBarState == KEYGUARD; } Loading @@ -394,18 +471,4 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat mView.dump(fd, pw, args); } /** An interface that provides the desired state of {@link KeyguardStatusBarView}. */ public interface ViewStateProvider { /** Provides the state. */ ViewState provideViewState(); } /** A POJO for the desired state of {@link KeyguardStatusBarView}. */ static class ViewState { final float mAlpha; ViewState(float alpha) { this.mAlpha = alpha; } } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +41 −81 Original line number Diff line number Diff line Loading @@ -180,7 +180,6 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.Executor; import java.util.function.Consumer; import java.util.function.Function; import javax.inject.Inject; import javax.inject.Provider; Loading Loading @@ -261,17 +260,6 @@ public class NotificationPanelViewController extends PanelViewController { private static final Rect M_DUMMY_DIRTY_RECT = new Rect(0, 0, 1, 1); private static final Rect EMPTY_RECT = new Rect(); private final AnimatableProperty KEYGUARD_HEADS_UP_SHOWING_AMOUNT = AnimatableProperty.from( "KEYGUARD_HEADS_UP_SHOWING_AMOUNT", (notificationPanelView, aFloat) -> setKeyguardHeadsUpShowingAmount(aFloat), (Function<NotificationPanelView, Float>) notificationPanelView -> getKeyguardHeadsUpShowingAmount(), R.id.keyguard_hun_animator_tag, R.id.keyguard_hun_animator_end_tag, R.id.keyguard_hun_animator_start_tag); private static final AnimationProperties KEYGUARD_HUN_PROPERTIES = new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); private final LayoutInflater mLayoutInflater; private final PowerManager mPowerManager; private final AccessibilityManager mAccessibilityManager; Loading Loading @@ -360,7 +348,6 @@ public class NotificationPanelViewController extends PanelViewController { private FlingAnimationUtils mFlingAnimationUtils; private int mStatusBarMinHeight; private int mStatusBarHeaderHeightKeyguard; private int mNotificationsHeaderCollideDistance; private float mOverStretchAmount; private float mDownX; private float mDownY; Loading Loading @@ -494,8 +481,6 @@ public class NotificationPanelViewController extends PanelViewController { private int mDarkIconSize; private int mHeadsUpInset; private boolean mHeadsUpPinnedMode; private float mKeyguardHeadsUpShowingAmount = 0.0f; private boolean mShowingKeyguardHeadsUp; private boolean mAllowExpandForSmallExpansion; private Runnable mExpandAfterLayoutRunnable; Loading Loading @@ -638,17 +623,6 @@ public class NotificationPanelViewController extends PanelViewController { } }; private final KeyguardStatusBarViewController.ViewStateProvider mViewStateProvider = new KeyguardStatusBarViewController.ViewStateProvider() { @Override public KeyguardStatusBarViewController.ViewState provideViewState() { float alphaQsExpansion = 1 - Math.min(1, computeQsExpansionFraction() * 2); float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion) * (1.0f - mKeyguardHeadsUpShowingAmount); return new KeyguardStatusBarViewController.ViewState(newAlpha); } }; @Inject public NotificationPanelViewController(NotificationPanelView view, @Main Resources resources, Loading Loading @@ -839,7 +813,7 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardStatusBarViewController = mKeyguardStatusBarViewComponentFactory.build( mKeyguardStatusBar, mViewStateProvider) mNotificationPanelViewStateProvider) .getKeyguardStatusBarViewController(); mKeyguardStatusBarViewController.init(); Loading Loading @@ -873,7 +847,7 @@ public class NotificationPanelViewController extends PanelViewController { mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() { @Override public void onFullyHiddenChanged(boolean isFullyHidden) { updateKeyguardStatusBarForHeadsUp(); mKeyguardStatusBarViewController.updateForHeadsUp(); } @Override Loading Loading @@ -910,8 +884,6 @@ public class NotificationPanelViewController extends PanelViewController { mStatusBarHeaderHeightKeyguard = mResources.getDimensionPixelSize( R.dimen.status_bar_header_height_keyguard); mQsPeekHeight = mResources.getDimensionPixelSize(R.dimen.qs_peek_height); mNotificationsHeaderCollideDistance = mResources.getDimensionPixelSize( R.dimen.header_notifications_collide_distance); mClockPositionAlgorithm.loadDimens(mResources); mQsFalsingThreshold = mResources.getDimensionPixelSize(R.dimen.qs_falsing_threshold); mPositionMinSideMargin = mResources.getDimensionPixelSize( Loading Loading @@ -2922,30 +2894,6 @@ public class NotificationPanelViewController extends PanelViewController { return Math.min(0, translation); } /** * @return the alpha to be used to fade out the contents on Keyguard (status bar, bottom area) * during swiping up */ private float getKeyguardContentsAlpha() { float alpha; if (mBarState == KEYGUARD) { // When on Keyguard, we hide the header as soon as we expanded close enough to the // header alpha = getExpandedHeight() / (mKeyguardStatusBar.getHeight() + mNotificationsHeaderCollideDistance); } else { // In SHADE_LOCKED, the top card is already really close to the header. Hide it as // soon as we start translating the stack. alpha = getExpandedHeight() / mKeyguardStatusBar.getHeight(); } alpha = MathUtils.saturate(alpha); alpha = (float) Math.pow(alpha, 0.75); return alpha; } private void updateKeyguardBottomAreaAlpha() { // There are two possible panel expansion behaviors: // • User dragging up to unlock: we want to fade out as quick as possible Loading Loading @@ -3241,31 +3189,6 @@ public class NotificationPanelViewController extends PanelViewController { mPanelAlphaEndAction = r; } private void updateKeyguardStatusBarForHeadsUp() { boolean showingKeyguardHeadsUp = mKeyguardShowing && mHeadsUpAppearanceController.shouldBeVisible(); if (mShowingKeyguardHeadsUp != showingKeyguardHeadsUp) { mShowingKeyguardHeadsUp = showingKeyguardHeadsUp; if (mKeyguardShowing) { PropertyAnimator.setProperty(mView, KEYGUARD_HEADS_UP_SHOWING_AMOUNT, showingKeyguardHeadsUp ? 1.0f : 0.0f, KEYGUARD_HUN_PROPERTIES, true /* animate */); } else { PropertyAnimator.applyImmediately(mView, KEYGUARD_HEADS_UP_SHOWING_AMOUNT, 0.0f); } } } private void setKeyguardHeadsUpShowingAmount(float amount) { mKeyguardHeadsUpShowingAmount = amount; mKeyguardStatusBarViewController.updateViewState(); } private float getKeyguardHeadsUpShowingAmount() { return mKeyguardHeadsUpShowingAmount; } public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) { mHeadsUpAnimatingAway = headsUpAnimatingAway; mNotificationStackScrollLayoutController.setHeadsUpAnimatingAway(headsUpAnimatingAway); Loading Loading @@ -4245,7 +4168,7 @@ public class NotificationPanelViewController extends PanelViewController { updateGestureExclusionRect(); mHeadsUpPinnedMode = inPinnedMode; updateHeadsUpVisibility(); updateKeyguardStatusBarForHeadsUp(); mKeyguardStatusBarViewController.updateForHeadsUp(); } @Override Loading Loading @@ -4404,7 +4327,7 @@ public class NotificationPanelViewController extends PanelViewController { } } } updateKeyguardStatusBarForHeadsUp(); mKeyguardStatusBarViewController.updateForHeadsUp(); if (keyguardShowing) { updateDozingVisibilities(false /* animate */); } Loading @@ -4429,6 +4352,43 @@ public class NotificationPanelViewController extends PanelViewController { } } /** * An interface that provides the current state of the notification panel and related views, * which is needed to calculate {@link KeyguardStatusBarView}'s state in * {@link KeyguardStatusBarViewController}. */ public interface NotificationPanelViewStateProvider { /** Returns the expanded height of the panel view. */ float getPanelViewExpandedHeight(); /** Returns the fraction of QS that's expanded. */ float getQsExpansionFraction(); /** * Returns true if heads up should be visible. * * TODO(b/138786270): If HeadsUpAppearanceController was injectable, we could inject it into * {@link KeyguardStatusBarViewController} and remove this method. */ boolean shouldHeadsUpBeVisible(); } private final NotificationPanelViewStateProvider mNotificationPanelViewStateProvider = new NotificationPanelViewStateProvider() { @Override public float getPanelViewExpandedHeight() { return getExpandedHeight(); } @Override public float getQsExpansionFraction() { return computeQsExpansionFraction(); } @Override public boolean shouldHeadsUpBeVisible() { return mHeadsUpAppearanceController.shouldBeVisible(); } }; /** * Reconfigures the shade to show the AOD UI (clock, smartspace, etc). This is called by the * screen off animation controller in order to animate in AOD without "actually" fully switching Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java +92 −6 Original line number Diff line number Diff line Loading @@ -86,15 +86,14 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { @Mock private SysuiStatusBarStateController mStatusBarStateController; private TestNotificationPanelViewStateProvider mNotificationPanelViewStateProvider; private KeyguardStatusBarView mKeyguardStatusBarView; private KeyguardStatusBarViewController mController; private float mAlpha = 0.5f; private final KeyguardStatusBarViewController.ViewStateProvider mViewStateProvider = () -> new KeyguardStatusBarViewController.ViewState(mAlpha); @Before public void setup() throws Exception { mNotificationPanelViewStateProvider = new TestNotificationPanelViewStateProvider(); MockitoAnnotations.initMocks(this); allowTestableLooperAsMainThread(); Loading @@ -114,7 +113,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { mStatusBarIconController, new StatusBarIconController.TintedIconManager.Factory(mFeatureFlags), mBatteryMeterViewController, mViewStateProvider, mNotificationPanelViewStateProvider, mKeyguardStateController, mKeyguardBypassController, mKeyguardUpdateMonitor, Loading Loading @@ -210,7 +209,6 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { @Test public void updateViewState_notKeyguardState_nothingUpdated() { mAlpha = 0.255f; mController.onViewAttached(); updateStateToNotKeyguard(); Loading Loading @@ -264,8 +262,59 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE); } @Test public void updateViewState_panelExpandedHeightZero_viewHidden() { mController.onViewAttached(); updateStateToKeyguard(); mNotificationPanelViewStateProvider.setPanelViewExpandedHeight(0); mController.updateViewState(); assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE); } @Test public void updateViewState_qsExpansionOne_viewHidden() { mController.onViewAttached(); updateStateToKeyguard(); mNotificationPanelViewStateProvider.setQsExpansionFraction(1f); mController.updateViewState(); assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE); } // TODO(b/195442899): Add more tests for #updateViewState once CLs are finalized. @Test public void updateForHeadsUp_headsUpShouldBeVisible_viewHidden() { mController.onViewAttached(); updateStateToKeyguard(); mKeyguardStatusBarView.setVisibility(View.VISIBLE); mNotificationPanelViewStateProvider.setShouldHeadsUpBeVisible(true); mController.updateForHeadsUp(/* animate= */ false); assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE); } @Test public void updateForHeadsUp_headsUpShouldNotBeVisible_viewShown() { mController.onViewAttached(); updateStateToKeyguard(); // Start with the opposite state. mNotificationPanelViewStateProvider.setShouldHeadsUpBeVisible(true); mController.updateForHeadsUp(/* animate= */ false); mNotificationPanelViewStateProvider.setShouldHeadsUpBeVisible(false); mController.updateForHeadsUp(/* animate= */ false); assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE); } private void updateStateToNotKeyguard() { updateStatusBarState(SHADE); } Loading Loading @@ -295,4 +344,41 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { callback.onFinishedGoingToSleep(0); } private static class TestNotificationPanelViewStateProvider implements NotificationPanelViewController.NotificationPanelViewStateProvider { TestNotificationPanelViewStateProvider() {} private float mPanelViewExpandedHeight = 100f; private float mQsExpansionFraction = 0f; private boolean mShouldHeadsUpBeVisible = false; @Override public float getPanelViewExpandedHeight() { return mPanelViewExpandedHeight; } @Override public float getQsExpansionFraction() { return mQsExpansionFraction; } @Override public boolean shouldHeadsUpBeVisible() { return mShouldHeadsUpBeVisible; } public void setPanelViewExpandedHeight(float panelViewExpandedHeight) { this.mPanelViewExpandedHeight = panelViewExpandedHeight; } public void setQsExpansionFraction(float qsExpansionFraction) { this.mQsExpansionFraction = qsExpansionFraction; } public void setShouldHeadsUpBeVisible(boolean shouldHeadsUpBeVisible) { this.mShouldHeadsUpBeVisible = shouldHeadsUpBeVisible; } } }