From 9d7b9b17fefb1c707898205b91c3cc1d4fae773b Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Thu, 21 Apr 2022 14:05:07 -0400 Subject: [PATCH] Hide sensitive clipboard content Bug: 228955553 Test: manual Change-Id: Ia74d5d47e589beaeafe95c43124c26f591a6ba81 --- .../SystemUI/res/layout/clipboard_overlay.xml | 26 +++++- packages/SystemUI/res/values/strings.xml | 2 + .../ClipboardOverlayController.java | 84 ++++++++++++------- .../clipboardoverlay/EditTextActivity.java | 9 ++ 4 files changed, 92 insertions(+), 29 deletions(-) diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml index b230438f66fd6..10bb6cbb95aa7 100644 --- a/packages/SystemUI/res/layout/clipboard_overlay.xml +++ b/packages/SystemUI/res/layout/clipboard_overlay.xml @@ -121,6 +121,30 @@ android:adjustViewBounds="true" android:layout_width="match_parent" android:layout_height="wrap_content"/> + + - + \ No newline at end of file diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 8f412e342fa8e..7e4150714b5c0 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2486,6 +2486,8 @@ Edit copied image Send to nearby device + + Tap to view Add diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java index 726d00c230d75..ee8363fe50d44 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java @@ -38,6 +38,7 @@ import android.annotation.MainThread; import android.app.RemoteAction; import android.content.BroadcastReceiver; import android.content.ClipData; +import android.content.ClipDescription; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -128,6 +129,8 @@ public class ClipboardOverlayController { private final View mClipboardPreview; private final ImageView mImagePreview; private final TextView mTextPreview; + private final TextView mHiddenTextPreview; + private final TextView mHiddenImagePreview; private final View mPreviewBorder; private final OverlayActionChip mEditChip; private final OverlayActionChip mRemoteCopyChip; @@ -186,6 +189,8 @@ public class ClipboardOverlayController { mClipboardPreview = requireNonNull(mView.findViewById(R.id.clipboard_preview)); mImagePreview = requireNonNull(mView.findViewById(R.id.image_preview)); mTextPreview = requireNonNull(mView.findViewById(R.id.text_preview)); + mHiddenTextPreview = requireNonNull(mView.findViewById(R.id.hidden_text_preview)); + mHiddenImagePreview = requireNonNull(mView.findViewById(R.id.hidden_image_preview)); mPreviewBorder = requireNonNull(mView.findViewById(R.id.preview_border)); mEditChip = requireNonNull(mView.findViewById(R.id.edit_chip)); mRemoteCopyChip = requireNonNull(mView.findViewById(R.id.remote_copy_chip)); @@ -270,21 +275,32 @@ public class ClipboardOverlayController { mExitAnimator.cancel(); } reset(); + + boolean isSensitive = clipData != null && clipData.getDescription().getExtras() != null + && clipData.getDescription().getExtras() + .getBoolean(ClipDescription.EXTRA_IS_SENSITIVE); if (clipData == null || clipData.getItemCount() == 0) { - showTextPreview(mContext.getResources().getString( - R.string.clipboard_overlay_text_copied)); + showTextPreview( + mContext.getResources().getString(R.string.clipboard_overlay_text_copied), + mTextPreview); } else if (!TextUtils.isEmpty(clipData.getItemAt(0).getText())) { ClipData.Item item = clipData.getItemAt(0); if (item.getTextLinks() != null) { AsyncTask.execute(() -> classifyText(clipData.getItemAt(0), clipSource)); } - showEditableText(item.getText()); + if (isSensitive) { + showEditableText( + mContext.getResources().getString(R.string.clipboard_text_hidden), true); + } else { + showEditableText(item.getText(), false); + } } else if (clipData.getItemAt(0).getUri() != null) { // How to handle non-image URIs? - showEditableImage(clipData.getItemAt(0).getUri()); + showEditableImage(clipData.getItemAt(0).getUri(), isSensitive); } else { showTextPreview( - mContext.getResources().getString(R.string.clipboard_overlay_text_copied)); + mContext.getResources().getString(R.string.clipboard_overlay_text_copied), + mTextPreview); } Intent remoteCopyIntent = getRemoteCopyIntent(clipData); // Only show remote copy if it's available. @@ -406,15 +422,23 @@ public class ClipboardOverlayController { animateOut(); } - private void showTextPreview(CharSequence text) { - mTextPreview.setVisibility(View.VISIBLE); + private void showSinglePreview(View v) { + mTextPreview.setVisibility(View.GONE); mImagePreview.setVisibility(View.GONE); - mTextPreview.setText(text.subSequence(0, Math.min(500, text.length()))); + mHiddenTextPreview.setVisibility(View.GONE); + mHiddenImagePreview.setVisibility(View.GONE); + v.setVisibility(View.VISIBLE); + } + + private void showTextPreview(CharSequence text, TextView textView) { + showSinglePreview(textView); + textView.setText(text.subSequence(0, Math.min(500, text.length()))); mEditChip.setVisibility(View.GONE); } - private void showEditableText(CharSequence text) { - showTextPreview(text); + private void showEditableText(CharSequence text, boolean hidden) { + TextView textView = hidden ? mHiddenTextPreview : mTextPreview; + showTextPreview(text, textView); mEditChip.setVisibility(View.VISIBLE); mActionContainerBackground.setVisibility(View.VISIBLE); mEditChip.setAlpha(1f); @@ -422,32 +446,36 @@ public class ClipboardOverlayController { mContext.getString(R.string.clipboard_edit_text_description)); View.OnClickListener listener = v -> editText(); mEditChip.setOnClickListener(listener); - mTextPreview.setOnClickListener(listener); + textView.setOnClickListener(listener); } - private void showEditableImage(Uri uri) { - ContentResolver resolver = mContext.getContentResolver(); - 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); - mImagePreview.setImageBitmap(thumbnail); - } catch (IOException e) { - Log.e(TAG, "Thumbnail loading failed", e); - showTextPreview( - mContext.getResources().getString(R.string.clipboard_overlay_text_copied)); - return; - } - mTextPreview.setVisibility(View.GONE); - mImagePreview.setVisibility(View.VISIBLE); + private void showEditableImage(Uri uri, boolean isSensitive) { mEditChip.setAlpha(1f); mActionContainerBackground.setVisibility(View.VISIBLE); View.OnClickListener listener = v -> editImage(uri); + if (isSensitive) { + showSinglePreview(mHiddenImagePreview); + mHiddenImagePreview.setOnClickListener(listener); + } else { + showSinglePreview(mImagePreview); + ContentResolver resolver = mContext.getContentResolver(); + 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); + mImagePreview.setImageBitmap(thumbnail); + } catch (IOException e) { + Log.e(TAG, "Thumbnail loading failed", e); + showTextPreview( + mContext.getResources().getString(R.string.clipboard_overlay_text_copied), + mTextPreview); + } + mImagePreview.setOnClickListener(listener); + } mEditChip.setOnClickListener(listener); mEditChip.setContentDescription( mContext.getString(R.string.clipboard_edit_image_description)); - mImagePreview.setOnClickListener(listener); } private Intent getRemoteCopyIntent(ClipData clipData) { diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java index 0d8987988f0a8..b54b83274f45c 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java @@ -20,10 +20,12 @@ import static java.util.Objects.requireNonNull; import android.app.Activity; import android.content.ClipData; +import android.content.ClipDescription; import android.content.ClipboardManager; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; +import android.os.PersistableBundle; import android.util.Log; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; @@ -41,6 +43,7 @@ public class EditTextActivity extends Activity private EditText mEditText; private ClipboardManager mClipboardManager; private TextView mAttribution; + private boolean mSensitive; @Override protected void onCreate(Bundle savedInstanceState) { @@ -72,6 +75,9 @@ public class EditTextActivity extends Activity } mEditText.setText(clip.getItemAt(0).getText()); mEditText.requestFocus(); + mSensitive = clip.getDescription().getExtras() != null + && clip.getDescription().getExtras() + .getBoolean(ClipDescription.EXTRA_IS_SENSITIVE); mClipboardManager.addPrimaryClipChangedListener(this); } @@ -88,6 +94,9 @@ public class EditTextActivity extends Activity private void saveToClipboard() { ClipData clip = ClipData.newPlainText("text", mEditText.getText()); + PersistableBundle extras = new PersistableBundle(); + extras.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, mSensitive); + clip.getDescription().setExtras(extras); mClipboardManager.setPrimaryClip(clip); hideImeAndFinish(); }