diff options
5 files changed, 244 insertions, 126 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index 45b234a6398a..f616e6f64750 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -699,19 +699,6 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange return bounds.width() > bounds.height(); } - /** Reverse the split position. */ - @SplitPosition - public static int reversePosition(@SplitPosition int position) { - switch (position) { - case SPLIT_POSITION_TOP_OR_LEFT: - return SPLIT_POSITION_BOTTOM_OR_RIGHT; - case SPLIT_POSITION_BOTTOM_OR_RIGHT: - return SPLIT_POSITION_TOP_OR_LEFT; - default: - return SPLIT_POSITION_UNDEFINED; - } - } - /** * Return if this layout is landscape. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java new file mode 100644 index 000000000000..042721c97053 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023 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.wm.shell.common.split; + +import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; +import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; +import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; +import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; +import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; + +import android.annotation.Nullable; +import android.app.ActivityManager; +import android.app.PendingIntent; +import android.content.Intent; + +import com.android.internal.util.ArrayUtils; +import com.android.wm.shell.ShellTaskOrganizer; + +/** Helper utility class for split screen components to use. */ +public class SplitScreenUtils { + /** Reverse the split position. */ + @SplitScreenConstants.SplitPosition + public static int reverseSplitPosition(@SplitScreenConstants.SplitPosition int position) { + switch (position) { + case SPLIT_POSITION_TOP_OR_LEFT: + return SPLIT_POSITION_BOTTOM_OR_RIGHT; + case SPLIT_POSITION_BOTTOM_OR_RIGHT: + return SPLIT_POSITION_TOP_OR_LEFT; + case SPLIT_POSITION_UNDEFINED: + default: + return SPLIT_POSITION_UNDEFINED; + } + } + + /** Returns true if the task is valid for split screen. */ + public static boolean isValidToSplit(ActivityManager.RunningTaskInfo taskInfo) { + return taskInfo != null && taskInfo.supportsMultiWindow + && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType()) + && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode()); + } + + /** Retrieve package name from an intent */ + @Nullable + public static String getPackageName(Intent intent) { + if (intent == null || intent.getComponent() == null) { + return null; + } + return intent.getComponent().getPackageName(); + } + + /** Retrieve package name from a PendingIntent */ + @Nullable + public static String getPackageName(PendingIntent pendingIntent) { + if (pendingIntent == null || pendingIntent.getIntent() == null) { + return null; + } + return getPackageName(pendingIntent.getIntent()); + } + + /** Retrieve package name from a taskId */ + @Nullable + public static String getPackageName(int taskId, ShellTaskOrganizer taskOrganizer) { + final ActivityManager.RunningTaskInfo taskInfo = taskOrganizer.getRunningTaskInfo(taskId); + return taskInfo != null ? getPackageName(taskInfo.baseIntent) : null; + } + + /** Returns true if they are the same package. */ + public static boolean samePackage(String packageName1, String packageName2) { + return packageName1 != null && packageName1.equals(packageName2); + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index 21eeaa2cafb3..7cb5cf2ea177 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -28,6 +28,9 @@ import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTas import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; +import static com.android.wm.shell.common.split.SplitScreenUtils.isValidToSplit; +import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition; +import static com.android.wm.shell.common.split.SplitScreenUtils.samePackage; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN; @@ -39,11 +42,8 @@ import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.PendingIntent; -import android.content.ActivityNotFoundException; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.graphics.Rect; import android.os.Bundle; @@ -82,8 +82,8 @@ import com.android.wm.shell.common.SingleInstanceRemoteListener; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.annotations.ExternalThread; -import com.android.wm.shell.common.split.SplitLayout; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; +import com.android.wm.shell.common.split.SplitScreenUtils; import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.draganddrop.DragAndDropPolicy; import com.android.wm.shell.protolog.ShellProtoLogGroup; @@ -318,10 +318,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return mStageCoordinator; } - public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) { - return mStageCoordinator.isValidToEnterSplitScreen(taskInfo); - } - @Nullable public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) { if (!isSplitScreenVisible() || splitPosition == SPLIT_POSITION_UNDEFINED) { @@ -480,39 +476,54 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, @Override public void startShortcut(String packageName, String shortcutId, @SplitPosition int position, @Nullable Bundle options, UserHandle user) { - IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() { - @Override - public void onAnimationStart(@WindowManager.TransitionOldType int transit, - RemoteAnimationTarget[] apps, - RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, - final IRemoteAnimationFinishedCallback finishedCallback) { - try { - finishedCallback.onAnimationFinished(); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to invoke onAnimationFinished", e); - } - final WindowContainerTransaction evictWct = new WindowContainerTransaction(); - mStageCoordinator.prepareEvictNonOpeningChildTasks(position, apps, evictWct); - mSyncQueue.queue(evictWct); + if (options == null) options = new Bundle(); + final ActivityOptions activityOptions = ActivityOptions.fromBundle(options); + + if (samePackage(packageName, getPackageName(reverseSplitPosition(position)))) { + if (supportMultiInstancesSplit(packageName)) { + activityOptions.setApplyMultipleTaskFlagForShortcut(true); + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); + } else if (isSplitScreenVisible()) { + mStageCoordinator.switchSplitPosition("startShortcut"); + return; + } else { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "Cancel entering split as not supporting multi-instances"); + Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text, + Toast.LENGTH_SHORT).show(); + return; } - @Override - public void onAnimationCancelled(boolean isKeyguardOccluded) { + } + + mStageCoordinator.startShortcut(packageName, shortcutId, position, + activityOptions.toBundle(), user); + } + + void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, + @Nullable Bundle options1, int taskId, @Nullable Bundle options2, + @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, + InstanceId instanceId) { + if (options1 == null) options1 = new Bundle(); + final ActivityOptions activityOptions = ActivityOptions.fromBundle(options1); + + final String packageName1 = shortcutInfo.getPackage(); + final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer); + if (samePackage(packageName1, packageName2)) { + if (supportMultiInstancesSplit(shortcutInfo.getPackage())) { + activityOptions.setApplyMultipleTaskFlagForShortcut(true); + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); + } else { + taskId = INVALID_TASK_ID; + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "Cancel entering split as not supporting multi-instances"); + Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text, + Toast.LENGTH_SHORT).show(); } - }; - options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, - null /* wct */); - RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(wrapper, - 0 /* duration */, 0 /* statusBarTransitionDelay */); - ActivityOptions activityOptions = ActivityOptions.fromBundle(options); - activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter)); - try { - LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class); - launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */, - activityOptions.toBundle(), user); - } catch (ActivityNotFoundException e) { - Slog.e(TAG, "Failed to launch shortcut", e); } + + mStageCoordinator.startShortcutAndTaskWithLegacyTransition(shortcutInfo, + activityOptions.toBundle(), taskId, options2, splitPosition, splitRatio, adapter, + instanceId); } /** @@ -530,8 +541,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { Intent fillInIntent = null; - if (launchSameAppAdjacently(pendingIntent, taskId)) { - if (supportMultiInstancesSplit(pendingIntent.getIntent().getComponent())) { + final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent); + final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer); + if (samePackage(packageName1, packageName2)) { + if (supportMultiInstancesSplit(packageName1)) { fillInIntent = new Intent(); fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); @@ -551,8 +564,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { Intent fillInIntent = null; - if (launchSameAppAdjacently(pendingIntent, taskId)) { - if (supportMultiInstancesSplit(pendingIntent.getIntent().getComponent())) { + final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent); + final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer); + if (samePackage(packageName1, packageName2)) { + if (supportMultiInstancesSplit(packageName1)) { fillInIntent = new Intent(); fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK"); @@ -573,8 +588,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { Intent fillInIntent1 = null; Intent fillInIntent2 = null; - if (launchSameAppAdjacently(pendingIntent1, pendingIntent2)) { - if (supportMultiInstancesSplit(pendingIntent1.getIntent().getComponent())) { + final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1); + final String packageName2 = SplitScreenUtils.getPackageName(pendingIntent2); + if (samePackage(packageName1, packageName2)) { + if (supportMultiInstancesSplit(packageName1)) { fillInIntent1 = new Intent(); fillInIntent1.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); fillInIntent2 = new Intent(); @@ -602,13 +619,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, if (fillInIntent == null) fillInIntent = new Intent(); fillInIntent.addFlags(FLAG_ACTIVITY_NO_USER_ACTION); - if (launchSameAppAdjacently(position, intent)) { - final ComponentName launching = intent.getIntent().getComponent(); - if (supportMultiInstancesSplit(launching)) { + final String packageName1 = SplitScreenUtils.getPackageName(intent); + final String packageName2 = getPackageName(reverseSplitPosition(position)); + if (SplitScreenUtils.samePackage(packageName1, packageName2)) { + if (supportMultiInstancesSplit(packageName1)) { // To prevent accumulating large number of instances in the background, reuse task // in the background with priority. final ActivityManager.RecentTaskInfo taskInfo = mRecentTasksOptional - .map(recentTasks -> recentTasks.findTaskInBackground(launching)) + .map(recentTasks -> recentTasks.findTaskInBackground( + intent.getIntent().getComponent())) .orElse(null); if (taskInfo != null) { startTask(taskInfo.taskId, position, options); @@ -636,63 +655,32 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, mStageCoordinator.startIntent(intent, fillInIntent, position, options); } + /** Retrieve package name of a specific split position if split screen is activated, otherwise + * returns the package name of the top running task. */ @Nullable - private String getPackageName(Intent intent) { - if (intent == null || intent.getComponent() == null) { - return null; - } - return intent.getComponent().getPackageName(); - } - - private boolean launchSameAppAdjacently(@SplitPosition int position, - PendingIntent pendingIntent) { - ActivityManager.RunningTaskInfo adjacentTaskInfo = null; + private String getPackageName(@SplitPosition int position) { + ActivityManager.RunningTaskInfo taskInfo; if (isSplitScreenVisible()) { - adjacentTaskInfo = getTaskInfo(SplitLayout.reversePosition(position)); + taskInfo = getTaskInfo(position); } else { - adjacentTaskInfo = mRecentTasksOptional - .map(recentTasks -> recentTasks.getTopRunningTask()).orElse(null); - if (!isValidToEnterSplitScreen(adjacentTaskInfo)) { - return false; + taskInfo = mRecentTasksOptional + .map(recentTasks -> recentTasks.getTopRunningTask()) + .orElse(null); + if (!isValidToSplit(taskInfo)) { + return null; } } - if (adjacentTaskInfo == null) { - return false; - } - - final String targetPackageName = getPackageName(pendingIntent.getIntent()); - final String adjacentPackageName = getPackageName(adjacentTaskInfo.baseIntent); - return targetPackageName != null && targetPackageName.equals(adjacentPackageName); - } - - private boolean launchSameAppAdjacently(PendingIntent pendingIntent, int taskId) { - final ActivityManager.RunningTaskInfo adjacentTaskInfo = - mTaskOrganizer.getRunningTaskInfo(taskId); - if (adjacentTaskInfo == null) { - return false; - } - final String targetPackageName = getPackageName(pendingIntent.getIntent()); - final String adjacentPackageName = getPackageName(adjacentTaskInfo.baseIntent); - return targetPackageName != null && targetPackageName.equals(adjacentPackageName); - } - - private boolean launchSameAppAdjacently(PendingIntent pendingIntent1, - PendingIntent pendingIntent2) { - final String targetPackageName = getPackageName(pendingIntent1.getIntent()); - final String adjacentPackageName = getPackageName(pendingIntent2.getIntent()); - return targetPackageName != null && targetPackageName.equals(adjacentPackageName); + return taskInfo != null ? SplitScreenUtils.getPackageName(taskInfo.baseIntent) : null; } @VisibleForTesting - /** Returns {@code true} if the component supports multi-instances split. */ - boolean supportMultiInstancesSplit(@Nullable ComponentName launching) { - if (launching == null) return false; - - final String packageName = launching.getPackageName(); - for (int i = 0; i < mAppsSupportMultiInstances.length; i++) { - if (mAppsSupportMultiInstances[i].equals(packageName)) { - return true; + boolean supportMultiInstancesSplit(String packageName) { + if (packageName != null) { + for (int i = 0; i < mAppsSupportMultiInstances.length; i++) { + if (mAppsSupportMultiInstances[i].equals(packageName)) { + return true; + } } } @@ -1011,7 +999,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startShortcutAndTaskWithLegacyTransition", (controller) -> - controller.mStageCoordinator.startShortcutAndTaskWithLegacyTransition( + controller.startShortcutAndTaskWithLegacyTransition( shortcutInfo, options1, taskId, options2, splitPosition, splitRatio, adapter, instanceId)); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 39cf5f1b95bd..219f87eac7f2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -36,12 +36,11 @@ import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER; import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER; -import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; -import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; +import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE; import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED; @@ -76,8 +75,10 @@ import android.app.ActivityOptions; import android.app.IActivityTaskManager; import android.app.PendingIntent; import android.app.WindowConfiguration; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; +import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.content.res.Configuration; import android.graphics.Rect; @@ -87,6 +88,7 @@ import android.os.Debug; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.util.Log; import android.util.Slog; import android.view.Choreographer; @@ -370,7 +372,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, int sideStagePosition; if (stageType == STAGE_TYPE_MAIN) { targetStage = mMainStage; - sideStagePosition = SplitLayout.reversePosition(stagePosition); + sideStagePosition = reverseSplitPosition(stagePosition); } else if (stageType == STAGE_TYPE_SIDE) { targetStage = mSideStage; sideStagePosition = stagePosition; @@ -428,6 +430,72 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, return mLogger; } + void startShortcut(String packageName, String shortcutId, @SplitPosition int position, + Bundle options, UserHandle user) { + final boolean isEnteringSplit = !isSplitActive(); + + IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() { + @Override + public void onAnimationStart(@WindowManager.TransitionOldType int transit, + RemoteAnimationTarget[] apps, + RemoteAnimationTarget[] wallpapers, + RemoteAnimationTarget[] nonApps, + final IRemoteAnimationFinishedCallback finishedCallback) { + boolean openingToSide = false; + if (apps != null) { + for (int i = 0; i < apps.length; ++i) { + if (apps[i].mode == MODE_OPENING + && mSideStage.containsTask(apps[i].taskId)) { + openingToSide = true; + break; + } + } + } + + if (isEnteringSplit && !openingToSide) { + mMainExecutor.execute(() -> exitSplitScreen( + mSideStage.getChildCount() == 0 ? mMainStage : mSideStage, + EXIT_REASON_UNKNOWN)); + } + + if (finishedCallback != null) { + try { + finishedCallback.onAnimationFinished(); + } catch (RemoteException e) { + Slog.e(TAG, "Error finishing legacy transition: ", e); + } + } + + if (!isEnteringSplit && openingToSide) { + final WindowContainerTransaction evictWct = new WindowContainerTransaction(); + prepareEvictNonOpeningChildTasks(position, apps, evictWct); + mSyncQueue.queue(evictWct); + } + } + @Override + public void onAnimationCancelled(boolean isKeyguardOccluded) { + if (isEnteringSplit) { + mMainExecutor.execute(() -> exitSplitScreen( + mSideStage.getChildCount() == 0 ? mMainStage : mSideStage, + EXIT_REASON_UNKNOWN)); + } + } + }; + options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, + null /* wct */); + RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(wrapper, + 0 /* duration */, 0 /* statusBarTransitionDelay */); + ActivityOptions activityOptions = ActivityOptions.fromBundle(options); + activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter)); + try { + LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class); + launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */, + activityOptions.toBundle(), user); + } catch (ActivityNotFoundException e) { + Slog.e(TAG, "Failed to launch shortcut", e); + } + } + /** Launches an activity into split. */ void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position, @Nullable Bundle options) { @@ -899,7 +967,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, case STAGE_TYPE_MAIN: { if (position != SPLIT_POSITION_UNDEFINED) { // Set the side stage opposite of what we want to the main stage. - setSideStagePosition(SplitLayout.reversePosition(position), wct); + setSideStagePosition(reverseSplitPosition(position), wct); } else { position = getMainStagePosition(); } @@ -923,7 +991,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, @SplitPosition int getMainStagePosition() { - return SplitLayout.reversePosition(mSideStagePosition); + return reverseSplitPosition(mSideStagePosition); } int getTaskId(@SplitPosition int splitPosition) { @@ -950,7 +1018,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSplitLayout.splitSwitching(t, topLeftStage.mRootLeash, bottomRightStage.mRootLeash, insets -> { WindowContainerTransaction wct = new WindowContainerTransaction(); - setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), wct); + setSideStagePosition(reverseSplitPosition(mSideStagePosition), wct); mSyncQueue.queue(wct); mSyncQueue.runInSync(st -> { updateSurfaceBounds(mSplitLayout, st, false /* applyResizingOffset */); @@ -1694,12 +1762,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } - boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) { - return taskInfo.supportsMultiWindow - && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType()) - && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode()); - } - @Override public void onSnappedToDismiss(boolean bottomOrRight, int reason) { final boolean mainStageToTop = diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java index ea3af9d96aa4..d0e26019f9bf 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java @@ -27,8 +27,6 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -201,7 +199,6 @@ public class SplitScreenControllerTests extends ShellTestCase { ActivityManager.RunningTaskInfo topRunningTask = createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent); doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(); - doReturn(true).when(mStageCoordinator).isValidToEnterSplitScreen(any()); mSplitScreenController.startIntent(pendingIntent, null, SPLIT_POSITION_TOP_OR_LEFT, null); @@ -222,7 +219,6 @@ public class SplitScreenControllerTests extends ShellTestCase { ActivityManager.RunningTaskInfo topRunningTask = createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent); doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(); - doReturn(true).when(mStageCoordinator).isValidToEnterSplitScreen(any()); // Put the same component into a task in the background ActivityManager.RecentTaskInfo sameTaskInfo = new ActivityManager.RecentTaskInfo(); doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any()); |