diff options
| author | 2022-01-27 17:44:51 +0000 | |
|---|---|---|
| committer | 2022-01-27 17:44:51 +0000 | |
| commit | fedcd5cc381574361efb7a2e864f8ea9bfc63f7e (patch) | |
| tree | 9689bc429c7509fad57118b1ebff96a17ab1dac7 | |
| parent | d42cf0d4153e563629b3f18434ec10a5578159d3 (diff) | |
| parent | 0a6b8a9941fd78e1873264387b6267eba1614704 (diff) | |
Merge "Add action chips to clipboard overlay"
4 files changed, 74 insertions, 15 deletions
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml index 7ffb3b235812..2a3761e4ca05 100644 --- a/packages/SystemUI/res/layout/clipboard_overlay.xml +++ b/packages/SystemUI/res/layout/clipboard_overlay.xml @@ -17,6 +17,7 @@ <com.android.systemui.clipboardoverlay.DraggableConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" + android:alpha="0" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java index 41a496332768..0e1cd51ce42c 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java @@ -60,8 +60,8 @@ public class ClipboardListener extends CoreStartable return; } if (mClipboardOverlayController == null) { - mClipboardOverlayController = new ClipboardOverlayController(mContext, - new TimeoutHandler(mContext)); + mClipboardOverlayController = + new ClipboardOverlayController(mContext, new TimeoutHandler(mContext)); } mClipboardOverlayController.setClipData(mClipboardManager.getPrimaryClip()); mClipboardOverlayController.setOnSessionCompleteListener(() -> { diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java index caf0307d4436..b6bcb871ff18 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java @@ -28,6 +28,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.MainThread; +import android.app.RemoteAction; import android.content.BroadcastReceiver; import android.content.ClipData; import android.content.ComponentName; @@ -43,6 +44,7 @@ import android.graphics.drawable.Icon; import android.hardware.display.DisplayManager; import android.hardware.input.InputManager; import android.net.Uri; +import android.os.AsyncTask; import android.os.Looper; import android.text.TextUtils; import android.util.Log; @@ -60,8 +62,13 @@ import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; +import android.view.textclassifier.TextClassification; +import android.view.textclassifier.TextClassificationManager; +import android.view.textclassifier.TextClassifier; +import android.view.textclassifier.TextLinks; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.policy.PhoneWindow; @@ -71,6 +78,7 @@ import com.android.systemui.screenshot.ScreenshotActionChip; import com.android.systemui.screenshot.TimeoutHandler; import java.io.IOException; +import java.util.ArrayList; /** * Controls state and UI for the overlay that appears when something is added to the clipboard @@ -93,6 +101,7 @@ public class ClipboardOverlayController { private final PhoneWindow mWindow; private final TimeoutHandler mTimeoutHandler; private final AccessibilityManager mAccessibilityManager; + private final TextClassifier mTextClassifier; private final DraggableConstraintLayout mView; private final ImageView mImagePreview; @@ -101,9 +110,13 @@ public class ClipboardOverlayController { private final ScreenshotActionChip mRemoteCopyChip; private final View mActionContainerBackground; private final View mDismissButton; + private final LinearLayout mActionContainer; + private final ArrayList<ScreenshotActionChip> mActionChips = new ArrayList<>(); private Runnable mOnSessionCompleteListener; + + private InputMonitor mInputMonitor; private InputEventReceiver mInputEventReceiver; private BroadcastReceiver mCloseDialogsReceiver; @@ -117,6 +130,8 @@ public class ClipboardOverlayController { mContext = displayContext.createWindowContext(TYPE_SCREENSHOT, null); mAccessibilityManager = AccessibilityManager.getInstance(mContext); + mTextClassifier = requireNonNull(context.getSystemService(TextClassificationManager.class)) + .getTextClassifier(); mWindowManager = mContext.getSystemService(WindowManager.class); @@ -134,8 +149,9 @@ public class ClipboardOverlayController { mView = (DraggableConstraintLayout) LayoutInflater.from(mContext).inflate(R.layout.clipboard_overlay, null); - mActionContainerBackground = requireNonNull( - mView.findViewById(R.id.actions_container_background)); + mActionContainerBackground = + requireNonNull(mView.findViewById(R.id.actions_container_background)); + mActionContainer = requireNonNull(mView.findViewById(R.id.actions)); mImagePreview = requireNonNull(mView.findViewById(R.id.image_preview)); mTextPreview = requireNonNull(mView.findViewById(R.id.text_preview)); mEditChip = requireNonNull(mView.findViewById(R.id.edit_chip)); @@ -143,7 +159,7 @@ public class ClipboardOverlayController { mDismissButton = requireNonNull(mView.findViewById(R.id.dismiss_button)); mView.setOnDismissCallback(this::hideImmediate); - mView.setOnInteractionCallback(() -> mTimeoutHandler.resetTimeout()); + mView.setOnInteractionCallback(mTimeoutHandler::resetTimeout); mDismissButton.setOnClickListener(view -> animateOut()); @@ -166,7 +182,7 @@ public class ClipboardOverlayController { withWindowAttached(() -> { mWindow.setContentView(mView); updateInsets(mWindowManager.getCurrentWindowMetrics().getWindowInsets()); - mView.post(() -> getEnterAnimation().start()); + mView.post(this::animateIn); }); mTimeoutHandler.setOnTimeoutRunnable(this::animateOut); @@ -199,12 +215,15 @@ public class ClipboardOverlayController { void setClipData(ClipData clipData) { reset(); - 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)); } else if (!TextUtils.isEmpty(clipData.getItemAt(0).getText())) { - showEditableText(clipData.getItemAt(0).getText()); + ClipData.Item item = clipData.getItemAt(0); + if (item.getTextLinks() != null) { + AsyncTask.execute(() -> classifyText(clipData.getItemAt(0))); + } + showEditableText(item.getText()); } else if (clipData.getItemAt(0).getUri() != null) { // How to handle non-image URIs? showEditableImage(clipData.getItemAt(0).getUri()); @@ -212,7 +231,6 @@ public class ClipboardOverlayController { showTextPreview( mContext.getResources().getString(R.string.clipboard_overlay_text_copied)); } - mTimeoutHandler.resetTimeout(); } @@ -220,10 +238,40 @@ public class ClipboardOverlayController { mOnSessionCompleteListener = runnable; } + private void classifyText(ClipData.Item item) { + ArrayList<RemoteAction> actions = new ArrayList<>(); + for (TextLinks.TextLink link : item.getTextLinks().getLinks()) { + TextClassification classification = mTextClassifier.classifyText( + item.getText(), link.getStart(), link.getEnd(), null); + actions.addAll(classification.getActions()); + } + mView.post(() -> { + for (ScreenshotActionChip chip : mActionChips) { + mActionContainer.removeView(chip); + } + mActionChips.clear(); + for (RemoteAction action : actions) { + ScreenshotActionChip chip = constructActionChip(action); + mActionContainer.addView(chip); + mActionChips.add(chip); + } + }); + } + + private ScreenshotActionChip constructActionChip(RemoteAction action) { + ScreenshotActionChip chip = (ScreenshotActionChip) LayoutInflater.from(mContext).inflate( + R.layout.screenshot_action_chip, mActionContainer, false); + chip.setText(action.getTitle()); + chip.setIcon(action.getIcon(), false); + chip.setPendingIntent(action.getActionIntent(), this::animateOut); + chip.setAlpha(1); + return chip; + } + private void monitorOutsideTouches() { InputManager inputManager = mContext.getSystemService(InputManager.class); - InputMonitor monitor = inputManager.monitorGestureInput("clipboard overlay", 0); - mInputEventReceiver = new InputEventReceiver(monitor.getInputChannel(), + mInputMonitor = inputManager.monitorGestureInput("clipboard overlay", 0); + mInputEventReceiver = new InputEventReceiver(mInputMonitor.getInputChannel(), Looper.getMainLooper()) { @Override public void onInputEvent(InputEvent event) { @@ -311,6 +359,10 @@ public class ClipboardOverlayController { return nearbyIntent; } + private void animateIn() { + getEnterAnimation().start(); + } + private void animateOut() { getExitAnimation().start(); } @@ -390,6 +442,10 @@ public class ClipboardOverlayController { mInputEventReceiver.dispose(); mInputEventReceiver = null; } + if (mInputMonitor != null) { + mInputMonitor.dispose(); + mInputMonitor = null; + } if (mOnSessionCompleteListener != null) { mOnSessionCompleteListener.run(); } @@ -398,6 +454,10 @@ public class ClipboardOverlayController { private void reset() { mView.setTranslationX(0); mView.setAlpha(0); + for (ScreenshotActionChip chip : mActionChips) { + mActionContainer.removeView(chip); + } + mActionChips.clear(); mTimeoutHandler.cancelTimeout(); } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java index 6c01f0ea13a7..dec5afdaccfe 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java @@ -21,7 +21,6 @@ import android.content.Context; import android.graphics.drawable.Icon; import android.util.AttributeSet; import android.util.Log; -import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; @@ -129,7 +128,6 @@ public class ScreenshotActionChip extends FrameLayout { iconParams.setMarginStart(paddingHorizontal); iconParams.setMarginEnd(paddingHorizontal); } - mTextView.setVisibility(hasText ? View.VISIBLE : View.GONE); mIconView.setLayoutParams(iconParams); mTextView.setLayoutParams(textParams); } |