Merge "Waiting for Launcher stop from quick switch gesture" into main
diff --git a/OWNERS b/OWNERS
index 38963d0..b8aae78 100644
--- a/OWNERS
+++ b/OWNERS
@@ -12,7 +12,6 @@
 jonmiranda@google.com
 alexchau@google.com
 patmanning@google.com
-tsuharesu@google.com
 awickham@google.com
 
 # Launcher workspace eng team
diff --git a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
index 43716ab..477cd84 100644
--- a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
+++ b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
@@ -22,7 +22,10 @@
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Intent;
 import android.os.Bundle;
+import android.view.View;
 import android.view.WindowInsetsController;
 import android.view.WindowManager;
 
@@ -32,6 +35,7 @@
 import com.android.launcher3.model.WidgetsModel;
 import com.android.launcher3.popup.PopupDataProvider;
 import com.android.launcher3.widget.BaseWidgetSheet;
+import com.android.launcher3.widget.WidgetCell;
 import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 import com.android.launcher3.widget.picker.WidgetsFullSheet;
 
@@ -81,6 +85,23 @@
         return mDragLayer;
     }
 
+    @Override
+    public View.OnClickListener getItemOnClickListener() {
+        return v -> {
+            final AppWidgetProviderInfo info =
+                    (v instanceof WidgetCell) ? ((WidgetCell) v).getWidgetItem().widgetInfo : null;
+            if (info == null || info.provider == null) {
+                return;
+            }
+
+            setResult(RESULT_OK, new Intent()
+                    .putExtra(Intent.EXTRA_COMPONENT_NAME, info.provider)
+                    .putExtra(Intent.EXTRA_USER, info.getProfile()));
+
+            finish();
+        };
+    }
+
     private void refreshAndBindWidgets() {
         MODEL_EXECUTOR.execute(() -> {
             LauncherAppState app = LauncherAppState.getInstance(this);
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index c482911..ec9f4e5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -130,6 +130,8 @@
         super(context, attrs, defStyleAttr, defStyleRes);
         TaskbarActivityContext activityContext = ActivityContext.lookupContext(context);
 
+        setAlpha(0);
+        setVisibility(INVISIBLE);
         mIconOverlapAmount = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_overlap);
         mIconSpacing = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing);
         mIconSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size);
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 39633ea..e0ee28d 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -131,8 +131,7 @@
                     UiDevice.getInstance(getInstrumentation()).executeShellCommand(
                             getLauncherCommand(getLauncherInMyProcess()));
                     // b/143488140
-                    mDevice.pressHome();
-                    mDevice.waitForIdle();
+                    pressHomeAndWaitForOverviewClose();
                 }
             }
         };
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 7dfce56..f9d282c 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -169,10 +169,6 @@
     // TODO(Block 8): Clean up flags
 
     // TODO(Block 9): Clean up flags
-    public static final BooleanFlag UNFOLDED_WIDGET_PICKER = getDebugFlag(301918659,
-            "UNFOLDED_WIDGET_PICKER", DISABLED, "Enable new widget picker that takes "
-                    + "advantage of the unfolded foldable format");
-
     public static final BooleanFlag MULTI_SELECT_EDIT_MODE = getDebugFlag(270709220,
             "MULTI_SELECT_EDIT_MODE", DISABLED, "Enable new multi-select edit mode "
                     + "for home screen");
diff --git a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
index cbc6f44..71957e1 100644
--- a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
+++ b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
@@ -62,7 +62,7 @@
                 override fun getLayoutManager(): RecyclerView.LayoutManager? = null
             }
 
-        executorRunnable?.cancel(/* interrupt= */ true)
+        executorRunnable?.cancel(/* interrupt= */ false)
         executorRunnable =
             ExecutorRunnable.createAndExecute(
                 VIEW_PREINFLATION_EXECUTOR,
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index c30342a..8f5e2b6 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -147,6 +147,11 @@
         return mAppWidgetHostViewScale;
     }
 
+    /** Returns the {@link WidgetItem} for this {@link WidgetCell}. */
+    public WidgetItem getWidgetItem() {
+        return mItem;
+    }
+
     /**
      * Called to clear the view and free attached resources. (e.g., {@link Bitmap}
      */
diff --git a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
index e46726d..d44ccf5 100644
--- a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
@@ -17,11 +17,13 @@
 
 import android.content.Context
 import android.content.res.Configuration
+import android.content.res.Resources
 import android.graphics.Point
 import android.graphics.Rect
 import android.util.DisplayMetrics
 import android.view.Surface
 import androidx.test.core.app.ApplicationProvider
+import androidx.test.platform.app.InstrumentationRegistry
 import com.android.launcher3.testing.shared.ResourceUtils
 import com.android.launcher3.util.DisplayController
 import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext
@@ -30,6 +32,8 @@
 import com.android.launcher3.util.rule.TestStabilityRule
 import com.android.launcher3.util.window.CachedDisplayInfo
 import com.android.launcher3.util.window.WindowManagerProxy
+import com.android.wm.shell.Flags
+import com.google.common.truth.Truth
 import java.io.BufferedReader
 import java.io.File
 import java.io.PrintWriter
@@ -49,11 +53,18 @@
  * For an implementation that mocks InvariantDeviceProfile, use [FakeInvariantDeviceProfileTest]
  */
 abstract class AbstractDeviceProfileTest {
+    protected val testContext: Context = InstrumentationRegistry.getInstrumentation().context
     protected lateinit var context: SandboxContext
     protected open val runningContext: Context = ApplicationProvider.getApplicationContext()
     private val displayController: DisplayController = mock()
     private val windowManagerProxy: WindowManagerProxy = mock()
     private val launcherPrefs: LauncherPrefs = mock()
+    private val allowLeftRightSplitInPortrait: Boolean = initAllowLeftRightSplitInPortrait()
+    fun initAllowLeftRightSplitInPortrait() : Boolean {
+        val res = Resources.getSystem();
+        val resId = res.getIdentifier("config_leftRightSplitInPortrait", "bool", "android")
+        return Flags.enableLeftRightSplitInPortrait() && resId > 0 && res.getBoolean(resId)
+    }
 
     @Rule @JvmField val testStabilityRule = TestStabilityRule()
 
@@ -306,6 +317,25 @@
         whenever(info.isTransientTaskbar).thenReturn(isGestureMode)
     }
 
+    /** Asserts that the given device profile matches a previously dumped device profile state. */
+    protected fun assertDump(dp: DeviceProfile, folderName: String, filename: String) {
+        val dump = dump(context!!, dp, "${folderName}_$filename.txt")
+        var expected = readDumpFromAssets(testContext, "$folderName/$filename.txt")
+
+        // TODO(b/315230497): We don't currently have device-specific device profile dumps, so just
+        //  update the result before we do the comparison
+        if (allowLeftRightSplitInPortrait) {
+            val isLeftRightSplitInPortrait = when {
+                allowLeftRightSplitInPortrait && dp.isTablet -> !dp.isLandscape
+                else -> dp.isLandscape
+            }
+            expected = expected.replace(Regex("isLeftRightSplit:\\w+"),
+                    "isLeftRightSplit:$isLeftRightSplitInPortrait")
+        }
+
+        Truth.assertThat(dump).isEqualTo(expected)
+    }
+
     /** Create a new dump of DeviceProfile, saves to a file in the device and returns it */
     protected fun dump(context: Context, dp: DeviceProfile, fileName: String): String {
         val stringWriter = StringWriter()
diff --git a/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt b/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
index 9b67310..9409ac1 100644
--- a/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
+++ b/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
@@ -30,7 +30,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
-    private val testContext: Context = InstrumentationRegistry.getInstrumentation().context
     private val folderName: String = "DeviceProfileDumpTest"
     @Test
     fun phonePortrait3Button() {
@@ -154,9 +153,6 @@
     }
 
     private fun assertDump(dp: DeviceProfile, filename: String) {
-        val dump = dump(context!!, dp, "${folderName}_$filename.txt")
-        val expected = readDumpFromAssets(testContext, "$folderName/$filename.txt")
-
-        assertThat(dump).isEqualTo(expected)
+        assertDump(dp, folderName, filename);
     }
 }
diff --git a/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt b/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt
index b4591ba..b8d74aa 100644
--- a/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt
+++ b/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt
@@ -18,6 +18,7 @@
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
+import com.android.launcher3.util.rule.TestStabilityRule
 import java.util.concurrent.ExecutorService
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertFalse
@@ -65,8 +66,11 @@
     }
 
     @Test
+    @TestStabilityRule.Stability(
+        flavors = TestStabilityRule.LOCAL or TestStabilityRule.PLATFORM_POSTSUBMIT
+    ) // b/316588649
     fun run_and_cancel_cancelCallback() {
-        underTest.cancel(true)
+        underTest.cancel(false)
         awaitAllExecutorCompleted()
 
         assertFalse(isCallbackExecuted)
@@ -77,7 +81,7 @@
     fun run_and_cancelAfterCompletion_executeAll() {
         awaitAllExecutorCompleted()
 
-        underTest.cancel(true)
+        underTest.cancel(false)
 
         assertTrue(isTaskExecuted)
         assertTrue(isCallbackExecuted)