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

Commit d2cdb1c9 authored by Ats Jenk's avatar Ats Jenk Committed by Android (Google) Code Review
Browse files

Merge "Pass bubble drop target bounds to desktop indicator" into main

parents 76b5b552 fb296048
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.shared.bubbles

import android.graphics.Rect

/**
 * Provide bounds for Bubbles drop targets that are shown when dragging over drag zones
 */
interface BubbleDropTargetBoundsProvider {
    /**
     * Get bubble bar expanded view visual drop target bounds on screen
     */
    fun getBubbleBarExpandedViewDropTargetBounds(onLeft: Boolean): Rect
}
 No newline at end of file
+6 −0
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.bubbles.BubbleBarUpdate;
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
import com.android.wm.shell.shared.bubbles.DeviceConfig;
import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
@@ -925,6 +926,11 @@ public class BubbleController implements ConfigurationChangeListener,
        return mBubblePositioner;
    }

    /** Provides bounds for drag zone drop targets */
    public BubbleDropTargetBoundsProvider getBubbleDropTargetBoundsProvider() {
        return mBubblePositioner;
    }

    BubbleIconFactory getIconFactory() {
        return mBubbleIconFactory;
    }
+16 −1
Original line number Diff line number Diff line
@@ -27,19 +27,21 @@ import android.graphics.RectF;
import android.view.Surface;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;

import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.IconNormalizer;
import com.android.wm.shell.R;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
import com.android.wm.shell.shared.bubbles.DeviceConfig;

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

    /** The screen edge the bubble stack is pinned to */
    public enum StackPinnedEdge {
@@ -100,6 +102,7 @@ public class BubblePositioner {
    private int mManageButtonHeight;
    private int mOverflowHeight;
    private int mMinimumFlyoutWidthLargeScreen;
    private int mBubbleBarExpandedViewDropTargetPadding;

    private PointF mRestingStackPosition;

@@ -164,6 +167,8 @@ public class BubblePositioner {
                res.getDimensionPixelSize(R.dimen.bubble_bar_expanded_view_width),
                mPositionRect.width() - 2 * mExpandedViewPadding
        );
        mBubbleBarExpandedViewDropTargetPadding = res.getDimensionPixelSize(
                R.dimen.bubble_bar_expanded_view_drop_target_padding);

        if (mShowingInBubbleBar) {
            mExpandedViewLargeScreenWidth = mExpandedViewBubbleBarWidth;
@@ -965,4 +970,14 @@ public class BubblePositioner {
        int top = getExpandedViewBottomForBubbleBar() - height;
        out.offsetTo(left, top);
    }

    @NonNull
    @Override
    public Rect getBubbleBarExpandedViewDropTargetBounds(boolean onLeft) {
        Rect bounds = new Rect();
        getBubbleBarExpandedViewBounds(onLeft, false, bounds);
        bounds.inset(mBubbleBarExpandedViewDropTargetPadding,
                mBubbleBarExpandedViewDropTargetPadding);
        return bounds;
    }
}
+44 −30
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;

/**
@@ -119,6 +120,7 @@ public class DesktopModeVisualIndicator {
    private final RootTaskDisplayAreaOrganizer mRootTdaOrganizer;
    private final ActivityManager.RunningTaskInfo mTaskInfo;
    private final SurfaceControl mTaskSurface;
    private final @Nullable BubbleDropTargetBoundsProvider mBubbleBoundsProvider;
    private SurfaceControl mLeash;

    private final SyncTransactionQueue mSyncQueue;
@@ -133,13 +135,15 @@ public class DesktopModeVisualIndicator {
            ActivityManager.RunningTaskInfo taskInfo, DisplayController displayController,
            Context context, SurfaceControl taskSurface,
            RootTaskDisplayAreaOrganizer taskDisplayAreaOrganizer,
            DragStartState dragStartState) {
            DragStartState dragStartState,
            @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
        mSyncQueue = syncQueue;
        mTaskInfo = taskInfo;
        mDisplayController = displayController;
        mContext = context;
        mTaskSurface = taskSurface;
        mRootTdaOrganizer = taskDisplayAreaOrganizer;
        mBubbleBoundsProvider = bubbleBoundsProvider;
        mCurrentType = NO_INDICATOR;
        mDragStartState = dragStartState;
    }
@@ -329,6 +333,11 @@ public class DesktopModeVisualIndicator {
        });
    }

    @VisibleForTesting
    Rect getIndicatorBounds() {
        return mView.getBackground().getBounds();
    }

    /**
     * Fade indicator in as provided type. Animator fades it in while expanding the bounds outwards.
     */
@@ -336,7 +345,8 @@ public class DesktopModeVisualIndicator {
        mView.setBackgroundResource(R.drawable.desktop_windowing_transition_background);
        final VisualIndicatorAnimator animator = VisualIndicatorAnimator
                .fadeBoundsIn(mView, type,
                        mDisplayController.getDisplayLayout(mTaskInfo.displayId));
                        mDisplayController.getDisplayLayout(mTaskInfo.displayId),
                        mBubbleBoundsProvider);
        animator.start();
        mCurrentType = type;
    }
@@ -355,7 +365,8 @@ public class DesktopModeVisualIndicator {
        }
        final VisualIndicatorAnimator animator = VisualIndicatorAnimator
                .fadeBoundsOut(mView, mCurrentType,
                        mDisplayController.getDisplayLayout(mTaskInfo.displayId));
                        mDisplayController.getDisplayLayout(mTaskInfo.displayId),
                        mBubbleBoundsProvider);
        animator.start();
        if (finishCallback != null) {
            animator.addListener(new AnimatorListenerAdapter() {
@@ -383,7 +394,7 @@ public class DesktopModeVisualIndicator {
        } else {
            final VisualIndicatorAnimator animator = VisualIndicatorAnimator.animateIndicatorType(
                    mView, mDisplayController.getDisplayLayout(mTaskInfo.displayId), mCurrentType,
                    newType);
                    newType, mBubbleBoundsProvider);
            mCurrentType = newType;
            animator.start();
        }
@@ -438,8 +449,9 @@ public class DesktopModeVisualIndicator {
        }

        private static VisualIndicatorAnimator fadeBoundsIn(
                @NonNull View view, IndicatorType type, @NonNull DisplayLayout displayLayout) {
            final Rect endBounds = getIndicatorBounds(displayLayout, type);
                @NonNull View view, IndicatorType type, @NonNull DisplayLayout displayLayout,
                @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
            final Rect endBounds = getIndicatorBounds(displayLayout, type, bubbleBoundsProvider);
            final Rect startBounds = getMinBounds(endBounds);
            view.getBackground().setBounds(startBounds);

@@ -451,8 +463,9 @@ public class DesktopModeVisualIndicator {
        }

        private static VisualIndicatorAnimator fadeBoundsOut(
                @NonNull View view, IndicatorType type, @NonNull DisplayLayout displayLayout) {
            final Rect startBounds = getIndicatorBounds(displayLayout, type);
                @NonNull View view, IndicatorType type, @NonNull DisplayLayout displayLayout,
                @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
            final Rect startBounds = getIndicatorBounds(displayLayout, type, bubbleBoundsProvider);
            final Rect endBounds = getMinBounds(startBounds);
            view.getBackground().setBounds(startBounds);

@@ -468,15 +481,18 @@ public class DesktopModeVisualIndicator {
         * freeform to split, etc.)
         *
         * @param view                 the view for this indicator
         * @param displayLayout information about the display the transitioning task is currently on
         * @param displayLayout        information about the display the transitioning task is
         *                             currently on
         * @param origType             the original indicator type
         * @param newType              the new indicator type
         * @param bubbleBoundsProvider provides bounds for bubbles indicators
         */
        private static VisualIndicatorAnimator animateIndicatorType(@NonNull View view,
                @NonNull DisplayLayout displayLayout, IndicatorType origType,
                IndicatorType newType) {
            final Rect startBounds = getIndicatorBounds(displayLayout, origType);
            final Rect endBounds = getIndicatorBounds(displayLayout, newType);
                @NonNull DisplayLayout displayLayout, IndicatorType origType, IndicatorType newType,
                @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
            final Rect startBounds = getIndicatorBounds(displayLayout, origType,
                    bubbleBoundsProvider);
            final Rect endBounds = getIndicatorBounds(displayLayout, newType, bubbleBoundsProvider);
            final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
                    view, startBounds, endBounds);
            animator.setInterpolator(new DecelerateInterpolator());
@@ -485,7 +501,8 @@ public class DesktopModeVisualIndicator {
        }

        /** Calculates the bounds the indicator should have when fully faded in. */
        private static Rect getIndicatorBounds(DisplayLayout layout, IndicatorType type) {
        private static Rect getIndicatorBounds(DisplayLayout layout, IndicatorType type,
                @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
            final Rect desktopStableBounds = new Rect();
            layout.getStableBounds(desktopStableBounds);
            final int padding = desktopStableBounds.top;
@@ -514,20 +531,17 @@ public class DesktopModeVisualIndicator {
                            desktopStableBounds.width() - padding,
                            desktopStableBounds.height());
                case TO_BUBBLE_LEFT_INDICATOR:
                    // TODO(b/388851898): define based on bubble size on the device
                    return new Rect(
                            padding,
                            desktopStableBounds.height() / 2 - padding,
                            desktopStableBounds.width() / 2 - padding,
                            desktopStableBounds.height());
                    if (bubbleBoundsProvider == null) {
                        return new Rect();
                    }
                    return bubbleBoundsProvider.getBubbleBarExpandedViewDropTargetBounds(
                            /* onLeft= */ true);
                case TO_BUBBLE_RIGHT_INDICATOR:
                    // TODO(b/388851898): define based on bubble size on the device
                    return new Rect(
                            desktopStableBounds.width() / 2 + padding,
                            desktopStableBounds.height() / 2 - padding,
                            desktopStableBounds.width() - padding,
                            desktopStableBounds.height()
                    );
                    if (bubbleBoundsProvider == null) {
                        return new Rect();
                    }
                    return bubbleBoundsProvider.getBubbleBarExpandedViewDropTargetBounds(
                            /* onLeft= */ false);
                default:
                    throw new IllegalArgumentException("Invalid indicator type provided.");
            }
+2 −0
Original line number Diff line number Diff line
@@ -150,6 +150,7 @@ import java.util.Optional
import java.util.concurrent.Executor
import java.util.concurrent.TimeUnit
import java.util.function.Consumer
import kotlin.jvm.optionals.getOrNull

/** Handles moving tasks in and out of desktop */
class DesktopTasksController(
@@ -2706,6 +2707,7 @@ class DesktopTasksController(
                    taskSurface,
                    rootTaskDisplayAreaOrganizer,
                    dragStartState,
                    bubbleController.getOrNull()?.bubbleDropTargetBoundsProvider,
                )
        if (visualIndicator == null) visualIndicator = indicator
        return indicator.updateIndicatorType(PointF(inputX, taskTop))
Loading