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:
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user