diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java index f1e67479f5..53ca7ed18e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java @@ -40,8 +40,7 @@ public class FallbackTaskbarUIController extends TaskbarUIController { animateToRecentsState(toState); // Handle tapping on live tile. - RecentsView recentsView = mRecentsActivity.getOverviewPanel(); - recentsView.setTaskLaunchListener(toState == RecentsState.DEFAULT + getRecentsView().setTaskLaunchListener(toState == RecentsState.DEFAULT ? (() -> animateToRecentsState(RecentsState.BACKGROUND_APP)) : null); } }; @@ -85,4 +84,9 @@ public class FallbackTaskbarUIController extends TaskbarUIController { anim.start(); } } + + @Override + public RecentsView getRecentsView() { + return mRecentsActivity.getOverviewPanel(); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 317f6a4884..2bcf179a4c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -48,6 +48,7 @@ import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.OnboardingPrefs; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.RecentsAnimationCallbacks; +import com.android.quickstep.views.RecentsView; import java.io.PrintWriter; import java.util.Arrays; @@ -393,4 +394,9 @@ public class LauncherTaskbarUIController extends TaskbarUIController { mTaskbarLauncherStateController.dumpLogs(prefix + "\t", pw); } + + @Override + public RecentsView getRecentsView() { + return mLauncher.getOverviewPanel(); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index fad9ff490c..9fb13db8f6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -90,6 +90,7 @@ import com.android.launcher3.util.SettingsCache; import com.android.launcher3.util.TraceHelper; import com.android.launcher3.util.ViewCache; import com.android.launcher3.views.ActivityContext; +import com.android.quickstep.views.RecentsView; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.rotation.RotationButtonController; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -132,6 +133,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { private final boolean mIsUserSetupComplete; private final boolean mIsNavBarForceVisible; private final boolean mIsNavBarKidsMode; + private boolean mIsDestroyed = false; // The flag to know if the window is excluded from magnification region computation. private boolean mIsExcludeFromMagnificationRegion = false; @@ -755,42 +757,63 @@ public class TaskbarActivityContext extends BaseTaskbarContext { if (info.isDisabled()) { ItemClickHandler.handleDisabledItemClicked(info, this); } else { - Intent intent = new Intent(info.getIntent()) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) { - Toast.makeText(this, R.string.safemode_shortcut_error, - Toast.LENGTH_SHORT).show(); - } else if (info.isPromise()) { - TestLogging.recordEvent( - TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon"); - intent = new PackageManagerHelper(this) - .getMarketIntent(info.getTargetPackage()) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); + TaskbarUIController taskbarUIController = mControllers.uiController; + RecentsView recents = taskbarUIController.getRecentsView(); + if (recents != null + && taskbarUIController.getRecentsView().isSplitSelectionActive()) { + // If we are selecting a second app for split, launch the split tasks + taskbarUIController.triggerSecondAppForSplit(info, info.intent, view); + } else { + // Else launch the selected task + Intent intent = new Intent(info.getIntent()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) { + Toast.makeText(this, R.string.safemode_shortcut_error, + Toast.LENGTH_SHORT).show(); + } else if (info.isPromise()) { + TestLogging.recordEvent( + TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon"); + intent = new PackageManagerHelper(this) + .getMarketIntent(info.getTargetPackage()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); - } else if (info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) { - TestLogging.recordEvent( - TestProtocol.SEQUENCE_MAIN, "start: taskbarDeepShortcut"); - String id = info.getDeepShortcutId(); - String packageName = intent.getPackage(); - getSystemService(LauncherApps.class) - .startShortcut(packageName, id, null, null, info.user); - } else { - startItemInfoActivity(info); + } else if (info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) { + TestLogging.recordEvent( + TestProtocol.SEQUENCE_MAIN, "start: taskbarDeepShortcut"); + String id = info.getDeepShortcutId(); + String packageName = intent.getPackage(); + getSystemService(LauncherApps.class) + .startShortcut(packageName, id, null, null, info.user); + } else { + startItemInfoActivity(info); + } + + mControllers.uiController.onTaskbarIconLaunched(info); + } catch (NullPointerException + | ActivityNotFoundException + | SecurityException e) { + Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT) + .show(); + Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e); } - - mControllers.uiController.onTaskbarIconLaunched(info); - mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); - } catch (NullPointerException | ActivityNotFoundException | SecurityException e) { - Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT) - .show(); - Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e); } + mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); } } else if (tag instanceof AppInfo) { - startItemInfoActivity((AppInfo) tag); - mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag); + AppInfo info = (AppInfo) tag; + TaskbarUIController taskbarUIController = mControllers.uiController; + RecentsView recents = taskbarUIController.getRecentsView(); + if (recents != null + && taskbarUIController.getRecentsView().isSplitSelectionActive()) { + // If we are selecting a second app for split, launch the split tasks + taskbarUIController.triggerSecondAppForSplit(info, info.intent, view); + } else { + // Else launch the selected task + startItemInfoActivity((AppInfo) tag); + mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag); + } mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); } else { Log.e(TAG, "Unknown type clicked: " + tag); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 11521260e9..0af25966ea 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -15,13 +15,18 @@ */ package com.android.launcher3.taskbar; +import android.content.Intent; +import android.graphics.drawable.BitmapDrawable; import android.view.MotionEvent; import android.view.View; import androidx.annotation.CallSuper; +import androidx.annotation.Nullable; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; +import com.android.quickstep.views.RecentsView; +import com.android.quickstep.views.TaskView; import java.io.PrintWriter; import java.util.stream.Stream; @@ -128,4 +133,38 @@ public class TaskbarUIController { prefix, getClass().getSimpleName())); } + + /** + * Returns RecentsView. Overwritten in LauncherTaskbarUIController and + * FallbackTaskbarUIController with Launcher-specific implementations. Returns null for other + * UI controllers (like DesktopTaskbarUIController) that don't have a RecentsView. + */ + public @Nullable RecentsView getRecentsView() { + return null; + } + + /** + * Uses the clicked Taskbar icon to launch a second app for splitscreen. + */ + public void triggerSecondAppForSplit(ItemInfoWithIcon info, Intent intent, View startingView) { + RecentsView recents = getRecentsView(); + TaskView foundTaskView = recents.getTaskViewByComponentName(info.getTargetComponent()); + if (foundTaskView != null) { + recents.confirmSplitSelect( + foundTaskView, + foundTaskView.getTask(), + foundTaskView.getIconView().getDrawable(), + foundTaskView.getThumbnail(), + foundTaskView.getThumbnail().getThumbnail(), + /* intent */ null); + } else { + recents.confirmSplitSelect( + /* containerTaskView */ null, + /* task */ null, + new BitmapDrawable(info.bitmap.icon), + startingView, + /* thumbnail */ null, + intent); + } + } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 35414a644a..fed982c6fe 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -74,9 +74,12 @@ import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.WindowConfiguration; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.content.LocusId; import android.content.res.Configuration; +import android.graphics.Bitmap; import android.graphics.BlendMode; import android.graphics.Canvas; import android.graphics.Color; @@ -661,8 +664,6 @@ public abstract class RecentsView