Merge "Add Accessibility Resize support." into rvc-dev

This commit is contained in:
Ben Lin
2020-06-18 18:54:46 +00:00
committed by Android (Google) Code Review
4 changed files with 111 additions and 34 deletions

View File

@@ -174,5 +174,8 @@
<item type="id" name="accessibility_action_controls_move_before" /> <item type="id" name="accessibility_action_controls_move_before" />
<item type="id" name="accessibility_action_controls_move_after" /> <item type="id" name="accessibility_action_controls_move_after" />
<!-- Accessibility actions for PIP -->
<item type="id" name="action_pip_resize" />
</resources> </resources>

View File

@@ -2392,6 +2392,9 @@
<!-- Button to skip to the prev media on picture-in-picture (PIP) [CHAR LIMIT=30] --> <!-- 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> <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 --> <!-- Tuner string -->
<string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string> <string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string>
<!-- Tuner string --> <!-- Tuner string -->

View File

@@ -15,6 +15,7 @@
*/ */
package com.android.systemui.pip.phone; package com.android.systemui.pip.phone;
import android.content.Context;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region; import android.graphics.Region;
import android.os.Bundle; import android.os.Bundle;
@@ -26,6 +27,10 @@ import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection; import android.view.accessibility.IAccessibilityInteractionConnection;
import android.view.accessibility.IAccessibilityInteractionConnectionCallback; 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.ArrayList;
import java.util.List; import java.util.List;
@@ -43,16 +48,30 @@ public class PipAccessibilityInteractionConnection
private static final long ACCESSIBILITY_NODE_ID = 1; private static final long ACCESSIBILITY_NODE_ID = 1;
private List<AccessibilityNodeInfo> mAccessibilityNodeInfoList; private List<AccessibilityNodeInfo> mAccessibilityNodeInfoList;
private Context mContext;
private Handler mHandler; private Handler mHandler;
private PipMotionHelper mMotionHelper; private PipMotionHelper mMotionHelper;
private PipTaskOrganizer mTaskOrganizer;
private PipSnapAlgorithm mSnapAlgorithm;
private Runnable mUpdateMovementBoundCallback;
private AccessibilityCallbacks mCallbacks; 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(); private Rect mTmpBounds = new Rect();
public PipAccessibilityInteractionConnection(PipMotionHelper motionHelper, public PipAccessibilityInteractionConnection(Context context, PipMotionHelper motionHelper,
AccessibilityCallbacks callbacks, Handler handler) { PipTaskOrganizer taskOrganizer, PipSnapAlgorithm snapAlgorithm,
AccessibilityCallbacks callbacks, Runnable updateMovementBoundCallback,
Handler handler) {
mContext = context;
mHandler = handler; mHandler = handler;
mMotionHelper = motionHelper; mMotionHelper = motionHelper;
mTaskOrganizer = taskOrganizer;
mSnapAlgorithm = snapAlgorithm;
mUpdateMovementBoundCallback = updateMovementBoundCallback;
mCallbacks = callbacks; mCallbacks = callbacks;
} }
@@ -78,6 +97,17 @@ public class PipAccessibilityInteractionConnection
// We only support one view. A request for anything else is invalid // We only support one view. A request for anything else is invalid
boolean result = false; boolean result = false;
if (accessibilityNodeId == AccessibilityNodeInfo.ROOT_NODE_ID) { if (accessibilityNodeId == AccessibilityNodeInfo.ROOT_NODE_ID) {
// 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) { switch (action) {
case AccessibilityNodeInfo.ACTION_CLICK: case AccessibilityNodeInfo.ACTION_CLICK:
mHandler.post(() -> { mHandler.post(() -> {
@@ -108,6 +138,7 @@ public class PipAccessibilityInteractionConnection
// Leave result as false // Leave result as false
} }
} }
}
try { try {
callback.setPerformAccessibilityActionResult(result, interactionId); callback.setPerformAccessibilityActionResult(result, interactionId);
} catch (RemoteException re) { } catch (RemoteException re) {
@@ -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 @Override
public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
String viewId, Region interactiveRegion, int interactionId, String viewId, Region interactiveRegion, int interactionId,
@@ -175,7 +227,21 @@ public class PipAccessibilityInteractionConnection
// Do nothing. // 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(); AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
info.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID, info.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID,
AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_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_DISMISS);
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_MOVE_WINDOW); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_MOVE_WINDOW);
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND); 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.setImportantForAccessibility(true);
info.setClickable(true); info.setClickable(true);
info.setVisibleToUser(true); info.setVisibleToUser(true);
@@ -193,7 +261,7 @@ public class PipAccessibilityInteractionConnection
if (mAccessibilityNodeInfoList == null) { if (mAccessibilityNodeInfoList == null) {
mAccessibilityNodeInfoList = new ArrayList<>(1); mAccessibilityNodeInfoList = new ArrayList<>(1);
} }
AccessibilityNodeInfo info = obtainRootAccessibilityNodeInfo(); AccessibilityNodeInfo info = obtainRootAccessibilityNodeInfo(mContext);
mAccessibilityNodeInfoList.clear(); mAccessibilityNodeInfoList.clear();
mAccessibilityNodeInfoList.add(info); mAccessibilityNodeInfoList.add(info);
return mAccessibilityNodeInfoList; return mAccessibilityNodeInfoList;

View File

@@ -250,8 +250,9 @@ public class PipTouchHandler {
mPipBoundsHandler = pipBoundsHandler; mPipBoundsHandler = pipBoundsHandler;
mFloatingContentCoordinator = floatingContentCoordinator; mFloatingContentCoordinator = floatingContentCoordinator;
mConnection = new PipAccessibilityInteractionConnection(mMotionHelper, mConnection = new PipAccessibilityInteractionConnection(mContext, mMotionHelper,
this::onAccessibilityShowMenu, mHandler); pipTaskOrganizer, pipSnapAlgorithm, this::onAccessibilityShowMenu,
this::updateMovementBounds, mHandler);
mTargetView = new DismissCircleView(context); mTargetView = new DismissCircleView(context);
mTargetViewContainer = new FrameLayout(context); mTargetViewContainer = new FrameLayout(context);
@@ -499,6 +500,8 @@ public class PipTouchHandler {
mInsetBounds.set(insetBounds); mInsetBounds.set(insetBounds);
updateMovementBounds(); updateMovementBounds();
mMovementBoundsExtraOffsets = extraOffset; mMovementBoundsExtraOffsets = extraOffset;
mConnection.onMovementBoundsChanged(mNormalBounds, mExpandedBounds, mNormalMovementBounds,
mExpandedMovementBounds);
// If we have a deferred resize, apply it now // If we have a deferred resize, apply it now
if (mDeferResizeToNormalBoundsUntilRotation == displayRotation) { if (mDeferResizeToNormalBoundsUntilRotation == displayRotation) {