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

Commit 3e6c837f authored by Matt Sziklay's avatar Matt Sziklay Committed by Automerger Merge Worker
Browse files

Merge "Delegate handle menu operations to a separate class." into udc-dev am:...

Merge "Delegate handle menu operations to a separate class." into udc-dev am: aa3a23f8 am: 2c362818

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22600141



Change-Id: I34a6499c0fdd1c43bc052a26d113dbe4c0498daa
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 42167fff 2c362818
Loading
Loading
Loading
Loading
+19 −214
Original line number Diff line number Diff line
@@ -17,17 +17,12 @@
package com.android.wm.shell.windowdecor;

import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Region;
@@ -39,11 +34,6 @@ import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.window.SurfaceSyncGroup;
import android.window.WindowContainerTransaction;

import com.android.launcher3.icons.IconProvider;
@@ -90,6 +80,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    private AdditionalWindow mHandleMenuAppInfoPill;
    private AdditionalWindow mHandleMenuWindowingPill;
    private AdditionalWindow mHandleMenuMoreActionsPill;
    private HandleMenu mHandleMenu;

    private Drawable mAppIcon;
    private CharSequence mAppName;
@@ -122,29 +113,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        mSyncQueue = syncQueue;

        loadAppInfo();
        loadHandleMenuDimensions();
    }

    private void loadHandleMenuDimensions() {
        final Resources resources = mDecorWindowContext.getResources();
        mMenuWidth = loadDimensionPixelSize(resources,
                R.dimen.desktop_mode_handle_menu_width);
        mMarginMenuTop = loadDimensionPixelSize(resources,
                R.dimen.desktop_mode_handle_menu_margin_top);
        mMarginMenuStart = loadDimensionPixelSize(resources,
                R.dimen.desktop_mode_handle_menu_margin_start);
        mMarginMenuSpacing = loadDimensionPixelSize(resources,
                R.dimen.desktop_mode_handle_menu_pill_spacing_margin);
        mAppInfoPillHeight = loadDimensionPixelSize(resources,
                R.dimen.desktop_mode_handle_menu_app_info_pill_height);
        mWindowingPillHeight = loadDimensionPixelSize(resources,
                R.dimen.desktop_mode_handle_menu_windowing_pill_height);
        mShadowRadius = loadDimensionPixelSize(resources,
                R.dimen.desktop_mode_handle_menu_shadow_radius);
        mCornerRadius = loadDimensionPixelSize(resources,
                R.dimen.desktop_mode_handle_menu_corner_radius);
        mMoreActionsPillHeight = loadDimensionPixelSize(resources,
                R.dimen.desktop_mode_handle_menu_more_actions_pill_height);
    }

    @Override
@@ -197,20 +165,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM;
        final boolean isDragResizeable = isFreeform && taskInfo.isResizeable;

        if (mHandleMenuAppInfoPill != null) {
            updateHandleMenuPillPositions();
            startT.setPosition(mHandleMenuAppInfoPill.mWindowSurface,
                    mHandleMenuAppInfoPillPosition.x, mHandleMenuAppInfoPillPosition.y);

            // Only show windowing buttons in proto2. Proto1 uses a system-level mode only.
            final boolean shouldShowWindowingPill = DesktopModeStatus.isProto2Enabled();
            if (shouldShowWindowingPill) {
                startT.setPosition(mHandleMenuWindowingPill.mWindowSurface,
                        mHandleMenuWindowingPillPosition.x, mHandleMenuWindowingPillPosition.y);
            }

            startT.setPosition(mHandleMenuMoreActionsPill.mWindowSurface,
                    mHandleMenuMoreActionsPillPosition.x, mHandleMenuMoreActionsPillPosition.y);
        if (isHandleMenuActive()) {
            mHandleMenu.relayout(startT);
        }

        final WindowDecorLinearLayout oldRootView = mResult.mRootView;
@@ -297,7 +253,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    }

    boolean isHandleMenuActive() {
        return mHandleMenuAppInfoPill != null;
        return mHandleMenu != null;
    }

    private void loadAppInfo() {
@@ -327,136 +283,16 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
     * Create and display handle menu window
     */
    void createHandleMenu() {
        final SurfaceSyncGroup ssg = new SurfaceSyncGroup(TAG);
        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        updateHandleMenuPillPositions();

        createAppInfoPill(t, ssg);

        // Only show windowing buttons in proto2. Proto1 uses a system-level mode only.
        final boolean shouldShowWindowingPill = DesktopModeStatus.isProto2Enabled();
        if (shouldShowWindowingPill) {
            createWindowingPill(t, ssg);
        }

        createMoreActionsPill(t, ssg);

        ssg.addTransaction(t);
        ssg.markSyncReady();
        setupHandleMenu(shouldShowWindowingPill);
    }

    private void createAppInfoPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) {
        final int x = (int) mHandleMenuAppInfoPillPosition.x;
        final int y = (int) mHandleMenuAppInfoPillPosition.y;
        mHandleMenuAppInfoPill = addWindow(
                R.layout.desktop_mode_window_decor_handle_menu_app_info_pill,
                "Menu's app info pill",
                t, ssg, x, y, mMenuWidth, mAppInfoPillHeight, mShadowRadius, mCornerRadius);
    }

    private void createWindowingPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) {
        final int x = (int) mHandleMenuWindowingPillPosition.x;
        final int y = (int) mHandleMenuWindowingPillPosition.y;
        mHandleMenuWindowingPill = addWindow(
                R.layout.desktop_mode_window_decor_handle_menu_windowing_pill,
                "Menu's windowing pill",
                t, ssg, x, y, mMenuWidth, mWindowingPillHeight, mShadowRadius, mCornerRadius);
    }

    private void createMoreActionsPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) {
        final int x = (int) mHandleMenuMoreActionsPillPosition.x;
        final int y = (int) mHandleMenuMoreActionsPillPosition.y;
        mHandleMenuMoreActionsPill = addWindow(
                R.layout.desktop_mode_window_decor_handle_menu_more_actions_pill,
                "Menu's more actions pill",
                t, ssg, x, y, mMenuWidth, mMoreActionsPillHeight, mShadowRadius, mCornerRadius);
    }

    private void setupHandleMenu(boolean windowingPillShown) {
        // App Info pill setup.
        final View appInfoPillView = mHandleMenuAppInfoPill.mWindowViewHost.getView();
        final ImageButton collapseBtn = appInfoPillView.findViewById(R.id.collapse_menu_button);
        final ImageView appIcon = appInfoPillView.findViewById(R.id.application_icon);
        final TextView appName = appInfoPillView.findViewById(R.id.application_name);
        collapseBtn.setOnClickListener(mOnCaptionButtonClickListener);
        appInfoPillView.setOnTouchListener(mOnCaptionTouchListener);
        appIcon.setImageDrawable(mAppIcon);
        appName.setText(mAppName);

        // Windowing pill setup.
        if (windowingPillShown) {
            final View windowingPillView = mHandleMenuWindowingPill.mWindowViewHost.getView();
            final ImageButton fullscreenBtn = windowingPillView.findViewById(
                    R.id.fullscreen_button);
            final ImageButton splitscreenBtn = windowingPillView.findViewById(
                    R.id.split_screen_button);
            final ImageButton floatingBtn = windowingPillView.findViewById(R.id.floating_button);
            final ImageButton desktopBtn = windowingPillView.findViewById(R.id.desktop_button);
            fullscreenBtn.setOnClickListener(mOnCaptionButtonClickListener);
            splitscreenBtn.setOnClickListener(mOnCaptionButtonClickListener);
            floatingBtn.setOnClickListener(mOnCaptionButtonClickListener);
            desktopBtn.setOnClickListener(mOnCaptionButtonClickListener);
            // The button corresponding to the windowing mode that the task is currently in uses a
            // different color than the others.
            final ColorStateList activeColorStateList = ColorStateList.valueOf(
                    mContext.getColor(R.color.desktop_mode_caption_menu_buttons_color_active));
            final ColorStateList inActiveColorStateList = ColorStateList.valueOf(
                    mContext.getColor(R.color.desktop_mode_caption_menu_buttons_color_inactive));
            fullscreenBtn.setImageTintList(
                    mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
                            ? activeColorStateList : inActiveColorStateList);
            splitscreenBtn.setImageTintList(
                    mTaskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
                            ? activeColorStateList : inActiveColorStateList);
            floatingBtn.setImageTintList(mTaskInfo.getWindowingMode() == WINDOWING_MODE_PINNED
                    ? activeColorStateList : inActiveColorStateList);
            desktopBtn.setImageTintList(mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
                    ? activeColorStateList : inActiveColorStateList);
        }

        // More Actions pill setup.
        final View moreActionsPillView = mHandleMenuMoreActionsPill.mWindowViewHost.getView();
        final Button closeBtn = moreActionsPillView.findViewById(R.id.close_button);
        closeBtn.setOnClickListener(mOnCaptionButtonClickListener);
    }

    /**
     * Updates the handle menu pills' position variables to reflect their next positions
     */
    private void updateHandleMenuPillPositions() {
        final int menuX, menuY;
        final int captionWidth = mTaskInfo.getConfiguration()
                .windowConfiguration.getBounds().width();
        if (mRelayoutParams.mLayoutResId
                == R.layout.desktop_mode_app_controls_window_decor) {
            // Align the handle menu to the left of the caption.
            menuX = mRelayoutParams.mCaptionX + mMarginMenuStart;
            menuY = mRelayoutParams.mCaptionY + mMarginMenuTop;
        } else {
            // Position the handle menu at the center of the caption.
            menuX = mRelayoutParams.mCaptionX + (captionWidth / 2) - (mMenuWidth / 2);
            menuY = mRelayoutParams.mCaptionY + mMarginMenuStart;
        }

        // App Info pill setup.
        final int appInfoPillY = menuY;
        mHandleMenuAppInfoPillPosition.set(menuX, appInfoPillY);

        // Only show windowing buttons in proto2. Proto1 uses a system-level mode only.
        final boolean shouldShowWindowingPill = DesktopModeStatus.isProto2Enabled();

        final int windowingPillY, moreActionsPillY;
        if (shouldShowWindowingPill) {
            windowingPillY = appInfoPillY + mAppInfoPillHeight + mMarginMenuSpacing;
            mHandleMenuWindowingPillPosition.set(menuX, windowingPillY);
            moreActionsPillY = windowingPillY + mWindowingPillHeight + mMarginMenuSpacing;
            mHandleMenuMoreActionsPillPosition.set(menuX, moreActionsPillY);
        } else {
            // Just start after the end of the app info pill + margins.
            moreActionsPillY = appInfoPillY + mAppInfoPillHeight + mMarginMenuSpacing;
            mHandleMenuMoreActionsPillPosition.set(menuX, moreActionsPillY);
        }
        mHandleMenu = new HandleMenu.Builder(this)
                .setAppIcon(mAppIcon)
                .setAppName(mAppName)
                .setOnClickListener(mOnCaptionButtonClickListener)
                .setOnTouchListener(mOnCaptionTouchListener)
                .setLayoutId(mRelayoutParams.mLayoutResId)
                .setCaptionPosition(mRelayoutParams.mCaptionX, mRelayoutParams.mCaptionY)
                .setWindowingButtonsVisible(DesktopModeStatus.isProto2Enabled())
                .build();
        mHandleMenu.show();
    }

    /**
@@ -464,14 +300,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
     */
    void closeHandleMenu() {
        if (!isHandleMenuActive()) return;
        mHandleMenuAppInfoPill.releaseView();
        mHandleMenuAppInfoPill = null;
        if (mHandleMenuWindowingPill != null) {
            mHandleMenuWindowingPill.releaseView();
            mHandleMenuWindowingPill = null;
        }
        mHandleMenuMoreActionsPill.releaseView();
        mHandleMenuMoreActionsPill = null;
        mHandleMenu.close();
        mHandleMenu = null;
    }

    @Override
@@ -488,10 +318,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    void closeHandleMenuIfNeeded(MotionEvent ev) {
        if (!isHandleMenuActive()) return;

        // When this is called before the layout is fully inflated, width will be 0.
        // Menu is not visible in this scenario, so skip the check if that is the case.
        if (mHandleMenuAppInfoPill.mWindowViewHost.getView().getWidth() == 0) return;

        PointF inputPoint = offsetCaptionLocation(ev);

        // If this is called before open_menu_button's onClick, we don't want to close
@@ -501,22 +327,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                inputPoint.x,
                inputPoint.y);

        final boolean pointInAppInfoPill = pointInView(
                mHandleMenuAppInfoPill.mWindowViewHost.getView(),
                inputPoint.x - mHandleMenuAppInfoPillPosition.x,
                inputPoint.y - mHandleMenuAppInfoPillPosition.y);
        boolean pointInWindowingPill = false;
        if (mHandleMenuWindowingPill != null) {
            pointInWindowingPill = pointInView(mHandleMenuWindowingPill.mWindowViewHost.getView(),
                    inputPoint.x - mHandleMenuWindowingPillPosition.x,
                    inputPoint.y - mHandleMenuWindowingPillPosition.y);
        }
        final boolean pointInMoreActionsPill = pointInView(
                mHandleMenuMoreActionsPill.mWindowViewHost.getView(),
                inputPoint.x - mHandleMenuMoreActionsPillPosition.x,
                inputPoint.y - mHandleMenuMoreActionsPillPosition.y);
        if (!pointInAppInfoPill && !pointInWindowingPill
                && !pointInMoreActionsPill && !pointInOpenMenuButton) {
        if (!mHandleMenu.isValidMenuInput(inputPoint) && !pointInOpenMenuButton) {
            closeHandleMenu();
        }
    }
@@ -573,13 +384,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            final View handle = caption.findViewById(R.id.caption_handle);
            clickIfPointInView(new PointF(ev.getX(), ev.getY()), handle);
        } else {
            final View appInfoPill = mHandleMenuAppInfoPill.mWindowViewHost.getView();
            final ImageButton collapse = appInfoPill.findViewById(R.id.collapse_menu_button);
            // Translate the input point from display coordinates to the same space as the collapse
            // button, meaning its parent (app info pill view).
            final PointF inputPoint = new PointF(ev.getX() - mHandleMenuAppInfoPillPosition.x,
                    ev.getY() - mHandleMenuAppInfoPillPosition.y);
            clickIfPointInView(inputPoint, collapse);
            mHandleMenu.checkClickEvent(ev);
        }
    }

@@ -591,7 +396,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        return false;
    }

    private boolean pointInView(View v, float x, float y) {
    boolean pointInView(View v, float x, float y) {
        return v != null && v.getLeft() <= x && v.getRight() >= x
                && v.getTop() <= y && v.getBottom() >= y;
    }
+402 −0

File added.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Diff line number Diff line
@@ -458,7 +458,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        SurfaceControlViewHost mWindowViewHost;
        Supplier<SurfaceControl.Transaction> mTransactionSupplier;

        private AdditionalWindow(SurfaceControl surfaceControl,
        AdditionalWindow(SurfaceControl surfaceControl,
                SurfaceControlViewHost surfaceControlViewHost,
                Supplier<SurfaceControl.Transaction> transactionSupplier) {
            mWindowSurface = surfaceControl;