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

Commit a8178f54 authored by Peter Cai's avatar Peter Cai Committed by Selim Cinek
Browse files

HeadsUpAppearanceController: allow heads-up to draw beyond bounds

On some devices with huge `rounded_corner_content_padding`, the icon of
heads-up notifications will be clipped or even completely removed from
view. This is caused by `HeadsUpStatusBarView` trying to align the
heads-up icon with where the icon would be on a normal notification
card, which would end up outside of the status bar contents view when
`rounded_corner_content_padding` is set to beyond a certain value.

This patch fixes the problem by allowing heads-up content to overflow
the normal status bar content region when it is shown. As long as the
rounded corner is not too huge, the aligning position of the icon should
not be a problem of its own.

Fixes: 131813566
Test: atest SystemUiTests
Change-Id: I0fb8856c301a438ca87b06fcdbcf5323d9cda18c
parent f4d73340
Loading
Loading
Loading
Loading
+40 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.view.View;
import android.view.WindowInsets;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.ViewClippingUtil;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.DarkIconDispatcher;
@@ -67,6 +68,13 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
    private final View.OnLayoutChangeListener mStackScrollLayoutChangeListener =
            (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom)
                    -> updatePanelTranslation();
    private final ViewClippingUtil.ClippingParameters mParentClippingParams =
            new ViewClippingUtil.ClippingParameters() {
                @Override
                public boolean shouldFinish(View view) {
                    return view.getId() == R.id.status_bar;
                }
            };
    private boolean mAnimationsEnabled = true;
    Point mPoint;

@@ -239,6 +247,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
        if (mShown != isShown) {
            mShown = isShown;
            if (isShown) {
                updateParentClipping(false /* shouldClip */);
                mHeadsUpStatusBarView.setVisibility(View.VISIBLE);
                show(mHeadsUpStatusBarView);
                hide(mClockView, View.INVISIBLE);
@@ -256,25 +265,54 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
                if (mOperatorNameView != null) {
                    show(mOperatorNameView);
                }
                hide(mHeadsUpStatusBarView, View.GONE);
                hide(mHeadsUpStatusBarView, View.GONE, () -> {
                    updateParentClipping(true /* shouldClip */);
                });
            }
        }
    }

    private void updateParentClipping(boolean shouldClip) {
        ViewClippingUtil.setClippingDeactivated(
                mHeadsUpStatusBarView, !shouldClip, mParentClippingParams);
    }

    /**
     * Hides the view and sets the state to endState when finished.
     *
     * @param view The view to hide.
     * @param endState One of {@link View#INVISIBLE} or {@link View#GONE}.
     * @see HeadsUpAppearanceController#hide(View, int, Runnable)
     * @see View#setVisibility(int)
     *
     */
    private void hide(View view, int endState) {
        hide(view, endState, null);
    }

    /**
     * Hides the view and sets the state to endState when finished.
     *
     * @param view The view to hide.
     * @param endState One of {@link View#INVISIBLE} or {@link View#GONE}.
     * @param callback Runnable to be executed after the view has been hidden.
     * @see View#setVisibility(int)
     *
     */
    private void hide(View view, int endState, Runnable callback) {
        if (mAnimationsEnabled) {
            CrossFadeHelper.fadeOut(view, CONTENT_FADE_DURATION /* duration */,
                    0 /* delay */, () -> view.setVisibility(endState));
                    0 /* delay */, () -> {
                        view.setVisibility(endState);
                        if (callback != null) {
                            callback.run();
                        }
                    });
        } else {
            view.setVisibility(endState);
            if (callback != null) {
                callback.run();
            }
        }
    }