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

Commit bd2caf6a authored by Mady Mellor's avatar Mady Mellor Committed by Android (Google) Code Review
Browse files

Merge "Inset the bubble bar expanded view instead of drawing our own header" into udc-qpr-dev

parents 89b4cd74 0a7f7818
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -228,12 +228,12 @@
    <dimen name="bubble_user_education_stack_padding">16dp</dimen>
    <!-- Size of the bubble bar (height), should match transient_taskbar_size in Launcher. -->
    <dimen name="bubblebar_size">72dp</dimen>
    <!-- The size of the drag handle / menu shown along with a bubble bar expanded view. -->
    <dimen name="bubble_bar_expanded_view_handle_size">40dp</dimen>
    <!-- The width of the drag handle shown along with a bubble bar expanded view. -->
    <dimen name="bubble_bar_expanded_view_handle_width">128dp</dimen>
    <!-- The height of the drag handle shown along with a bubble bar expanded view. -->
    <dimen name="bubble_bar_expanded_view_handle_height">4dp</dimen>
    <!-- The size of the caption bar inset at the top of bubble bar expanded view. -->
    <dimen name="bubble_bar_expanded_view_caption_height">32dp</dimen>
    <!-- The height of the dots shown for the caption menu in the bubble bar expanded view.. -->
    <dimen name="bubble_bar_expanded_view_caption_dot_size">4dp</dimen>
    <!-- The spacing between the dots for the caption menu in the bubble bar expanded view.. -->
    <dimen name="bubble_bar_expanded_view_caption_dot_spacing">4dp</dimen>
    <!-- Minimum width of the bubble bar manage menu. -->
    <dimen name="bubble_bar_manage_menu_min_width">200dp</dimen>
    <!-- Size of the dismiss icon in the bubble bar manage menu. -->
+7 −1
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import android.graphics.PointF;
import android.util.Log;
import android.widget.FrameLayout;

import androidx.annotation.Nullable;

import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.animation.PhysicsAnimator;
import com.android.wm.shell.bubbles.BubbleOverflow;
@@ -111,7 +113,8 @@ public class BubbleBarAnimationHelper {
    /**
     * Animates the provided bubble's expanded view to the expanded state.
     */
    public void animateExpansion(BubbleViewProvider expandedBubble) {
    public void animateExpansion(BubbleViewProvider expandedBubble,
            @Nullable Runnable afterAnimation) {
        mExpandedBubble = expandedBubble;
        if (mExpandedBubble == null) {
            return;
@@ -160,6 +163,9 @@ public class BubbleBarAnimationHelper {
                    bev.setAnimationMatrix(null);
                    updateExpandedView();
                    bev.setSurfaceZOrderedOnTop(false);
                    if (afterAnimation != null) {
                        afterAnimation.run();
                    }
                })
                .start();
    }
+33 −38
Original line number Diff line number Diff line
@@ -16,12 +16,12 @@

package com.android.wm.shell.bubbles.bar;

import android.annotation.ColorInt;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -63,7 +63,8 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
    private @Nullable TaskView mTaskView;
    private @Nullable BubbleOverflowContainerView mOverflowView;

    private int mHandleHeight;
    private int mCaptionHeight;

    private int mBackgroundColor;
    private float mCornerRadius = 0f;

@@ -97,8 +98,8 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
        super.onFinishInflate();
        Context context = getContext();
        setElevation(getResources().getDimensionPixelSize(R.dimen.bubble_elevation));
        mHandleHeight = context.getResources().getDimensionPixelSize(
                R.dimen.bubble_bar_expanded_view_handle_size);
        mCaptionHeight = context.getResources().getDimensionPixelSize(
                R.dimen.bubble_bar_expanded_view_caption_height);
        addView(mHandleView);
        applyThemeAttrs();
        setClipToOutline(true);
@@ -136,6 +137,9 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
            addView(mTaskView);
            mTaskView.setEnableSurfaceClipping(true);
            mTaskView.setCornerRadius(mCornerRadius);

            // Handle view needs to draw on top of task view.
            bringChildToFront(mHandleView);
        }
        mMenuViewController = new BubbleBarMenuViewController(mContext, this);
        mMenuViewController.setListener(new BubbleBarMenuViewController.Listener() {
@@ -169,6 +173,10 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
        });
    }

    public BubbleBarHandleView getHandleView() {
        return mHandleView;
    }

    // TODO (b/275087636): call this when theme/config changes
    /** Updates the view based on the current theme. */
    public void applyThemeAttrs() {
@@ -183,12 +191,12 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView

        ta.recycle();

        mHandleHeight = getResources().getDimensionPixelSize(
                R.dimen.bubble_bar_expanded_view_handle_size);
        mCaptionHeight = getResources().getDimensionPixelSize(
                R.dimen.bubble_bar_expanded_view_caption_height);

        if (mTaskView != null) {
            mTaskView.setCornerRadius(mCornerRadius);
            updateHandleAndBackgroundColor(true /* animated */);
            updateHandleColor(true /* animated */);
        }
    }

@@ -196,13 +204,12 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int menuViewHeight = Math.min(mHandleHeight, height);
        int menuViewHeight = Math.min(mCaptionHeight, height);
        measureChild(mHandleView, widthMeasureSpec, MeasureSpec.makeMeasureSpec(menuViewHeight,
                MeasureSpec.getMode(heightMeasureSpec)));

        if (mTaskView != null) {
            int taskViewHeight = height - menuViewHeight;
            measureChild(mTaskView, widthMeasureSpec, MeasureSpec.makeMeasureSpec(taskViewHeight,
            measureChild(mTaskView, widthMeasureSpec, MeasureSpec.makeMeasureSpec(height,
                    MeasureSpec.getMode(heightMeasureSpec)));
        }
    }
@@ -210,19 +217,20 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        // Drag handle above
        final int dragHandleBottom = t + mHandleView.getMeasuredHeight();
        mHandleView.layout(l, t, r, dragHandleBottom);
        final int captionBottom = t + mCaptionHeight;
        if (mTaskView != null) {
            mTaskView.layout(l, dragHandleBottom, r,
                    dragHandleBottom + mTaskView.getMeasuredHeight());
            mTaskView.layout(l, t, r,
                    t + mTaskView.getMeasuredHeight());
            mTaskView.setCaptionInsets(Insets.of(0, mCaptionHeight, 0, 0));
        }
        // Handle draws on top of task view in the caption area.
        mHandleView.layout(l, t, r, captionBottom);
    }

    @Override
    public void onTaskCreated() {
        setContentVisibility(true);
        updateHandleAndBackgroundColor(false /* animated */);
        updateHandleColor(false /* animated */);
    }

    @Override
@@ -298,33 +306,20 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
    }

    /**
     * Updates the background color to match with task view status/bg color, and sets handle color
     * to contrast with the background
     * Updates the handle color based on the task view status bar or background color; if those
     * are transparent it defaults to the background color pulled from system theme attributes.
     */
    private void updateHandleAndBackgroundColor(boolean animated) {
        if (mTaskView == null) return;
        final int color = getTaskViewColor();
        final boolean isRegionDark = Color.luminance(color) <= 0.5;
        mHandleView.updateHandleColor(isRegionDark, animated);
        setBackgroundColor(color);
    }

    /**
     * Retrieves task view status/nav bar color or background if available
     *
     * TODO (b/283075226): Update with color sampling when
     *                     RegionSamplingHelper or alternative is available
     */
    private @ColorInt int getTaskViewColor() {
        if (mTaskView == null || mTaskView.getTaskInfo() == null) return mBackgroundColor;
    private void updateHandleColor(boolean animated) {
        if (mTaskView == null || mTaskView.getTaskInfo() == null) return;
        int color = mBackgroundColor;
        ActivityManager.TaskDescription taskDescription = mTaskView.getTaskInfo().taskDescription;
        if (taskDescription.getStatusBarColor() != Color.TRANSPARENT) {
            return taskDescription.getStatusBarColor();
            color = taskDescription.getStatusBarColor();
        } else if (taskDescription.getBackgroundColor() != Color.TRANSPARENT) {
            return taskDescription.getBackgroundColor();
        } else {
            return mBackgroundColor;
            color = taskDescription.getBackgroundColor();
        }
        final boolean isRegionDark = Color.luminance(color) <= 0.5;
        mHandleView.updateHandleColor(isRegionDark, animated);
    }

    /**
+32 −15
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ import android.animation.ObjectAnimator;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Outline;
import android.graphics.Rect;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewOutlineProvider;
@@ -37,8 +38,12 @@ import com.android.wm.shell.R;
public class BubbleBarHandleView extends View {
    private static final long COLOR_CHANGE_DURATION = 120;

    private int mHandleWidth;
    private int mHandleHeight;
    // The handle view is currently rendered as 3 evenly spaced dots.
    private int mDotSize;
    private int mDotSpacing;
    // Path used to draw the dots
    private final Path mPath = new Path();

    private @ColorInt int mHandleLightColor;
    private @ColorInt int mHandleDarkColor;
    private @Nullable ObjectAnimator mColorChangeAnim;
@@ -58,11 +63,10 @@ public class BubbleBarHandleView extends View {
    public BubbleBarHandleView(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        mHandleWidth = getResources().getDimensionPixelSize(
                R.dimen.bubble_bar_expanded_view_handle_width);
        mHandleHeight = getResources().getDimensionPixelSize(
                R.dimen.bubble_bar_expanded_view_handle_height);
        mDotSize = getResources().getDimensionPixelSize(
                R.dimen.bubble_bar_expanded_view_caption_dot_size);
        mDotSpacing = getResources().getDimensionPixelSize(
                R.dimen.bubble_bar_expanded_view_caption_dot_spacing);
        mHandleLightColor = ContextCompat.getColor(getContext(),
                R.color.bubble_bar_expanded_view_handle_light);
        mHandleDarkColor = ContextCompat.getColor(getContext(),
@@ -74,13 +78,26 @@ public class BubbleBarHandleView extends View {
            public void getOutline(View view, Outline outline) {
                final int handleCenterX = view.getWidth() / 2;
                final int handleCenterY = view.getHeight() / 2;
                final float handleRadius = mHandleHeight / 2f;
                Rect handleBounds = new Rect(
                        handleCenterX - mHandleWidth / 2,
                        handleCenterY - mHandleHeight / 2,
                        handleCenterX + mHandleWidth / 2,
                        handleCenterY + mHandleHeight / 2);
                outline.setRoundRect(handleBounds, handleRadius);
                final int handleTotalWidth = mDotSize * 3 + mDotSpacing * 2;
                final int handleLeft = handleCenterX - handleTotalWidth / 2;
                final int handleTop = handleCenterY - mDotSize / 2;
                final int handleBottom = handleTop + mDotSize;
                RectF dot1 = new RectF(
                        handleLeft, handleTop,
                        handleLeft + mDotSize, handleBottom);
                RectF dot2 = new RectF(
                        dot1.right + mDotSpacing, handleTop,
                        dot1.right + mDotSpacing + mDotSize, handleBottom
                );
                RectF dot3 = new RectF(
                        dot2.right + mDotSpacing, handleTop,
                        dot2.right + mDotSpacing + mDotSize, handleBottom
                );
                mPath.reset();
                mPath.addOval(dot1, Path.Direction.CW);
                mPath.addOval(dot2, Path.Direction.CW);
                mPath.addOval(dot3, Path.Direction.CW);
                outline.setPath(mPath);
            }
        });
    }
+17 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.Context;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.ColorDrawable;
import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
@@ -68,6 +69,10 @@ public class BubbleBarLayerView extends FrameLayout
    private final Region mTouchableRegion = new Region();
    private final Rect mTempRect = new Rect();

    // Used to ensure touch target size for the menu shown on a bubble expanded view
    private TouchDelegate mHandleTouchDelegate;
    private final Rect mHandleTouchBounds = new Rect();

    public BubbleBarLayerView(Context context, BubbleController controller) {
        super(context);
        mBubbleController = controller;
@@ -164,7 +169,17 @@ public class BubbleBarLayerView extends FrameLayout

        mIsExpanded = true;
        mBubbleController.getSysuiProxy().onStackExpandChanged(true);
        mAnimationHelper.animateExpansion(mExpandedBubble);
        mAnimationHelper.animateExpansion(mExpandedBubble, () -> {
            if (mExpandedView == null) return;
            // Touch delegate for the menu
            BubbleBarHandleView view = mExpandedView.getHandleView();
            view.getBoundsOnScreen(mHandleTouchBounds);
            mHandleTouchBounds.top -= mPositioner.getBubblePaddingTop();
            mHandleTouchDelegate = new TouchDelegate(mHandleTouchBounds,
                    mExpandedView.getHandleView());
            setTouchDelegate(mHandleTouchDelegate);
        });

        showScrim(true);
    }

@@ -175,6 +190,7 @@ public class BubbleBarLayerView extends FrameLayout
        mAnimationHelper.animateCollapse(() -> removeView(viewToRemove));
        mBubbleController.getSysuiProxy().onStackExpandChanged(false);
        mExpandedView = null;
        setTouchDelegate(null);
        showScrim(false);
    }