Just show toast on clipboard change if user not set up

Bug: 251778420
Test: wiped phone and verified that only a toast was shown before setup
Test: atest ClipboardListenerTest
Change-Id: I7d5b0c0cda2191e487468f52a7ad345ba8b54a86
Merged-In: I7d5b0c0cda2191e487468f52a7ad345ba8b54a86
(cherry picked from commit 14a958756ff5725093199e68d04d22a85badcc16)
Merged-In: I7d5b0c0cda2191e487468f52a7ad345ba8b54a86
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java
index 82e5704..805a20a 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java
@@ -16,15 +16,21 @@
 
 package com.android.systemui.clipboardoverlay;
 
+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;
+
+import static com.google.android.setupcompat.util.WizardManagerHelper.SETTINGS_SECURE_USER_SETUP_COMPLETE;
 
 import android.content.ClipData;
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.os.SystemProperties;
 import android.provider.DeviceConfig;
+import android.provider.Settings;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -56,6 +62,7 @@
     private final DeviceConfigProxy mDeviceConfig;
     private final Provider<ClipboardOverlayController> mOverlayProvider;
     private final ClipboardOverlayControllerLegacyFactory mOverlayFactory;
+    private final ClipboardToast mClipboardToast;
     private final ClipboardManager mClipboardManager;
     private final UiEventLogger mUiEventLogger;
     private final FeatureFlags mFeatureFlags;
@@ -66,6 +73,7 @@
     public ClipboardListener(Context context, DeviceConfigProxy deviceConfigProxy,
             Provider<ClipboardOverlayController> clipboardOverlayControllerProvider,
             ClipboardOverlayControllerLegacyFactory overlayFactory,
+            ClipboardToast clipboardToast,
             ClipboardManager clipboardManager,
             UiEventLogger uiEventLogger,
             FeatureFlags featureFlags) {
@@ -73,6 +81,7 @@
         mDeviceConfig = deviceConfigProxy;
         mOverlayProvider = clipboardOverlayControllerProvider;
         mOverlayFactory = overlayFactory;
+        mClipboardToast = clipboardToast;
         mClipboardManager = clipboardManager;
         mUiEventLogger = uiEventLogger;
         mFeatureFlags = featureFlags;
@@ -102,6 +111,15 @@
             return;
         }
 
+        if (!isUserSetupComplete()) {
+            // just show a toast, user should not access intents from this state
+            if (shouldShowToast(clipData)) {
+                mUiEventLogger.log(CLIPBOARD_TOAST_SHOWN, 0, clipSource);
+                mClipboardToast.showCopiedToast();
+            }
+            return;
+        }
+
         boolean enabled = mFeatureFlags.isEnabled(Flags.CLIPBOARD_OVERLAY_REFACTOR);
         if (mClipboardOverlay == null || enabled != mUsingNewOverlay) {
             mUsingNewOverlay = enabled;
@@ -136,10 +154,26 @@
         return clipData.getDescription().getExtras().getBoolean(EXTRA_SUPPRESS_OVERLAY, false);
     }
 
+    boolean shouldShowToast(ClipData clipData) {
+        if (clipData == null) {
+            return false;
+        } else if (clipData.getDescription().getClassificationStatus() == CLASSIFICATION_COMPLETE) {
+            // only show for classification complete if we aren't already showing a toast, to ignore
+            // the duplicate ClipData with classification
+            return !mClipboardToast.isShowing();
+        }
+        return true;
+    }
+
     private static boolean isEmulator() {
         return SystemProperties.getBoolean("ro.boot.qemu", false);
     }
 
+    private boolean isUserSetupComplete() {
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                SETTINGS_SECURE_USER_SETUP_COMPLETE, 0) == 1;
+    }
+
     interface ClipboardOverlay {
         void setClipData(ClipData clipData, String clipSource);
 
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java
index a0b2ab9..1e7dbe6 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayEvent.java
@@ -41,7 +41,9 @@
     @UiEvent(doc = "clipboard overlay tapped outside")
     CLIPBOARD_OVERLAY_TAP_OUTSIDE(1077),
     @UiEvent(doc = "clipboard overlay dismissed, miscellaneous reason")
-    CLIPBOARD_OVERLAY_DISMISSED_OTHER(1078);
+    CLIPBOARD_OVERLAY_DISMISSED_OTHER(1078),
+    @UiEvent(doc = "clipboard toast shown")
+    CLIPBOARD_TOAST_SHOWN(1270);
 
     private final int mId;
 
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java
new file mode 100644
index 0000000..0ed7d27
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java
@@ -0,0 +1,56 @@
+/*
+ * 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 android.widget.Toast;
+
+import com.android.systemui.R;
+
+import javax.inject.Inject;
+
+/**
+ * Utility class for showing a simple clipboard toast on copy.
+ */
+class ClipboardToast extends Toast.Callback {
+    private final Context mContext;
+    private Toast mCopiedToast;
+
+    @Inject
+    ClipboardToast(Context context) {
+        mContext = context;
+    }
+
+    void showCopiedToast() {
+        if (mCopiedToast != null) {
+            mCopiedToast.cancel();
+        }
+        mCopiedToast = Toast.makeText(mContext,
+                R.string.clipboard_overlay_text_copied, Toast.LENGTH_SHORT);
+        mCopiedToast.show();
+    }
+
+    boolean isShowing() {
+        return mCopiedToast != null;
+    }
+
+    @Override // Toast.Callback
+    public void onToastHidden() {
+        super.onToastHidden();
+        mCopiedToast = null;
+    }
+}
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 e7e6918..bdd496e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java
@@ -18,6 +18,8 @@
 
 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;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -32,6 +34,7 @@
 import android.content.ClipboardManager;
 import android.os.PersistableBundle;
 import android.provider.DeviceConfig;
+import android.provider.Settings;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -66,6 +69,8 @@
     @Mock
     private ClipboardOverlayController mOverlayController;
     @Mock
+    private ClipboardToast mClipboardToast;
+    @Mock
     private UiEventLogger mUiEventLogger;
     @Mock
     private FeatureFlags mFeatureFlags;
@@ -84,6 +89,8 @@
     @Spy
     private Provider<ClipboardOverlayController> mOverlayControllerProvider;
 
+    private ClipboardListener mClipboardListener;
+
 
     @Before
     public void setup() {
@@ -93,7 +100,8 @@
         when(mClipboardOverlayControllerLegacyFactory.create(any()))
                 .thenReturn(mOverlayControllerLegacy);
         when(mClipboardManager.hasPrimaryClip()).thenReturn(true);
-
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), SETTINGS_SECURE_USER_SETUP_COMPLETE, 1);
 
         mSampleClipData = new ClipData("Test", new String[]{"text/plain"},
                 new ClipData.Item("Test Item"));
@@ -101,16 +109,17 @@
         when(mClipboardManager.getPrimaryClipSource()).thenReturn(mSampleSource);
 
         mDeviceConfigProxy = new DeviceConfigProxyFake();
+
+        mClipboardListener = new ClipboardListener(getContext(), mDeviceConfigProxy,
+                mOverlayControllerProvider, mClipboardOverlayControllerLegacyFactory,
+                mClipboardToast, mClipboardManager, mUiEventLogger, mFeatureFlags);
     }
 
     @Test
     public void test_disabled() {
         mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED,
                 "false", false);
-        ClipboardListener listener = new ClipboardListener(getContext(), mDeviceConfigProxy,
-                mOverlayControllerProvider, mClipboardOverlayControllerLegacyFactory,
-                mClipboardManager, mUiEventLogger, mFeatureFlags);
-        listener.start();
+        mClipboardListener.start();
         verifyZeroInteractions(mClipboardManager);
         verifyZeroInteractions(mUiEventLogger);
     }
@@ -119,10 +128,7 @@
     public void test_enabled() {
         mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED,
                 "true", false);
-        ClipboardListener listener = new ClipboardListener(getContext(), mDeviceConfigProxy,
-                mOverlayControllerProvider, mClipboardOverlayControllerLegacyFactory,
-                mClipboardManager, mUiEventLogger, mFeatureFlags);
-        listener.start();
+        mClipboardListener.start();
         verify(mClipboardManager).addPrimaryClipChangedListener(any());
         verifyZeroInteractions(mUiEventLogger);
     }
@@ -133,11 +139,8 @@
 
         mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED,
                 "true", false);
-        ClipboardListener listener = new ClipboardListener(getContext(), mDeviceConfigProxy,
-                mOverlayControllerProvider, mClipboardOverlayControllerLegacyFactory,
-                mClipboardManager, mUiEventLogger, mFeatureFlags);
-        listener.start();
-        listener.onPrimaryClipChanged();
+        mClipboardListener.start();
+        mClipboardListener.onPrimaryClipChanged();
 
         verify(mClipboardOverlayControllerLegacyFactory).create(any());
 
@@ -152,14 +155,14 @@
         // Should clear the overlay controller
         mRunnableCaptor.getValue().run();
 
-        listener.onPrimaryClipChanged();
+        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.
 
-        listener.onPrimaryClipChanged();
+        mClipboardListener.onPrimaryClipChanged();
 
         verify(mClipboardOverlayControllerLegacyFactory, times(2)).create(any());
         verifyZeroInteractions(mOverlayControllerProvider);
@@ -171,11 +174,8 @@
 
         mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED,
                 "true", false);
-        ClipboardListener listener = new ClipboardListener(getContext(), mDeviceConfigProxy,
-                mOverlayControllerProvider, mClipboardOverlayControllerLegacyFactory,
-                mClipboardManager, mUiEventLogger, mFeatureFlags);
-        listener.start();
-        listener.onPrimaryClipChanged();
+        mClipboardListener.start();
+        mClipboardListener.onPrimaryClipChanged();
 
         verify(mOverlayControllerProvider).get();
 
@@ -190,14 +190,14 @@
         // Should clear the overlay controller
         mRunnableCaptor.getValue().run();
 
-        listener.onPrimaryClipChanged();
+        mClipboardListener.onPrimaryClipChanged();
 
         verify(mOverlayControllerProvider, times(2)).get();
 
         // Not calling the runnable here, just change the clip again and verify that the overlay is
         // NOT recreated.
 
-        listener.onPrimaryClipChanged();
+        mClipboardListener.onPrimaryClipChanged();
 
         verify(mOverlayControllerProvider, times(2)).get();
         verifyZeroInteractions(mClipboardOverlayControllerLegacyFactory);
@@ -233,13 +233,10 @@
     public void test_logging_enterAndReenter() {
         when(mFeatureFlags.isEnabled(Flags.CLIPBOARD_OVERLAY_REFACTOR)).thenReturn(false);
 
-        ClipboardListener listener = new ClipboardListener(getContext(), mDeviceConfigProxy,
-                mOverlayControllerProvider, mClipboardOverlayControllerLegacyFactory,
-                mClipboardManager, mUiEventLogger, mFeatureFlags);
-        listener.start();
+        mClipboardListener.start();
 
-        listener.onPrimaryClipChanged();
-        listener.onPrimaryClipChanged();
+        mClipboardListener.onPrimaryClipChanged();
+        mClipboardListener.onPrimaryClipChanged();
 
         verify(mUiEventLogger, times(1)).log(
                 ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ENTERED, 0, mSampleSource);
@@ -251,17 +248,29 @@
     public void test_logging_enterAndReenter_new() {
         when(mFeatureFlags.isEnabled(Flags.CLIPBOARD_OVERLAY_REFACTOR)).thenReturn(true);
 
-        ClipboardListener listener = new ClipboardListener(getContext(), mDeviceConfigProxy,
-                mOverlayControllerProvider, mClipboardOverlayControllerLegacyFactory,
-                mClipboardManager, mUiEventLogger, mFeatureFlags);
-        listener.start();
+        mClipboardListener.start();
 
-        listener.onPrimaryClipChanged();
-        listener.onPrimaryClipChanged();
+        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_userSetupIncomplete_showsToast() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), SETTINGS_SECURE_USER_SETUP_COMPLETE, 0);
+
+        mClipboardListener.start();
+        mClipboardListener.onPrimaryClipChanged();
+
+        verify(mUiEventLogger, times(1)).log(
+                ClipboardOverlayEvent.CLIPBOARD_TOAST_SHOWN, 0, mSampleSource);
+        verify(mClipboardToast, times(1)).showCopiedToast();
+        verifyZeroInteractions(mOverlayControllerProvider);
+        verifyZeroInteractions(mClipboardOverlayControllerLegacyFactory);
+    }
 }