Merge "Add clipboard logging" into tm-dev

This commit is contained in:
Miranda Kephart
2022-03-30 15:38:08 +00:00
committed by Android (Google) Code Review
7 changed files with 197 additions and 12 deletions

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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);
}
}