Merge "[View Controllers] (3/3) Move (most of) KSBVC's alpha calculation out of NPVController and into KSBVC." into sc-v2-dev am: e38d387169

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15597557

Change-Id: I496750c1cc69269836944d5df53b84fc08125f92
This commit is contained in:
TreeHugger Robot
2021-08-31 17:21:52 +00:00
committed by Automerger Merge Worker
4 changed files with 220 additions and 110 deletions

View File

@@ -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;
@@ -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}. */

View File

@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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(
@@ -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,
@@ -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;
@@ -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
@@ -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()
@@ -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;
}
@@ -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;
}
}
}

View File

@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -635,17 +620,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,
@@ -836,7 +810,7 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardStatusBarViewController =
mKeyguardStatusBarViewComponentFactory.build(
mKeyguardStatusBar,
mViewStateProvider)
mNotificationPanelViewStateProvider)
.getKeyguardStatusBarViewController();
mKeyguardStatusBarViewController.init();
@@ -870,7 +844,7 @@ public class NotificationPanelViewController extends PanelViewController {
mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() {
@Override
public void onFullyHiddenChanged(boolean isFullyHidden) {
updateKeyguardStatusBarForHeadsUp();
mKeyguardStatusBarViewController.updateForHeadsUp();
}
@Override
@@ -907,8 +881,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(
@@ -2916,30 +2888,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
@@ -3235,31 +3183,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);
@@ -4237,7 +4160,7 @@ public class NotificationPanelViewController extends PanelViewController {
updateGestureExclusionRect();
mHeadsUpPinnedMode = inPinnedMode;
updateHeadsUpVisibility();
updateKeyguardStatusBarForHeadsUp();
mKeyguardStatusBarViewController.updateForHeadsUp();
}
@Override
@@ -4396,7 +4319,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
}
updateKeyguardStatusBarForHeadsUp();
mKeyguardStatusBarViewController.updateForHeadsUp();
if (keyguardShowing) {
updateDozingVisibilities(false /* animate */);
}
@@ -4421,6 +4344,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

View File

@@ -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();
@@ -114,7 +113,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
mStatusBarIconController,
new StatusBarIconController.TintedIconManager.Factory(mFeatureFlags),
mBatteryMeterViewController,
mViewStateProvider,
mNotificationPanelViewStateProvider,
mKeyguardStateController,
mKeyguardBypassController,
mKeyguardUpdateMonitor,
@@ -210,7 +209,6 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
@Test
public void updateViewState_notKeyguardState_nothingUpdated() {
mAlpha = 0.255f;
mController.onViewAttached();
updateStateToNotKeyguard();
@@ -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);
}
@@ -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;
}
}
}