Loading core/java/android/app/ActivityTaskManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -393,6 +393,20 @@ public class ActivityTaskManager { } } /** * Whether to allow non-resizable apps to be shown in multi-window. The app will be letterboxed * if the request orientation is not met, and will be shown in size-compat mode if the container * size has changed. * @hide */ public static boolean supportsNonResizableMultiWindow() { try { return ActivityTaskManager.getService().supportsNonResizableMultiWindow(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * @return whether the UI mode of the given config supports error dialogs (ANR, crash, etc). * @hide Loading core/java/android/app/IActivityTaskManager.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -289,6 +289,13 @@ interface IActivityTaskManager { void setSplitScreenResizing(boolean resizing); boolean supportsLocalVoiceInteraction(); /** * Whether to allow non-resizable apps to be shown in multi-window. The app will be letterboxed * if the request orientation is not met, and will be shown in size-compat mode if the container * size has changed. */ boolean supportsNonResizableMultiWindow(); // Get device configuration ConfigurationInfo getDeviceConfigurationInfo(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java +3 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.graphics.Rect; import android.view.SurfaceControl; import android.window.WindowContainerToken; Loading Loading @@ -88,7 +89,8 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan ProtoLog.v(WM_SHELL_TASK_ORG, "pair task1=%d task2=%d in AppPair=%s", task1.taskId, task2.taskId, this); if (!task1.isResizeable || !task2.isResizeable) { if ((!task1.isResizeable || !task2.isResizeable) && !ActivityTaskManager.supportsNonResizableMultiWindow()) { ProtoLog.e(WM_SHELL_TASK_ORG, "Can't pair unresizeable tasks task1.isResizeable=%b task1.isResizeable=%b", task1.isResizeable, task2.isResizeable); Loading libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/SplitScreenTransitions.java +5 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.WindowConfiguration; import android.graphics.Rect; import android.os.IBinder; Loading Loading @@ -91,9 +92,11 @@ public class SplitScreenTransitions implements Transitions.TransitionHandler { // is nothing behind it. ((type == TRANSIT_CLOSE || type == TRANSIT_TO_BACK) && triggerTask.parentTaskId == mListener.mPrimary.taskId) // if a non-resizable is launched, we also need to leave split-screen. // if a non-resizable is launched when it is not supported in multi window, // we also need to leave split-screen. || ((type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT) && !triggerTask.isResizeable); && !triggerTask.isResizeable && !ActivityTaskManager.supportsNonResizableMultiWindow()); // In both cases, dismiss the primary if (shouldDismiss) { WindowManagerProxy.buildDismissSplit(out, mListener, Loading libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java +25 −3 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import com.android.wm.shell.transition.Transitions; import java.util.ArrayList; import java.util.List; import java.util.function.BooleanSupplier; /** * Proxy to simplify calls into window manager/activity manager Loading Loading @@ -208,11 +209,17 @@ class WindowManagerProxy { return false; } ActivityManager.RunningTaskInfo topHomeTask = null; // One-time lazy wrapper to avoid duplicated IPC in loop. Not store as class variable // because the value can be changed at runtime. final BooleanSupplier supportsNonResizableMultiWindow = createSupportsNonResizableMultiWindowSupplier(); for (int i = rootTasks.size() - 1; i >= 0; --i) { final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i); // Only move resizeable task to split secondary. However, we have an exception // for non-resizable home because we will minimize to show it. if (!rootTask.isResizeable && rootTask.topActivityType != ACTIVITY_TYPE_HOME) { // Check whether to move resizeable task to split secondary. // Also, we have an exception for non-resizable home because we will minimize to show // it. if (!rootTask.isResizeable && rootTask.topActivityType != ACTIVITY_TYPE_HOME && !supportsNonResizableMultiWindow.getAsBoolean()) { continue; } // Only move fullscreen tasks to split secondary. Loading Loading @@ -357,6 +364,21 @@ class WindowManagerProxy { outWct.setFocusable(tiles.mPrimary.token, true /* focusable */); } /** Creates a lazy wrapper to get whether it supports non-resizable in multi window. */ private static BooleanSupplier createSupportsNonResizableMultiWindowSupplier() { return new BooleanSupplier() { private Boolean mSupportsNonResizableMultiWindow; @Override public boolean getAsBoolean() { if (mSupportsNonResizableMultiWindow == null) { mSupportsNonResizableMultiWindow = ActivityTaskManager.supportsNonResizableMultiWindow(); } return mSupportsNonResizableMultiWindow; } }; } /** * Utility to apply a sync transaction serially with other sync transactions. * Loading Loading
core/java/android/app/ActivityTaskManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -393,6 +393,20 @@ public class ActivityTaskManager { } } /** * Whether to allow non-resizable apps to be shown in multi-window. The app will be letterboxed * if the request orientation is not met, and will be shown in size-compat mode if the container * size has changed. * @hide */ public static boolean supportsNonResizableMultiWindow() { try { return ActivityTaskManager.getService().supportsNonResizableMultiWindow(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * @return whether the UI mode of the given config supports error dialogs (ANR, crash, etc). * @hide Loading
core/java/android/app/IActivityTaskManager.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -289,6 +289,13 @@ interface IActivityTaskManager { void setSplitScreenResizing(boolean resizing); boolean supportsLocalVoiceInteraction(); /** * Whether to allow non-resizable apps to be shown in multi-window. The app will be letterboxed * if the request orientation is not met, and will be shown in size-compat mode if the container * size has changed. */ boolean supportsNonResizableMultiWindow(); // Get device configuration ConfigurationInfo getDeviceConfigurationInfo(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java +3 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.graphics.Rect; import android.view.SurfaceControl; import android.window.WindowContainerToken; Loading Loading @@ -88,7 +89,8 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan ProtoLog.v(WM_SHELL_TASK_ORG, "pair task1=%d task2=%d in AppPair=%s", task1.taskId, task2.taskId, this); if (!task1.isResizeable || !task2.isResizeable) { if ((!task1.isResizeable || !task2.isResizeable) && !ActivityTaskManager.supportsNonResizableMultiWindow()) { ProtoLog.e(WM_SHELL_TASK_ORG, "Can't pair unresizeable tasks task1.isResizeable=%b task1.isResizeable=%b", task1.isResizeable, task2.isResizeable); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/SplitScreenTransitions.java +5 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.WindowConfiguration; import android.graphics.Rect; import android.os.IBinder; Loading Loading @@ -91,9 +92,11 @@ public class SplitScreenTransitions implements Transitions.TransitionHandler { // is nothing behind it. ((type == TRANSIT_CLOSE || type == TRANSIT_TO_BACK) && triggerTask.parentTaskId == mListener.mPrimary.taskId) // if a non-resizable is launched, we also need to leave split-screen. // if a non-resizable is launched when it is not supported in multi window, // we also need to leave split-screen. || ((type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT) && !triggerTask.isResizeable); && !triggerTask.isResizeable && !ActivityTaskManager.supportsNonResizableMultiWindow()); // In both cases, dismiss the primary if (shouldDismiss) { WindowManagerProxy.buildDismissSplit(out, mListener, Loading
libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java +25 −3 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import com.android.wm.shell.transition.Transitions; import java.util.ArrayList; import java.util.List; import java.util.function.BooleanSupplier; /** * Proxy to simplify calls into window manager/activity manager Loading Loading @@ -208,11 +209,17 @@ class WindowManagerProxy { return false; } ActivityManager.RunningTaskInfo topHomeTask = null; // One-time lazy wrapper to avoid duplicated IPC in loop. Not store as class variable // because the value can be changed at runtime. final BooleanSupplier supportsNonResizableMultiWindow = createSupportsNonResizableMultiWindowSupplier(); for (int i = rootTasks.size() - 1; i >= 0; --i) { final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i); // Only move resizeable task to split secondary. However, we have an exception // for non-resizable home because we will minimize to show it. if (!rootTask.isResizeable && rootTask.topActivityType != ACTIVITY_TYPE_HOME) { // Check whether to move resizeable task to split secondary. // Also, we have an exception for non-resizable home because we will minimize to show // it. if (!rootTask.isResizeable && rootTask.topActivityType != ACTIVITY_TYPE_HOME && !supportsNonResizableMultiWindow.getAsBoolean()) { continue; } // Only move fullscreen tasks to split secondary. Loading Loading @@ -357,6 +364,21 @@ class WindowManagerProxy { outWct.setFocusable(tiles.mPrimary.token, true /* focusable */); } /** Creates a lazy wrapper to get whether it supports non-resizable in multi window. */ private static BooleanSupplier createSupportsNonResizableMultiWindowSupplier() { return new BooleanSupplier() { private Boolean mSupportsNonResizableMultiWindow; @Override public boolean getAsBoolean() { if (mSupportsNonResizableMultiWindow == null) { mSupportsNonResizableMultiWindow = ActivityTaskManager.supportsNonResizableMultiWindow(); } return mSupportsNonResizableMultiWindow; } }; } /** * Utility to apply a sync transaction serially with other sync transactions. * Loading