Fix headsup notification RemoteInputView appearance animation
This CL fixes a bug where the appearance animation of the RemoteInputView in a headsup collapsed notification was slightly broken. The RemoteInputView would do its appearance animation partly outside (below) the notification boundaries. This was because the RemoteInputView was prevented to overlap the hint during the expand animation. Bug: 174148361 Test: atest RemoteInputViewTest, Manual, i.e. posting various types of Notifications from the Notify2-RVC application with a reply action added to them. Then observing the animations visually and analyzing frames from screen recordings. Change-Id: I90a637e9b57dea0e365699cef9e088a562301f55
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.collection.inflation;
|
||||
|
||||
import static com.android.systemui.flags.Flags.NOTIFICATION_INLINE_REPLY_ANIMATION;
|
||||
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
|
||||
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED;
|
||||
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;
|
||||
@@ -30,6 +31,7 @@ import android.view.ViewGroup;
|
||||
|
||||
import com.android.internal.util.NotificationMessagingUtil;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
||||
import com.android.systemui.statusbar.NotificationPresenter;
|
||||
import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
||||
@@ -71,6 +73,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
|
||||
private NotificationListContainer mListContainer;
|
||||
private BindRowCallback mBindRowCallback;
|
||||
private NotificationClicker mNotificationClicker;
|
||||
private FeatureFlags mFeatureFlags;
|
||||
|
||||
@Inject
|
||||
public NotificationRowBinderImpl(
|
||||
@@ -82,7 +85,8 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
|
||||
RowContentBindStage rowContentBindStage,
|
||||
Provider<RowInflaterTask> rowInflaterTaskProvider,
|
||||
ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder,
|
||||
IconManager iconManager) {
|
||||
IconManager iconManager,
|
||||
FeatureFlags featureFlags) {
|
||||
mContext = context;
|
||||
mNotifBindPipeline = notifBindPipeline;
|
||||
mRowContentBindStage = rowContentBindStage;
|
||||
@@ -92,6 +96,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
|
||||
mRowInflaterTaskProvider = rowInflaterTaskProvider;
|
||||
mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder;
|
||||
mIconManager = iconManager;
|
||||
mFeatureFlags = featureFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,6 +181,8 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
|
||||
entry.setRow(row);
|
||||
mNotifBindPipeline.manageRow(entry, row);
|
||||
mBindRowCallback.onBindRow(row);
|
||||
row.setInlineReplyAnimationFlagEnabled(
|
||||
mFeatureFlags.isEnabled(NOTIFICATION_INLINE_REPLY_ANIMATION));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -284,6 +284,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
private View.OnClickListener mOnAppClickListener;
|
||||
private View.OnClickListener mOnFeedbackClickListener;
|
||||
private Path mExpandingClipPath;
|
||||
private boolean mIsInlineReplyAnimationFlagEnabled = false;
|
||||
|
||||
// Listener will be called when receiving a long click event.
|
||||
// Use #setLongPressPosition to optionally assign positional data with the long press.
|
||||
@@ -3073,6 +3074,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setInlineReplyAnimationFlagEnabled(boolean isEnabled) {
|
||||
mIsInlineReplyAnimationFlagEnabled = isEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActualHeight(int height, boolean notifyListeners) {
|
||||
boolean changed = height != getActualHeight();
|
||||
@@ -3092,7 +3097,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
}
|
||||
int contentHeight = Math.max(getMinHeight(), height);
|
||||
for (NotificationContentView l : mLayouts) {
|
||||
l.setContentHeight(contentHeight);
|
||||
if (mIsInlineReplyAnimationFlagEnabled) {
|
||||
l.setContentHeight(height);
|
||||
} else {
|
||||
l.setContentHeight(contentHeight);
|
||||
}
|
||||
}
|
||||
if (mIsSummaryWithChildren) {
|
||||
mChildrenContainer.setActualHeight(height);
|
||||
|
||||
@@ -627,6 +627,13 @@ public class NotificationContentView extends FrameLayout implements Notification
|
||||
int hint;
|
||||
if (mHeadsUpChild != null && isVisibleOrTransitioning(VISIBLE_TYPE_HEADSUP)) {
|
||||
hint = getViewHeight(VISIBLE_TYPE_HEADSUP);
|
||||
if (mHeadsUpRemoteInput != null && mHeadsUpRemoteInput.isAnimatingAppearance()
|
||||
&& mHeadsUpRemoteInputController.isFocusAnimationFlagActive()) {
|
||||
// While the RemoteInputView is animating its appearance, it should be allowed
|
||||
// to overlap the hint, therefore no space is reserved for the hint during the
|
||||
// appearance animation of the RemoteInputView
|
||||
hint = 0;
|
||||
}
|
||||
} else if (mExpandedChild != null) {
|
||||
hint = getViewHeight(VISIBLE_TYPE_EXPANDED);
|
||||
} else if (mContractedChild != null) {
|
||||
|
||||
@@ -143,6 +143,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
||||
private NotificationViewWrapper mWrapper;
|
||||
|
||||
private Integer mDefocusTargetHeight = null;
|
||||
private boolean mIsAnimatingAppearance = false;
|
||||
|
||||
|
||||
// TODO(b/193539698): remove this; views shouldn't have access to their controller, and places
|
||||
@@ -418,6 +419,10 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isAnimatingAppearance() {
|
||||
return mIsAnimatingAppearance;
|
||||
}
|
||||
|
||||
/**
|
||||
* View will ensure to use at most the provided defocusTargetHeight, when defocusing animated.
|
||||
* This is to ensure that the parent can resize itself to the targetHeight while the defocus
|
||||
@@ -624,8 +629,16 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
||||
animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
|
||||
animator.start();
|
||||
} else if (mIsFocusAnimationFlagActive && getVisibility() != VISIBLE) {
|
||||
mIsAnimatingAppearance = true;
|
||||
setAlpha(0f);
|
||||
getFocusAnimator(crossFadeView).start();
|
||||
Animator focusAnimator = getFocusAnimator(crossFadeView);
|
||||
focusAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation, boolean isReverse) {
|
||||
mIsAnimatingAppearance = false;
|
||||
}
|
||||
});
|
||||
focusAnimator.start();
|
||||
}
|
||||
focus();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@ import static com.android.systemui.statusbar.notification.stack.StackStateAnimat
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
@@ -392,12 +394,15 @@ public class RemoteInputViewTest extends SysuiTestCase {
|
||||
// Start focus animation
|
||||
view.focusAnimated(crossFadeView);
|
||||
|
||||
assertTrue(view.isAnimatingAppearance());
|
||||
|
||||
// fast forward to end of animation
|
||||
mAnimatorTestRule.advanceTimeBy(ANIMATION_DURATION_STANDARD);
|
||||
|
||||
// assert that crossFadeView's alpha is reset to 1f after the animation (hidden behind
|
||||
// RemoteInputView)
|
||||
assertEquals(1f, crossFadeView.getAlpha());
|
||||
assertFalse(view.isAnimatingAppearance());
|
||||
assertEquals(View.VISIBLE, view.getVisibility());
|
||||
assertEquals(1f, view.getAlpha());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user