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

Commit 7c34cb44 authored by Yining Liu's avatar Yining Liu
Browse files

Optimize the alpha reset of notification content views

Previously, we reset the alpha of all Content Views (private layout,
public layout, and children container) to 1 when the showing layout
changes to avoid accidentally make a transparent content view visible.
However, this introduces a issue: when an alpha animation is going on a
view and its alpha is reset, there will be a flicker. This change fixed
this issue by setting the old alpha back to the new showing layout
after the alpha reset to avoid breaking the animation.

Bug: 292024656
Test: atest ExpandableNotificationRowTest
Flag: ACONFIG notification_content_alpha_optimization DEVELOPMENT
Change-Id: I68368ecf93cd654ed6ebe74a49efc2ea2e012a8b
parent 49c0d057
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -547,19 +547,26 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
    }

    private void setContentAlpha(float contentAlpha) {
        View contentView = getContentView();
        if (contentView.hasOverlappingRendering()) {
            int layerType = contentAlpha == 0.0f || contentAlpha == 1.0f ? LAYER_TYPE_NONE
                    : LAYER_TYPE_HARDWARE;
            contentView.setLayerType(layerType, null);
        }
        contentView.setAlpha(contentAlpha);
        setAlphaAndLayerType(getContentView(), contentAlpha);
        // After updating the current view, reset all views.
        if (contentAlpha == 1f) {
            resetAllContentAlphas();
        }
    }

    /**
     * Set a content view's alpha value and hardware layer type for fluent animations
     * @param contentView the view to set
     * @param alpha the alpha value to set
     */
    protected void setAlphaAndLayerType(View contentView, float alpha) {
        if (contentView.hasOverlappingRendering()) {
            int layerType = alpha == 0.0f || alpha == 1.0f ? LAYER_TYPE_NONE : LAYER_TYPE_HARDWARE;
            contentView.setLayerType(layerType, null);
        }
        contentView.setAlpha(alpha);
    }

    /**
     * If a subclass's {@link #getContentView()} returns different views depending on state,
     * this method is an opportunity to reset the alpha of ALL content views, not just the
+9 −0
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ import com.android.systemui.statusbar.notification.logging.NotificationCounters;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
@@ -2863,6 +2864,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
            return;
        }
        float oldAlpha = getContentView().getAlpha();

        if (!animated) {
            mPublicLayout.animate().cancel();
@@ -2873,6 +2875,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
            resetAllContentAlphas();
            mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
            updateChildrenVisibility();
            if (NotificationContentAlphaOptimization.isEnabled()) {
                // We want to set the old alpha to the now-showing layout to avoid breaking an
                // on-going animation
                if (oldAlpha != 1f) {
                    setAlphaAndLayerType(mShowingPublic ? mPublicLayout : mPrivateLayout, oldAlpha);
                }
            }
        } else {
            animateShowingPublic(delay, duration, mShowingPublic);
        }
+56 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ import com.android.systemui.statusbar.notification.SourceType;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
import com.android.systemui.statusbar.phone.KeyguardBypassController;

@@ -329,6 +330,61 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
                + "seems out of sync.", group.getChildrenContainer().isUserLocked());
    }

    @Test
    @EnableFlags(NotificationContentAlphaOptimization.FLAG_NAME)
    public void setHideSensitive_shouldNotDisturbAnimation() throws Exception {
        //Given: A row that is during alpha animation
        ExpandableNotificationRow row = mNotificationTestHelper.createRow();

        assertEquals(row.getPrivateLayout(), row.getContentView());
        row.setContentAlpha(0.5f);

        //When: Set its hideSensitive without changing the content view to show
        row.setHideSensitive(
                /* hideSensitive= */ false,
                /* animated= */ false,
                /* delay=  */ 0L,
                /* duration=  */ 0L
        );
        assertEquals(row.getPrivateLayout(), row.getContentView());

        //Then: The alpha value should not be reset
        assertEquals(0.5f, row.getPrivateLayout().getAlpha(), 0);
    }

    @Test
    @EnableFlags(NotificationContentAlphaOptimization.FLAG_NAME)
    public void setHideSensitive_changeContent_shouldNotDisturbAnimation() throws Exception {

        // Given: A sensitive row that has public version but is not hiding sensitive,
        // and is during an animation that sets its alpha value to be 0.5f
        Notification publicNotif = mNotificationTestHelper.createNotification();
        publicNotif.publicVersion = mNotificationTestHelper.createNotification();
        ExpandableNotificationRow row = mNotificationTestHelper.createRow(publicNotif);
        row.setSensitive(true, false);
        row.setContentAlpha(0.5f);

        assertEquals(0.5f, row.getPrivateLayout().getAlpha(), 0);
        assertEquals(View.VISIBLE, row.getPrivateLayout().getVisibility());

        // When: Change its hideSensitive and changes the content view to show the public version
        row.setHideSensitive(
                /* hideSensitive= */ true,
                /* animated= */ false,
                /* delay=  */ 0L,
                /* duration=  */ 0L
        );

        // Then: The alpha value of private layout should be reset to 1, private layout be
        // INVISIBLE;
        // The alpha value of public layout should be 0.5 to preserve the animation state, public
        // layout should be VISIBLE
        assertEquals(View.INVISIBLE, row.getPrivateLayout().getVisibility());
        assertEquals(1f, row.getPrivateLayout().getAlpha(), 0);
        assertEquals(View.VISIBLE, row.getPublicLayout().getVisibility());
        assertEquals(0.5f, row.getPublicLayout().getAlpha(), 0);
    }

    @Test
    public void testReinflatedOnDensityChange() throws Exception {
        ExpandableNotificationRow row = mNotificationTestHelper.createRow();