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

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

Change-Id: I4d4fa1fafeb5981d7534697dcd35d42e46678a3b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Matt Casey
2022-05-10 21:41:20 +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_UPDATED;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.SysUISingleton;
@@ -37,6 +41,13 @@ import javax.inject.Inject;
@SysUISingleton
public class ClipboardListener extends CoreStartable
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 ClipboardOverlayControllerFactory mOverlayFactory;
@@ -68,18 +79,44 @@ public class ClipboardListener extends CoreStartable
if (!mClipboardManager.hasPrimaryClip()) {
return;
}
String clipSource = mClipboardManager.getPrimaryClipSource();
ClipData clipData = mClipboardManager.getPrimaryClip();
if (shouldSuppressOverlay(clipData, clipSource, isEmulator())) {
Log.i(TAG, "Clipboard overlay suppressed.");
return;
}
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(), clipSource);
mClipboardOverlayController.setClipData(clipData, clipSource);
mClipboardOverlayController.setOnSessionCompleteListener(() -> {
// Session is complete, free memory until it's needed again.
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 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.times;
import static org.mockito.Mockito.verify;
@@ -26,7 +28,9 @@ import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipboardManager;
import android.os.PersistableBundle;
import android.provider.DeviceConfig;
import androidx.test.filters.SmallTest;
@@ -139,4 +143,30 @@ public class ClipboardListenerTest extends SysuiTestCase {
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));
}
}