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

Commit c58c52d5 authored by Liana Kazanova (xWF)'s avatar Liana Kazanova (xWF) Committed by Android (Google) Code Review
Browse files

Revert "Update A11y strings for flex split"

This reverts commit 39ed2478.

Reason for revert: DroidMonitor: Potential culprit for b/421184598 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted

Bug: 421184598
Change-Id: I446c7fea6075ea9c73f4708d1891af87f4287af4
parent 39ed2478
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -21,11 +21,9 @@

    <!-- Accessibility actions for the docked stack divider -->
    <item type="id" name="action_move_tl_full" />
    <item type="id" name="action_move_tl_90" />
    <item type="id" name="action_move_tl_70" />
    <item type="id" name="action_move_tl_50" />
    <item type="id" name="action_move_tl_30" />
    <item type="id" name="action_move_tl_10" />
    <item type="id" name="action_move_rb_full" />
    <item type="id" name="action_swap_apps" />

+12 −16
Original line number Diff line number Diff line
@@ -83,33 +83,29 @@
    <string name="divider_title">Split screen divider</string>

    <!-- Accessibility action for moving docked stack divider to make the left screen full screen [CHAR LIMIT=NONE] -->
    <string name="accessibility_action_divider_left_full">Make left app full screen</string>
    <string name="accessibility_action_divider_left_full">Left full screen</string>
    <!-- Accessibility action for moving docked stack divider to make the left screen 70% [CHAR LIMIT=NONE] -->
    <string formatted="false" name="accessibility_action_divider_left_10">10% left, 90% right</string>
    <string formatted="false" name="accessibility_action_divider_left_30">30% left, 70% right</string>
    <string name="accessibility_action_divider_left_70">Left 70%</string>
    <!-- Accessibility action for moving docked stack divider to make the left screen 50% [CHAR LIMIT=NONE] -->
    <string formatted="false" name="accessibility_action_divider_left_50">50% left, 50% right</string>
    <string name="accessibility_action_divider_left_50">Left 50%</string>
    <!-- Accessibility action for moving docked stack divider to make the left screen 30% [CHAR LIMIT=NONE] -->
    <string formatted="false" name="accessibility_action_divider_left_70">70% left, 30% right</string>
    <string formatted="false" name="accessibility_action_divider_left_90">90% left, 10% right</string>
    <string name="accessibility_action_divider_left_30">Left 30%</string>
    <!-- Accessibility action for moving docked stack divider to make the right screen full screen [CHAR LIMIT=NONE] -->
    <string name="accessibility_action_divider_right_full">Make right app full screen</string>
    <string name="accessibility_action_divider_right_full">Right full screen</string>
    <!-- Accessibility action for swapping the apps around the divider (double tap action) [CHAR LIMIT=NONE] -->
    <string name="accessibility_action_divider_swap_vertical">Swap top app with bottom app, keep current split</string>
    <string name="accessibility_action_divider_swap_horizontal">Swap left app with right app, keep current split</string>
    <string name="accessibility_action_divider_swap_vertical">Swap top app with bottom</string>
    <string name="accessibility_action_divider_swap_horizontal">Swap left app with right</string>

    <!-- Accessibility action for moving docked stack divider to make the top screen full screen [CHAR LIMIT=NONE] -->
    <string name="accessibility_action_divider_top_full">Make top app full screen</string>
    <string name="accessibility_action_divider_top_full">Top full screen</string>
    <!-- Accessibility action for moving docked stack divider to make the top screen 70% [CHAR LIMIT=NONE] -->
    <string formatted="false" name="accessibility_action_divider_top_10">10% top, 90% bottom</string>
    <string formatted="false" name="accessibility_action_divider_top_30">30% top, 70% bottom</string>
    <string name="accessibility_action_divider_top_70">Top 70%</string>
    <!-- Accessibility action for moving docked stack divider to make the top screen 50% [CHAR LIMIT=NONE] -->
    <string formatted="false" name="accessibility_action_divider_top_50">50% top, 50% bottom</string>
    <string name="accessibility_action_divider_top_50">Top 50%</string>
    <!-- Accessibility action for moving docked stack divider to make the top screen 30% [CHAR LIMIT=NONE] -->
    <string formatted="false" name="accessibility_action_divider_top_70">70% top, 30% bottom</string>
    <string formatted="false" name="accessibility_action_divider_top_90">90% top, 10% bottom</string>
    <string name="accessibility_action_divider_top_30">Top 30%</string>
    <!-- Accessibility action for moving docked stack divider to make the bottom screen full screen [CHAR LIMIT=NONE] -->
    <string name="accessibility_action_divider_bottom_full">Make bottom app full screen</string>
    <string name="accessibility_action_divider_bottom_full">Bottom full screen</string>

    <!-- Accessibility label for splitting to the left drop zone [CHAR LIMIT=NONE] -->
    <string name="accessibility_split_left">Split left</string>
+23 −23
Original line number Diff line number Diff line
@@ -100,7 +100,6 @@ public class DividerSnapAlgorithm {
    private final boolean mIsLeftRightSplit;
    /** In SNAP_MODE_MINIMIZED, the side of the screen on which an app will "dock" when minimized */
    private final int mDockSide;
    private final SplitTargetProvider mSplitTargetProvider;

    /**
     * The first, and usually only, snap target between the left/top screen edge and center.
@@ -127,16 +126,14 @@ public class DividerSnapAlgorithm {
    private final MotionSpec mMotionSpec;

    public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
            boolean isLeftRightSplit, Rect insets, Rect pinnedTaskbarInsets, int dockSide,
            SplitTargetProvider splitTargetProvider) {
            boolean isLeftRightSplit, Rect insets, Rect pinnedTaskbarInsets, int dockSide) {
        this(res, displayWidth, displayHeight, dividerSize, isLeftRightSplit, insets,
                pinnedTaskbarInsets, dockSide, true /* resizable */,
                splitTargetProvider);
                pinnedTaskbarInsets, dockSide, false /* minimized */, true /* resizable */);
    }

    public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
            boolean isLeftRightSplit, Rect insets, Rect pinnedTaskbarInsets, int dockSide,
            boolean isHomeResizable, SplitTargetProvider splitTargetProvider) {
            boolean isMinimizedMode, boolean isHomeResizable) {
        mMinFlingVelocityPxPerSecond =
                MIN_FLING_VELOCITY_DP_PER_SECOND * res.getDisplayMetrics().density;
        mMinDismissVelocityPxPerSecond =
@@ -146,10 +143,17 @@ public class DividerSnapAlgorithm {
        mDisplayHeight = displayHeight;
        mIsLeftRightSplit = isLeftRightSplit;
        mDockSide = dockSide;
        mSplitTargetProvider = splitTargetProvider;
        mInsets.set(insets);
        mPinnedTaskbarInsets.set(pinnedTaskbarInsets);
        mSnapMode = mSplitTargetProvider.getSnapMode();
        if (Flags.enableFlexibleTwoAppSplit()) {
            mSnapMode = SNAP_FLEXIBLE_HYBRID;
        } else {
            // Set SNAP_MODE_MINIMIZED, SNAP_MODE_16_9, or SNAP_FIXED_RATIO depending on config
            mSnapMode = isMinimizedMode
                    ? SNAP_MODE_MINIMIZED
                    : res.getInteger(
                            com.android.internal.R.integer.config_dockedStackDividerSnapMode);
        }
        mFreeSnapMode = res.getBoolean(
                com.android.internal.R.bool.config_dockedStackDividerFreeSnapMode);
        mFixedRatio = res.getFraction(
@@ -354,10 +358,8 @@ public class DividerSnapAlgorithm {
     */
    private void addNonDismissingTargets(List<Integer> positions, int dividerMax) {
        // Get the desired layout for our snap mode.
        List<Integer> targetSpec = mSplitTargetProvider
                .getTargets(false /*includeDismissal*/)
                .stream().map(SplitTargetProvider.SplitTarget::getSnapPosition)
                .toList();
        List<Integer> targetSpec =
                SplitSpec.getSnapTargetLayout(mSnapMode, areOffscreenRatiosSupported());

        if (positions.size() != targetSpec.size()) {
            throw new IllegalStateException("unexpected number of snap positions");
@@ -370,18 +372,12 @@ public class DividerSnapAlgorithm {
            int position = positions.get(i);

            if (!midpointPassed) {
                if (target == SNAP_TO_2_50_50) {
                    // midpoint
                maybeAddTarget(position, position - getStartInset(), target);
            } else if (target == SNAP_TO_2_50_50) {
                mTargets.add(new SnapTarget(position, target));
                midpointPassed = true;
            } else {
                    // before midpoint
                    maybeAddTarget(position, position - getStartInset(), target);
                }
            } else {
                // after midpoint
                maybeAddTarget(position,
                        dividerMax - getEndInset() - (position + mDividerSize),
                maybeAddTarget(position, dividerMax - getEndInset() - (position + mDividerSize),
                        target);
            }
        }
@@ -556,6 +552,10 @@ public class DividerSnapAlgorithm {
        return mMotionSpec;
    }

    public int getSnapMode() {
        return mSnapMode;
    }

    /**
     * An object, calculated at boot time, representing a legal position for the split screen
     * divider (i.e. the divider can be dragged to this spot).
+52 −20
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@ import com.android.wm.shell.shared.desktopmode.DesktopState;

import com.google.android.msdl.data.model.MSDLToken;

import java.util.List;
import java.util.Objects;

/**
@@ -119,8 +118,6 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
     */
    private final Rect mDividerBounds = new Rect();
    private final Rect mTempRect = new Rect();
    private SplitTargetProvider mSplitTargetProvider;

    private FrameLayout mDividerBar;

    static final Property<DividerView, Integer> DIVIDER_HEIGHT_PROPERTY =
@@ -152,20 +149,48 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
    };

    final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() {
        private List<SplitTargetProvider.SplitTarget> mTargets;

        @Override
        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
            super.onInitializeAccessibilityNodeInfo(host, info);

            mTargets = mSplitTargetProvider.getTargets(true /*includeDismissal*/);
            mTargets.forEach(target ->
                    info.addAction(new AccessibilityAction(target.getA11yActionId(),
                            mContext.getString(target.getA11yActionString()))));
            final DividerSnapAlgorithm snapAlgorithm = mSplitLayout.mDividerSnapAlgorithm;
            if (mSplitLayout.isLeftRightSplit()) {
                info.addAction(new AccessibilityAction(R.id.action_move_tl_full,
                        mContext.getString(R.string.accessibility_action_divider_left_full)));
                if (snapAlgorithm.isFirstSplitTargetAvailable()) {
                    info.addAction(new AccessibilityAction(R.id.action_move_tl_70,
                            mContext.getString(R.string.accessibility_action_divider_left_70)));
                }
                if (snapAlgorithm.showMiddleSplitTargetForAccessibility()) {
                    // Only show the middle target if there are more than 1 split target
                    info.addAction(new AccessibilityAction(R.id.action_move_tl_50,
                            mContext.getString(R.string.accessibility_action_divider_left_50)));
                }
                if (snapAlgorithm.isLastSplitTargetAvailable()) {
                    info.addAction(new AccessibilityAction(R.id.action_move_tl_30,
                            mContext.getString(R.string.accessibility_action_divider_left_30)));
                }
                info.addAction(new AccessibilityAction(R.id.action_move_rb_full,
                        mContext.getString(R.string.accessibility_action_divider_right_full)));
                info.addAction(new AccessibilityAction(R.id.action_swap_apps,
                        mContext.getString(R.string.accessibility_action_divider_swap_horizontal)));
            } else {
                info.addAction(new AccessibilityAction(R.id.action_move_tl_full,
                        mContext.getString(R.string.accessibility_action_divider_top_full)));
                if (snapAlgorithm.isFirstSplitTargetAvailable()) {
                    info.addAction(new AccessibilityAction(R.id.action_move_tl_70,
                            mContext.getString(R.string.accessibility_action_divider_top_70)));
                }
                if (snapAlgorithm.showMiddleSplitTargetForAccessibility()) {
                    // Only show the middle target if there are more than 1 split target
                    info.addAction(new AccessibilityAction(R.id.action_move_tl_50,
                            mContext.getString(R.string.accessibility_action_divider_top_50)));
                }
                if (snapAlgorithm.isLastSplitTargetAvailable()) {
                    info.addAction(new AccessibilityAction(R.id.action_move_tl_30,
                            mContext.getString(R.string.accessibility_action_divider_top_30)));
                }
                info.addAction(new AccessibilityAction(R.id.action_move_rb_full,
                        mContext.getString(R.string.accessibility_action_divider_bottom_full)));
                info.addAction(new AccessibilityAction(R.id.action_swap_apps,
                        mContext.getString(R.string.accessibility_action_divider_swap_vertical)));
            }
@@ -179,12 +204,21 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
                return true;
            }

            SplitTargetProvider.SplitTarget selectedTarget = mTargets.stream()
                    .filter(target -> target.getA11yActionId() == action)
                    .findFirst()
                    .orElse(null);
            if (selectedTarget != null) {
                mSplitLayout.snapToTarget(selectedTarget.getSnapPosition());
            SnapTarget nextTarget = null;
            DividerSnapAlgorithm snapAlgorithm = mSplitLayout.mDividerSnapAlgorithm;
            if (action == R.id.action_move_tl_full) {
                nextTarget = snapAlgorithm.getDismissEndTarget();
            } else if (action == R.id.action_move_tl_70) {
                nextTarget = snapAlgorithm.getLastSplitTarget();
            } else if (action == R.id.action_move_tl_50) {
                nextTarget = snapAlgorithm.getMiddleTarget();
            } else if (action == R.id.action_move_tl_30) {
                nextTarget = snapAlgorithm.getFirstSplitTarget();
            } else if (action == R.id.action_move_rb_full) {
                nextTarget = snapAlgorithm.getDismissStartTarget();
            }
            if (nextTarget != null) {
                mSplitLayout.snapToTarget(mSplitLayout.getDividerPosition(), nextTarget);
                return true;
            }
            return super.performAccessibilityAction(host, action, args);
@@ -212,7 +246,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
    /** Sets up essential dependencies of the divider bar. */
    public void setup(SplitLayout layout, SplitWindowManager splitWindowManager,
            SurfaceControlViewHost viewHost, InsetsState insetsState,
            DesktopState desktopState, SplitTargetProvider splitTargetProvider) {
            DesktopState desktopState) {
        mSplitLayout = layout;
        mSplitWindowManager = splitWindowManager;
        mViewHost = viewHost;
@@ -232,9 +266,6 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
                : desktopState.canEnterDesktopMode()
                        ? R.dimen.desktop_mode_portrait_split_divider_handle_region_height
                        : R.dimen.split_divider_handle_region_height);

        mSplitTargetProvider = splitTargetProvider;
        mHandle.setAccessibilityDelegate(mHandleDelegate);
    }

    void onInsetsChanged(InsetsState insetsState, boolean animate) {
@@ -283,6 +314,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
        mInteractive = true;
        mHideHandle = false;
        setOnTouchListener(this);
        mHandle.setAccessibilityDelegate(mHandleDelegate);
        setWillNotDraw(false);
        mPaint.setColor(getResources().getColor(R.color.split_divider_background, null));
        mPaint.setAntiAlias(true);
+0 −207
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.common.split

import android.content.res.Resources
import com.android.wm.shell.Flags
import com.android.wm.shell.R
import com.android.wm.shell.common.split.SplitTargetProvider.SplitTarget
import com.android.wm.shell.shared.split.SplitScreenConstants

/**
 * For a given snap mode, based on current feature flags and resource config values, generates list
 * of viable snap targets which should be accessed via the [SplitTargetProvider] interface
 */
class SnapToTargetConverter(val res: Resources,
                            isMinimizedMode: Boolean) : SplitTargetProvider {

    private var snapMode: Int = 0

    init {
        snapMode = if (Flags.enableFlexibleTwoAppSplit()) {
            DividerSnapAlgorithm.SNAP_FLEXIBLE_HYBRID
        } else {
            if (isMinimizedMode)
                DividerSnapAlgorithm.SNAP_MODE_MINIMIZED
            else
                res.getInteger(com.android.internal.R.integer.config_dockedStackDividerSnapMode)
        }
    }

    /** See [SplitScreenUtils.isLeftRightSplit] */
    private fun isLeftRightSplit() : Boolean {
        val mAllowLeftRightSplitInPortrait = SplitScreenUtils.allowLeftRightSplitInPortrait(res)
        return SplitScreenUtils.isLeftRightSplit(
            mAllowLeftRightSplitInPortrait,
            res.configuration
        )
    }

    /**
     * @param includeDismissal if true then the returned list will include the start and end
     *                         dismiss targets at the start and end of the list, respectively.
     * @return A [List] of [SplitTarget] for the device's current [snapMode], by ordering of left
     *         to right based on the different snap positions
     */
    override fun getTargets(includeDismissal: Boolean): List<SplitTarget> {
        val targets: MutableList<SplitTarget> = ArrayList()
        val areOffscreenRatiosSupported = SplitScreenUtils.allowOffscreenRatios(res)
        val isLeftRightSplit = isLeftRightSplit()
        if (includeDismissal) {
            targets.add(
                SplitTarget(
                    SplitScreenConstants.SNAP_TO_START_AND_DISMISS,
                    if (isLeftRightSplit) R.string.accessibility_action_divider_right_full else
                        R.string.accessibility_action_divider_bottom_full,
                    R.id.action_move_tl_full
                )
            )
        }
        when (snapMode) {
            DividerSnapAlgorithm.SNAP_ONLY_1_1 -> targets.add(
                SplitTarget(
                    SplitScreenConstants.SNAP_TO_2_50_50,
                    if (isLeftRightSplit) R.string.accessibility_action_divider_left_50 else
                        R.string.accessibility_action_divider_top_50,
                    R.id.action_move_tl_50
                )
            )

            DividerSnapAlgorithm.SNAP_MODE_MINIMIZED -> targets.add(
                SplitTarget(
                    SplitScreenConstants.SNAP_TO_MINIMIZE,
                    if (isLeftRightSplit) R.string.accessibility_action_divider_left_full else
                        R.string.accessibility_action_divider_top_full,
                    R.id.action_move_tl_full
                )
            )

            DividerSnapAlgorithm.SNAP_MODE_16_9, DividerSnapAlgorithm.SNAP_FIXED_RATIO ->
                targets.addAll(
                    getOnscreenTargets(isLeftRightSplit)
                )

            DividerSnapAlgorithm.SNAP_FLEXIBLE_SPLIT -> {
                if (areOffscreenRatiosSupported) {
                    targets.add(
                        SplitTarget(
                            SplitScreenConstants.SNAP_TO_2_10_90,
                            if (isLeftRightSplit) R.string.accessibility_action_divider_left_10
                            else R.string.accessibility_action_divider_top_10,
                            R.id.action_move_tl_90
                        )
                    )
                    targets.add(
                        SplitTarget(
                            SplitScreenConstants.SNAP_TO_2_50_50,
                            if (isLeftRightSplit) R.string.accessibility_action_divider_left_50
                            else R.string.accessibility_action_divider_top_50,
                            R.id.action_move_tl_50
                        )
                    )
                    targets.add(
                        SplitTarget(
                            SplitScreenConstants.SNAP_TO_2_90_10,
                            if (isLeftRightSplit) R.string.accessibility_action_divider_left_90
                            else R.string.accessibility_action_divider_top_90,
                            R.id.action_move_tl_10
                        )
                    )
                } else {
                    targets.addAll(getOnscreenTargets(isLeftRightSplit))
                }
            }

            DividerSnapAlgorithm.SNAP_FLEXIBLE_HYBRID -> {
                if (areOffscreenRatiosSupported) {
                    targets.add(
                        SplitTarget(
                            SplitScreenConstants.SNAP_TO_2_10_90,
                            if (isLeftRightSplit) R.string.accessibility_action_divider_left_10
                            else R.string.accessibility_action_divider_top_10,
                            R.id.action_move_tl_90
                        )
                    )
                    targets.addAll(getOnscreenTargets(isLeftRightSplit))
                    targets.add(
                        SplitTarget(
                            SplitScreenConstants.SNAP_TO_2_90_10,
                            if (isLeftRightSplit) R.string.accessibility_action_divider_left_90
                            else R.string.accessibility_action_divider_top_90,
                            R.id.action_move_tl_10
                        )
                    )
                } else {
                    targets.addAll(getOnscreenTargets(isLeftRightSplit))
                }
            }
            else -> throw IllegalStateException("unrecognized snap mode")
        }

        if (includeDismissal) {
            targets.add(
                SplitTarget(
                    SplitScreenConstants.SNAP_TO_END_AND_DISMISS,
                    if (isLeftRightSplit) R.string.accessibility_action_divider_left_full else
                        R.string.accessibility_action_divider_top_full,
                    R.id.action_move_rb_full
                )
            )
        }
        return targets
    }

    /**
     * Current snap mode of the device. You really probably shouldn't be using this. Exposed only
     * for the few use cases that actually need it.
     */
    override fun getSnapMode(): Int {
        return snapMode
    }

    /**
     * @return Default, 3 non-flex split targets. 30/50/70, in that specific order.
     */
    private fun getOnscreenTargets(isLeftRightSplit: Boolean): List<SplitTarget> {
        val targets: MutableList<SplitTarget> = java.util.ArrayList(3)
        targets.add(
            SplitTarget(
                SplitScreenConstants.SNAP_TO_2_33_66,
                if (isLeftRightSplit) R.string.accessibility_action_divider_left_30 else
                    R.string.accessibility_action_divider_top_30,
                R.id.action_move_tl_30
            )
        )
        targets.add(
            SplitTarget(
                SplitScreenConstants.SNAP_TO_2_50_50,
                if (isLeftRightSplit) R.string.accessibility_action_divider_left_50 else
                    R.string.accessibility_action_divider_top_50,
                R.id.action_move_tl_50
            )
        )
        targets.add(
            SplitTarget(
                SplitScreenConstants.SNAP_TO_2_66_33,
                if (isLeftRightSplit) R.string.accessibility_action_divider_left_70 else
                    R.string.accessibility_action_divider_top_70,
                R.id.action_move_tl_70
            )
        )
        return targets
    }
}
 No newline at end of file
Loading