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

Commit 617d096a authored by Ats Jenk's avatar Ats Jenk
Browse files

Create a11y action menu for app handle in bubbles

Following actions are available:
* collapse
* dismiss
* move left/right

Bug: 357933784
Flag: com.android.wm.shell.enable_bubble_bar
Test: open action menu from app handle, test that a bubble can be
  collapsed, dismissed and moved left or right depending which side of
  the screen the bubble is on
Change-Id: I43abbdbecf66c19f298ac752820b5a5ed30059be
parent e156b428
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import org.junit.runner.RunWith
import org.mockito.kotlin.mock
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import com.android.wm.shell.common.bubbles.BubbleBarLocation
import java.util.concurrent.Semaphore
import java.util.concurrent.TimeUnit
import java.util.function.Consumer
@@ -458,5 +459,7 @@ class BubbleStackViewTest {
        override fun isShowingAsBubbleBar(): Boolean = false

        override fun hideCurrentInputMethod() {}

        override fun updateBubbleBarLocation(location: BubbleBarLocation) {}
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@
    <item type="id" name="action_move_top_right"/>
    <item type="id" name="action_move_bottom_left"/>
    <item type="id" name="action_move_bottom_right"/>
    <item type="id" name="action_move_bubble_bar_left"/>
    <item type="id" name="action_move_bubble_bar_right"/>

    <item type="id" name="dismiss_view"/>
</resources>
+4 −0
Original line number Diff line number Diff line
@@ -143,6 +143,10 @@
    <string name="bubble_accessibility_action_expand_menu">expand menu</string>
    <!-- Click action label for bubbles to collapse menu. [CHAR LIMIT=30]-->
    <string name="bubble_accessibility_action_collapse_menu">collapse menu</string>
    <!-- Action in accessibility menu to move the bubble bar to the left side of the screen. [CHAR_LIMIT=30] -->
    <string name="bubble_accessibility_action_move_bar_left">Move left</string>
    <!-- Action in accessibility menu to move the bubble bar to the right side of the screen. [CHAR_LIMIT=30] -->
    <string name="bubble_accessibility_action_move_bar_right">Move right</string>
    <!-- Accessibility announcement when the stack of bubbles expands. [CHAR LIMIT=NONE]-->
    <string name="bubble_accessibility_announce_expand">expand <xliff:g id="bubble_title" example="Messages">%1$s</xliff:g></string>
    <!-- Accessibility announcement when the stack of bubbles collapses. [CHAR LIMIT=NONE]-->
+7 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.wm.shell.bubbles

import com.android.wm.shell.common.bubbles.BubbleBarLocation

/** Manager interface for bubble expanded views. */
interface BubbleExpandedViewManager {

@@ -30,6 +32,7 @@ interface BubbleExpandedViewManager {
    fun isStackExpanded(): Boolean
    fun isShowingAsBubbleBar(): Boolean
    fun hideCurrentInputMethod()
    fun updateBubbleBarLocation(location: BubbleBarLocation)

    companion object {
        /**
@@ -78,6 +81,10 @@ interface BubbleExpandedViewManager {
                override fun hideCurrentInputMethod() {
                    controller.hideCurrentInputMethod()
                }

                override fun updateBubbleBarLocation(location: BubbleBarLocation) {
                    controller.bubbleBarLocation = location
                }
            }
        }
    }
+54 −10
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.view.LayoutInflater;
@@ -35,6 +36,8 @@ import android.view.ViewOutlineProvider;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;

import com.android.wm.shell.R;
import com.android.wm.shell.bubbles.Bubble;
import com.android.wm.shell.bubbles.BubbleExpandedViewManager;
@@ -43,6 +46,7 @@ import com.android.wm.shell.bubbles.BubblePositioner;
import com.android.wm.shell.bubbles.BubbleTaskView;
import com.android.wm.shell.bubbles.BubbleTaskViewHelper;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
import com.android.wm.shell.taskview.TaskView;

import java.util.function.Supplier;
@@ -82,6 +86,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
    private static final String TAG = BubbleBarExpandedView.class.getSimpleName();
    private static final int INVALID_TASK_ID = -1;

    private Bubble mBubble;
    private BubbleExpandedViewManager mManager;
    private BubblePositioner mPositioner;
    private boolean mIsOverflow;
@@ -190,16 +195,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
            // Handle view needs to draw on top of task view.
            bringChildToFront(mHandleView);

            mHandleView.setAccessibilityDelegate(new AccessibilityDelegate() {
                @Override
                public void onInitializeAccessibilityNodeInfo(View host,
                        AccessibilityNodeInfo info) {
                    super.onInitializeAccessibilityNodeInfo(host, info);
                    info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
                            AccessibilityNodeInfo.ACTION_CLICK, getResources().getString(
                            R.string.bubble_accessibility_action_expand_menu)));
                }
            });
            mHandleView.setAccessibilityDelegate(new HandleViewAccessibilityDelegate());
        }
        mMenuViewController = new BubbleBarMenuViewController(mContext, this);
        mMenuViewController.setListener(new BubbleBarMenuViewController.Listener() {
@@ -338,6 +334,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView

    /** Updates the bubble shown in the expanded view. */
    public void update(Bubble bubble) {
        mBubble = bubble;
        mBubbleTaskViewHelper.update(bubble);
        mMenuViewController.updateMenu(bubble);
    }
@@ -476,4 +473,51 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
            invalidateOutline();
        }
    }

    private class HandleViewAccessibilityDelegate extends AccessibilityDelegate {
        @Override
        public void onInitializeAccessibilityNodeInfo(@NonNull View host,
                @NonNull AccessibilityNodeInfo info) {
            super.onInitializeAccessibilityNodeInfo(host, info);
            info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
                    AccessibilityNodeInfo.ACTION_CLICK, getResources().getString(
                    R.string.bubble_accessibility_action_expand_menu)));
            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
            if (mPositioner.isBubbleBarOnLeft()) {
                info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
                        R.id.action_move_bubble_bar_right, getResources().getString(
                        R.string.bubble_accessibility_action_move_bar_right)));
            } else {
                info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
                        R.id.action_move_bubble_bar_left, getResources().getString(
                        R.string.bubble_accessibility_action_move_bar_left)));
            }
        }

        @Override
        public boolean performAccessibilityAction(@NonNull View host, int action,
                @Nullable Bundle args) {
            if (super.performAccessibilityAction(host, action, args)) {
                return true;
            }
            if (action == AccessibilityNodeInfo.ACTION_COLLAPSE) {
                mManager.collapseStack();
                return true;
            }
            if (action == AccessibilityNodeInfo.ACTION_DISMISS) {
                mManager.dismissBubble(mBubble, Bubbles.DISMISS_USER_GESTURE);
                return true;
            }
            if (action == R.id.action_move_bubble_bar_left) {
                mManager.updateBubbleBarLocation(BubbleBarLocation.LEFT);
                return true;
            }
            if (action == R.id.action_move_bubble_bar_right) {
                mManager.updateBubbleBarLocation(BubbleBarLocation.RIGHT);
                return true;
            }
            return false;
        }
    }
}