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

Commit 79de08f5 authored by Peter Cai's avatar Peter Cai Committed by Bruno Martins
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.

Change-Id: I0fb8856c301a438ca87b06fcdbcf5323d9cda18c
parent 22de74f8
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.statusbar.CrossFadeHelper;
@@ -66,6 +67,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;

@@ -236,6 +244,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
            boolean isRightClock = clockView.getId() == R.id.clock_right;
            mShown = isShown;
            if (isShown) {
                updateParentClipping(false /* shouldClip */);
                mHeadsUpStatusBarView.setVisibility(View.VISIBLE);
                show(mHeadsUpStatusBarView);
                if (!isRightClock) {
@@ -251,25 +260,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();
            }
        }
    }