Merge "Launch multiple tasks at once" into sc-v2-dev
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index ab88b2b..3e2fb63 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -96,7 +96,11 @@
                 public void onDraw() {
                     View view = mLauncher.getDragLayer();
                     ViewRootImpl viewRootImpl = view.getViewRootImpl();
-                    setSurface(viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
+                    boolean applied = setSurface(
+                            viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
+                    if (!applied) {
+                        dispatchTransactionSurface(mDepth);
+                    }
                     view.post(() -> view.getViewTreeObserver().removeOnDrawListener(this));
                 }
             };
@@ -202,20 +206,22 @@
 
     /**
      * Sets the specified app target surface to apply the blur to.
+     * @return true when surface was valid and transaction was dispatched.
      */
-    public void setSurface(SurfaceControl surface) {
+    public boolean setSurface(SurfaceControl surface) {
         // Set launcher as the SurfaceControl when we don't need an external target anymore.
         if (surface == null) {
             ViewRootImpl viewRootImpl = mLauncher.getDragLayer().getViewRootImpl();
             surface = viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null;
         }
-
         if (mSurface != surface) {
             mSurface = surface;
             if (surface != null) {
                 dispatchTransactionSurface(mDepth);
+                return true;
             }
         }
+        return false;
     }
 
     @Override
@@ -229,6 +235,8 @@
             setDepth(toDepth);
         } else if (toState == LauncherState.OVERVIEW) {
             dispatchTransactionSurface(mDepth);
+        } else if (toState == LauncherState.BACKGROUND_APP) {
+            mLauncher.getDragLayer().getViewTreeObserver().addOnDrawListener(mOnDrawListener);
         }
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index 0afa480..b7c5db2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -123,11 +123,9 @@
          */
         public void updateInsetsTouchability(InsetsInfo insetsInfo) {
             insetsInfo.touchableRegion.setEmpty();
-            if (mActivity.isThreeButtonNav()) {
-                // Always have nav buttons be touchable
-                mControllers.navbarButtonsViewController.addVisibleButtonsRegion(
-                        mTaskbarDragLayer, insetsInfo.touchableRegion);
-            }
+            // Always have nav buttons be touchable
+            mControllers.navbarButtonsViewController.addVisibleButtonsRegion(
+                    mTaskbarDragLayer, insetsInfo.touchableRegion);
 
             if (mTaskbarDragLayer.getAlpha() < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) {
                 // Let touches pass through us.
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index c2c721a..1cf50f7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -71,7 +71,7 @@
             }
         }
         activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
+        activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_EMPTY);
         Object itemInfo = hostView.getTag();
         if (itemInfo instanceof ItemInfo) {
             mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options);
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index f420ec2..9c61c1b 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -454,7 +454,6 @@
         mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.WORK].recyclerView);
 
         if (mUsingTabs) {
-            setupWorkToggle();
             mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher);
             mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher);
             mAH[AdapterHolder.WORK].recyclerView.setId(R.id.apps_list_view_work);
@@ -485,6 +484,7 @@
     }
 
     private void setupWorkToggle() {
+        removeWorkToggle();
         if (Utilities.ATLEAST_P) {
             mWorkModeSwitch = (WorkModeSwitch) mLauncher.getLayoutInflater().inflate(
                     R.layout.work_mode_fab, this, false);
@@ -497,6 +497,14 @@
         }
     }
 
+    private void removeWorkToggle() {
+        if (mWorkModeSwitch == null) return;
+        if (mWorkModeSwitch.getParent() == this) {
+            this.removeView(mWorkModeSwitch);
+        }
+        mWorkModeSwitch = null;
+    }
+
     private void replaceRVContainer(boolean showTabs) {
         for (int i = 0; i < mAH.length; i++) {
             AllAppsRecyclerView rv = mAH[i].recyclerView;
@@ -519,8 +527,10 @@
             mViewPager = (AllAppsPagedView) newView;
             mViewPager.initParentViews(this);
             mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
+            setupWorkToggle();
         } else {
             mViewPager = null;
+            removeWorkToggle();
         }
     }
 
@@ -539,14 +549,6 @@
             mWorkModeSwitch.setWorkTabVisible(currentActivePage == AdapterHolder.WORK
                     && mAllAppsStore.hasModelFlag(
                     FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION));
-
-            if (currentActivePage == AdapterHolder.WORK) {
-                if (mWorkModeSwitch.getParent() == null) {
-                    addView(mWorkModeSwitch);
-                }
-            } else {
-                removeView(mWorkModeSwitch);
-            }
         }
     }
 
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index a800d34..5d3af08 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -51,6 +51,7 @@
 
     @Nullable
     private KeyboardInsetAnimationCallback mKeyboardInsetAnimationCallback;
+    private boolean mWorkTabVisible;
 
     public WorkModeSwitch(Context context) {
         this(context, null, 0);
@@ -91,11 +92,10 @@
      */
     public void setWorkTabVisible(boolean workTabVisible) {
         clearAnimation();
-        if (workTabVisible) {
+        mWorkTabVisible = workTabVisible;
+        if (workTabVisible && mWorkEnabled) {
             setEnabled(true);
-            if (mWorkEnabled) {
-                setVisibility(VISIBLE);
-            }
+            setVisibility(VISIBLE);
             setAlpha(0);
             animate().alpha(1).start();
         } else {
@@ -105,7 +105,7 @@
 
     @Override
     public void onClick(View view) {
-        if (Utilities.ATLEAST_P) {
+        if (Utilities.ATLEAST_P && mWorkTabVisible) {
             setEnabled(false);
             Launcher.fromContext(getContext()).getStatsLogManager().logger().log(
                     LAUNCHER_TURN_OFF_WORK_APPS_TAP);
@@ -137,7 +137,7 @@
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        if (Utilities.ATLEAST_R) {
+        if (Utilities.ATLEAST_R && mWorkTabVisible) {
             setTranslationY(0);
             if (insets.isVisible(WindowInsets.Type.ime())) {
                 Insets keyboardInsets = insets.getInsets(WindowInsets.Type.ime());
diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
index fae55cc..f9a9997 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -15,6 +15,7 @@
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
+import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -66,15 +67,18 @@
         onError(mDevice, description, e);
     }
 
+    static File diagFile(Description description, String prefix, String ext) {
+        return new File(getInstrumentation().getTargetContext().getFilesDir(),
+                prefix + "-" + description.getTestClass().getSimpleName() + "."
+                        + description.getMethodName() + "." + ext);
+    }
+
     public static void onError(UiDevice device, Description description, Throwable e) {
         Log.d("b/196820244", "onError 1");
         if (device == null) return;
         Log.d("b/196820244", "onError 2");
-        final File parentFile = getInstrumentation().getTargetContext().getFilesDir();
-        final File sceenshot = new File(parentFile,
-                "TestScreenshot-" + description.getMethodName() + ".png");
-        final File hierarchy = new File(parentFile,
-                "Hierarchy-" + description.getMethodName() + ".zip");
+        final File sceenshot = diagFile(description, "TestScreenshot", "png");
+        final File hierarchy = diagFile(description, "Hierarchy", "zip");
 
         // Dump window hierarchy
         try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(hierarchy))) {
@@ -97,13 +101,13 @@
         device.takeScreenshot(sceenshot);
 
         // Dump accessibility hierarchy
-        final File accessibilityHierarchyFile = new File(parentFile,
-                "AccessibilityHierarchy-" + description.getMethodName() + ".uix");
         try {
-            device.dumpWindowHierarchy(accessibilityHierarchyFile);
+            device.dumpWindowHierarchy(diagFile(description, "AccessibilityHierarchy", "uix"));
         } catch (IOException ex) {
             Log.e(TAG, "Failed to save accessibility hierarchy", ex);
         }
+
+        dumpCommand("logcat -d -s TestRunner", diagFile(description, "FilteredLogcat", "txt"));
     }
 
     private static void dumpStringCommand(String cmd, OutputStream out) throws IOException {
@@ -111,6 +115,14 @@
         dumpCommand(cmd, out);
     }
 
+    private static void dumpCommand(String cmd, File out) {
+        try (BufferedOutputStream buffered = new BufferedOutputStream(
+                new FileOutputStream(out))) {
+            dumpCommand(cmd, buffered);
+        } catch (IOException ex) {
+        }
+    }
+
     private static void dumpCommand(String cmd, OutputStream out) throws IOException {
         try (AutoCloseInputStream in = new AutoCloseInputStream(getInstrumentation()
                 .getUiAutomation().executeShellCommand(cmd))) {