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

Commit bd6d0ad8 authored by shawnlin's avatar shawnlin
Browse files

Make systemui support waterfall

- Status bar content should be always below waterfall. We have to
minus status bar height with waterfall inset top to get the correct
content height and set the top padding/margin to waterfall inset top.

- Update paddings/margins for waterfall insets in below 3 places, which
also move setup rouned corner padding from ScreenDecorations to these 3
places.
   1. PhoneStatusBar
   2. QuickStatusBarHeader
   3. KeyguardStatusBarView

- Adjust notification minimum expand height for waterfall in
NotificationStackScrollLayout.

Bug: 146876976
Test: manual-select waterfall cutout overlay in develop option and check
the status bar.
Test: atest SystemUITests

Change-Id: Ib489e0ac69433635c3be990b5f8e56a3704b4a09
parent 97753051
Loading
Loading
Loading
Loading
+8 −86
Original line number Diff line number Diff line
@@ -22,12 +22,8 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;

import static com.android.systemui.tuner.TunablePadding.FLAG_END;
import static com.android.systemui.tuner.TunablePadding.FLAG_START;

import android.annotation.Dimension;
import android.app.ActivityManager;
import android.app.Fragment;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -69,13 +65,7 @@ import com.android.internal.util.Preconditions;
import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.SecureSetting;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.tuner.TunablePadding;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.leak.RotationUtils;
@@ -86,8 +76,6 @@ import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;

import dagger.Lazy;

/**
 * An overlay that draws screen decorations in software (e.g for rounded corners or display cutout)
 * for antialiasing and emulation purposes.
@@ -102,7 +90,6 @@ public class ScreenDecorations extends SystemUI implements Tunable {
    private static final boolean DEBUG_SCREENSHOT_ROUNDED_CORNERS =
            SystemProperties.getBoolean("debug.screenshot_rounded_corners", false);
    private static final boolean VERBOSE = false;
    private final Lazy<StatusBar> mStatusBarLazy;

    private DisplayManager mDisplayManager;
    private final BroadcastDispatcher mBroadcastDispatcher;
@@ -146,12 +133,10 @@ public class ScreenDecorations extends SystemUI implements Tunable {

    @Inject
    public ScreenDecorations(Context context,
            Lazy<StatusBar> statusBarLazy,
            @Main Handler handler,
            BroadcastDispatcher broadcastDispatcher,
            TunerService tunerService) {
        super(context);
        mStatusBarLazy = statusBarLazy;
        mMainHandler = handler;
        mBroadcastDispatcher = broadcastDispatcher;
        mTunerService = tunerService;
@@ -161,7 +146,6 @@ public class ScreenDecorations extends SystemUI implements Tunable {
    public void start() {
        mHandler = startHandlerThread();
        mHandler.post(this::startOnScreenDecorationsThread);
        setupStatusBarPaddingIfNeeded();
    }

    @VisibleForTesting
@@ -440,42 +424,6 @@ public class ScreenDecorations extends SystemUI implements Tunable {
                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout);
    }


    private void setupStatusBarPaddingIfNeeded() {
        // TODO: This should be moved to a more appropriate place, as it is not related to the
        // screen decorations overlay.
        int padding = mContext.getResources().getDimensionPixelSize(
                R.dimen.rounded_corner_content_padding);
        if (padding != 0) {
            setupStatusBarPadding(padding);
        }

    }

    private void setupStatusBarPadding(int padding) {
        // Add some padding to all the content near the edge of the screen.
        StatusBar statusBar = mStatusBarLazy.get();
        final View notificationShadeWindowView = statusBar.getNotificationShadeWindowView();
        if (notificationShadeWindowView != null) {
            TunablePadding.addTunablePadding(
                    notificationShadeWindowView.findViewById(R.id.keyguard_header),
                    PADDING, padding, FLAG_END);

            final FragmentHostManager fragmentHostManager =
                    FragmentHostManager.get(notificationShadeWindowView);
            fragmentHostManager.addTagListener(QS.TAG,
                    new TunablePaddingTagListener(padding, R.id.header));
        }

        final View statusBarWindow = statusBar.getStatusBarWindow();
        if (statusBarWindow != null) {
            final FragmentHostManager fragmentHostManager =
                    FragmentHostManager.get(statusBarWindow);
            fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
                    new TunablePaddingTagListener(padding, R.id.status_bar));
        }
    }

    @VisibleForTesting
    WindowManager.LayoutParams getWindowLayoutParams() {
        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -566,32 +514,6 @@ public class ScreenDecorations extends SystemUI implements Tunable {
        view.setLayoutParams(params);
    }

    @VisibleForTesting
    static class TunablePaddingTagListener implements FragmentListener {

        private final int mPadding;
        private final int mId;
        private TunablePadding mTunablePadding;

        public TunablePaddingTagListener(int padding, int id) {
            mPadding = padding;
            mId = id;
        }

        @Override
        public void onFragmentViewCreated(String tag, Fragment fragment) {
            if (mTunablePadding != null) {
                mTunablePadding.destroy();
            }
            View view = fragment.getView();
            if (mId != 0) {
                view = view.findViewById(mId);
            }
            mTunablePadding = TunablePadding.addTunablePadding(view, PADDING, mPadding,
                    FLAG_START | FLAG_END);
        }
    }

    public static class DisplayCutoutView extends View implements DisplayManager.DisplayListener,
            RegionInterceptableView {

@@ -763,11 +685,11 @@ public class ScreenDecorations extends SystemUI implements Tunable {
                return false;
            }
            if (mStart) {
                return displayCutout.getSafeInsetLeft() > 0
                        || displayCutout.getSafeInsetTop() > 0;
                return !displayCutout.getBoundingRectLeft().isEmpty()
                        || !displayCutout.getBoundingRectTop().isEmpty();
            } else {
                return displayCutout.getSafeInsetRight() > 0
                        || displayCutout.getSafeInsetBottom() > 0;
                return !displayCutout.getBoundingRectRight().isEmpty()
                        || !displayCutout.getBoundingRectBottom().isEmpty();
            }
        }

@@ -809,15 +731,15 @@ public class ScreenDecorations extends SystemUI implements Tunable {

        private int getGravity(DisplayCutout displayCutout) {
            if (mStart) {
                if (displayCutout.getSafeInsetLeft() > 0) {
                if (!displayCutout.getBoundingRectLeft().isEmpty()) {
                    return Gravity.LEFT;
                } else if (displayCutout.getSafeInsetTop() > 0) {
                } else if (!displayCutout.getBoundingRectTop().isEmpty()) {
                    return Gravity.TOP;
                }
            } else {
                if (displayCutout.getSafeInsetRight() > 0) {
                if (!displayCutout.getBoundingRectRight().isEmpty()) {
                    return Gravity.RIGHT;
                } else if (displayCutout.getSafeInsetBottom() > 0) {
                } else if (!displayCutout.getBoundingRectBottom().isEmpty()) {
                    return Gravity.BOTTOM;
                }
            }
+20 −9
Original line number Diff line number Diff line
@@ -61,9 +61,9 @@ import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.qs.QSDetail.Callback;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
import com.android.systemui.statusbar.phone.StatusBarWindowView;
import com.android.systemui.statusbar.phone.StatusIconContainer;
import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.policy.DateView;
@@ -146,6 +146,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
        }
    };
    private boolean mHasTopCutout = false;
    private int mRoundedCornerPadding = 0;

    @Inject
    public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
@@ -325,6 +326,9 @@ public class QuickStatusBarHeader extends RelativeLayout implements
        Resources resources = mContext.getResources();
        updateMinimumHeight();

        mRoundedCornerPadding = resources.getDimensionPixelSize(
                R.dimen.rounded_corner_content_padding);

        // Update height for a few views, especially due to landscape mode restricting space.
        mHeaderTextContainerView.getLayoutParams().height =
                resources.getDimensionPixelSize(R.dimen.qs_header_tooltip_height);
@@ -432,16 +436,23 @@ public class QuickStatusBarHeader extends RelativeLayout implements
    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        DisplayCutout cutout = insets.getDisplayCutout();
        Pair<Integer, Integer> padding = PhoneStatusBarView.cornerCutoutMargins(

        // Handle padding of QuickStatusBarHeader
        Pair<Integer, Integer> cornerCutoutPadding = StatusBarWindowView.cornerCutoutMargins(
                cutout, getDisplay());
        if (padding == null) {
        Pair<Integer, Integer> padding =
                StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner(
                        cutout, cornerCutoutPadding, mRoundedCornerPadding);
        setPadding(padding.first, 0, padding.second, getPaddingBottom());

        // Handle padding of SystemIconsView
        final int waterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top;
        mSystemIconsView.setPaddingRelative(
                    getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start), 0,
                    getResources().getDimensionPixelSize(R.dimen.status_bar_padding_end), 0);
        } else {
            mSystemIconsView.setPadding(padding.first, 0, padding.second, 0);
                getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start),
                waterfallTopInset,
                getResources().getDimensionPixelSize(R.dimen.status_bar_padding_end),
                0);

        }
        return super.onApplyWindowInsets(insets);
    }

+12 −1
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import android.util.Log;
import android.util.MathUtils;
import android.util.Pair;
import android.view.ContextThemeWrapper;
import android.view.DisplayCutout;
import android.view.InputDevice;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -513,6 +514,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
    private float mLastSentExpandedHeight;
    private boolean mWillExpand;

    private int mWaterfallTopInset;

    @Inject
    public NotificationStackScrollLayout(
            @Named(VIEW_CONTEXT) Context context,
@@ -1714,6 +1717,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        mBottomInset = insets.getSystemWindowInsetBottom();

        mWaterfallTopInset = 0;
        final DisplayCutout cutout = insets.getDisplayCutout();
        if (cutout != null) {
            mWaterfallTopInset = cutout.getWaterfallInsets().top;
        }

        if (ANCHOR_SCROLLING) {
            // TODO
        } else {
@@ -5310,7 +5319,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd

    @ShadeViewRefactor(RefactorComponent.COORDINATOR)
    public int getMinExpansionHeight() {
        return mShelf.getIntrinsicHeight() - (mShelf.getIntrinsicHeight() - mStatusBarHeight) / 2;
        return mShelf.getIntrinsicHeight()
                - (mShelf.getIntrinsicHeight() - mStatusBarHeight + mWaterfallTopInset) / 2
                + mWaterfallTopInset;
    }

    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+29 −15
Original line number Diff line number Diff line
@@ -102,6 +102,9 @@ public class KeyguardStatusBarView extends RelativeLayout
     */
    private int mCutoutSideNudge = 0;

    private DisplayCutout mDisplayCutout;
    private int mRoundedCornerPadding = 0;

    public KeyguardStatusBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
@@ -159,9 +162,15 @@ public class KeyguardStatusBarView extends RelativeLayout
                getResources().getDimensionPixelSize(R.dimen.keyguard_carrier_text_margin));
        mCarrierLabel.setLayoutParams(lp);

        lp = (MarginLayoutParams) getLayoutParams();
        updateKeyguardStatusBarHeight();
    }

    private void updateKeyguardStatusBarHeight() {
        final int waterfallTop =
                mDisplayCutout == null ? 0 : mDisplayCutout.getWaterfallInsets().top;
        MarginLayoutParams lp =  (MarginLayoutParams) getLayoutParams();
        lp.height =  getResources().getDimensionPixelSize(
                R.dimen.status_bar_header_height_keyguard);
                R.dimen.status_bar_header_height_keyguard) + waterfallTop;
        setLayoutParams(lp);
    }

@@ -175,6 +184,8 @@ public class KeyguardStatusBarView extends RelativeLayout
                R.dimen.display_cutout_margin_consumption);
        mShowPercentAvailable = getContext().getResources().getBoolean(
                com.android.internal.R.bool.config_battery_percentage_setting_available);
        mRoundedCornerPadding = res.getDimensionPixelSize(
                R.dimen.rounded_corner_content_padding);
    }

    private void updateVisibilities() {
@@ -225,23 +236,26 @@ public class KeyguardStatusBarView extends RelativeLayout
    }

    private boolean updateLayoutConsideringCutout() {
        DisplayCutout dc = getRootWindowInsets().getDisplayCutout();
        mDisplayCutout = getRootWindowInsets().getDisplayCutout();
        updateKeyguardStatusBarHeight();

        Pair<Integer, Integer> cornerCutoutMargins =
                PhoneStatusBarView.cornerCutoutMargins(dc, getDisplay());
        updateCornerCutoutPadding(cornerCutoutMargins);
        if (dc == null || cornerCutoutMargins != null) {
                StatusBarWindowView.cornerCutoutMargins(mDisplayCutout, getDisplay());
        updatePadding(cornerCutoutMargins);
        if (mDisplayCutout == null || cornerCutoutMargins != null) {
            return updateLayoutParamsNoCutout();
        } else {
            return updateLayoutParamsForCutout(dc);
            return updateLayoutParamsForCutout();
        }
    }

    private void updateCornerCutoutPadding(Pair<Integer, Integer> cornerCutoutMargins) {
        if (cornerCutoutMargins != null) {
            setPadding(cornerCutoutMargins.first, 0, cornerCutoutMargins.second, 0);
        } else {
            setPadding(0, 0, 0, 0);
        }
    private void updatePadding(Pair<Integer, Integer> cornerCutoutMargins) {
        final int waterfallTop =
                mDisplayCutout == null ? 0 : mDisplayCutout.getWaterfallInsets().top;
        Pair<Integer, Integer> padding =
                StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner(
                        mDisplayCutout, cornerCutoutMargins, mRoundedCornerPadding);
        setPadding(padding.first, waterfallTop, padding.second, 0);
    }

    private boolean updateLayoutParamsNoCutout() {
@@ -268,7 +282,7 @@ public class KeyguardStatusBarView extends RelativeLayout
        return true;
    }

    private boolean updateLayoutParamsForCutout(DisplayCutout dc) {
    private boolean updateLayoutParamsForCutout() {
        if (mLayoutState == LAYOUT_CUTOUT) {
            return false;
        }
@@ -279,7 +293,7 @@ public class KeyguardStatusBarView extends RelativeLayout
        }

        Rect bounds = new Rect();
        boundsFromDirection(dc, Gravity.TOP, bounds);
        boundsFromDirection(mDisplayCutout, Gravity.TOP, bounds);

        mCutoutSpace.setVisibility(View.VISIBLE);
        RelativeLayout.LayoutParams lp = (LayoutParams) mCutoutSpace.getLayoutParams();
+11 −22
Original line number Diff line number Diff line
@@ -88,33 +88,11 @@ public class NotificationShadeWindowView extends FrameLayout {
            boolean paddingChanged = insets.top != getPaddingTop()
                    || insets.bottom != getPaddingBottom();

            int rightCutout = 0;
            int leftCutout = 0;
            DisplayCutout displayCutout = getRootWindowInsets().getDisplayCutout();
            if (displayCutout != null) {
                leftCutout = displayCutout.getSafeInsetLeft();
                rightCutout = displayCutout.getSafeInsetRight();
            }

            int targetLeft = Math.max(insets.left, leftCutout);
            int targetRight = Math.max(insets.right, rightCutout);

            // Super-special right inset handling, because scrims and backdrop need to ignore it.
            if (targetRight != mRightInset || targetLeft != mLeftInset) {
                mRightInset = targetRight;
                mLeftInset = targetLeft;
                applyMargins();
            }
            // Drop top inset, and pass through bottom inset.
            if (paddingChanged) {
                setPadding(0, 0, 0, 0);
            }
        } else {
            if (mRightInset != 0 || mLeftInset != 0) {
                mRightInset = 0;
                mLeftInset = 0;
                applyMargins();
            }
            boolean changed = getPaddingLeft() != 0
                    || getPaddingRight() != 0
                    || getPaddingTop() != 0
@@ -123,6 +101,17 @@ public class NotificationShadeWindowView extends FrameLayout {
                setPadding(0, 0, 0, 0);
            }
        }

        mLeftInset = 0;
        mRightInset = 0;
        DisplayCutout displayCutout = getRootWindowInsets().getDisplayCutout();
        if (displayCutout != null) {
            mLeftInset = displayCutout.getSafeInsetLeft();
            mRightInset = displayCutout.getSafeInsetRight();
        }
        mLeftInset = Math.max(insets.left, mLeftInset);
        mRightInset = Math.max(insets.right, mRightInset);
        applyMargins();
        return windowInsets;
    }

Loading