Merge "Allow dev tools to suppress clipboard overlay." into tm-dev am: 627b6b9c8f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18205875

Change-Id: If3e3d0ed3a9bcf4e86b71a25d44022d35cd627e8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Matt Casey
2022-05-10 20:29:37 +00:00
committed by Automerger Merge Worker
2 changed files with 69 additions and 2 deletions

View File

@@ -20,10 +20,14 @@ import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBO
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ENTERED; 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_OVERLAY_UPDATED;
import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.os.SystemProperties;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLogger;
import com.android.systemui.CoreStartable; import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.SysUISingleton;
@@ -37,6 +41,13 @@ import javax.inject.Inject;
@SysUISingleton @SysUISingleton
public class ClipboardListener extends CoreStartable public class ClipboardListener extends CoreStartable
implements ClipboardManager.OnPrimaryClipChangedListener { implements ClipboardManager.OnPrimaryClipChangedListener {
private static final String TAG = "ClipboardListener";
@VisibleForTesting
static final String SHELL_PACKAGE = "com.android.shell";
@VisibleForTesting
static final String EXTRA_SUPPRESS_OVERLAY =
"com.android.systemui.SUPPRESS_CLIPBOARD_OVERLAY";
private final DeviceConfigProxy mDeviceConfig; private final DeviceConfigProxy mDeviceConfig;
private final ClipboardOverlayControllerFactory mOverlayFactory; private final ClipboardOverlayControllerFactory mOverlayFactory;
@@ -68,18 +79,44 @@ public class ClipboardListener extends CoreStartable
if (!mClipboardManager.hasPrimaryClip()) { if (!mClipboardManager.hasPrimaryClip()) {
return; return;
} }
String clipSource = mClipboardManager.getPrimaryClipSource(); String clipSource = mClipboardManager.getPrimaryClipSource();
ClipData clipData = mClipboardManager.getPrimaryClip();
if (shouldSuppressOverlay(clipData, clipSource, isEmulator())) {
Log.i(TAG, "Clipboard overlay suppressed.");
return;
}
if (mClipboardOverlayController == null) { if (mClipboardOverlayController == null) {
mClipboardOverlayController = mOverlayFactory.create(mContext); mClipboardOverlayController = mOverlayFactory.create(mContext);
mUiEventLogger.log(CLIPBOARD_OVERLAY_ENTERED, 0, clipSource); mUiEventLogger.log(CLIPBOARD_OVERLAY_ENTERED, 0, clipSource);
} else { } else {
mUiEventLogger.log(CLIPBOARD_OVERLAY_UPDATED, 0, clipSource); mUiEventLogger.log(CLIPBOARD_OVERLAY_UPDATED, 0, clipSource);
} }
mClipboardOverlayController.setClipData( mClipboardOverlayController.setClipData(clipData, clipSource);
mClipboardManager.getPrimaryClip(), clipSource);
mClipboardOverlayController.setOnSessionCompleteListener(() -> { mClipboardOverlayController.setOnSessionCompleteListener(() -> {
// Session is complete, free memory until it's needed again. // Session is complete, free memory until it's needed again.
mClipboardOverlayController = null; mClipboardOverlayController = null;
}); });
} }
// The overlay is suppressed if EXTRA_SUPPRESS_OVERLAY is true and the device is an emulator or
// the source package is SHELL_PACKAGE. This is meant to suppress the overlay when the emulator
// or a mirrored device is syncing the clipboard.
@VisibleForTesting
static boolean shouldSuppressOverlay(ClipData clipData, String clipSource,
boolean isEmulator) {
if (!(isEmulator || SHELL_PACKAGE.equals(clipSource))) {
return false;
}
if (clipData == null || clipData.getDescription().getExtras() == null) {
return false;
}
return clipData.getDescription().getExtras().getBoolean(EXTRA_SUPPRESS_OVERLAY, false);
}
private static boolean isEmulator() {
return SystemProperties.getBoolean("ro.boot.qemu", false);
}
} }

View File

@@ -19,6 +19,8 @@ package com.android.systemui.clipboardoverlay;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_ENABLED; import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_ENABLED;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -26,7 +28,9 @@ import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.os.PersistableBundle;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
@@ -139,4 +143,30 @@ public class ClipboardListenerTest extends SysuiTestCase {
verify(mClipboardOverlayControllerFactory, times(2)).create(any()); verify(mClipboardOverlayControllerFactory, times(2)).create(any());
} }
@Test
public void test_shouldSuppressOverlay() {
// Regardless of the package or emulator, nothing should be suppressed without the flag
assertFalse(ClipboardListener.shouldSuppressOverlay(mSampleClipData, mSampleSource,
false));
assertFalse(ClipboardListener.shouldSuppressOverlay(mSampleClipData,
ClipboardListener.SHELL_PACKAGE, false));
assertFalse(ClipboardListener.shouldSuppressOverlay(mSampleClipData, mSampleSource,
true));
ClipDescription desc = new ClipDescription("Test", new String[]{"text/plain"});
PersistableBundle bundle = new PersistableBundle();
bundle.putBoolean(ClipboardListener.EXTRA_SUPPRESS_OVERLAY, true);
desc.setExtras(bundle);
ClipData suppressableClipData = new ClipData(desc, new ClipData.Item("Test Item"));
// Clip data with the suppression extra is only honored in the emulator or with the shell
// package.
assertFalse(ClipboardListener.shouldSuppressOverlay(suppressableClipData, mSampleSource,
false));
assertTrue(ClipboardListener.shouldSuppressOverlay(suppressableClipData, mSampleSource,
true));
assertTrue(ClipboardListener.shouldSuppressOverlay(suppressableClipData,
ClipboardListener.SHELL_PACKAGE, false));
}
} }