Merge "Fixing Heads Up Notifications not reacting to action touches in split shade" into sc-v2-dev am: 4772ecd698
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16031101 Change-Id: I42ab7a4ccbe291511f2a70a35c12aff7a20d4e92
This commit is contained in:
@@ -22,7 +22,6 @@ import android.animation.ValueAnimator;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.MathUtils;
|
import android.util.MathUtils;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
@@ -111,7 +110,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
private Interpolator mCurrentAppearInterpolator;
|
private Interpolator mCurrentAppearInterpolator;
|
||||||
|
|
||||||
NotificationBackgroundView mBackgroundNormal;
|
NotificationBackgroundView mBackgroundNormal;
|
||||||
private RectF mAppearAnimationRect = new RectF();
|
|
||||||
private float mAnimationTranslationY;
|
private float mAnimationTranslationY;
|
||||||
private boolean mDrawingAppearAnimation;
|
private boolean mDrawingAppearAnimation;
|
||||||
private ValueAnimator mAppearAnimator;
|
private ValueAnimator mAppearAnimator;
|
||||||
@@ -123,13 +121,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
private long mLastActionUpTime;
|
private long mLastActionUpTime;
|
||||||
|
|
||||||
private float mNormalBackgroundVisibilityAmount;
|
private float mNormalBackgroundVisibilityAmount;
|
||||||
private ValueAnimator.AnimatorUpdateListener mBackgroundVisibilityUpdater
|
|
||||||
= new ValueAnimator.AnimatorUpdateListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationUpdate(ValueAnimator animation) {
|
|
||||||
setNormalBackgroundVisibilityAmount(mBackgroundNormal.getAlpha());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private FakeShadowView mFakeShadow;
|
private FakeShadowView mFakeShadow;
|
||||||
private int mCurrentBackgroundTint;
|
private int mCurrentBackgroundTint;
|
||||||
private int mTargetTint;
|
private int mTargetTint;
|
||||||
@@ -138,11 +129,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
private float mOverrideAmount;
|
private float mOverrideAmount;
|
||||||
private boolean mShadowHidden;
|
private boolean mShadowHidden;
|
||||||
private boolean mIsHeadsUpAnimation;
|
private boolean mIsHeadsUpAnimation;
|
||||||
private int mHeadsUpAddStartLocation;
|
|
||||||
private float mHeadsUpLocation;
|
|
||||||
/* In order to track headsup longpress coorindate. */
|
/* In order to track headsup longpress coorindate. */
|
||||||
protected Point mTargetPoint;
|
protected Point mTargetPoint;
|
||||||
private boolean mIsAppearing;
|
|
||||||
private boolean mDismissed;
|
private boolean mDismissed;
|
||||||
private boolean mRefocusOnDismiss;
|
private boolean mRefocusOnDismiss;
|
||||||
private AccessibilityManager mAccessibilityManager;
|
private AccessibilityManager mAccessibilityManager;
|
||||||
@@ -154,7 +142,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
setClipChildren(false);
|
setClipChildren(false);
|
||||||
setClipToPadding(false);
|
setClipToPadding(false);
|
||||||
updateColors();
|
updateColors();
|
||||||
initDimens();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateColors() {
|
private void updateColors() {
|
||||||
@@ -166,17 +153,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
R.color.notification_ripple_untinted_color);
|
R.color.notification_ripple_untinted_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initDimens() {
|
|
||||||
mHeadsUpAddStartLocation = getResources().getDimensionPixelSize(
|
|
||||||
com.android.internal.R.dimen.notification_content_margin_start);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDensityOrFontScaleChanged() {
|
|
||||||
super.onDensityOrFontScaleChanged();
|
|
||||||
initDimens();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload background colors from resources and invalidate views.
|
* Reload background colors from resources and invalidate views.
|
||||||
*/
|
*/
|
||||||
@@ -438,7 +414,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
Runnable onFinishedRunnable, AnimatorListenerAdapter animationListener) {
|
Runnable onFinishedRunnable, AnimatorListenerAdapter animationListener) {
|
||||||
enableAppearDrawing(true);
|
enableAppearDrawing(true);
|
||||||
mIsHeadsUpAnimation = isHeadsUpAnimation;
|
mIsHeadsUpAnimation = isHeadsUpAnimation;
|
||||||
mHeadsUpLocation = endLocation;
|
|
||||||
if (mDrawingAppearAnimation) {
|
if (mDrawingAppearAnimation) {
|
||||||
startAppearAnimation(false /* isAppearing */, translationDirection,
|
startAppearAnimation(false /* isAppearing */, translationDirection,
|
||||||
delay, duration, onFinishedRunnable, animationListener);
|
delay, duration, onFinishedRunnable, animationListener);
|
||||||
@@ -452,7 +427,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear) {
|
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear) {
|
||||||
enableAppearDrawing(true);
|
enableAppearDrawing(true);
|
||||||
mIsHeadsUpAnimation = isHeadsUpAppear;
|
mIsHeadsUpAnimation = isHeadsUpAppear;
|
||||||
mHeadsUpLocation = mHeadsUpAddStartLocation;
|
|
||||||
if (mDrawingAppearAnimation) {
|
if (mDrawingAppearAnimation) {
|
||||||
startAppearAnimation(true /* isAppearing */, isHeadsUpAppear ? 0.0f : -1.0f, delay,
|
startAppearAnimation(true /* isAppearing */, isHeadsUpAppear ? 0.0f : -1.0f, delay,
|
||||||
duration, null, null);
|
duration, null, null);
|
||||||
@@ -474,7 +448,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
mAppearAnimationTranslation = 0;
|
mAppearAnimationTranslation = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mIsAppearing = isAppearing;
|
|
||||||
|
|
||||||
float targetValue;
|
float targetValue;
|
||||||
if (isAppearing) {
|
if (isAppearing) {
|
||||||
@@ -782,8 +755,4 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
void onActivated(ActivatableNotificationView view);
|
void onActivated(ActivatableNotificationView view);
|
||||||
void onActivationReset(ActivatableNotificationView view);
|
void onActivationReset(ActivatableNotificationView view);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnDimmedListener {
|
|
||||||
void onSetDimmed(boolean dimmed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ public class AmbientState {
|
|||||||
private boolean mPanelFullWidth;
|
private boolean mPanelFullWidth;
|
||||||
private boolean mPulsing;
|
private boolean mPulsing;
|
||||||
private boolean mUnlockHintRunning;
|
private boolean mUnlockHintRunning;
|
||||||
private int mIntrinsicPadding;
|
|
||||||
private float mHideAmount;
|
private float mHideAmount;
|
||||||
private boolean mAppearing;
|
private boolean mAppearing;
|
||||||
private float mPulseHeight = MAX_PULSE_HEIGHT;
|
private float mPulseHeight = MAX_PULSE_HEIGHT;
|
||||||
@@ -82,6 +81,7 @@ public class AmbientState {
|
|||||||
private float mAppearFraction;
|
private float mAppearFraction;
|
||||||
private boolean mIsShadeOpening;
|
private boolean mIsShadeOpening;
|
||||||
private float mOverExpansion;
|
private float mOverExpansion;
|
||||||
|
private int mStackTopMargin;
|
||||||
|
|
||||||
/** Distance of top of notifications panel from top of screen. */
|
/** Distance of top of notifications panel from top of screen. */
|
||||||
private float mStackY = 0;
|
private float mStackY = 0;
|
||||||
@@ -94,7 +94,6 @@ public class AmbientState {
|
|||||||
|
|
||||||
/** Height of the notifications panel without top padding when expansion completes. */
|
/** Height of the notifications panel without top padding when expansion completes. */
|
||||||
private float mStackEndHeight;
|
private float mStackEndHeight;
|
||||||
private float mTransitionToFullShadeAmount;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Height of the notifications panel without top padding when expansion completes.
|
* @return Height of the notifications panel without top padding when expansion completes.
|
||||||
@@ -493,14 +492,6 @@ public class AmbientState {
|
|||||||
return mUnlockHintRunning;
|
return mUnlockHintRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIntrinsicPadding(int intrinsicPadding) {
|
|
||||||
mIntrinsicPadding = intrinsicPadding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIntrinsicPadding() {
|
|
||||||
return mIntrinsicPadding;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return whether a view is dozing and not pulsing right now
|
* @return whether a view is dozing and not pulsing right now
|
||||||
*/
|
*/
|
||||||
@@ -577,29 +568,10 @@ public class AmbientState {
|
|||||||
mOnPulseHeightChangedListener = onPulseHeightChangedListener;
|
mOnPulseHeightChangedListener = onPulseHeightChangedListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Runnable getOnPulseHeightChangedListener() {
|
|
||||||
return mOnPulseHeightChangedListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTrackedHeadsUpRow(ExpandableNotificationRow row) {
|
public void setTrackedHeadsUpRow(ExpandableNotificationRow row) {
|
||||||
mTrackedHeadsUpRow = row;
|
mTrackedHeadsUpRow = row;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the amount of pixels we have currently dragged down if we're transitioning to the full
|
|
||||||
* shade. 0.0f means we're not transitioning yet.
|
|
||||||
*/
|
|
||||||
public void setTransitionToFullShadeAmount(float transitionToFullShadeAmount) {
|
|
||||||
mTransitionToFullShadeAmount = transitionToFullShadeAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get
|
|
||||||
*/
|
|
||||||
public float getTransitionToFullShadeAmount() {
|
|
||||||
return mTransitionToFullShadeAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the currently tracked heads up row, if there is one and it is currently above the
|
* Returns the currently tracked heads up row, if there is one and it is currently above the
|
||||||
* shelf (still appearing).
|
* shelf (still appearing).
|
||||||
@@ -622,4 +594,12 @@ public class AmbientState {
|
|||||||
public void setHasAlertEntries(boolean hasAlertEntries) {
|
public void setHasAlertEntries(boolean hasAlertEntries) {
|
||||||
mHasAlertEntries = hasAlertEntries;
|
mHasAlertEntries = hasAlertEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStackTopMargin(int stackTopMargin) {
|
||||||
|
mStackTopMargin = stackTopMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStackTopMargin() {
|
||||||
|
return mStackTopMargin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4287,7 +4287,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
||||||
void setIntrinsicPadding(int intrinsicPadding) {
|
void setIntrinsicPadding(int intrinsicPadding) {
|
||||||
mIntrinsicPadding = intrinsicPadding;
|
mIntrinsicPadding = intrinsicPadding;
|
||||||
mAmbientState.setIntrinsicPadding(intrinsicPadding);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import android.util.MathUtils;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.animation.Interpolators;
|
import com.android.systemui.animation.Interpolators;
|
||||||
import com.android.systemui.statusbar.NotificationShelf;
|
import com.android.systemui.statusbar.NotificationShelf;
|
||||||
@@ -54,8 +56,7 @@ public class StackScrollAlgorithm {
|
|||||||
private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
|
private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
|
||||||
private boolean mIsExpanded;
|
private boolean mIsExpanded;
|
||||||
private boolean mClipNotificationScrollToTop;
|
private boolean mClipNotificationScrollToTop;
|
||||||
private int mStatusBarHeight;
|
@VisibleForTesting float mHeadsUpInset;
|
||||||
private float mHeadsUpInset;
|
|
||||||
private int mPinnedZTranslationExtra;
|
private int mPinnedZTranslationExtra;
|
||||||
private float mNotificationScrimPadding;
|
private float mNotificationScrimPadding;
|
||||||
|
|
||||||
@@ -75,9 +76,9 @@ public class StackScrollAlgorithm {
|
|||||||
mPaddingBetweenElements = res.getDimensionPixelSize(
|
mPaddingBetweenElements = res.getDimensionPixelSize(
|
||||||
R.dimen.notification_divider_height);
|
R.dimen.notification_divider_height);
|
||||||
mCollapsedSize = res.getDimensionPixelSize(R.dimen.notification_min_height);
|
mCollapsedSize = res.getDimensionPixelSize(R.dimen.notification_min_height);
|
||||||
mStatusBarHeight = res.getDimensionPixelSize(R.dimen.status_bar_height);
|
|
||||||
mClipNotificationScrollToTop = res.getBoolean(R.bool.config_clipNotificationScrollToTop);
|
mClipNotificationScrollToTop = res.getBoolean(R.bool.config_clipNotificationScrollToTop);
|
||||||
mHeadsUpInset = mStatusBarHeight + res.getDimensionPixelSize(
|
int statusBarHeight = res.getDimensionPixelSize(R.dimen.status_bar_height);
|
||||||
|
mHeadsUpInset = statusBarHeight + res.getDimensionPixelSize(
|
||||||
R.dimen.heads_up_status_bar_padding);
|
R.dimen.heads_up_status_bar_padding);
|
||||||
mPinnedZTranslationExtra = res.getDimensionPixelSize(
|
mPinnedZTranslationExtra = res.getDimensionPixelSize(
|
||||||
R.dimen.heads_up_pinned_elevation);
|
R.dimen.heads_up_pinned_elevation);
|
||||||
@@ -562,13 +563,14 @@ public class StackScrollAlgorithm {
|
|||||||
|
|
||||||
// Move the tracked heads up into position during the appear animation, by interpolating
|
// Move the tracked heads up into position during the appear animation, by interpolating
|
||||||
// between the HUN inset (where it will appear as a HUN) and the end position in the shade
|
// between the HUN inset (where it will appear as a HUN) and the end position in the shade
|
||||||
|
float headsUpTranslation = mHeadsUpInset - ambientState.getStackTopMargin();
|
||||||
ExpandableNotificationRow trackedHeadsUpRow = ambientState.getTrackedHeadsUpRow();
|
ExpandableNotificationRow trackedHeadsUpRow = ambientState.getTrackedHeadsUpRow();
|
||||||
if (trackedHeadsUpRow != null) {
|
if (trackedHeadsUpRow != null) {
|
||||||
ExpandableViewState childState = trackedHeadsUpRow.getViewState();
|
ExpandableViewState childState = trackedHeadsUpRow.getViewState();
|
||||||
if (childState != null) {
|
if (childState != null) {
|
||||||
float endPosition = childState.yTranslation - ambientState.getStackTranslation();
|
float endPosition = childState.yTranslation - ambientState.getStackTranslation();
|
||||||
childState.yTranslation = MathUtils.lerp(
|
childState.yTranslation = MathUtils.lerp(
|
||||||
mHeadsUpInset, endPosition, ambientState.getAppearFraction());
|
headsUpTranslation, endPosition, ambientState.getAppearFraction());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,7 +604,7 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (row.isPinned()) {
|
if (row.isPinned()) {
|
||||||
childState.yTranslation = Math.max(childState.yTranslation, mHeadsUpInset);
|
childState.yTranslation = Math.max(childState.yTranslation, headsUpTranslation);
|
||||||
childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
|
childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
|
||||||
childState.hidden = false;
|
childState.hidden = false;
|
||||||
ExpandableViewState topState =
|
ExpandableViewState topState =
|
||||||
|
|||||||
@@ -1011,6 +1011,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
constraintSet.setMargin(R.id.notification_stack_scroller, TOP, topMargin);
|
constraintSet.setMargin(R.id.notification_stack_scroller, TOP, topMargin);
|
||||||
constraintSet.setMargin(R.id.qs_frame, TOP, topMargin);
|
constraintSet.setMargin(R.id.qs_frame, TOP, topMargin);
|
||||||
constraintSet.applyTo(mNotificationContainerParent);
|
constraintSet.applyTo(mNotificationContainerParent);
|
||||||
|
mAmbientState.setStackTopMargin(topMargin);
|
||||||
mNotificationsQSContainerController.setSplitShadeEnabled(mShouldUseSplitNotificationShade);
|
mNotificationsQSContainerController.setSplitShadeEnabled(mShouldUseSplitNotificationShade);
|
||||||
|
|
||||||
updateKeyguardStatusViewAlignment(/* animate= */false);
|
updateKeyguardStatusViewAlignment(/* animate= */false);
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.android.systemui.statusbar.notification.stack
|
||||||
|
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.R
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
||||||
|
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController
|
||||||
|
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mockito.Mockito.mock
|
||||||
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
class StackScrollAlgorithmTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
private val hostView = FrameLayout(context)
|
||||||
|
private val stackScrollAlgorithm = StackScrollAlgorithm(context, hostView)
|
||||||
|
private val expandableViewState = ExpandableViewState()
|
||||||
|
private val notificationRow = mock(ExpandableNotificationRow::class.java)
|
||||||
|
private val ambientState = AmbientState(
|
||||||
|
context,
|
||||||
|
SectionProvider { _, _ -> false },
|
||||||
|
BypassController { false })
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
whenever(notificationRow.viewState).thenReturn(expandableViewState)
|
||||||
|
hostView.addView(notificationRow)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUpTranslationSetToDefaultValue() {
|
||||||
|
whenever(notificationRow.isPinned).thenReturn(true)
|
||||||
|
whenever(notificationRow.isHeadsUp).thenReturn(true)
|
||||||
|
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, 0)
|
||||||
|
|
||||||
|
assertThat(expandableViewState.yTranslation).isEqualTo(stackScrollAlgorithm.mHeadsUpInset)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testHeadsUpTranslationChangesBasedOnStackMargin() {
|
||||||
|
whenever(notificationRow.isPinned).thenReturn(true)
|
||||||
|
whenever(notificationRow.isHeadsUp).thenReturn(true)
|
||||||
|
val minHeadsUpTranslation = context.resources
|
||||||
|
.getDimensionPixelSize(R.dimen.notification_side_paddings)
|
||||||
|
|
||||||
|
// split shade case with top margin introduced by shade's status bar
|
||||||
|
ambientState.stackTopMargin = 100
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, 0)
|
||||||
|
|
||||||
|
// top margin presence should decrease heads up translation up to minHeadsUpTranslation
|
||||||
|
assertThat(expandableViewState.yTranslation).isEqualTo(minHeadsUpTranslation)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user