diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java index 4f7f8ba2b45c..b9373be76b9a 100644 --- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java @@ -566,11 +566,6 @@ public final class SystemUiDeviceConfigFlags { */ public static final String VOLUME_SEPARATE_NOTIFICATION = "volume_separate_notification"; - /** - * (boolean) Whether the clipboard overlay is enabled. - */ - public static final String CLIPBOARD_OVERLAY_ENABLED = "clipboard_overlay_enabled"; - /** * (boolean) Whether widget provider info would be saved to / loaded from system persistence * layer as opposed to individual manifests in respective apps. diff --git a/packages/SystemUI/res/layout/clipboard_overlay_legacy.xml b/packages/SystemUI/res/layout/clipboard_overlay_legacy.xml deleted file mode 100644 index 1a1fc75a41a1..000000000000 --- a/packages/SystemUI/res/layout/clipboard_overlay_legacy.xml +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java index 805a20a6d965..1c26841a00be 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java @@ -18,7 +18,6 @@ import static android.content.ClipDescription.CLASSIFICATION_COMPLETE; -import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_ENABLED; import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ENTERED; import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_UPDATED; import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_TOAST_SHOWN; @@ -29,7 +28,6 @@ import android.content.ClipboardManager; import android.content.Context; import android.os.SystemProperties; -import android.provider.DeviceConfig; import android.provider.Settings; import android.util.Log; @@ -37,9 +35,6 @@ import com.android.internal.logging.UiEventLogger; import com.android.systemui.CoreStartable; import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.flags.FeatureFlags; -import com.android.systemui.flags.Flags; -import com.android.systemui.util.DeviceConfigProxy; import javax.inject.Inject; import javax.inject.Provider; @@ -59,42 +54,28 @@ public class ClipboardListener implements "com.android.systemui.SUPPRESS_CLIPBOARD_OVERLAY"; private final Context mContext; - private final DeviceConfigProxy mDeviceConfig; private final Provider mOverlayProvider; - private final ClipboardOverlayControllerLegacyFactory mOverlayFactory; private final ClipboardToast mClipboardToast; private final ClipboardManager mClipboardManager; private final UiEventLogger mUiEventLogger; - private final FeatureFlags mFeatureFlags; - private boolean mUsingNewOverlay; private ClipboardOverlay mClipboardOverlay; @Inject - public ClipboardListener(Context context, DeviceConfigProxy deviceConfigProxy, + public ClipboardListener(Context context, Provider clipboardOverlayControllerProvider, - ClipboardOverlayControllerLegacyFactory overlayFactory, ClipboardToast clipboardToast, ClipboardManager clipboardManager, - UiEventLogger uiEventLogger, - FeatureFlags featureFlags) { + UiEventLogger uiEventLogger) { mContext = context; - mDeviceConfig = deviceConfigProxy; mOverlayProvider = clipboardOverlayControllerProvider; - mOverlayFactory = overlayFactory; mClipboardToast = clipboardToast; mClipboardManager = clipboardManager; mUiEventLogger = uiEventLogger; - mFeatureFlags = featureFlags; - - mUsingNewOverlay = mFeatureFlags.isEnabled(Flags.CLIPBOARD_OVERLAY_REFACTOR); } @Override public void start() { - if (mDeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, true)) { - mClipboardManager.addPrimaryClipChangedListener(this); - } + mClipboardManager.addPrimaryClipChangedListener(this); } @Override @@ -120,14 +101,8 @@ public void onPrimaryClipChanged() { return; } - boolean enabled = mFeatureFlags.isEnabled(Flags.CLIPBOARD_OVERLAY_REFACTOR); - if (mClipboardOverlay == null || enabled != mUsingNewOverlay) { - mUsingNewOverlay = enabled; - if (enabled) { - mClipboardOverlay = mOverlayProvider.get(); - } else { - mClipboardOverlay = mOverlayFactory.create(mContext); - } + if (mClipboardOverlay == null) { + mClipboardOverlay = mOverlayProvider.get(); mUiEventLogger.log(CLIPBOARD_OVERLAY_ENTERED, 0, clipSource); } else { mUiEventLogger.log(CLIPBOARD_OVERLAY_UPDATED, 0, clipSource); diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerLegacy.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerLegacy.java deleted file mode 100644 index 3a040829ba0c..000000000000 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerLegacy.java +++ /dev/null @@ -1,963 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.clipboardoverlay; - -import static android.content.Intent.ACTION_CLOSE_SYSTEM_DIALOGS; -import static android.content.res.Configuration.ORIENTATION_PORTRAIT; -import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; - -import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_SHOW_ACTIONS; -import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_SHOW_EDIT_BUTTON; -import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ACTION_TAPPED; -import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_DISMISSED_OTHER; -import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_DISMISS_TAPPED; -import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_EDIT_TAPPED; -import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_REMOTE_COPY_TAPPED; -import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SHARE_TAPPED; -import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SWIPE_DISMISSED; -import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_TAP_OUTSIDE; -import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_TIMED_OUT; - -import static java.util.Objects.requireNonNull; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; -import android.animation.TimeInterpolator; -import android.animation.ValueAnimator; -import android.annotation.MainThread; -import android.app.ICompatCameraControlCallback; -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; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Insets; -import android.graphics.Paint; -import android.graphics.Rect; -import android.graphics.Region; -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.provider.DeviceConfig; -import android.text.TextUtils; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.MathUtils; -import android.util.Size; -import android.util.TypedValue; -import android.view.Display; -import android.view.DisplayCutout; -import android.view.Gravity; -import android.view.InputEvent; -import android.view.InputEventReceiver; -import android.view.InputMonitor; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewRootImpl; -import android.view.ViewTreeObserver; -import android.view.WindowInsets; -import android.view.WindowManager; -import android.view.accessibility.AccessibilityManager; -import android.view.animation.LinearInterpolator; -import android.view.animation.PathInterpolator; -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 androidx.annotation.NonNull; -import androidx.core.view.ViewCompat; -import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; - -import com.android.internal.logging.UiEventLogger; -import com.android.internal.policy.PhoneWindow; -import com.android.systemui.R; -import com.android.systemui.broadcast.BroadcastDispatcher; -import com.android.systemui.broadcast.BroadcastSender; -import com.android.systemui.screenshot.DraggableConstraintLayout; -import com.android.systemui.screenshot.FloatingWindowUtil; -import com.android.systemui.screenshot.OverlayActionChip; -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 - */ -public class ClipboardOverlayControllerLegacy implements ClipboardListener.ClipboardOverlay { - private static final String TAG = "ClipboardOverlayCtrlr"; - private static final String REMOTE_COPY_ACTION = "android.intent.action.REMOTE_COPY"; - - /** Constants for screenshot/copy deconflicting */ - public static final String SCREENSHOT_ACTION = "com.android.systemui.SCREENSHOT"; - public static final String SELF_PERMISSION = "com.android.systemui.permission.SELF"; - public static final String COPY_OVERLAY_ACTION = "com.android.systemui.COPY"; - - private static final String EXTRA_EDIT_SOURCE_CLIPBOARD = "edit_source_clipboard"; - - private static final int CLIPBOARD_DEFAULT_TIMEOUT_MILLIS = 6000; - private static final int SWIPE_PADDING_DP = 12; // extra padding around views to allow swipe - private static final int FONT_SEARCH_STEP_PX = 4; - - private final Context mContext; - private final ClipboardLogger mClipboardLogger; - private final BroadcastDispatcher mBroadcastDispatcher; - private final DisplayManager mDisplayManager; - private final DisplayMetrics mDisplayMetrics; - private final WindowManager mWindowManager; - private final WindowManager.LayoutParams mWindowLayoutParams; - private final PhoneWindow mWindow; - private final TimeoutHandler mTimeoutHandler; - private final AccessibilityManager mAccessibilityManager; - private final TextClassifier mTextClassifier; - - private final DraggableConstraintLayout mView; - private final View mClipboardPreview; - private final ImageView mImagePreview; - private final TextView mTextPreview; - private final TextView mHiddenPreview; - private final View mPreviewBorder; - private final OverlayActionChip mEditChip; - private final OverlayActionChip mShareChip; - private final OverlayActionChip mRemoteCopyChip; - private final View mActionContainerBackground; - private final View mDismissButton; - private final LinearLayout mActionContainer; - private final ArrayList mActionChips = new ArrayList<>(); - - private Runnable mOnSessionCompleteListener; - - private InputMonitor mInputMonitor; - private InputEventReceiver mInputEventReceiver; - - private BroadcastReceiver mCloseDialogsReceiver; - private BroadcastReceiver mScreenshotReceiver; - - private boolean mBlockAttach = false; - private Animator mExitAnimator; - private Animator mEnterAnimator; - private final int mOrientation; - private boolean mKeyboardVisible; - - - public ClipboardOverlayControllerLegacy(Context context, - BroadcastDispatcher broadcastDispatcher, - BroadcastSender broadcastSender, - TimeoutHandler timeoutHandler, UiEventLogger uiEventLogger) { - mBroadcastDispatcher = broadcastDispatcher; - mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class)); - final Context displayContext = context.createDisplayContext(getDefaultDisplay()); - mContext = displayContext.createWindowContext(TYPE_SCREENSHOT, null); - - mClipboardLogger = new ClipboardLogger(uiEventLogger); - - mAccessibilityManager = AccessibilityManager.getInstance(mContext); - mTextClassifier = requireNonNull(context.getSystemService(TextClassificationManager.class)) - .getTextClassifier(); - - mWindowManager = mContext.getSystemService(WindowManager.class); - - mDisplayMetrics = new DisplayMetrics(); - mContext.getDisplay().getRealMetrics(mDisplayMetrics); - - mTimeoutHandler = timeoutHandler; - mTimeoutHandler.setDefaultTimeoutMillis(CLIPBOARD_DEFAULT_TIMEOUT_MILLIS); - - // Setup the window that we are going to use - mWindowLayoutParams = FloatingWindowUtil.getFloatingWindowParams(); - mWindowLayoutParams.setTitle("ClipboardOverlay"); - - mWindow = FloatingWindowUtil.getFloatingWindow(mContext); - mWindow.setWindowManager(mWindowManager, null, null); - - setWindowFocusable(false); - - mView = (DraggableConstraintLayout) - LayoutInflater.from(mContext).inflate(R.layout.clipboard_overlay_legacy, null); - mActionContainerBackground = - requireNonNull(mView.findViewById(R.id.actions_container_background)); - mActionContainer = requireNonNull(mView.findViewById(R.id.actions)); - mClipboardPreview = requireNonNull(mView.findViewById(R.id.clipboard_preview)); - mImagePreview = requireNonNull(mView.findViewById(R.id.image_preview)); - mTextPreview = requireNonNull(mView.findViewById(R.id.text_preview)); - mHiddenPreview = requireNonNull(mView.findViewById(R.id.hidden_preview)); - mPreviewBorder = requireNonNull(mView.findViewById(R.id.preview_border)); - mEditChip = requireNonNull(mView.findViewById(R.id.edit_chip)); - mShareChip = requireNonNull(mView.findViewById(R.id.share_chip)); - mRemoteCopyChip = requireNonNull(mView.findViewById(R.id.remote_copy_chip)); - mEditChip.setAlpha(1); - mShareChip.setAlpha(1); - mRemoteCopyChip.setAlpha(1); - mDismissButton = requireNonNull(mView.findViewById(R.id.dismiss_button)); - - mShareChip.setContentDescription(mContext.getString(com.android.internal.R.string.share)); - mView.setCallbacks(new DraggableConstraintLayout.SwipeDismissCallbacks() { - @Override - public void onInteraction() { - mTimeoutHandler.resetTimeout(); - } - - @Override - public void onSwipeDismissInitiated(Animator animator) { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_SWIPE_DISMISSED); - mExitAnimator = animator; - } - - @Override - public void onDismissComplete() { - hideImmediate(); - } - }); - - mTextPreview.getViewTreeObserver().addOnPreDrawListener(() -> { - int availableHeight = mTextPreview.getHeight() - - (mTextPreview.getPaddingTop() + mTextPreview.getPaddingBottom()); - mTextPreview.setMaxLines(availableHeight / mTextPreview.getLineHeight()); - return true; - }); - - mDismissButton.setOnClickListener(view -> { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_DISMISS_TAPPED); - animateOut(); - }); - - mEditChip.setIcon(Icon.createWithResource(mContext, R.drawable.ic_screenshot_edit), true); - mRemoteCopyChip.setIcon( - Icon.createWithResource(mContext, R.drawable.ic_baseline_devices_24), true); - mShareChip.setIcon(Icon.createWithResource(mContext, R.drawable.ic_screenshot_share), true); - mOrientation = mContext.getResources().getConfiguration().orientation; - - attachWindow(); - withWindowAttached(() -> { - mWindow.setContentView(mView); - WindowInsets insets = mWindowManager.getCurrentWindowMetrics().getWindowInsets(); - mKeyboardVisible = insets.isVisible(WindowInsets.Type.ime()); - updateInsets(insets); - mWindow.peekDecorView().getViewTreeObserver().addOnGlobalLayoutListener( - new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - WindowInsets insets = - mWindowManager.getCurrentWindowMetrics().getWindowInsets(); - boolean keyboardVisible = insets.isVisible(WindowInsets.Type.ime()); - if (keyboardVisible != mKeyboardVisible) { - mKeyboardVisible = keyboardVisible; - updateInsets(insets); - } - } - }); - mWindow.peekDecorView().getViewRootImpl().setActivityConfigCallback( - new ViewRootImpl.ActivityConfigCallback() { - @Override - public void onConfigurationChanged(Configuration overrideConfig, - int newDisplayId) { - if (mContext.getResources().getConfiguration().orientation - != mOrientation) { - mClipboardLogger.logSessionComplete( - CLIPBOARD_OVERLAY_DISMISSED_OTHER); - hideImmediate(); - } - } - - @Override - public void requestCompatCameraControl( - boolean showControl, boolean transformationApplied, - ICompatCameraControlCallback callback) { - Log.w(TAG, "unexpected requestCompatCameraControl call"); - } - }); - }); - - mTimeoutHandler.setOnTimeoutRunnable(() -> { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_TIMED_OUT); - animateOut(); - }); - - mCloseDialogsReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_DISMISSED_OTHER); - animateOut(); - } - } - }; - - mBroadcastDispatcher.registerReceiver(mCloseDialogsReceiver, - new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS)); - mScreenshotReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (SCREENSHOT_ACTION.equals(intent.getAction())) { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_DISMISSED_OTHER); - animateOut(); - } - } - }; - - mBroadcastDispatcher.registerReceiver(mScreenshotReceiver, - new IntentFilter(SCREENSHOT_ACTION), null, null, Context.RECEIVER_EXPORTED, - SELF_PERMISSION); - monitorOutsideTouches(); - - Intent copyIntent = new Intent(COPY_OVERLAY_ACTION); - // Set package name so the system knows it's safe - copyIntent.setPackage(mContext.getPackageName()); - broadcastSender.sendBroadcast(copyIntent, SELF_PERMISSION); - } - - @Override // ClipboardListener.ClipboardOverlay - public void setClipData(ClipData clipData, String clipSource) { - if (mExitAnimator != null && mExitAnimator.isRunning()) { - mExitAnimator.cancel(); - } - reset(); - String accessibilityAnnouncement; - - 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), - mTextPreview); - accessibilityAnnouncement = mContext.getString(R.string.clipboard_content_copied); - } else if (!TextUtils.isEmpty(clipData.getItemAt(0).getText())) { - ClipData.Item item = clipData.getItemAt(0); - if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, - CLIPBOARD_OVERLAY_SHOW_ACTIONS, false)) { - if (item.getTextLinks() != null) { - AsyncTask.execute(() -> classifyText(clipData.getItemAt(0), clipSource)); - } - } - if (isSensitive) { - showEditableText( - mContext.getResources().getString(R.string.clipboard_asterisks), true); - } else { - showEditableText(item.getText(), false); - } - showShareChip(clipData); - accessibilityAnnouncement = mContext.getString(R.string.clipboard_text_copied); - } else if (clipData.getItemAt(0).getUri() != null) { - if (tryShowEditableImage(clipData.getItemAt(0).getUri(), isSensitive)) { - showShareChip(clipData); - 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 = IntentCreator.getRemoteCopyIntent(clipData, mContext); - // Only show remote copy if it's available. - PackageManager packageManager = mContext.getPackageManager(); - if (packageManager.resolveActivity( - remoteCopyIntent, PackageManager.ResolveInfoFlags.of(0)) != null) { - mRemoteCopyChip.setContentDescription( - mContext.getString(R.string.clipboard_send_nearby_description)); - mRemoteCopyChip.setVisibility(View.VISIBLE); - mRemoteCopyChip.setOnClickListener((v) -> { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_REMOTE_COPY_TAPPED); - mContext.startActivity(remoteCopyIntent); - animateOut(); - }); - mActionContainerBackground.setVisibility(View.VISIBLE); - } else { - mRemoteCopyChip.setVisibility(View.GONE); - } - withWindowAttached(() -> { - if (mEnterAnimator == null || !mEnterAnimator.isRunning()) { - mView.post(this::animateIn); - } - mView.announceForAccessibility(accessibilityAnnouncement); - }); - mTimeoutHandler.resetTimeout(); - } - - @Override // ClipboardListener.ClipboardOverlay - public void setOnSessionCompleteListener(Runnable runnable) { - mOnSessionCompleteListener = runnable; - } - - private void classifyText(ClipData.Item item, String source) { - ArrayList 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(() -> { - resetActionChips(); - if (actions.size() > 0) { - mActionContainerBackground.setVisibility(View.VISIBLE); - for (RemoteAction action : actions) { - Intent targetIntent = action.getActionIntent().getIntent(); - ComponentName component = targetIntent.getComponent(); - if (component != null && !TextUtils.equals(source, - component.getPackageName())) { - OverlayActionChip chip = constructActionChip(action); - mActionContainer.addView(chip); - mActionChips.add(chip); - break; // only show at most one action chip - } - } - } - }); - } - - private void showShareChip(ClipData clip) { - mShareChip.setVisibility(View.VISIBLE); - mActionContainerBackground.setVisibility(View.VISIBLE); - mShareChip.setOnClickListener((v) -> shareContent(clip)); - } - - private OverlayActionChip constructActionChip(RemoteAction action) { - OverlayActionChip chip = (OverlayActionChip) LayoutInflater.from(mContext).inflate( - R.layout.overlay_action_chip, mActionContainer, false); - chip.setText(action.getTitle()); - chip.setContentDescription(action.getTitle()); - chip.setIcon(action.getIcon(), false); - chip.setPendingIntent(action.getActionIntent(), () -> { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_ACTION_TAPPED); - animateOut(); - }); - chip.setAlpha(1); - return chip; - } - - private void monitorOutsideTouches() { - InputManager inputManager = mContext.getSystemService(InputManager.class); - mInputMonitor = inputManager.monitorGestureInput("clipboard overlay", 0); - mInputEventReceiver = new InputEventReceiver(mInputMonitor.getInputChannel(), - Looper.getMainLooper()) { - @Override - public void onInputEvent(InputEvent event) { - if (event instanceof MotionEvent) { - MotionEvent motionEvent = (MotionEvent) event; - if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) { - Region touchRegion = new Region(); - - final Rect tmpRect = new Rect(); - mPreviewBorder.getBoundsOnScreen(tmpRect); - tmpRect.inset( - (int) FloatingWindowUtil.dpToPx(mDisplayMetrics, -SWIPE_PADDING_DP), - (int) FloatingWindowUtil.dpToPx(mDisplayMetrics, - -SWIPE_PADDING_DP)); - touchRegion.op(tmpRect, Region.Op.UNION); - mActionContainerBackground.getBoundsOnScreen(tmpRect); - tmpRect.inset( - (int) FloatingWindowUtil.dpToPx(mDisplayMetrics, -SWIPE_PADDING_DP), - (int) FloatingWindowUtil.dpToPx(mDisplayMetrics, - -SWIPE_PADDING_DP)); - touchRegion.op(tmpRect, Region.Op.UNION); - mDismissButton.getBoundsOnScreen(tmpRect); - touchRegion.op(tmpRect, Region.Op.UNION); - if (!touchRegion.contains( - (int) motionEvent.getRawX(), (int) motionEvent.getRawY())) { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_TAP_OUTSIDE); - animateOut(); - } - } - } - finishInputEvent(event, true /* handled */); - } - }; - } - - private void editImage(Uri uri) { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_EDIT_TAPPED); - mContext.startActivity(IntentCreator.getImageEditIntent(uri, mContext)); - animateOut(); - } - - private void editText() { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_EDIT_TAPPED); - mContext.startActivity(IntentCreator.getTextEditorIntent(mContext)); - animateOut(); - } - - private void shareContent(ClipData clip) { - mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_SHARE_TAPPED); - mContext.startActivity(IntentCreator.getShareIntent(clip, mContext)); - animateOut(); - } - - private void showSinglePreview(View v) { - mTextPreview.setVisibility(View.GONE); - mImagePreview.setVisibility(View.GONE); - mHiddenPreview.setVisibility(View.GONE); - v.setVisibility(View.VISIBLE); - } - - private void showTextPreview(CharSequence text, TextView textView) { - showSinglePreview(textView); - final CharSequence truncatedText = text.subSequence(0, Math.min(500, text.length())); - textView.setText(truncatedText); - updateTextSize(truncatedText, textView); - - textView.addOnLayoutChangeListener( - (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - if (right - left != oldRight - oldLeft) { - updateTextSize(truncatedText, textView); - } - }); - mEditChip.setVisibility(View.GONE); - } - - private void updateTextSize(CharSequence text, TextView textView) { - Paint paint = new Paint(textView.getPaint()); - Resources res = textView.getResources(); - float minFontSize = res.getDimensionPixelSize(R.dimen.clipboard_overlay_min_font); - float maxFontSize = res.getDimensionPixelSize(R.dimen.clipboard_overlay_max_font); - if (isOneWord(text) && fitsInView(text, textView, paint, minFontSize)) { - // If the text is a single word and would fit within the TextView at the min font size, - // find the biggest font size that will fit. - float fontSizePx = minFontSize; - while (fontSizePx + FONT_SEARCH_STEP_PX < maxFontSize - && fitsInView(text, textView, paint, fontSizePx + FONT_SEARCH_STEP_PX)) { - fontSizePx += FONT_SEARCH_STEP_PX; - } - // Need to turn off autosizing, otherwise setTextSize is a no-op. - textView.setAutoSizeTextTypeWithDefaults(TextView.AUTO_SIZE_TEXT_TYPE_NONE); - // It's possible to hit the max font size and not fill the width, so centering - // horizontally looks better in this case. - textView.setGravity(Gravity.CENTER); - textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, (int) fontSizePx); - } else { - // Otherwise just stick with autosize. - textView.setAutoSizeTextTypeUniformWithConfiguration((int) minFontSize, - (int) maxFontSize, FONT_SEARCH_STEP_PX, TypedValue.COMPLEX_UNIT_PX); - textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.START); - } - } - - private static boolean fitsInView(CharSequence text, TextView textView, Paint paint, - float fontSizePx) { - paint.setTextSize(fontSizePx); - float size = paint.measureText(text.toString()); - float availableWidth = textView.getWidth() - textView.getPaddingLeft() - - textView.getPaddingRight(); - return size < availableWidth; - } - - private static boolean isOneWord(CharSequence text) { - return text.toString().split("\\s+", 2).length == 1; - } - - private void showEditableText(CharSequence text, boolean hidden) { - TextView textView = hidden ? mHiddenPreview : mTextPreview; - showTextPreview(text, textView); - View.OnClickListener listener = v -> editText(); - setAccessibilityActionToEdit(textView); - if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, - CLIPBOARD_OVERLAY_SHOW_EDIT_BUTTON, false)) { - mEditChip.setVisibility(View.VISIBLE); - mActionContainerBackground.setVisibility(View.VISIBLE); - mEditChip.setContentDescription( - mContext.getString(R.string.clipboard_edit_text_description)); - mEditChip.setOnClickListener(listener); - } - textView.setOnClickListener(listener); - } - - 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) { - mHiddenPreview.setText(mContext.getString(R.string.clipboard_text_hidden)); - showSinglePreview(mHiddenPreview); - if (isEditableImage) { - mHiddenPreview.setOnClickListener(listener); - setAccessibilityActionToEdit(mHiddenPreview); - } - } 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); - setAccessibilityActionToEdit(mImagePreview); - } catch (IOException e) { - Log.e(TAG, "Thumbnail loading failed", e); - showTextPreview( - mContext.getResources().getString(R.string.clipboard_overlay_text_copied), - mTextPreview); - isEditableImage = false; - } - } else { - showTextPreview( - mContext.getResources().getString(R.string.clipboard_overlay_text_copied), - mTextPreview); - } - if (isEditableImage && DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_SHOW_EDIT_BUTTON, false)) { - mEditChip.setVisibility(View.VISIBLE); - mActionContainerBackground.setVisibility(View.VISIBLE); - mEditChip.setOnClickListener(listener); - mEditChip.setContentDescription( - mContext.getString(R.string.clipboard_edit_image_description)); - } - return isEditableImage; - } - - private void setAccessibilityActionToEdit(View view) { - ViewCompat.replaceAccessibilityAction(view, - AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK, - mContext.getString(R.string.clipboard_edit), null); - } - - private void animateIn() { - if (mAccessibilityManager.isEnabled()) { - mDismissButton.setVisibility(View.VISIBLE); - } - mEnterAnimator = getEnterAnimation(); - mEnterAnimator.start(); - } - - private void animateOut() { - if (mExitAnimator != null && mExitAnimator.isRunning()) { - return; - } - Animator anim = getExitAnimation(); - anim.addListener(new AnimatorListenerAdapter() { - private boolean mCancelled; - - @Override - public void onAnimationCancel(Animator animation) { - super.onAnimationCancel(animation); - mCancelled = true; - } - - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - if (!mCancelled) { - hideImmediate(); - } - } - }); - mExitAnimator = anim; - anim.start(); - } - - private Animator getEnterAnimation() { - TimeInterpolator linearInterpolator = new LinearInterpolator(); - TimeInterpolator scaleInterpolator = new PathInterpolator(0, 0, 0, 1f); - AnimatorSet enterAnim = new AnimatorSet(); - - ValueAnimator rootAnim = ValueAnimator.ofFloat(0, 1); - rootAnim.setInterpolator(linearInterpolator); - rootAnim.setDuration(66); - rootAnim.addUpdateListener(animation -> { - mView.setAlpha(animation.getAnimatedFraction()); - }); - - ValueAnimator scaleAnim = ValueAnimator.ofFloat(0, 1); - scaleAnim.setInterpolator(scaleInterpolator); - scaleAnim.setDuration(333); - scaleAnim.addUpdateListener(animation -> { - float previewScale = MathUtils.lerp(.9f, 1f, animation.getAnimatedFraction()); - mClipboardPreview.setScaleX(previewScale); - mClipboardPreview.setScaleY(previewScale); - mPreviewBorder.setScaleX(previewScale); - mPreviewBorder.setScaleY(previewScale); - - float pivotX = mClipboardPreview.getWidth() / 2f + mClipboardPreview.getX(); - mActionContainerBackground.setPivotX(pivotX - mActionContainerBackground.getX()); - mActionContainer.setPivotX(pivotX - ((View) mActionContainer.getParent()).getX()); - float actionsScaleX = MathUtils.lerp(.7f, 1f, animation.getAnimatedFraction()); - float actionsScaleY = MathUtils.lerp(.9f, 1f, animation.getAnimatedFraction()); - mActionContainer.setScaleX(actionsScaleX); - mActionContainer.setScaleY(actionsScaleY); - mActionContainerBackground.setScaleX(actionsScaleX); - mActionContainerBackground.setScaleY(actionsScaleY); - }); - - ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1); - alphaAnim.setInterpolator(linearInterpolator); - alphaAnim.setDuration(283); - alphaAnim.addUpdateListener(animation -> { - float alpha = animation.getAnimatedFraction(); - mClipboardPreview.setAlpha(alpha); - mPreviewBorder.setAlpha(alpha); - mDismissButton.setAlpha(alpha); - mActionContainer.setAlpha(alpha); - }); - - mActionContainer.setAlpha(0); - mPreviewBorder.setAlpha(0); - mClipboardPreview.setAlpha(0); - enterAnim.play(rootAnim).with(scaleAnim); - enterAnim.play(alphaAnim).after(50).after(rootAnim); - - enterAnim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - mView.setAlpha(1); - mTimeoutHandler.resetTimeout(); - } - }); - return enterAnim; - } - - private Animator getExitAnimation() { - TimeInterpolator linearInterpolator = new LinearInterpolator(); - TimeInterpolator scaleInterpolator = new PathInterpolator(.3f, 0, 1f, 1f); - AnimatorSet exitAnim = new AnimatorSet(); - - ValueAnimator rootAnim = ValueAnimator.ofFloat(0, 1); - rootAnim.setInterpolator(linearInterpolator); - rootAnim.setDuration(100); - rootAnim.addUpdateListener(anim -> mView.setAlpha(1 - anim.getAnimatedFraction())); - - ValueAnimator scaleAnim = ValueAnimator.ofFloat(0, 1); - scaleAnim.setInterpolator(scaleInterpolator); - scaleAnim.setDuration(250); - scaleAnim.addUpdateListener(animation -> { - float previewScale = MathUtils.lerp(1f, .9f, animation.getAnimatedFraction()); - mClipboardPreview.setScaleX(previewScale); - mClipboardPreview.setScaleY(previewScale); - mPreviewBorder.setScaleX(previewScale); - mPreviewBorder.setScaleY(previewScale); - - float pivotX = mClipboardPreview.getWidth() / 2f + mClipboardPreview.getX(); - mActionContainerBackground.setPivotX(pivotX - mActionContainerBackground.getX()); - mActionContainer.setPivotX(pivotX - ((View) mActionContainer.getParent()).getX()); - float actionScaleX = MathUtils.lerp(1f, .8f, animation.getAnimatedFraction()); - float actionScaleY = MathUtils.lerp(1f, .9f, animation.getAnimatedFraction()); - mActionContainer.setScaleX(actionScaleX); - mActionContainer.setScaleY(actionScaleY); - mActionContainerBackground.setScaleX(actionScaleX); - mActionContainerBackground.setScaleY(actionScaleY); - }); - - ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1); - alphaAnim.setInterpolator(linearInterpolator); - alphaAnim.setDuration(166); - alphaAnim.addUpdateListener(animation -> { - float alpha = 1 - animation.getAnimatedFraction(); - mClipboardPreview.setAlpha(alpha); - mPreviewBorder.setAlpha(alpha); - mDismissButton.setAlpha(alpha); - mActionContainer.setAlpha(alpha); - }); - - exitAnim.play(alphaAnim).with(scaleAnim); - exitAnim.play(rootAnim).after(150).after(alphaAnim); - return exitAnim; - } - - private void hideImmediate() { - // Note this may be called multiple times if multiple dismissal events happen at the same - // time. - mTimeoutHandler.cancelTimeout(); - final View decorView = mWindow.peekDecorView(); - if (decorView != null && decorView.isAttachedToWindow()) { - mWindowManager.removeViewImmediate(decorView); - } - if (mCloseDialogsReceiver != null) { - mBroadcastDispatcher.unregisterReceiver(mCloseDialogsReceiver); - mCloseDialogsReceiver = null; - } - if (mScreenshotReceiver != null) { - mBroadcastDispatcher.unregisterReceiver(mScreenshotReceiver); - mScreenshotReceiver = null; - } - if (mInputEventReceiver != null) { - mInputEventReceiver.dispose(); - mInputEventReceiver = null; - } - if (mInputMonitor != null) { - mInputMonitor.dispose(); - mInputMonitor = null; - } - if (mOnSessionCompleteListener != null) { - mOnSessionCompleteListener.run(); - } - } - - private void resetActionChips() { - for (OverlayActionChip chip : mActionChips) { - mActionContainer.removeView(chip); - } - mActionChips.clear(); - } - - private void reset() { - mView.setTranslationX(0); - mView.setAlpha(0); - mActionContainerBackground.setVisibility(View.GONE); - mShareChip.setVisibility(View.GONE); - mEditChip.setVisibility(View.GONE); - mRemoteCopyChip.setVisibility(View.GONE); - resetActionChips(); - mTimeoutHandler.cancelTimeout(); - mClipboardLogger.reset(); - } - - @MainThread - private void attachWindow() { - View decorView = mWindow.getDecorView(); - if (decorView.isAttachedToWindow() || mBlockAttach) { - return; - } - mBlockAttach = true; - mWindowManager.addView(decorView, mWindowLayoutParams); - decorView.requestApplyInsets(); - mView.requestApplyInsets(); - decorView.getViewTreeObserver().addOnWindowAttachListener( - new ViewTreeObserver.OnWindowAttachListener() { - @Override - public void onWindowAttached() { - mBlockAttach = false; - } - - @Override - public void onWindowDetached() { - } - } - ); - } - - private void withWindowAttached(Runnable action) { - View decorView = mWindow.getDecorView(); - if (decorView.isAttachedToWindow()) { - action.run(); - } else { - decorView.getViewTreeObserver().addOnWindowAttachListener( - new ViewTreeObserver.OnWindowAttachListener() { - @Override - public void onWindowAttached() { - mBlockAttach = false; - decorView.getViewTreeObserver().removeOnWindowAttachListener(this); - action.run(); - } - - @Override - public void onWindowDetached() { - } - }); - } - } - - private void updateInsets(WindowInsets insets) { - int orientation = mContext.getResources().getConfiguration().orientation; - FrameLayout.LayoutParams p = (FrameLayout.LayoutParams) mView.getLayoutParams(); - if (p == null) { - return; - } - DisplayCutout cutout = insets.getDisplayCutout(); - Insets navBarInsets = insets.getInsets(WindowInsets.Type.navigationBars()); - Insets imeInsets = insets.getInsets(WindowInsets.Type.ime()); - if (cutout == null) { - p.setMargins(0, 0, 0, Math.max(imeInsets.bottom, navBarInsets.bottom)); - } else { - Insets waterfall = cutout.getWaterfallInsets(); - if (orientation == ORIENTATION_PORTRAIT) { - p.setMargins( - waterfall.left, - Math.max(cutout.getSafeInsetTop(), waterfall.top), - waterfall.right, - Math.max(imeInsets.bottom, - Math.max(cutout.getSafeInsetBottom(), - Math.max(navBarInsets.bottom, waterfall.bottom)))); - } else { - p.setMargins( - waterfall.left, - waterfall.top, - waterfall.right, - Math.max(imeInsets.bottom, - Math.max(navBarInsets.bottom, waterfall.bottom))); - } - } - mView.setLayoutParams(p); - mView.requestLayout(); - } - - private Display getDefaultDisplay() { - return mDisplayManager.getDisplay(DEFAULT_DISPLAY); - } - - /** - * Updates the window focusability. If the window is already showing, then it updates the - * window immediately, otherwise the layout params will be applied when the window is next - * shown. - */ - private void setWindowFocusable(boolean focusable) { - int flags = mWindowLayoutParams.flags; - if (focusable) { - mWindowLayoutParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; - } else { - mWindowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; - } - if (mWindowLayoutParams.flags == flags) { - return; - } - final View decorView = mWindow.peekDecorView(); - if (decorView != null && decorView.isAttachedToWindow()) { - mWindowManager.updateViewLayout(decorView, mWindowLayoutParams); - } - } - - static class ClipboardLogger { - private final UiEventLogger mUiEventLogger; - private boolean mGuarded = false; - - ClipboardLogger(UiEventLogger uiEventLogger) { - mUiEventLogger = uiEventLogger; - } - - void logSessionComplete(@NonNull UiEventLogger.UiEventEnum event) { - if (!mGuarded) { - mGuarded = true; - mUiEventLogger.log(event); - } - } - - void reset() { - mGuarded = false; - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerLegacyFactory.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerLegacyFactory.java deleted file mode 100644 index 0d989a78947d..000000000000 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerLegacyFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.clipboardoverlay; - -import android.content.Context; - -import com.android.internal.logging.UiEventLogger; -import com.android.systemui.broadcast.BroadcastDispatcher; -import com.android.systemui.broadcast.BroadcastSender; -import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.screenshot.TimeoutHandler; - -import javax.inject.Inject; - -/** - * A factory that churns out ClipboardOverlayControllerLegacys on demand. - */ -@SysUISingleton -public class ClipboardOverlayControllerLegacyFactory { - - private final UiEventLogger mUiEventLogger; - private final BroadcastDispatcher mBroadcastDispatcher; - private final BroadcastSender mBroadcastSender; - - @Inject - public ClipboardOverlayControllerLegacyFactory(BroadcastDispatcher broadcastDispatcher, - BroadcastSender broadcastSender, UiEventLogger uiEventLogger) { - this.mBroadcastDispatcher = broadcastDispatcher; - this.mBroadcastSender = broadcastSender; - this.mUiEventLogger = uiEventLogger; - } - - /** - * One new ClipboardOverlayControllerLegacy, coming right up! - */ - public ClipboardOverlayControllerLegacy create(Context context) { - return new ClipboardOverlayControllerLegacy(context, mBroadcastDispatcher, mBroadcastSender, - new TimeoutHandler(context), mUiEventLogger); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 012615b0c653..6f948a018b85 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -480,7 +480,6 @@ object Flags { unreleasedFlag(1600, "a11y_floating_menu_fling_spring_animations") // 1700 - clipboard - @JvmField val CLIPBOARD_OVERLAY_REFACTOR = releasedFlag(1700, "clipboard_overlay_refactor") @JvmField val CLIPBOARD_REMOTE_BEHAVIOR = releasedFlag(1701, "clipboard_remote_behavior") // 1800 - shade container @@ -539,6 +538,5 @@ object Flags { // 2600 - keyboard shortcut // TODO(b/259352579): Tracking Bug - @JvmField - val SHORTCUT_LIST_SEARCH_LAYOUT = unreleasedFlag(2600, "shortcut_list_search_layout") + @JvmField val SHORTCUT_LIST_SEARCH_LAYOUT = unreleasedFlag(2600, "shortcut_list_search_layout") } diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java index bdd496ec219b..71c335e6b173 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java @@ -16,8 +16,6 @@ package com.android.systemui.clipboardoverlay; -import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_ENABLED; - import static com.google.android.setupcompat.util.WizardManagerHelper.SETTINGS_SECURE_USER_SETUP_COMPLETE; import static org.junit.Assert.assertEquals; @@ -33,7 +31,6 @@ import android.content.ClipDescription; import android.content.ClipboardManager; import android.os.PersistableBundle; -import android.provider.DeviceConfig; import android.provider.Settings; import androidx.test.filters.SmallTest; @@ -41,9 +38,6 @@ import com.android.internal.logging.UiEventLogger; import com.android.systemui.SysuiTestCase; -import com.android.systemui.flags.FeatureFlags; -import com.android.systemui.flags.Flags; -import com.android.systemui.util.DeviceConfigProxyFake; import org.junit.Before; import org.junit.Test; @@ -63,18 +57,11 @@ public class ClipboardListenerTest extends SysuiTestCase { @Mock private ClipboardManager mClipboardManager; @Mock - private ClipboardOverlayControllerLegacyFactory mClipboardOverlayControllerLegacyFactory; - @Mock - private ClipboardOverlayControllerLegacy mOverlayControllerLegacy; - @Mock private ClipboardOverlayController mOverlayController; @Mock private ClipboardToast mClipboardToast; @Mock private UiEventLogger mUiEventLogger; - @Mock - private FeatureFlags mFeatureFlags; - private DeviceConfigProxyFake mDeviceConfigProxy; private ClipData mSampleClipData; private String mSampleSource = "Example source"; @@ -97,8 +84,6 @@ public void setup() { mOverlayControllerProvider = () -> mOverlayController; MockitoAnnotations.initMocks(this); - when(mClipboardOverlayControllerLegacyFactory.create(any())) - .thenReturn(mOverlayControllerLegacy); when(mClipboardManager.hasPrimaryClip()).thenReturn(true); Settings.Secure.putInt( mContext.getContentResolver(), SETTINGS_SECURE_USER_SETUP_COMPLETE, 1); @@ -108,26 +93,13 @@ public void setup() { when(mClipboardManager.getPrimaryClip()).thenReturn(mSampleClipData); when(mClipboardManager.getPrimaryClipSource()).thenReturn(mSampleSource); - mDeviceConfigProxy = new DeviceConfigProxyFake(); - - mClipboardListener = new ClipboardListener(getContext(), mDeviceConfigProxy, - mOverlayControllerProvider, mClipboardOverlayControllerLegacyFactory, - mClipboardToast, mClipboardManager, mUiEventLogger, mFeatureFlags); + mClipboardListener = new ClipboardListener(getContext(), mOverlayControllerProvider, + mClipboardToast, mClipboardManager, mUiEventLogger); } - @Test - public void test_disabled() { - mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, - "false", false); - mClipboardListener.start(); - verifyZeroInteractions(mClipboardManager); - verifyZeroInteractions(mUiEventLogger); - } @Test - public void test_enabled() { - mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, - "true", false); + public void test_initialization() { mClipboardListener.start(); verify(mClipboardManager).addPrimaryClipChangedListener(any()); verifyZeroInteractions(mUiEventLogger); @@ -135,45 +107,6 @@ public void test_enabled() { @Test public void test_consecutiveCopies() { - when(mFeatureFlags.isEnabled(Flags.CLIPBOARD_OVERLAY_REFACTOR)).thenReturn(false); - - mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, - "true", false); - mClipboardListener.start(); - mClipboardListener.onPrimaryClipChanged(); - - verify(mClipboardOverlayControllerLegacyFactory).create(any()); - - verify(mOverlayControllerLegacy).setClipData( - mClipDataCaptor.capture(), mStringCaptor.capture()); - - assertEquals(mSampleClipData, mClipDataCaptor.getValue()); - assertEquals(mSampleSource, mStringCaptor.getValue()); - - verify(mOverlayControllerLegacy).setOnSessionCompleteListener(mRunnableCaptor.capture()); - - // Should clear the overlay controller - mRunnableCaptor.getValue().run(); - - mClipboardListener.onPrimaryClipChanged(); - - verify(mClipboardOverlayControllerLegacyFactory, times(2)).create(any()); - - // Not calling the runnable here, just change the clip again and verify that the overlay is - // NOT recreated. - - mClipboardListener.onPrimaryClipChanged(); - - verify(mClipboardOverlayControllerLegacyFactory, times(2)).create(any()); - verifyZeroInteractions(mOverlayControllerProvider); - } - - @Test - public void test_consecutiveCopies_new() { - when(mFeatureFlags.isEnabled(Flags.CLIPBOARD_OVERLAY_REFACTOR)).thenReturn(true); - - mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, - "true", false); mClipboardListener.start(); mClipboardListener.onPrimaryClipChanged(); @@ -200,7 +133,6 @@ public void test_consecutiveCopies_new() { mClipboardListener.onPrimaryClipChanged(); verify(mOverlayControllerProvider, times(2)).get(); - verifyZeroInteractions(mClipboardOverlayControllerLegacyFactory); } @Test @@ -231,23 +163,6 @@ public void test_shouldSuppressOverlay() { @Test public void test_logging_enterAndReenter() { - when(mFeatureFlags.isEnabled(Flags.CLIPBOARD_OVERLAY_REFACTOR)).thenReturn(false); - - mClipboardListener.start(); - - mClipboardListener.onPrimaryClipChanged(); - mClipboardListener.onPrimaryClipChanged(); - - verify(mUiEventLogger, times(1)).log( - ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ENTERED, 0, mSampleSource); - verify(mUiEventLogger, times(1)).log( - ClipboardOverlayEvent.CLIPBOARD_OVERLAY_UPDATED, 0, mSampleSource); - } - - @Test - public void test_logging_enterAndReenter_new() { - when(mFeatureFlags.isEnabled(Flags.CLIPBOARD_OVERLAY_REFACTOR)).thenReturn(true); - mClipboardListener.start(); mClipboardListener.onPrimaryClipChanged(); @@ -271,6 +186,5 @@ public void test_userSetupIncomplete_showsToast() { ClipboardOverlayEvent.CLIPBOARD_TOAST_SHOWN, 0, mSampleSource); verify(mClipboardToast, times(1)).showCopiedToast(); verifyZeroInteractions(mOverlayControllerProvider); - verifyZeroInteractions(mClipboardOverlayControllerLegacyFactory); } }