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

Commit 30017003 authored by Matt Casey's avatar Matt Casey Committed by Android (Google) Code Review
Browse files

Merge "Preliminary accessibility support for CropView" into sc-dev

parents e49eb506 fade3095
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -247,6 +247,10 @@
    <string name="screenshot_dismiss_description">Dismiss screenshot</string>
    <!-- Content description indicating that the view is a preview of the screenshot that was just taken [CHAR LIMIT=NONE] -->
    <string name="screenshot_preview_description">Screenshot preview</string>
    <!-- Content description for the top boundary of the screenshot being cropped [CHAR LIMIT=NONE] -->
    <string name="screenshot_top_boundary">Top boundary</string>
    <!-- Content description for the bottom boundary of the screenshot being cropped [CHAR LIMIT=NONE] -->
    <string name="screenshot_bottom_boundary">Bottom boundary</string>

    <!-- Notification title displayed for screen recording [CHAR LIMIT=50]-->
    <string name="screenrecord_name">Screen Recorder</string>
+89 −0
Original line number Diff line number Diff line
@@ -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.
     */