diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d997ca2fa4a46..acd076af5741c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -247,6 +247,10 @@
Dismiss screenshot
Screenshot preview
+
+ Top boundary
+
+ Bottom boundary
Screen Recorder
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
index 9383aefeb6b68..1386ddfa7692a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
@@ -24,15 +24,21 @@ import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.Rect;
+import android.os.Bundle;
import android.util.AttributeSet;
+import android.util.IntArray;
import android.util.Log;
import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
import androidx.annotation.Nullable;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
+import com.android.internal.widget.ExploreByTouchHelper;
import com.android.systemui.R;
/**
@@ -80,6 +86,8 @@ public class CropView extends View {
t.recycle();
// 48 dp touchable region around each handle.
mCropTouchMargin = 24 * getResources().getDisplayMetrics().density;
+
+ setAccessibilityDelegate(new AccessibilityHelper());
}
@Override
@@ -231,6 +239,87 @@ public class CropView extends View {
return CropBoundary.NONE;
}
+ private class AccessibilityHelper extends ExploreByTouchHelper {
+
+ private static final int TOP_HANDLE_ID = 1;
+ private static final int BOTTOM_HANDLE_ID = 2;
+
+ AccessibilityHelper() {
+ super(CropView.this);
+ }
+
+ @Override
+ protected int getVirtualViewAt(float x, float y) {
+ if (Math.abs(y - fractionToPixels(mTopCrop)) < mCropTouchMargin) {
+ return TOP_HANDLE_ID;
+ }
+ if (Math.abs(y - fractionToPixels(mBottomCrop)) < mCropTouchMargin) {
+ return BOTTOM_HANDLE_ID;
+ }
+ return ExploreByTouchHelper.INVALID_ID;
+ }
+
+ @Override
+ protected void getVisibleVirtualViews(IntArray virtualViewIds) {
+ virtualViewIds.add(TOP_HANDLE_ID);
+ virtualViewIds.add(BOTTOM_HANDLE_ID);
+ }
+
+ @Override
+ protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
+ switch(virtualViewId) {
+ case TOP_HANDLE_ID:
+ event.setContentDescription(
+ getResources().getString(R.string.screenshot_top_boundary));
+ break;
+ case BOTTOM_HANDLE_ID:
+ event.setContentDescription(
+ getResources().getString(R.string.screenshot_bottom_boundary));
+ break;
+ }
+ }
+
+ @Override
+ protected void onPopulateNodeForVirtualView(int virtualViewId,
+ AccessibilityNodeInfo node) {
+ switch(virtualViewId) {
+ case TOP_HANDLE_ID:
+ node.setContentDescription(
+ getResources().getString(R.string.screenshot_top_boundary));
+ setNodePositions(mTopCrop, node);
+ break;
+ case BOTTOM_HANDLE_ID:
+ node.setContentDescription(
+ getResources().getString(R.string.screenshot_bottom_boundary));
+ setNodePositions(mBottomCrop, node);
+ break;
+ }
+
+ // TODO: need to figure out the full set of actions to support here.
+ node.addAction(
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
+ node.setClickable(true);
+ node.setFocusable(true);
+ }
+
+ @Override
+ protected boolean onPerformActionForVirtualView(
+ int virtualViewId, int action, Bundle arguments) {
+ return false;
+ }
+
+ private void setNodePositions(float fraction, AccessibilityNodeInfo node) {
+ int pixels = fractionToPixels(fraction);
+ Rect rect = new Rect(0, (int) (pixels - mCropTouchMargin),
+ getWidth(), (int) (pixels + mCropTouchMargin));
+ node.setBoundsInParent(rect);
+ int[] pos = new int[2];
+ getLocationOnScreen(pos);
+ rect.offset(pos[0], pos[1]);
+ node.setBoundsInScreen(rect);
+ }
+ }
+
/**
* Listen for crop motion events and state.
*/