Loading packages/SystemUI/res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -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> Loading packages/SystemUI/src/com/android/systemui/screenshot/CropView.java +89 −0 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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 Loading Loading @@ -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. */ Loading Loading
packages/SystemUI/res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -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> Loading
packages/SystemUI/src/com/android/systemui/screenshot/CropView.java +89 −0 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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 Loading Loading @@ -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. */ Loading