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. */