Merge "Indicate PiP animation type from Launcher to SysUI" into ub-launcher3-master
diff --git a/OWNERS b/OWNERS
index 7340e84..bf4cd0b 100644
--- a/OWNERS
+++ b/OWNERS
@@ -8,9 +8,26 @@
 hyunyoungs@google.com
 mrcasey@google.com
 sunnygoyal@google.com
+awickham@google.com
 twickham@google.com
 winsonc@google.com
 zakcohen@google.com
+santie@google.com
+vadimt@google.com
+mett@google.com
+jonmiranda@google.com
+pinyaoting@google.com
+sfufa@google.com
+gwasserman@google.com
+jamesoleary@google.com
+joshtrask@google.com
+mrenouf@google.com
+mkephart@google.com
+hwwang@google.com
+tracyzhou@google.com
+peanutbutter@google.com
+xuqiu@google.com
+sreyasr@google.com
 
 per-file FeatureFlags.java = sunnygoyal@google.com, adamcohen@google.com
 per-file BaseFlags.java = sunnygoyal@google.com, adamcohen@google.com
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 3046564..27ef93c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -575,8 +575,8 @@
 
     @Override
     protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) {
-        // If the task overlay is modal, should disable left and right swiping.
-        if (getCurrentPageTaskView() != null && !getCurrentPageTaskView().isTaskOverlayModal()) {
+        // Enables swiping to the left or right only if the task overlay is not modal.
+        if (getCurrentPageTaskView() == null || !getCurrentPageTaskView().isTaskOverlayModal()) {
             super.determineScrollingStart(ev, touchSlopScale);
         }
     }
diff --git a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
index 3e84a76..9a053f2 100644
--- a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
+++ b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
@@ -3,6 +3,8 @@
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
 
 import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
+import static com.android.launcher3.util.rule.TestStabilityRule.UNBUNDLED_POSTSUBMIT;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -16,6 +18,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.launcher3.Launcher;
+import com.android.launcher3.util.rule.TestStabilityRule;
 import com.android.quickstep.views.DigitalWellBeingToast;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
@@ -32,6 +35,8 @@
             resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
 
     @Test
+    // b/150303529
+    @TestStabilityRule.Stability(flavors = UNBUNDLED_POSTSUBMIT | PLATFORM_POSTSUBMIT)
     public void testToast() throws Exception {
         startAppFast(CALCULATOR_PACKAGE);
 
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 28ed588..03d7c3e 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -81,8 +81,7 @@
 
     @Test
     public void testAllAppsFromOverview() throws Exception {
-        // When actions are enabled, all apps isn't present in overview
-        if (mLauncher.overviewActionsEnabled()) {
+        if (!mLauncher.hasAllAppsInOverview()) {
             return;
         }
 
@@ -146,7 +145,7 @@
                 launcher -> assertEquals("Dismissing a task didn't remove 1 task from Overview",
                         numTasks - 1, getTaskCount(launcher)));
 
-        if (!mLauncher.overviewActionsEnabled() && (!TestHelpers.isInLauncherProcess()
+        if (mLauncher.hasAllAppsInOverview() && (!TestHelpers.isInLauncherProcess()
                 || getFromLauncher(launcher -> !launcher.getDeviceProfile().isLandscape))) {
             // Test switching to all apps and back.
             final AllAppsFromOverview allApps = overview.switchToAllApps();
@@ -190,8 +189,7 @@
 
     @Test
     public void testAppIconLaunchFromAllAppsFromOverview() throws Exception {
-        // All apps doesn't exist in Overview when actions are enabled
-        if (mLauncher.overviewActionsEnabled()) {
+        if (!mLauncher.hasAllAppsInOverview()) {
             return;
         }
 
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index 114c491..1841134 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -67,7 +67,6 @@
         super(context, attrs, defStyle);
 
         mCacheExpireAlarm = new Alarm();
-        mCacheExpireAlarm.setOnAlarmListener(this);
     }
 
     @Override
@@ -75,6 +74,7 @@
         super.onAttachedToWindow();
         if (mHadPendingAlarm) {
             mCacheExpireAlarm.setAlarm(CACHE_EXPIRE_TIMEOUT);
+            mCacheExpireAlarm.setOnAlarmListener(this);
             mHadPendingAlarm = false;
         }
     }
@@ -84,6 +84,7 @@
         super.onDetachedFromWindow();
         if (mCacheExpireAlarm.alarmPending()) {
             mCacheExpireAlarm.cancelAlarm();
+            mCacheExpireAlarm.setOnAlarmListener(null);
             mHadPendingAlarm = true;
         }
     }
@@ -168,6 +169,7 @@
         }
         // Cancel any pending alarm and set cache expiry after some time
         mCacheExpireAlarm.setAlarm(CACHE_EXPIRE_TIMEOUT);
+        mCacheExpireAlarm.setOnAlarmListener(this);
         if (uninstallDisabled) {
             return false;
         }
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 0927b26..02e98e8 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -87,9 +87,11 @@
 import com.android.launcher3.model.WidgetsModel;
 import com.android.launcher3.pm.InstallSessionHelper;
 import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.widget.custom.CustomWidgetManager;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -128,7 +130,8 @@
 
         private static final Set<MainThreadInitializedObject> WHITELIST = new HashSet<>(
                 Arrays.asList(UserCache.INSTANCE, InstallSessionHelper.INSTANCE,
-                        LauncherAppState.INSTANCE, InvariantDeviceProfile.INSTANCE));
+                        LauncherAppState.INSTANCE, InvariantDeviceProfile.INSTANCE,
+                        CustomWidgetManager.INSTANCE, PluginManagerWrapper.INSTANCE));
 
         private final InvariantDeviceProfile mIdp;
         private final Map<MainThreadInitializedObject, Object> mObjectMap = new HashMap<>();
@@ -145,6 +148,14 @@
             return this;
         }
 
+        public void onDestroy() {
+            CustomWidgetManager customWidgetManager = (CustomWidgetManager) mObjectMap.get(
+                    CustomWidgetManager.INSTANCE);
+            if (customWidgetManager != null) {
+                customWidgetManager.onDestroy();
+            }
+        }
+
         /**
          * Find a cached object from mObjectMap if we have already created one. If not, generate
          * an object using the provider.
@@ -349,6 +360,9 @@
         private void inflateAndAddWidgets(LauncherAppWidgetInfo info, WidgetsModel widgetsModel) {
             WidgetItem widgetItem = widgetsModel.getWidgetProviderInfoByProviderName(
                     info.providerName);
+            if (widgetItem == null) {
+                return;
+            }
             AppWidgetHostView view = new AppWidgetHostView(mContext);
             view.setAppWidget(-1, widgetItem.widgetInfo);
             view.updateAppWidget(null);
@@ -385,9 +399,11 @@
                 }
 
                 WorkspaceFetcher fetcher;
+                PreviewContext previewContext = null;
                 if (needsToMigrate && success) {
+                    previewContext = new PreviewContext(mContext, mIdp);
                     LauncherAppState appForPreview = new LauncherAppState(
-                            new PreviewContext(mContext, mIdp), null /* iconCacheFileName */);
+                            previewContext, null /* iconCacheFileName */);
                     fetcher = new WorkspaceItemsInfoFromPreviewFetcher(appForPreview);
                     MODEL_EXECUTOR.execute(fetcher);
                 } else {
@@ -396,6 +412,9 @@
                             (LauncherModel.ModelUpdateTask) fetcher);
                 }
                 WorkspaceResult workspaceResult = fetcher.get();
+                if (previewContext != null) {
+                    previewContext.onDestroy();
+                }
 
                 if (workspaceResult == null) {
                     return;
@@ -557,6 +576,7 @@
         public WorkspaceResult call() throws Exception {
             List<ShortcutInfo> allShortcuts = new ArrayList<>();
             loadWorkspace(allShortcuts, LauncherSettings.Favorites.PREVIEW_CONTENT_URI);
+            mBgDataModel.widgetsModel.update(mApp, null);
             return new WorkspaceResult(mBgDataModel.workspaceItems, mBgDataModel.appWidgets,
                     mBgDataModel.widgetsModel);
         }
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index fbf01fc..62904ae 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -104,7 +104,7 @@
 public class LoaderTask implements Runnable {
     private static final String TAG = "LoaderTask";
 
-    private final LauncherAppState mApp;
+    protected final LauncherAppState mApp;
     private final AllAppsList mBgAllAppsList;
     protected final BgDataModel mBgDataModel;
 
diff --git a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
index 2aed936..0ea7d85 100644
--- a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
+++ b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
@@ -51,6 +51,7 @@
     public static final MainThreadInitializedObject<CustomWidgetManager> INSTANCE =
             new MainThreadInitializedObject<>(CustomWidgetManager::new);
 
+    private final Context mContext;
     /**
      * auto provider Id is an ever-increasing number that serves as the providerId whenever a new
      * custom widget has been connected.
@@ -62,6 +63,7 @@
     private Consumer<PackageUserKey> mWidgetRefreshCallback;
 
     private CustomWidgetManager(Context context) {
+        mContext = context;
         mPlugins = new SparseArray<>();
         mCustomWidgets = new ArrayList<>();
         mWidgetsIdMap = new SparseArray<>();
@@ -69,6 +71,10 @@
                 .addPluginListener(this, CustomWidgetPlugin.class, true);
     }
 
+    public void onDestroy() {
+        PluginManagerWrapper.INSTANCE.get(mContext).removePluginListener(this);
+    }
+
     @Override
     public void onPluginConnected(CustomWidgetPlugin plugin, Context context) {
         mPlugins.put(mAutoProviderId, plugin);
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index ae32692..0b99e7a 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -249,6 +249,10 @@
             ComponentName providerName) {
         ArrayList<WidgetItem> widgetsList = mWidgetsList.get(
                 new PackageItemInfo(providerName.getPackageName()));
+        if (widgetsList == null) {
+            return null;
+        }
+
         for (WidgetItem item : widgetsList) {
             if (item.componentName.equals(providerName)) {
                 return item;
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 4481e9d..17858a0 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -331,21 +331,25 @@
     }
 
     private String getSystemAnomalyMessage() {
-        UiObject2 object = mDevice.findObject(By.res("android", "alertTitle"));
-        if (object != null) {
-            return "System alert popup is visible: " + object.getText();
+        try {
+            UiObject2 object = mDevice.findObject(By.res("android", "alertTitle"));
+            if (object != null) {
+                return "System alert popup is visible: " + object.getText();
+            }
+
+            object = mDevice.findObject(By.res("android", "message"));
+            if (object != null) {
+                return "Message popup by " + object.getApplicationPackage() + " is visible: "
+                        + object.getText();
+            }
+
+            if (hasSystemUiObject("keyguard_status_view")) return "Phone is locked";
+
+            if (!mDevice.hasObject(By.textStartsWith(""))) return "Screen is empty";
+        } catch (Throwable e) {
+            Log.w(TAG, "getSystemAnomalyMessage failed", e);
         }
 
-        object = mDevice.findObject(By.res("android", "message"));
-        if (object != null) {
-            return "Message popup by " + object.getApplicationPackage() + " is visible: "
-                    + object.getText();
-        }
-
-        if (hasSystemUiObject("keyguard_status_view")) return "Phone is locked";
-
-        if (!mDevice.hasObject(By.textStartsWith(""))) return "Screen is empty";
-
         return null;
     }
 
@@ -565,7 +569,7 @@
                     return waitForLauncherObject(APPS_RES_ID);
                 }
                 case OVERVIEW: {
-                    if (mDevice.isNaturalOrientation() && !overviewActionsEnabled()) {
+                    if (hasAllAppsInOverview()) {
                         waitForLauncherObject(APPS_RES_ID);
                     } else {
                         waitUntilGone(APPS_RES_ID);
@@ -1213,7 +1217,24 @@
         getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING);
     }
 
-    public boolean overviewActionsEnabled() {
+    public boolean hasAllAppsInOverview() {
+        // Vertical bar layouts don't contain all apps
+        if (!mDevice.isNaturalOrientation()) {
+            return false;
+        }
+        // Portrait two button (quickstep) always has all apps.
+        if (getNavigationModel() == NavigationModel.TWO_BUTTON) {
+            return true;
+        }
+        // Overview actions hide all apps
+        if (overviewActionsEnabled()) {
+            return false;
+        }
+        // ...otherwise there should be all apps
+        return true;
+    }
+
+    private boolean overviewActionsEnabled() {
         return getTestInfo(TestProtocol.REQUEST_OVERVIEW_ACTIONS_ENABLED).getBoolean(
                 TestProtocol.TEST_INFO_RESPONSE_FIELD);
     }