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

Commit 967aae75 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Vertical bubbles in landscape"

parents c1a295c6 6ea766ed
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config
    private ScrimView mBubbleScrim;
    @Nullable private BubbleStackView mStackView;
    private BubbleIconFactory mBubbleIconFactory;
    private BubblePositioner mBubblePositioner;

    /**
     * The relative position of the stack when we removed it and nulled it out. If the stack is
@@ -387,7 +388,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config
                dumpManager, floatingContentCoordinator,
                new BubbleDataRepository(context, launcherApps), sysUiState, notificationManager,
                statusBarService, windowManager, windowManagerShellWrapper, launcherApps, logger,
                mainHandler, organizer);
                mainHandler, organizer, new BubblePositioner(context, windowManager));
    }

    /**
@@ -419,7 +420,8 @@ public class BubbleController implements Bubbles, ConfigurationController.Config
            LauncherApps launcherApps,
            BubbleLogger bubbleLogger,
            Handler mainHandler,
            ShellTaskOrganizer organizer) {
            ShellTaskOrganizer organizer,
            BubblePositioner positioner) {
        dumpManager.registerDumpable(TAG, this);
        mContext = context;
        mShadeController = shadeController;
@@ -530,6 +532,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config

        mBubbleIconFactory = new BubbleIconFactory(context);
        mTaskListener = new MultiWindowTaskListener(mMainHandler, organizer);
        mBubblePositioner = positioner;

        launcherApps.registerCallback(new LauncherApps.Callback() {
            @Override
@@ -809,6 +812,11 @@ public class BubbleController implements Bubbles, ConfigurationController.Config
        return mTaskListener;
    }

    @Override
    public BubblePositioner getPositioner() {
        return mBubblePositioner;
    }

    /**
     * BubbleStackView is lazily created by this method the first time a Bubble is added. This
     * method initializes the stack view and adds it to the StatusBar just above the scrim.
@@ -818,9 +826,10 @@ public class BubbleController implements Bubbles, ConfigurationController.Config
            mStackView = new BubbleStackView(
                    mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator,
                    this::onAllBubblesAnimatedOut, this::onImeVisibilityChanged,
                    this::hideCurrentInputMethod, this::onBubbleExpandChanged);
                    this::hideCurrentInputMethod, this::onBubbleExpandChanged, mBubblePositioner);
            mStackView.setStackStartPosition(mPositionFromRemovedStack);
            mStackView.addView(mBubbleScrim);
            mStackView.onOrientationChanged();
            if (mExpandListener != null) {
                mStackView.setExpandListener(mExpandListener);
            }
@@ -978,10 +987,14 @@ public class BubbleController implements Bubbles, ConfigurationController.Config

    @Override
    public void onConfigChanged(Configuration newConfig) {
        if (mBubblePositioner != null) {
            // This doesn't trigger any changes, always update it
            mBubblePositioner.update(newConfig.orientation);
        }
        if (mStackView != null && newConfig != null) {
            if (newConfig.orientation != mOrientation) {
                mOrientation = newConfig.orientation;
                mStackView.onOrientationChanged(newConfig.orientation);
                mStackView.onOrientationChanged();
            }
            if (newConfig.densityDpi != mDensityDpi) {
                mDensityDpi = newConfig.densityDpi;
+89 −64
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
import android.os.Bundle;
@@ -48,7 +47,6 @@ import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@@ -83,24 +81,26 @@ public class BubbleExpandedView extends LinearLayout {
    private boolean mImeVisible;
    private boolean mNeedsNewHeight;

    private Point mDisplaySize;
    private int mMinHeight;
    private int mOverflowHeight;
    private int mSettingsIconHeight;
    private int mPointerWidth;
    private int mPointerHeight;
    private ShapeDrawable mPointerDrawable;
    private ShapeDrawable mCurrentPointer;
    private ShapeDrawable mTopPointer;
    private ShapeDrawable mLeftPointer;
    private ShapeDrawable mRightPointer;
    private int mExpandedViewPadding;
    private float mCornerRadius = 0f;

    @Nullable private Bubble mBubble;
    private PendingIntent mPendingIntent;

    // TODO(b/170891664): Don't use a flag, set the BubbleOverflow object instead
    private boolean mIsOverflow;

    private Bubbles mBubbles = Dependency.get(Bubbles.class);
    private WindowManager mWindowManager;
    private BubbleStackView mStackView;
    private BubblePositioner mPositioner;

    /**
     * Container for the ActivityView that has a solid, round-rect background that shows if the
@@ -224,17 +224,6 @@ public class BubbleExpandedView extends LinearLayout {
        updateDimensions();
    }

    void updateDimensions() {
        mDisplaySize = new Point();
        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        // Get the real size -- this includes screen decorations (notches, statusbar, navbar).
        mWindowManager.getDefaultDisplay().getRealSize(mDisplaySize);
        Resources res = getResources();
        mMinHeight = res.getDimensionPixelSize(R.dimen.bubble_expanded_default_height);
        mOverflowHeight = res.getDimensionPixelSize(R.dimen.bubble_overflow_height);
        mPointerMargin = res.getDimensionPixelSize(R.dimen.bubble_pointer_margin);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onFinishInflate() {
@@ -245,14 +234,22 @@ public class BubbleExpandedView extends LinearLayout {
        mPointerWidth = res.getDimensionPixelSize(R.dimen.bubble_pointer_width);
        mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);

        mPointerDrawable = new ShapeDrawable(TriangleShape.create(
        mTopPointer = new ShapeDrawable(TriangleShape.create(
                mPointerWidth, mPointerHeight, true /* pointUp */));
        mLeftPointer = new ShapeDrawable(TriangleShape.createHorizontal(
                mPointerWidth, mPointerHeight, true /* pointLeft */));
        mRightPointer = new ShapeDrawable(TriangleShape.createHorizontal(
                mPointerWidth, mPointerHeight, false /* pointLeft */));

        mCurrentPointer = mTopPointer;
        mPointerView.setVisibility(INVISIBLE);

        mSettingsIconHeight = getContext().getResources().getDimensionPixelSize(
                R.dimen.bubble_manage_button_height);
        mSettingsIcon = findViewById(R.id.settings_button);

        mPositioner = mBubbles.getPositioner();

        mTaskView = new TaskView(mContext, mBubbles.getTaskManager());
        // Set ActivityView's alpha value as zero, since there is no view content to be shown.
        setContentVisibility(false);
@@ -282,8 +279,7 @@ public class BubbleExpandedView extends LinearLayout {
        applyThemeAttrs();

        mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
        setPadding(mExpandedViewPadding, mExpandedViewPadding, mExpandedViewPadding,
                mExpandedViewPadding);
        setClipToPadding(false);
        setOnTouchListener((view, motionEvent) -> {
            if (mTaskView == null) {
                return false;
@@ -311,6 +307,52 @@ public class BubbleExpandedView extends LinearLayout {
        setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
    }

    void updateDimensions() {
        Resources res = getResources();
        mMinHeight = res.getDimensionPixelSize(R.dimen.bubble_expanded_default_height);
        mOverflowHeight = res.getDimensionPixelSize(R.dimen.bubble_overflow_height);
        mPointerMargin = res.getDimensionPixelSize(R.dimen.bubble_pointer_margin);
    }

    void applyThemeAttrs() {
        final TypedArray ta = mContext.obtainStyledAttributes(new int[] {
                android.R.attr.dialogCornerRadius,
                android.R.attr.colorBackgroundFloating});
        mCornerRadius = ta.getDimensionPixelSize(0, 0);
        mExpandedViewContainer.setBackgroundColor(ta.getColor(1, Color.WHITE));
        ta.recycle();

        if (mTaskView != null && ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
                mContext.getResources())) {
            mTaskView.setCornerRadius(mCornerRadius);
        }
        updatePointerView();
    }

    private void updatePointerView() {
        final int mode =
                getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
        switch (mode) {
            case Configuration.UI_MODE_NIGHT_NO:
                mCurrentPointer.setTint(getResources().getColor(R.color.bubbles_light));
                break;
            case Configuration.UI_MODE_NIGHT_YES:
                mCurrentPointer.setTint(getResources().getColor(R.color.bubbles_dark));
                break;
        }
        LayoutParams lp = (LayoutParams) mPointerView.getLayoutParams();
        if (mCurrentPointer == mLeftPointer || mCurrentPointer == mRightPointer) {
            lp.width = mPointerHeight;
            lp.height = mPointerWidth;
        } else {
            lp.width = mPointerWidth;
            lp.height = mPointerHeight;
        }
        mPointerView.setLayoutParams(lp);
        mPointerView.setBackground(mCurrentPointer);
    }


    private String getBubbleKey() {
        return mBubble != null ? mBubble.getKey() : "null";
    }
@@ -371,32 +413,6 @@ public class BubbleExpandedView extends LinearLayout {
        }
    }

    void applyThemeAttrs() {
        final TypedArray ta = mContext.obtainStyledAttributes(new int[] {
                android.R.attr.dialogCornerRadius,
                android.R.attr.colorBackgroundFloating});
        mCornerRadius = ta.getDimensionPixelSize(0, 0);
        mExpandedViewContainer.setBackgroundColor(ta.getColor(1, Color.WHITE));
        ta.recycle();

        if (mTaskView != null && ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
                mContext.getResources())) {
            mTaskView.setCornerRadius(mCornerRadius);
        }

        final int mode =
                getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
        switch (mode) {
            case Configuration.UI_MODE_NIGHT_NO:
                mPointerDrawable.setTint(getResources().getColor(R.color.bubbles_light));
                break;
            case Configuration.UI_MODE_NIGHT_YES:
                mPointerDrawable.setTint(getResources().getColor(R.color.bubbles_dark));
                break;
        }
        mPointerView.setBackground(mPointerDrawable);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
@@ -522,12 +538,12 @@ public class BubbleExpandedView extends LinearLayout {
        }

        if (mBubble != null || mIsOverflow) {
            float desiredHeight = mOverflowHeight;
            if (!mIsOverflow) {
                desiredHeight = Math.max(mBubble.getDesiredHeight(mContext), mMinHeight);
            }
            float desiredHeight = mIsOverflow
                    ? mOverflowHeight
                    : mBubble.getDesiredHeight(mContext);
            desiredHeight = Math.max(desiredHeight, mMinHeight);
            float height = Math.min(desiredHeight, getMaxExpandedHeight());
            height = Math.max(height, mIsOverflow ? mOverflowHeight : mMinHeight);
            height = Math.max(height, mMinHeight);
            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mTaskView.getLayoutParams();
            mNeedsNewHeight = lp.height != height;
            if (!mImeVisible) {
@@ -546,21 +562,17 @@ public class BubbleExpandedView extends LinearLayout {
    }

    private int getMaxExpandedHeight() {
        mWindowManager.getDefaultDisplay().getRealSize(mDisplaySize);
        int expandedContainerY = mExpandedViewContainerLocation != null
                ? mExpandedViewContainerLocation[1]
                // Remove top insets back here because availableRect.height would account for that
                ? mExpandedViewContainerLocation[1] - mPositioner.getInsets().top
                : 0;
        int bottomInset = getRootWindowInsets() != null
                ? getRootWindowInsets().getStableInsetBottom()
                : 0;

        return mDisplaySize.y
        return mPositioner.getAvailableRect().height()
                - expandedContainerY
                - getPaddingTop()
                - getPaddingBottom()
                - mSettingsIconHeight
                - mPointerHeight
                - mPointerMargin - bottomInset;
                - mPointerMargin;
    }

    /**
@@ -585,12 +597,25 @@ public class BubbleExpandedView extends LinearLayout {
    }

    /**
     * Set the x position that the tip of the triangle should point to.
     * Set the position that the tip of the triangle should point to.
     */
    public void setPointerPosition(float x) {
        float halfPointerWidth = mPointerWidth / 2f;
        float pointerLeft = x - halfPointerWidth - mExpandedViewPadding;
        mPointerView.setTranslationX(pointerLeft);
    public void setPointerPosition(float x, float y, boolean isLandscape, boolean onLeft) {
        // Pointer gets drawn in the padding
        int paddingLeft = (isLandscape && onLeft) ? mPointerHeight : 0;
        int paddingRight = (isLandscape && !onLeft) ? mPointerHeight : 0;
        int paddingTop = isLandscape ? 0 : mExpandedViewPadding;
        setPadding(paddingLeft, paddingTop, paddingRight, 0);

        if (isLandscape) {
            // TODO: why setY vs setTranslationY ? linearlayout?
            mPointerView.setY(y - (mPointerWidth / 2f));
            mPointerView.setTranslationX(onLeft ? -mPointerHeight : x - mExpandedViewPadding);
        } else {
            mPointerView.setTranslationY(0f);
            mPointerView.setTranslationX(x - mExpandedViewPadding - (mPointerWidth / 2f));
        }
        mCurrentPointer = isLandscape ? onLeft ? mLeftPointer : mRightPointer : mTopPointer;
        updatePointerView();
        mPointerView.setVisibility(VISIBLE);
    }

+89 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.bubbles;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Insets;
import android.graphics.Rect;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;

import androidx.annotation.VisibleForTesting;

/**
 * Keeps track of display size, configuration, and specific bubble sizes. One place for all
 * placement and positioning calculations to refer to.
 */
public class BubblePositioner {

    private WindowManager mWindowManager;
    private Rect mPositionRect;
    private int mOrientation;
    private Insets mInsets;

    public BubblePositioner(Context context, WindowManager windowManager) {
        mWindowManager = windowManager;
        update(Configuration.ORIENTATION_UNDEFINED);
    }

    public void update(int orientation) {
        WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics();
        mPositionRect = new Rect(windowMetrics.getBounds());
        WindowInsets metricInsets = windowMetrics.getWindowInsets();

        Insets insets = metricInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
                | WindowInsets.Type.statusBars()
                | WindowInsets.Type.displayCutout());
        update(orientation, insets, windowMetrics.getBounds());
    }

    @VisibleForTesting
    public void update(int orientation, Insets insets, Rect bounds) {
        mOrientation = orientation;
        mInsets = insets;

        mPositionRect = new Rect(bounds);
        mPositionRect.left += mInsets.left;
        mPositionRect.top += mInsets.top;
        mPositionRect.right -= mInsets.right;
        mPositionRect.bottom -= mInsets.bottom;
    }

    /**
     * @return a rect of available screen space for displaying bubbles in the correct orientation,
     * accounting for system bars and cutouts.
     */
    public Rect getAvailableRect() {
        return mPositionRect;
    }

    /**
     * @return the current orientation.
     */
    public int getOrientation() {
        return mOrientation;
    }

    /**
     * @return the relevant insets (status bar, nav bar, cutouts).
     */
    public Insets getInsets() {
        return mInsets;
    }
}
+172 −127

File changed.

Preview size limit exceeded, changes collapsed.

+4 −1
Original line number Diff line number Diff line
@@ -128,6 +128,9 @@ public interface Bubbles {
    /** Set a listener to be notified of when overflow view update. */
    void setOverflowListener(BubbleData.Listener listener);

    /** The task listener for events in bubble tasks. **/
    /** The task listener for events in bubble tasks. */
    MultiWindowTaskListener getTaskManager();

    /** Contains information to help position things on the screen.  */
    BubblePositioner getPositioner();
}
Loading