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

Commit 9adc4795 authored by Priyanka Advani's avatar Priyanka Advani Committed by Android (Google) Code Review
Browse files

Merge "Revert "Create DeviceConfig class for positioning bubbles"" into main

parents 57ea0232 887780e3
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -787,7 +787,7 @@ public class BubbleController implements ConfigurationChangeListener,
                mLayerView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
                    if (!windowInsets.equals(mWindowInsets) && mLayerView != null) {
                        mWindowInsets = windowInsets;
                        mBubblePositioner.update(DeviceConfig.create(mContext, mWindowManager));
                        mBubblePositioner.update();
                        mLayerView.onDisplaySizeChanged();
                    }
                    return windowInsets;
@@ -797,7 +797,7 @@ public class BubbleController implements ConfigurationChangeListener,
                mStackView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
                    if (!windowInsets.equals(mWindowInsets) && mStackView != null) {
                        mWindowInsets = windowInsets;
                        mBubblePositioner.update(DeviceConfig.create(mContext, mWindowManager));
                        mBubblePositioner.update();
                        mStackView.onDisplaySizeChanged();
                    }
                    return windowInsets;
@@ -979,7 +979,7 @@ public class BubbleController implements ConfigurationChangeListener,
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        if (mBubblePositioner != null) {
            mBubblePositioner.update(DeviceConfig.create(mContext, mWindowManager));
            mBubblePositioner.update();
        }
        if (mStackView != null && newConfig != null) {
            if (newConfig.densityDpi != mDensityDpi
+55 −24
Original line number Diff line number Diff line
@@ -16,7 +16,10 @@

package com.android.wm.shell.bubbles;

import static android.view.View.LAYOUT_DIRECTION_RTL;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Insets;
import android.graphics.Point;
@@ -25,7 +28,9 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Log;
import android.view.Surface;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;

import androidx.annotation.VisibleForTesting;

@@ -63,12 +68,15 @@ public class BubblePositioner {
    private static final float EXPANDED_VIEW_BUBBLE_BAR_LANDSCAPE_WIDTH_PERCENT = 0.4f;

    private Context mContext;
    private DeviceConfig mDeviceConfig;
    private WindowManager mWindowManager;
    private Rect mScreenRect;
    private @Surface.Rotation int mRotation = Surface.ROTATION_0;
    private Insets mInsets;
    private boolean mImeVisible;
    private int mImeHeight;
    private boolean mIsLargeScreen;
    private boolean mIsSmallTablet;

    private Rect mPositionRect;
    private int mDefaultMaxBubbles;
    private int mMaxBubbles;
@@ -102,27 +110,44 @@ public class BubblePositioner {

    public BubblePositioner(Context context, WindowManager windowManager) {
        mContext = context;
        mDeviceConfig = DeviceConfig.create(context, windowManager);
        update(mDeviceConfig);
        mWindowManager = windowManager;
        update();
    }

    /**
     * Available space and inset information. Call this when config changes
     * occur or when added to a window.
     */
    public void update(DeviceConfig deviceConfig) {
        mDeviceConfig = deviceConfig;
    public void update() {
        WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics();
        if (windowMetrics == null) {
            return;
        }
        WindowInsets metricInsets = windowMetrics.getWindowInsets();
        Insets insets = metricInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
                | WindowInsets.Type.statusBars()
                | WindowInsets.Type.displayCutout());

        final Rect bounds = windowMetrics.getBounds();
        Configuration config = mContext.getResources().getConfiguration();
        mIsLargeScreen = config.smallestScreenWidthDp >= 600;
        if (mIsLargeScreen) {
            float largestEdgeDp = Math.max(config.screenWidthDp, config.screenHeightDp);
            mIsSmallTablet = largestEdgeDp < 960;
        } else {
            mIsSmallTablet = false;
        }

        if (BubbleDebugConfig.DEBUG_POSITIONER) {
            Log.w(TAG, "update positioner:"
                    + " rotation: " + mRotation
                    + " insets: " + deviceConfig.getInsets()
                    + " isLargeScreen: " + deviceConfig.isLargeScreen()
                    + " isSmallTablet: " + deviceConfig.isSmallTablet()
                    + " insets: " + insets
                    + " isLargeScreen: " + mIsLargeScreen
                    + " isSmallTablet: " + mIsSmallTablet
                    + " showingInBubbleBar: " + mShowingInBubbleBar
                    + " bounds: " + deviceConfig.getWindowBounds());
                    + " bounds: " + bounds);
        }
        updateInternal(mRotation, deviceConfig.getInsets(), deviceConfig.getWindowBounds());
        updateInternal(mRotation, insets, bounds);
    }

    @VisibleForTesting
@@ -150,15 +175,15 @@ public class BubblePositioner {
            mExpandedViewLargeScreenWidth = isLandscape()
                    ? (int) (bounds.width() * EXPANDED_VIEW_BUBBLE_BAR_LANDSCAPE_WIDTH_PERCENT)
                    : (int) (bounds.width() * EXPANDED_VIEW_BUBBLE_BAR_PORTRAIT_WIDTH_PERCENT);
        } else if (mDeviceConfig.isSmallTablet()) {
        } else if (mIsSmallTablet) {
            mExpandedViewLargeScreenWidth = (int) (bounds.width()
                    * EXPANDED_VIEW_SMALL_TABLET_WIDTH_PERCENT);
        } else {
            mExpandedViewLargeScreenWidth =
                    res.getDimensionPixelSize(R.dimen.bubble_expanded_view_largescreen_width);
        }
        if (mDeviceConfig.isLargeScreen()) {
            if (mDeviceConfig.isSmallTablet()) {
        if (mIsLargeScreen) {
            if (mIsSmallTablet) {
                final int centeredInset = (bounds.width() - mExpandedViewLargeScreenWidth) / 2;
                mExpandedViewLargeScreenInsetClosestEdge = centeredInset;
                mExpandedViewLargeScreenInsetFurthestEdge = centeredInset;
@@ -239,12 +264,13 @@ public class BubblePositioner {

    /** @return whether the device is in landscape orientation. */
    public boolean isLandscape() {
        return mDeviceConfig.isLandscape();
        return mContext.getResources().getConfiguration().orientation
                == Configuration.ORIENTATION_LANDSCAPE;
    }

    /** @return whether the screen is considered large. */
    public boolean isLargeScreen() {
        return mDeviceConfig.isLargeScreen();
        return mIsLargeScreen;
    }

    /**
@@ -255,7 +281,7 @@ public class BubblePositioner {
     * to the left or right side.
     */
    public boolean showBubblesVertically() {
        return isLandscape() || mDeviceConfig.isLargeScreen();
        return isLandscape() || mIsLargeScreen;
    }

    /** Size of the bubble. */
@@ -308,7 +334,7 @@ public class BubblePositioner {
    }

    private int getExpandedViewLargeScreenInsetFurthestEdge(boolean isOverflow) {
        if (isOverflow && mDeviceConfig.isLargeScreen()) {
        if (isOverflow && mIsLargeScreen) {
            return mScreenRect.width()
                    - mExpandedViewLargeScreenInsetClosestEdge
                    - mOverflowWidth;
@@ -332,7 +358,7 @@ public class BubblePositioner {
        final int pointerTotalHeight = getPointerSize();
        final int expandedViewLargeScreenInsetFurthestEdge =
                getExpandedViewLargeScreenInsetFurthestEdge(isOverflow);
        if (mDeviceConfig.isLargeScreen()) {
        if (mIsLargeScreen) {
            // Note:
            // If we're in portrait OR if we're a small tablet, then the two insets values will
            // be equal. If we're landscape and a large tablet, the two values will be different.
@@ -413,12 +439,12 @@ public class BubblePositioner {
     */
    public float getExpandedViewHeight(BubbleViewProvider bubble) {
        boolean isOverflow = bubble == null || BubbleOverflow.KEY.equals(bubble.getKey());
        if (isOverflow && showBubblesVertically() && !mDeviceConfig.isLargeScreen()) {
        if (isOverflow && showBubblesVertically() && !mIsLargeScreen) {
            // overflow in landscape on phone is max
            return MAX_HEIGHT;
        }

        if (mDeviceConfig.isLargeScreen() && !mDeviceConfig.isSmallTablet() && !isOverflow) {
        if (mIsLargeScreen && !mIsSmallTablet && !isOverflow) {
            // the expanded view height on large tablets is calculated based on the shortest screen
            // size and is the same in both portrait and landscape
            int maxVerticalInset = Math.max(mInsets.top, mInsets.bottom);
@@ -503,9 +529,11 @@ public class BubblePositioner {
     */
    public PointF getExpandedBubbleXY(int index, BubbleStackView.StackViewState state) {
        boolean showBubblesVertically = showBubblesVertically();
        boolean isRtl = mContext.getResources().getConfiguration().getLayoutDirection()
                == LAYOUT_DIRECTION_RTL;

        int onScreenIndex;
        if (showBubblesVertically || !mDeviceConfig.isRtl()) {
        if (showBubblesVertically || !isRtl) {
            onScreenIndex = index;
        } else {
            // If bubbles are shown horizontally, check if RTL language is used.
@@ -526,10 +554,10 @@ public class BubblePositioner {
        if (showBubblesVertically) {
            int inset = mExpandedViewLargeScreenInsetClosestEdge;
            y = rowStart + positionInRow;
            int left = mDeviceConfig.isLargeScreen()
            int left = mIsLargeScreen
                    ? inset - mExpandedViewPadding - mBubbleSize
                    : mPositionRect.left;
            int right = mDeviceConfig.isLargeScreen()
            int right = mIsLargeScreen
                    ? mPositionRect.right - inset + mExpandedViewPadding
                    : mPositionRect.right - mBubbleSize;
            x = state.onLeft
@@ -665,10 +693,13 @@ public class BubblePositioner {
     * @param isAppBubble whether this start position is for an app bubble or not.
     */
    public PointF getDefaultStartPosition(boolean isAppBubble) {
        final int layoutDirection = mContext.getResources().getConfiguration().getLayoutDirection();
        // Normal bubbles start on the left if we're in LTR, right otherwise.
        // TODO (b/294284894): update language around "app bubble" here
        // App bubbles start on the right in RTL, left otherwise.
        final boolean startOnLeft = isAppBubble ? mDeviceConfig.isRtl() : !mDeviceConfig.isRtl();
        final boolean startOnLeft = isAppBubble
                ? layoutDirection == LAYOUT_DIRECTION_RTL
                : layoutDirection != LAYOUT_DIRECTION_RTL;
        return getStartPosition(startOnLeft ? StackPinnedEdge.LEFT : StackPinnedEdge.RIGHT);
    }

+2 −5
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@ import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewPropertyAnimator;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManagerPolicyConstants;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
@@ -1002,8 +1001,7 @@ public class BubbleStackView extends FrameLayout

        mOrientationChangedListener =
                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
                    mPositioner.update(DeviceConfig.create(mContext, mContext.getSystemService(
                            WindowManager.class)));
                    mPositioner.update();
                    onDisplaySizeChanged();
                    mExpandedAnimationController.updateResources();
                    mStackAnimationController.updateResources();
@@ -1524,8 +1522,7 @@ public class BubbleStackView extends FrameLayout
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        WindowManager windowManager = mContext.getSystemService(WindowManager.class);
        mPositioner.update(DeviceConfig.create(mContext, Objects.requireNonNull(windowManager)));
        mPositioner.update();
        getViewTreeObserver().addOnComputeInternalInsetsListener(this);
        getViewTreeObserver().addOnDrawListener(mSystemGestureExcludeUpdater);
    }
+0 −67
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.wm.shell.bubbles

import android.content.Context
import android.content.res.Configuration
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
import android.graphics.Insets
import android.graphics.Rect
import android.view.View.LAYOUT_DIRECTION_RTL
import android.view.WindowInsets
import android.view.WindowManager
import kotlin.math.max

/** Contains device configuration used for positioning bubbles on the screen. */
data class DeviceConfig(
        val isLargeScreen: Boolean,
        val isSmallTablet: Boolean,
        val isLandscape: Boolean,
        val isRtl: Boolean,
        val windowBounds: Rect,
        val insets: Insets
) {
    companion object {

        private const val LARGE_SCREEN_MIN_EDGE_DP = 600
        private const val SMALL_TABLET_MAX_EDGE_DP = 960

        @JvmStatic
        fun create(context: Context, windowManager: WindowManager): DeviceConfig {
            val windowMetrics = windowManager.currentWindowMetrics
            val metricInsets = windowMetrics.windowInsets
            val insets = metricInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
                    or WindowInsets.Type.statusBars()
                    or WindowInsets.Type.displayCutout())
            val windowBounds = windowMetrics.bounds
            val config: Configuration = context.resources.configuration
            val isLargeScreen = config.smallestScreenWidthDp >= LARGE_SCREEN_MIN_EDGE_DP
            val largestEdgeDp = max(config.screenWidthDp, config.screenHeightDp)
            val isSmallTablet = isLargeScreen && largestEdgeDp < SMALL_TABLET_MAX_EDGE_DP
            val isLandscape = context.resources.configuration.orientation == ORIENTATION_LANDSCAPE
            val isRtl = context.resources.configuration.layoutDirection == LAYOUT_DIRECTION_RTL
            return DeviceConfig(
                    isLargeScreen = isLargeScreen,
                    isSmallTablet = isSmallTablet,
                    isLandscape = isLandscape,
                    isRtl = isRtl,
                    windowBounds = windowBounds,
                    insets = insets
            )
        }
    }
}
+1 −5
Original line number Diff line number Diff line
@@ -28,16 +28,13 @@ import android.graphics.drawable.ColorDrawable;
import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.FrameLayout;

import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.bubbles.BubbleOverflow;
import com.android.wm.shell.bubbles.BubblePositioner;
import com.android.wm.shell.bubbles.BubbleViewProvider;
import com.android.wm.shell.bubbles.DeviceConfig;

import java.util.Objects;
import java.util.function.Consumer;

import kotlin.Unit;
@@ -107,8 +104,7 @@ public class BubbleBarLayerView extends FrameLayout
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        WindowManager windowManager = mContext.getSystemService(WindowManager.class);
        mPositioner.update(DeviceConfig.create(mContext, Objects.requireNonNull(windowManager)));
        mPositioner.update();
        getViewTreeObserver().addOnComputeInternalInsetsListener(this);
    }

Loading