Merge "Announce clipboard entrance in accessibility mode" into tm-dev am: 52ed8bad43

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18186420

Change-Id: Ifab8004abdf7a4c8a1c69dd2286f41fefbc1853c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Miranda Kephart
2022-05-12 15:24:08 +00:00
committed by Automerger Merge Worker
4 changed files with 52 additions and 25 deletions

View File

@@ -67,9 +67,9 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginStart="@dimen/overlay_offset_x" android:layout_marginStart="@dimen/overlay_offset_x"
android:layout_marginBottom="8dp" android:layout_marginBottom="12dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="@id/actions_container_background" app:layout_constraintBottom_toBottomOf="parent"
android:elevation="7dp" android:elevation="7dp"
app:layout_constraintEnd_toEndOf="@id/clipboard_preview_end" app:layout_constraintEnd_toEndOf="@id/clipboard_preview_end"
app:layout_constraintTop_toTopOf="@id/clipboard_preview_top" app:layout_constraintTop_toTopOf="@id/clipboard_preview_top"

View File

@@ -2497,6 +2497,12 @@
<string name="clipboard_send_nearby_description">Send to nearby device</string> <string name="clipboard_send_nearby_description">Send to nearby device</string>
<!-- Text informing user that copied content is hidden [CHAR LIMIT=NONE] --> <!-- Text informing user that copied content is hidden [CHAR LIMIT=NONE] -->
<string name="clipboard_text_hidden">Tap to view</string> <string name="clipboard_text_hidden">Tap to view</string>
<!-- Accessibility announcement informing user that text has been copied [CHAR LIMIT=NONE] -->
<string name="clipboard_text_copied">Text copied</string>
<!-- Accessibility announcement informing user that text has been copied [CHAR LIMIT=NONE] -->
<string name="clipboard_image_copied">Image copied</string>
<!-- Accessibility announcement informing user that something has been copied [CHAR LIMIT=NONE] -->
<string name="clipboard_content_copied">Content copied</string>
<!-- Generic "add" string [CHAR LIMIT=NONE] --> <!-- Generic "add" string [CHAR LIMIT=NONE] -->
<string name="add">Add</string> <string name="add">Add</string>

View File

@@ -302,6 +302,7 @@ public class ClipboardOverlayController {
mExitAnimator.cancel(); mExitAnimator.cancel();
} }
reset(); reset();
String accessibilityAnnouncement;
boolean isSensitive = clipData != null && clipData.getDescription().getExtras() != null boolean isSensitive = clipData != null && clipData.getDescription().getExtras() != null
&& clipData.getDescription().getExtras() && clipData.getDescription().getExtras()
@@ -310,6 +311,7 @@ public class ClipboardOverlayController {
showTextPreview( showTextPreview(
mContext.getResources().getString(R.string.clipboard_overlay_text_copied), mContext.getResources().getString(R.string.clipboard_overlay_text_copied),
mTextPreview); mTextPreview);
accessibilityAnnouncement = mContext.getString(R.string.clipboard_content_copied);
} else if (!TextUtils.isEmpty(clipData.getItemAt(0).getText())) { } else if (!TextUtils.isEmpty(clipData.getItemAt(0).getText())) {
ClipData.Item item = clipData.getItemAt(0); ClipData.Item item = clipData.getItemAt(0);
if (item.getTextLinks() != null) { if (item.getTextLinks() != null) {
@@ -321,13 +323,18 @@ public class ClipboardOverlayController {
} else { } else {
showEditableText(item.getText(), false); showEditableText(item.getText(), false);
} }
accessibilityAnnouncement = mContext.getString(R.string.clipboard_text_copied);
} else if (clipData.getItemAt(0).getUri() != null) { } else if (clipData.getItemAt(0).getUri() != null) {
// How to handle non-image URIs? if (tryShowEditableImage(clipData.getItemAt(0).getUri(), isSensitive)) {
showEditableImage(clipData.getItemAt(0).getUri(), isSensitive); accessibilityAnnouncement = mContext.getString(R.string.clipboard_image_copied);
} else {
accessibilityAnnouncement = mContext.getString(R.string.clipboard_content_copied);
}
} else { } else {
showTextPreview( showTextPreview(
mContext.getResources().getString(R.string.clipboard_overlay_text_copied), mContext.getResources().getString(R.string.clipboard_overlay_text_copied),
mTextPreview); mTextPreview);
accessibilityAnnouncement = mContext.getString(R.string.clipboard_content_copied);
} }
Intent remoteCopyIntent = getRemoteCopyIntent(clipData); Intent remoteCopyIntent = getRemoteCopyIntent(clipData);
// Only show remote copy if it's available. // Only show remote copy if it's available.
@@ -344,7 +351,12 @@ public class ClipboardOverlayController {
} else { } else {
mRemoteCopyChip.setVisibility(View.GONE); mRemoteCopyChip.setVisibility(View.GONE);
} }
withWindowAttached(() -> mView.post(this::animateIn)); withWindowAttached(() -> {
updateInsets(
mWindowManager.getCurrentWindowMetrics().getWindowInsets());
mView.post(this::animateIn);
mView.announceForAccessibility(accessibilityAnnouncement);
});
mTimeoutHandler.resetTimeout(); mTimeoutHandler.resetTimeout();
} }
@@ -476,34 +488,47 @@ public class ClipboardOverlayController {
textView.setOnClickListener(listener); textView.setOnClickListener(listener);
} }
private void showEditableImage(Uri uri, boolean isSensitive) { private boolean tryShowEditableImage(Uri uri, boolean isSensitive) {
mEditChip.setAlpha(1f);
mActionContainerBackground.setVisibility(View.VISIBLE);
View.OnClickListener listener = v -> editImage(uri); View.OnClickListener listener = v -> editImage(uri);
ContentResolver resolver = mContext.getContentResolver();
String mimeType = resolver.getType(uri);
boolean isEditableImage = mimeType != null && mimeType.startsWith("image");
if (isSensitive) { if (isSensitive) {
showSinglePreview(mHiddenImagePreview); showSinglePreview(mHiddenImagePreview);
if (isEditableImage) {
mHiddenImagePreview.setOnClickListener(listener); mHiddenImagePreview.setOnClickListener(listener);
} else { }
showSinglePreview(mImagePreview); } else if (isEditableImage) { // if the MIMEtype is image, try to load
ContentResolver resolver = mContext.getContentResolver();
try { try {
int size = mContext.getResources().getDimensionPixelSize(R.dimen.overlay_x_scale); int size = mContext.getResources().getDimensionPixelSize(R.dimen.overlay_x_scale);
// The width of the view is capped, height maintains aspect ratio, so allow it to be // The width of the view is capped, height maintains aspect ratio, so allow it to be
// taller if needed. // taller if needed.
Bitmap thumbnail = resolver.loadThumbnail(uri, new Size(size, size * 4), null); Bitmap thumbnail = resolver.loadThumbnail(uri, new Size(size, size * 4), null);
showSinglePreview(mImagePreview);
mImagePreview.setImageBitmap(thumbnail); mImagePreview.setImageBitmap(thumbnail);
mImagePreview.setOnClickListener(listener);
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "Thumbnail loading failed", e); Log.e(TAG, "Thumbnail loading failed", e);
showTextPreview( showTextPreview(
mContext.getResources().getString(R.string.clipboard_overlay_text_copied), mContext.getResources().getString(R.string.clipboard_overlay_text_copied),
mTextPreview); mTextPreview);
isEditableImage = false;
} }
mImagePreview.setOnClickListener(listener); } else {
showTextPreview(
mContext.getResources().getString(R.string.clipboard_overlay_text_copied),
mTextPreview);
} }
if (isEditableImage) {
mEditChip.setVisibility(View.VISIBLE);
mEditChip.setAlpha(1f);
mActionContainerBackground.setVisibility(View.VISIBLE);
mEditChip.setOnClickListener(listener); mEditChip.setOnClickListener(listener);
mEditChip.setContentDescription( mEditChip.setContentDescription(
mContext.getString(R.string.clipboard_edit_image_description)); mContext.getString(R.string.clipboard_edit_image_description));
} }
return isEditableImage;
}
private Intent getRemoteCopyIntent(ClipData clipData) { private Intent getRemoteCopyIntent(ClipData clipData) {
String remoteCopyPackage = mContext.getString(R.string.config_remoteCopyPackage); String remoteCopyPackage = mContext.getString(R.string.config_remoteCopyPackage);

View File

@@ -78,7 +78,6 @@ import android.view.ViewTreeObserver;
import android.view.WindowInsets; import android.view.WindowInsets;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.WindowManagerGlobal; import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.widget.Toast; import android.widget.Toast;
import android.window.WindowContext; import android.window.WindowContext;
@@ -559,14 +558,9 @@ public class ScreenshotController {
private void saveScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect, private void saveScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect,
Insets screenInsets, ComponentName topComponent, boolean showFlash) { Insets screenInsets, ComponentName topComponent, boolean showFlash) {
if (mAccessibilityManager.isEnabled()) { withWindowAttached(() ->
AccessibilityEvent event = mScreenshotView.announceForAccessibility(
new AccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); mContext.getResources().getString(R.string.screenshot_saving_title)));
event.setContentDescription(
mContext.getResources().getString(R.string.screenshot_saving_title));
mAccessibilityManager.sendAccessibilityEvent(event);
}
if (mScreenshotView.isAttachedToWindow()) { if (mScreenshotView.isAttachedToWindow()) {
// if we didn't already dismiss for another reason // if we didn't already dismiss for another reason
@@ -633,6 +627,7 @@ public class ScreenshotController {
} }
} }
} }
@Override @Override
public void requestCompatCameraControl(boolean showControl, public void requestCompatCameraControl(boolean showControl,
boolean transformationApplied, boolean transformationApplied,
@@ -718,6 +713,7 @@ public class ScreenshotController {
Log.e(TAG, "requestScrollCapture failed", e); Log.e(TAG, "requestScrollCapture failed", e);
} }
} }
ListenableFuture<ScrollCaptureController.LongScreenshot> mLongScreenshotFuture; ListenableFuture<ScrollCaptureController.LongScreenshot> mLongScreenshotFuture;
private void runBatchScrollCapture(ScrollCaptureResponse response) { private void runBatchScrollCapture(ScrollCaptureResponse response) {