Announce clipboard entrance in accessibility mode

Also fixes issue where screenshots were not being announced.

Bug: 231614916
Fix: 231614916
Test: manual (with talkback)
Change-Id: Ic06e13078a57efecb573b641c6871da0fdc15ef5
This commit is contained in:
Miranda Kephart
2022-05-06 09:43:06 -04:00
parent c495949e13
commit aee312e123
4 changed files with 52 additions and 25 deletions

View File

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

View File

@@ -2484,6 +2484,12 @@
<string name="clipboard_send_nearby_description">Send to nearby device</string>
<!-- Text informing user that copied content is hidden [CHAR LIMIT=NONE] -->
<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] -->
<string name="add">Add</string>

View File

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

View File

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