diff options
7 files changed, 197 insertions, 12 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java index b60e26628c55..6a9317f2b543 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java @@ -17,11 +17,14 @@ package com.android.systemui.clipboardoverlay; 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 android.content.ClipboardManager; import android.content.Context; import android.provider.DeviceConfig; +import com.android.internal.logging.UiEventLogger; import com.android.systemui.CoreStartable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.util.DeviceConfigProxy; @@ -38,15 +41,18 @@ public class ClipboardListener extends CoreStartable private final DeviceConfigProxy mDeviceConfig; private final ClipboardOverlayControllerFactory mOverlayFactory; private final ClipboardManager mClipboardManager; + private final UiEventLogger mUiEventLogger; private ClipboardOverlayController mClipboardOverlayController; @Inject public ClipboardListener(Context context, DeviceConfigProxy deviceConfigProxy, - ClipboardOverlayControllerFactory overlayFactory, ClipboardManager clipboardManager) { + ClipboardOverlayControllerFactory overlayFactory, ClipboardManager clipboardManager, + UiEventLogger uiEventLogger) { super(context); mDeviceConfig = deviceConfigProxy; mOverlayFactory = overlayFactory; mClipboardManager = clipboardManager; + mUiEventLogger = uiEventLogger; } @Override @@ -62,11 +68,15 @@ public class ClipboardListener extends CoreStartable if (!mClipboardManager.hasPrimaryClip()) { return; } + String clipSource = mClipboardManager.getPrimaryClipSource(); if (mClipboardOverlayController == null) { mClipboardOverlayController = mOverlayFactory.create(mContext); + mUiEventLogger.log(CLIPBOARD_OVERLAY_ENTERED, 0, clipSource); + } else { + mUiEventLogger.log(CLIPBOARD_OVERLAY_UPDATED, 0, clipSource); } mClipboardOverlayController.setClipData( - mClipboardManager.getPrimaryClip(), mClipboardManager.getPrimaryClipSource()); + mClipboardManager.getPrimaryClip(), clipSource); mClipboardOverlayController.setOnSessionCompleteListener(() -> { // Session is complete, free memory until it's needed again. mClipboardOverlayController = null; diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java index be2397d37bed..9861392ba463 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java @@ -21,6 +21,12 @@ 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.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ACTION_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_SWIPE_DISMISSED; +import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_TIMED_OUT; + import static java.util.Objects.requireNonNull; import android.animation.Animator; @@ -71,6 +77,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import com.android.internal.logging.UiEventLogger; import com.android.internal.policy.PhoneWindow; import com.android.systemui.R; import com.android.systemui.screenshot.DraggableConstraintLayout; @@ -97,6 +104,7 @@ public class ClipboardOverlayController { private static final int SWIPE_PADDING_DP = 12; // extra padding around views to allow swipe private final Context mContext; + private final UiEventLogger mUiEventLogger; private final DisplayManager mDisplayManager; private final DisplayMetrics mDisplayMetrics; private final WindowManager mWindowManager; @@ -129,11 +137,14 @@ public class ClipboardOverlayController { private boolean mBlockAttach = false; - public ClipboardOverlayController(Context context, TimeoutHandler timeoutHandler) { + public ClipboardOverlayController( + Context context, TimeoutHandler timeoutHandler, UiEventLogger uiEventLogger) { mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class)); final Context displayContext = context.createDisplayContext(getDefaultDisplay()); mContext = displayContext.createWindowContext(TYPE_SCREENSHOT, null); + mUiEventLogger = uiEventLogger; + mAccessibilityManager = AccessibilityManager.getInstance(mContext); mTextClassifier = requireNonNull(context.getSystemService(TextClassificationManager.class)) .getTextClassifier(); @@ -175,6 +186,7 @@ public class ClipboardOverlayController { @Override public void onSwipeDismissInitiated(Animator animator) { + mUiEventLogger.log(CLIPBOARD_OVERLAY_SWIPE_DISMISSED); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { @@ -222,7 +234,10 @@ public class ClipboardOverlayController { mView.post(this::animateIn); }); - mTimeoutHandler.setOnTimeoutRunnable(this::animateOut); + mTimeoutHandler.setOnTimeoutRunnable(() -> { + mUiEventLogger.log(CLIPBOARD_OVERLAY_TIMED_OUT); + animateOut(); + }); mCloseDialogsReceiver = new BroadcastReceiver() { @Override @@ -306,7 +321,10 @@ public class ClipboardOverlayController { chip.setText(action.getTitle()); chip.setContentDescription(action.getTitle()); chip.setIcon(action.getIcon(), false); - chip.setPendingIntent(action.getActionIntent(), this::animateOut); + chip.setPendingIntent(action.getActionIntent(), () -> { + mUiEventLogger.log(CLIPBOARD_OVERLAY_ACTION_TAPPED); + animateOut(); + }); chip.setAlpha(1); return chip; } @@ -350,6 +368,7 @@ public class ClipboardOverlayController { } private void editImage(Uri uri) { + mUiEventLogger.log(CLIPBOARD_OVERLAY_EDIT_TAPPED); String editorPackage = mContext.getString(R.string.config_screenshotEditor); Intent editIntent = new Intent(Intent.ACTION_EDIT); if (!TextUtils.isEmpty(editorPackage)) { @@ -363,6 +382,7 @@ public class ClipboardOverlayController { } private void editText() { + mUiEventLogger.log(CLIPBOARD_OVERLAY_EDIT_TAPPED); Intent editIntent = new Intent(mContext, EditTextActivity.class); editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); mContext.startActivity(editIntent); @@ -370,6 +390,7 @@ public class ClipboardOverlayController { } private void showNearby() { + mUiEventLogger.log(CLIPBOARD_OVERLAY_REMOTE_COPY_TAPPED); mContext.startActivity(getRemoteCopyIntent()); animateOut(); } diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerFactory.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerFactory.java index e1c11c4e8b4d..275d295613f9 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerFactory.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerFactory.java @@ -18,6 +18,7 @@ package com.android.systemui.clipboardoverlay; import android.content.Context; +import com.android.internal.logging.UiEventLogger; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.screenshot.TimeoutHandler; @@ -28,14 +29,17 @@ import javax.inject.Inject; */ @SysUISingleton public class ClipboardOverlayControllerFactory { + private final UiEventLogger mUiEventLogger; @Inject - public ClipboardOverlayControllerFactory() {} + public ClipboardOverlayControllerFactory(UiEventLogger uiEventLogger) { + mUiEventLogger = uiEventLogger; + } /** * One new ClipboardOverlayController, coming right up! */ public ClipboardOverlayController create(Context context) { - return new ClipboardOverlayController(context, new TimeoutHandler(context)); + return new ClipboardOverlayController(context, new TimeoutHandler(context), mUiEventLogger); } } diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java new file mode 100644 index 000000000000..5604a9128261 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 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 com.android.internal.logging.UiEvent; +import com.android.internal.logging.UiEventLogger; + +public enum ClipboardOverlayEvent implements UiEventLogger.UiEventEnum { + @UiEvent(doc = "clipboard overlay entered") + CLIPBOARD_OVERLAY_ENTERED(949), + @UiEvent(doc = "clipboard overlay updated") + CLIPBOARD_OVERLAY_UPDATED(950), + @UiEvent(doc = "clipboard edit tapped") + CLIPBOARD_OVERLAY_EDIT_TAPPED(951), + @UiEvent(doc = "clipboard action tapped") + CLIPBOARD_OVERLAY_ACTION_TAPPED(952), + @UiEvent(doc = "clipboard remote copy tapped") + CLIPBOARD_OVERLAY_REMOTE_COPY_TAPPED(953), + @UiEvent(doc = "clipboard overlay timed out") + CLIPBOARD_OVERLAY_TIMED_OUT(954), + @UiEvent(doc = "clipboard overlay dismiss tapped") + CLIPBOARD_OVERLAY_DISMISS_TAPPED(955), + @UiEvent(doc = "clipboard overlay swipe dismissed") + CLIPBOARD_OVERLAY_SWIPE_DISMISSED(956); + + private final int mId; + + ClipboardOverlayEvent(int id) { + mId = id; + } + + @Override + public int getId() { + return mId; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java index f6aeb2ac4ebc..041de05aa3d4 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java @@ -36,6 +36,7 @@ import android.view.IWindowManager; import android.view.LayoutInflater; import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.UiEventLogger; import com.android.internal.util.NotificationMessagingUtil; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; @@ -296,7 +297,8 @@ public class DependencyProvider { /***/ @Provides @SysUISingleton - public ClipboardOverlayControllerFactory provideClipboardOverlayControllerFactory() { - return new ClipboardOverlayControllerFactory(); + public ClipboardOverlayControllerFactory provideClipboardOverlayControllerFactory( + UiEventLogger uiEventLogger) { + return new ClipboardOverlayControllerFactory(uiEventLogger); } } 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 e15b6cc62644..de04d3e9d059 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java @@ -32,6 +32,7 @@ import android.provider.DeviceConfig; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.logging.UiEventLogger; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.DeviceConfigProxyFake; @@ -53,6 +54,8 @@ public class ClipboardListenerTest extends SysuiTestCase { private ClipboardOverlayControllerFactory mClipboardOverlayControllerFactory; @Mock private ClipboardOverlayController mOverlayController; + @Mock + private UiEventLogger mUiEventLogger; private DeviceConfigProxyFake mDeviceConfigProxy; private ClipData mSampleClipData; @@ -87,9 +90,10 @@ public class ClipboardListenerTest extends SysuiTestCase { mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, "false", false); ClipboardListener listener = new ClipboardListener(getContext(), mDeviceConfigProxy, - mClipboardOverlayControllerFactory, mClipboardManager); + mClipboardOverlayControllerFactory, mClipboardManager, mUiEventLogger); listener.start(); verifyZeroInteractions(mClipboardManager); + verifyZeroInteractions(mUiEventLogger); } @Test @@ -97,9 +101,10 @@ public class ClipboardListenerTest extends SysuiTestCase { mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, "true", false); ClipboardListener listener = new ClipboardListener(getContext(), mDeviceConfigProxy, - mClipboardOverlayControllerFactory, mClipboardManager); + mClipboardOverlayControllerFactory, mClipboardManager, mUiEventLogger); listener.start(); verify(mClipboardManager).addPrimaryClipChangedListener(any()); + verifyZeroInteractions(mUiEventLogger); } @Test @@ -107,7 +112,7 @@ public class ClipboardListenerTest extends SysuiTestCase { mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, "true", false); ClipboardListener listener = new ClipboardListener(getContext(), mDeviceConfigProxy, - mClipboardOverlayControllerFactory, mClipboardManager); + mClipboardOverlayControllerFactory, mClipboardManager, mUiEventLogger); listener.start(); listener.onPrimaryClipChanged(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEventTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEventTest.java new file mode 100644 index 000000000000..c7c2cd8d7b4b --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEventTest.java @@ -0,0 +1,93 @@ +/* + * 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 static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_ENABLED; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.provider.DeviceConfig; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.logging.UiEventLogger; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.util.DeviceConfigProxyFake; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class ClipboardOverlayEventTest extends SysuiTestCase { + + @Mock + private ClipboardManager mClipboardManager; + @Mock + private ClipboardOverlayControllerFactory mClipboardOverlayControllerFactory; + @Mock + private ClipboardOverlayController mOverlayController; + @Mock + private UiEventLogger mUiEventLogger; + + private final String mSampleSource = "Example source"; + + private ClipboardListener mClipboardListener; + + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + when(mClipboardOverlayControllerFactory.create(any())).thenReturn( + mOverlayController); + when(mClipboardManager.hasPrimaryClip()).thenReturn(true); + + ClipData sampleClipData = new ClipData("Test", new String[]{"text/plain"}, + new ClipData.Item("Test Item")); + when(mClipboardManager.getPrimaryClip()).thenReturn(sampleClipData); + when(mClipboardManager.getPrimaryClipSource()).thenReturn(mSampleSource); + + DeviceConfigProxyFake deviceConfigProxy = new DeviceConfigProxyFake(); + deviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, + "true", false); + + mClipboardListener = new ClipboardListener(getContext(), deviceConfigProxy, + mClipboardOverlayControllerFactory, mClipboardManager, mUiEventLogger); + } + + @Test + public void test_enterAndReenter() { + 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); + } +} |