diff options
4 files changed, 111 insertions, 34 deletions
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index d47ad7fcdfbd..8212d6159737 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -174,5 +174,8 @@ <item type="id" name="accessibility_action_controls_move_before" /> <item type="id" name="accessibility_action_controls_move_after" /> + + <!-- Accessibility actions for PIP --> + <item type="id" name="action_pip_resize" /> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 73568eab5eac..b95af26e7b1b 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2392,6 +2392,9 @@ <!-- Button to skip to the prev media on picture-in-picture (PIP) [CHAR LIMIT=30] --> <string name="pip_skip_to_prev">Skip to previous</string> + <!-- Accessibility action for resizing PIP [CHAR LIMIT=NONE] --> + <string name="accessibility_action_pip_resize">Resize</string> + <!-- Tuner string --> <string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string> <!-- Tuner string --> diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java index f1eef4353d32..8b3f4cb196bf 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java @@ -15,6 +15,7 @@ */ package com.android.systemui.pip.phone; +import android.content.Context; import android.graphics.Rect; import android.graphics.Region; import android.os.Bundle; @@ -26,6 +27,10 @@ import android.view.accessibility.AccessibilityWindowInfo; import android.view.accessibility.IAccessibilityInteractionConnection; import android.view.accessibility.IAccessibilityInteractionConnectionCallback; +import com.android.systemui.R; +import com.android.systemui.pip.PipSnapAlgorithm; +import com.android.systemui.pip.PipTaskOrganizer; + import java.util.ArrayList; import java.util.List; @@ -43,16 +48,30 @@ public class PipAccessibilityInteractionConnection private static final long ACCESSIBILITY_NODE_ID = 1; private List<AccessibilityNodeInfo> mAccessibilityNodeInfoList; + private Context mContext; private Handler mHandler; private PipMotionHelper mMotionHelper; + private PipTaskOrganizer mTaskOrganizer; + private PipSnapAlgorithm mSnapAlgorithm; + private Runnable mUpdateMovementBoundCallback; private AccessibilityCallbacks mCallbacks; + private final Rect mNormalBounds = new Rect(); + private final Rect mExpandedBounds = new Rect(); + private final Rect mNormalMovementBounds = new Rect(); + private final Rect mExpandedMovementBounds = new Rect(); private Rect mTmpBounds = new Rect(); - public PipAccessibilityInteractionConnection(PipMotionHelper motionHelper, - AccessibilityCallbacks callbacks, Handler handler) { + public PipAccessibilityInteractionConnection(Context context, PipMotionHelper motionHelper, + PipTaskOrganizer taskOrganizer, PipSnapAlgorithm snapAlgorithm, + AccessibilityCallbacks callbacks, Runnable updateMovementBoundCallback, + Handler handler) { + mContext = context; mHandler = handler; mMotionHelper = motionHelper; + mTaskOrganizer = taskOrganizer; + mSnapAlgorithm = snapAlgorithm; + mUpdateMovementBoundCallback = updateMovementBoundCallback; mCallbacks = callbacks; } @@ -78,34 +97,46 @@ public class PipAccessibilityInteractionConnection // We only support one view. A request for anything else is invalid boolean result = false; if (accessibilityNodeId == AccessibilityNodeInfo.ROOT_NODE_ID) { - switch (action) { - case AccessibilityNodeInfo.ACTION_CLICK: - mHandler.post(() -> { - mCallbacks.onAccessibilityShowMenu(); - }); - result = true; - break; - case AccessibilityNodeInfo.ACTION_DISMISS: - mMotionHelper.dismissPip(); - result = true; - break; - case com.android.internal.R.id.accessibilityActionMoveWindow: - int newX = arguments.getInt( - AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_X); - int newY = arguments.getInt( - AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_Y); - Rect pipBounds = new Rect(); - pipBounds.set(mMotionHelper.getBounds()); - mTmpBounds.offsetTo(newX, newY); - mMotionHelper.movePip(mTmpBounds); - result = true; - break; - case AccessibilityNodeInfo.ACTION_EXPAND: - mMotionHelper.expandPipToFullscreen(); - result = true; - break; - default: - // Leave result as false + + // R constants are not final so this cannot be put in the switch-case. + if (action == R.id.action_pip_resize) { + if (mMotionHelper.getBounds().width() == mNormalBounds.width() + && mMotionHelper.getBounds().height() == mNormalBounds.height()) { + setToExpandedBounds(); + } else { + setToNormalBounds(); + } + result = true; + } else { + switch (action) { + case AccessibilityNodeInfo.ACTION_CLICK: + mHandler.post(() -> { + mCallbacks.onAccessibilityShowMenu(); + }); + result = true; + break; + case AccessibilityNodeInfo.ACTION_DISMISS: + mMotionHelper.dismissPip(); + result = true; + break; + case com.android.internal.R.id.accessibilityActionMoveWindow: + int newX = arguments.getInt( + AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_X); + int newY = arguments.getInt( + AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_Y); + Rect pipBounds = new Rect(); + pipBounds.set(mMotionHelper.getBounds()); + mTmpBounds.offsetTo(newX, newY); + mMotionHelper.movePip(mTmpBounds); + result = true; + break; + case AccessibilityNodeInfo.ACTION_EXPAND: + mMotionHelper.expandPipToFullscreen(); + result = true; + break; + default: + // Leave result as false + } } } try { @@ -115,6 +146,27 @@ public class PipAccessibilityInteractionConnection } } + private void setToExpandedBounds() { + float savedSnapFraction = mSnapAlgorithm.getSnapFraction( + new Rect(mTaskOrganizer.getLastReportedBounds()), mNormalMovementBounds); + mSnapAlgorithm.applySnapFraction(mExpandedBounds, mExpandedMovementBounds, + savedSnapFraction); + mTaskOrganizer.scheduleFinishResizePip(mExpandedBounds, (Rect bounds) -> { + mMotionHelper.synchronizePinnedStackBounds(); + mUpdateMovementBoundCallback.run(); + }); + } + + private void setToNormalBounds() { + float savedSnapFraction = mSnapAlgorithm.getSnapFraction( + new Rect(mTaskOrganizer.getLastReportedBounds()), mExpandedMovementBounds); + mSnapAlgorithm.applySnapFraction(mNormalBounds, mNormalMovementBounds, savedSnapFraction); + mTaskOrganizer.scheduleFinishResizePip(mNormalBounds, (Rect bounds) -> { + mMotionHelper.synchronizePinnedStackBounds(); + mUpdateMovementBoundCallback.run(); + }); + } + @Override public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, String viewId, Region interactiveRegion, int interactionId, @@ -175,7 +227,21 @@ public class PipAccessibilityInteractionConnection // Do nothing. } - public static AccessibilityNodeInfo obtainRootAccessibilityNodeInfo() { + /** + * Update the normal and expanded bounds so they can be used for Resize. + */ + void onMovementBoundsChanged(Rect normalBounds, Rect expandedBounds, Rect normalMovementBounds, + Rect expandedMovementBounds) { + mNormalBounds.set(normalBounds); + mExpandedBounds.set(expandedBounds); + mNormalMovementBounds.set(normalMovementBounds); + mExpandedMovementBounds.set(expandedMovementBounds); + } + + /** + * Update the Root node with PIP Accessibility action items. + */ + public static AccessibilityNodeInfo obtainRootAccessibilityNodeInfo(Context context) { AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(); info.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID, AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID); @@ -183,6 +249,8 @@ public class PipAccessibilityInteractionConnection info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_MOVE_WINDOW); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND); + info.addAction(new AccessibilityNodeInfo.AccessibilityAction(R.id.action_pip_resize, + context.getString(R.string.accessibility_action_pip_resize))); info.setImportantForAccessibility(true); info.setClickable(true); info.setVisibleToUser(true); @@ -193,7 +261,7 @@ public class PipAccessibilityInteractionConnection if (mAccessibilityNodeInfoList == null) { mAccessibilityNodeInfoList = new ArrayList<>(1); } - AccessibilityNodeInfo info = obtainRootAccessibilityNodeInfo(); + AccessibilityNodeInfo info = obtainRootAccessibilityNodeInfo(mContext); mAccessibilityNodeInfoList.clear(); mAccessibilityNodeInfoList.add(info); return mAccessibilityNodeInfoList; diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index 998b756b0261..199e3fadaf28 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -250,8 +250,9 @@ public class PipTouchHandler { mPipBoundsHandler = pipBoundsHandler; mFloatingContentCoordinator = floatingContentCoordinator; - mConnection = new PipAccessibilityInteractionConnection(mMotionHelper, - this::onAccessibilityShowMenu, mHandler); + mConnection = new PipAccessibilityInteractionConnection(mContext, mMotionHelper, + pipTaskOrganizer, pipSnapAlgorithm, this::onAccessibilityShowMenu, + this::updateMovementBounds, mHandler); mTargetView = new DismissCircleView(context); mTargetViewContainer = new FrameLayout(context); @@ -499,6 +500,8 @@ public class PipTouchHandler { mInsetBounds.set(insetBounds); updateMovementBounds(); mMovementBoundsExtraOffsets = extraOffset; + mConnection.onMovementBoundsChanged(mNormalBounds, mExpandedBounds, mNormalMovementBounds, + mExpandedMovementBounds); // If we have a deferred resize, apply it now if (mDeferResizeToNormalBoundsUntilRotation == displayRotation) { |