Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b01e37d authored by Johannes Gallmann's avatar Johannes Gallmann
Browse files

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
parent b642af90
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -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));
    }

    /**
+10 −1
Original line number Diff line number Diff line
@@ -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,8 +3097,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        }
        int contentHeight = Math.max(getMinHeight(), height);
        for (NotificationContentView l : mLayouts) {
            if (mIsInlineReplyAnimationFlagEnabled) {
                l.setContentHeight(height);
            } else {
                l.setContentHeight(contentHeight);
            }
        }
        if (mIsSummaryWithChildren) {
            mChildrenContainer.setActualHeight(height);
        }
+7 −0
Original line number Diff line number Diff line
@@ -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) {
+14 −1
Original line number Diff line number Diff line
@@ -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();
    }
+5 −0
Original line number Diff line number Diff line
@@ -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());
    }