Loading packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +10 −4 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.provider.Settings; import android.util.Slog; import android.view.LayoutInflater; import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.View; import android.window.TaskOrganizer; import android.window.WindowContainerToken; Loading Loading @@ -94,7 +93,6 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, private boolean mHomeStackResizable = false; private ForcedResizableInfoActivityController mForcedResizableController; private SystemWindows mSystemWindows; final SurfaceSession mSurfaceSession = new SurfaceSession(); private DisplayController mDisplayController; private DisplayImeController mImeController; final TransactionPool mTransactionPool; Loading Loading @@ -493,7 +491,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, return; } try { mSplits.init(mSurfaceSession); mSplits.init(); // Set starting tile bounds based on middle target final WindowContainerTransaction tct = new WindowContainerTransaction(); int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position; Loading @@ -505,7 +503,6 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, return; } ActivityManagerWrapper.getInstance().registerTaskStackListener(mActivityRestartListener); update(mDisplayController.getDisplayContext(displayId).getResources().getConfiguration()); } @Override Loading Loading @@ -582,6 +579,15 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } } void onTaskVanished() { mHandler.post(this::removeDivider); } void onTasksReady() { mHandler.post(() -> update(mDisplayController.getDisplayContext( mContext.getDisplayId()).getResources().getConfiguration())); } void updateVisibility(final boolean visible) { if (DEBUG) Slog.d(TAG, "Updating visibility " + mVisible + "->" + visible); if (mVisible != visible) { Loading packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java +75 −26 Original line number Diff line number Diff line Loading @@ -47,32 +47,65 @@ class SplitScreenTaskOrganizer extends TaskOrganizer { final Divider mDivider; private boolean mSplitScreenSupported = false; final SurfaceSession mSurfaceSession = new SurfaceSession(); SplitScreenTaskOrganizer(Divider divider) { mDivider = divider; } void init(SurfaceSession session) throws RemoteException { void init() throws RemoteException { registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); synchronized (this) { try { mPrimary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); mSecondary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); mPrimarySurface = mPrimary.token.getLeash(); mSecondarySurface = mSecondary.token.getLeash(); } catch (Exception e) { // teardown to prevent callbacks unregisterOrganizer(); throw e; } } } boolean isSplitScreenSupported() { return mSplitScreenSupported; } SurfaceControl.Transaction getTransaction() { return mDivider.mTransactionPool.acquire(); } void releaseTransaction(SurfaceControl.Transaction t) { mDivider.mTransactionPool.release(t); } @Override public void onTaskAppeared(RunningTaskInfo taskInfo) { synchronized (this) { if (mPrimary == null || mSecondary == null) { Log.w(TAG, "Received onTaskAppeared before creating root tasks " + taskInfo); return; } if (taskInfo.token.equals(mPrimary.token)) { mPrimarySurface = taskInfo.token.getLeash(); } else if (taskInfo.token.equals(mSecondary.token)) { mSecondarySurface = taskInfo.token.getLeash(); } if (!mSplitScreenSupported && mPrimarySurface != null && mSecondarySurface != null) { mSplitScreenSupported = true; // Initialize dim surfaces: mPrimaryDim = new SurfaceControl.Builder(session).setParent(mPrimarySurface) .setColorLayer().setName("Primary Divider Dim").build(); mSecondaryDim = new SurfaceControl.Builder(session).setParent(mSecondarySurface) .setColorLayer().setName("Secondary Divider Dim").build(); mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession) .setParent(mPrimarySurface).setColorLayer() .setName("Primary Divider Dim").build(); mSecondaryDim = new SurfaceControl.Builder(mSurfaceSession) .setParent(mSecondarySurface).setColorLayer() .setName("Secondary Divider Dim").build(); SurfaceControl.Transaction t = getTransaction(); t.setLayer(mPrimaryDim, Integer.MAX_VALUE); t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f}); Loading @@ -80,18 +113,34 @@ class SplitScreenTaskOrganizer extends TaskOrganizer { t.setColor(mSecondaryDim, new float[]{0f, 0f, 0f}); t.apply(); releaseTransaction(t); } boolean isSplitScreenSupported() { return mSplitScreenSupported; mDivider.onTasksReady(); } } SurfaceControl.Transaction getTransaction() { return mDivider.mTransactionPool.acquire(); } void releaseTransaction(SurfaceControl.Transaction t) { mDivider.mTransactionPool.release(t); @Override public void onTaskVanished(RunningTaskInfo taskInfo) { synchronized (this) { final boolean isPrimaryTask = mPrimary != null && taskInfo.token.equals(mPrimary.token); final boolean isSecondaryTask = mSecondary != null && taskInfo.token.equals(mSecondary.token); if (mSplitScreenSupported && (isPrimaryTask || isSecondaryTask)) { mSplitScreenSupported = false; SurfaceControl.Transaction t = getTransaction(); t.remove(mPrimaryDim); t.remove(mSecondaryDim); t.remove(mPrimarySurface); t.remove(mSecondarySurface); t.apply(); releaseTransaction(t); mDivider.onTaskVanished(); } } } @Override Loading services/core/java/com/android/server/wm/DisplayArea.java +9 −4 Original line number Diff line number Diff line Loading @@ -140,8 +140,12 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { void setOrganizer(IDisplayAreaOrganizer organizer) { if (mOrganizer == organizer) return; sendDisplayAreaVanished(); IDisplayAreaOrganizer lastOrganizer = mOrganizer; // Update the new display area organizer before calling sendDisplayAreaVanished since it // could result in a new SurfaceControl getting created that would notify the old organizer // about it. mOrganizer = organizer; sendDisplayAreaVanished(lastOrganizer); sendDisplayAreaAppeared(); } Loading @@ -150,9 +154,10 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { mOrganizerController.onDisplayAreaAppeared(mOrganizer, this); } void sendDisplayAreaVanished() { if (mOrganizer == null) return; mOrganizerController.onDisplayAreaVanished(mOrganizer, this); void sendDisplayAreaVanished(IDisplayAreaOrganizer organizer) { if (organizer == null) return; migrateToNewSurfaceControl(); mOrganizerController.onDisplayAreaVanished(organizer, this); } @Override Loading services/core/java/com/android/server/wm/Task.java +32 −11 Original line number Diff line number Diff line Loading @@ -2006,6 +2006,14 @@ class Task extends WindowContainer<WindowContainer> { return (prevWinMode == WINDOWING_MODE_FREEFORM) != (newWinMode == WINDOWING_MODE_FREEFORM); } @Override void migrateToNewSurfaceControl() { super.migrateToNewSurfaceControl(); mLastSurfaceSize.x = 0; mLastSurfaceSize.y = 0; updateSurfaceSize(getPendingTransaction()); } void updateSurfaceSize(SurfaceControl.Transaction transaction) { if (mSurfaceControl == null || mCreatedByOrganizer) { return; Loading Loading @@ -4402,16 +4410,25 @@ class Task extends WindowContainer<WindowContainer> { return mHasBeenVisible; } /** In the case that these three conditions are true, we want to send the Task to * the organizer: * 1. We have a SurfaceControl * 2. An organizer has been set * 3. We have finished drawing /** In the case that these conditions are true, we want to send the Task to the organizer: * 1. An organizer has been set * 2. The Task was created by the organizer * or * 2a. We have a SurfaceControl * 2b. We have finished drawing * Any time any of these conditions are updated, the updating code should call * sendTaskAppeared. */ boolean taskAppearedReady() { return mSurfaceControl != null && mTaskOrganizer != null && getHasBeenVisible(); if (mTaskOrganizer == null) { return false; } if (mCreatedByOrganizer) { return true; } return mSurfaceControl != null && getHasBeenVisible(); } private void sendTaskAppeared() { Loading @@ -4420,9 +4437,9 @@ class Task extends WindowContainer<WindowContainer> { } } private void sendTaskVanished() { if (mTaskOrganizer != null) { mAtmService.mTaskOrganizerController.onTaskVanished(mTaskOrganizer, this); private void sendTaskVanished(ITaskOrganizer organizer) { if (organizer != null) { mAtmService.mTaskOrganizerController.onTaskVanished(organizer, this); } } Loading @@ -4431,9 +4448,13 @@ class Task extends WindowContainer<WindowContainer> { if (mTaskOrganizer == organizer) { return false; } // Let the old organizer know it has lost control. sendTaskVanished(); ITaskOrganizer previousOrganizer = mTaskOrganizer; // Update the new task organizer before calling sendTaskVanished since it could result in // a new SurfaceControl getting created that would notify the old organizer about it. mTaskOrganizer = organizer; // Let the old organizer know it has lost control. sendTaskVanished(previousOrganizer); if (mTaskOrganizer != null) { sendTaskAppeared(); Loading services/core/java/com/android/server/wm/TaskOrganizerController.java +1 −0 Original line number Diff line number Diff line Loading @@ -211,6 +211,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { void removeTask(Task t) { if (t.mTaskAppearedSent) { t.migrateToNewSurfaceControl(); t.mTaskAppearedSent = false; mOrganizer.onTaskVanished(t); } Loading Loading
packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +10 −4 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.provider.Settings; import android.util.Slog; import android.view.LayoutInflater; import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.View; import android.window.TaskOrganizer; import android.window.WindowContainerToken; Loading Loading @@ -94,7 +93,6 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, private boolean mHomeStackResizable = false; private ForcedResizableInfoActivityController mForcedResizableController; private SystemWindows mSystemWindows; final SurfaceSession mSurfaceSession = new SurfaceSession(); private DisplayController mDisplayController; private DisplayImeController mImeController; final TransactionPool mTransactionPool; Loading Loading @@ -493,7 +491,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, return; } try { mSplits.init(mSurfaceSession); mSplits.init(); // Set starting tile bounds based on middle target final WindowContainerTransaction tct = new WindowContainerTransaction(); int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position; Loading @@ -505,7 +503,6 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, return; } ActivityManagerWrapper.getInstance().registerTaskStackListener(mActivityRestartListener); update(mDisplayController.getDisplayContext(displayId).getResources().getConfiguration()); } @Override Loading Loading @@ -582,6 +579,15 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } } void onTaskVanished() { mHandler.post(this::removeDivider); } void onTasksReady() { mHandler.post(() -> update(mDisplayController.getDisplayContext( mContext.getDisplayId()).getResources().getConfiguration())); } void updateVisibility(final boolean visible) { if (DEBUG) Slog.d(TAG, "Updating visibility " + mVisible + "->" + visible); if (mVisible != visible) { Loading
packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java +75 −26 Original line number Diff line number Diff line Loading @@ -47,32 +47,65 @@ class SplitScreenTaskOrganizer extends TaskOrganizer { final Divider mDivider; private boolean mSplitScreenSupported = false; final SurfaceSession mSurfaceSession = new SurfaceSession(); SplitScreenTaskOrganizer(Divider divider) { mDivider = divider; } void init(SurfaceSession session) throws RemoteException { void init() throws RemoteException { registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); synchronized (this) { try { mPrimary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); mSecondary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); mPrimarySurface = mPrimary.token.getLeash(); mSecondarySurface = mSecondary.token.getLeash(); } catch (Exception e) { // teardown to prevent callbacks unregisterOrganizer(); throw e; } } } boolean isSplitScreenSupported() { return mSplitScreenSupported; } SurfaceControl.Transaction getTransaction() { return mDivider.mTransactionPool.acquire(); } void releaseTransaction(SurfaceControl.Transaction t) { mDivider.mTransactionPool.release(t); } @Override public void onTaskAppeared(RunningTaskInfo taskInfo) { synchronized (this) { if (mPrimary == null || mSecondary == null) { Log.w(TAG, "Received onTaskAppeared before creating root tasks " + taskInfo); return; } if (taskInfo.token.equals(mPrimary.token)) { mPrimarySurface = taskInfo.token.getLeash(); } else if (taskInfo.token.equals(mSecondary.token)) { mSecondarySurface = taskInfo.token.getLeash(); } if (!mSplitScreenSupported && mPrimarySurface != null && mSecondarySurface != null) { mSplitScreenSupported = true; // Initialize dim surfaces: mPrimaryDim = new SurfaceControl.Builder(session).setParent(mPrimarySurface) .setColorLayer().setName("Primary Divider Dim").build(); mSecondaryDim = new SurfaceControl.Builder(session).setParent(mSecondarySurface) .setColorLayer().setName("Secondary Divider Dim").build(); mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession) .setParent(mPrimarySurface).setColorLayer() .setName("Primary Divider Dim").build(); mSecondaryDim = new SurfaceControl.Builder(mSurfaceSession) .setParent(mSecondarySurface).setColorLayer() .setName("Secondary Divider Dim").build(); SurfaceControl.Transaction t = getTransaction(); t.setLayer(mPrimaryDim, Integer.MAX_VALUE); t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f}); Loading @@ -80,18 +113,34 @@ class SplitScreenTaskOrganizer extends TaskOrganizer { t.setColor(mSecondaryDim, new float[]{0f, 0f, 0f}); t.apply(); releaseTransaction(t); } boolean isSplitScreenSupported() { return mSplitScreenSupported; mDivider.onTasksReady(); } } SurfaceControl.Transaction getTransaction() { return mDivider.mTransactionPool.acquire(); } void releaseTransaction(SurfaceControl.Transaction t) { mDivider.mTransactionPool.release(t); @Override public void onTaskVanished(RunningTaskInfo taskInfo) { synchronized (this) { final boolean isPrimaryTask = mPrimary != null && taskInfo.token.equals(mPrimary.token); final boolean isSecondaryTask = mSecondary != null && taskInfo.token.equals(mSecondary.token); if (mSplitScreenSupported && (isPrimaryTask || isSecondaryTask)) { mSplitScreenSupported = false; SurfaceControl.Transaction t = getTransaction(); t.remove(mPrimaryDim); t.remove(mSecondaryDim); t.remove(mPrimarySurface); t.remove(mSecondarySurface); t.apply(); releaseTransaction(t); mDivider.onTaskVanished(); } } } @Override Loading
services/core/java/com/android/server/wm/DisplayArea.java +9 −4 Original line number Diff line number Diff line Loading @@ -140,8 +140,12 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { void setOrganizer(IDisplayAreaOrganizer organizer) { if (mOrganizer == organizer) return; sendDisplayAreaVanished(); IDisplayAreaOrganizer lastOrganizer = mOrganizer; // Update the new display area organizer before calling sendDisplayAreaVanished since it // could result in a new SurfaceControl getting created that would notify the old organizer // about it. mOrganizer = organizer; sendDisplayAreaVanished(lastOrganizer); sendDisplayAreaAppeared(); } Loading @@ -150,9 +154,10 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { mOrganizerController.onDisplayAreaAppeared(mOrganizer, this); } void sendDisplayAreaVanished() { if (mOrganizer == null) return; mOrganizerController.onDisplayAreaVanished(mOrganizer, this); void sendDisplayAreaVanished(IDisplayAreaOrganizer organizer) { if (organizer == null) return; migrateToNewSurfaceControl(); mOrganizerController.onDisplayAreaVanished(organizer, this); } @Override Loading
services/core/java/com/android/server/wm/Task.java +32 −11 Original line number Diff line number Diff line Loading @@ -2006,6 +2006,14 @@ class Task extends WindowContainer<WindowContainer> { return (prevWinMode == WINDOWING_MODE_FREEFORM) != (newWinMode == WINDOWING_MODE_FREEFORM); } @Override void migrateToNewSurfaceControl() { super.migrateToNewSurfaceControl(); mLastSurfaceSize.x = 0; mLastSurfaceSize.y = 0; updateSurfaceSize(getPendingTransaction()); } void updateSurfaceSize(SurfaceControl.Transaction transaction) { if (mSurfaceControl == null || mCreatedByOrganizer) { return; Loading Loading @@ -4402,16 +4410,25 @@ class Task extends WindowContainer<WindowContainer> { return mHasBeenVisible; } /** In the case that these three conditions are true, we want to send the Task to * the organizer: * 1. We have a SurfaceControl * 2. An organizer has been set * 3. We have finished drawing /** In the case that these conditions are true, we want to send the Task to the organizer: * 1. An organizer has been set * 2. The Task was created by the organizer * or * 2a. We have a SurfaceControl * 2b. We have finished drawing * Any time any of these conditions are updated, the updating code should call * sendTaskAppeared. */ boolean taskAppearedReady() { return mSurfaceControl != null && mTaskOrganizer != null && getHasBeenVisible(); if (mTaskOrganizer == null) { return false; } if (mCreatedByOrganizer) { return true; } return mSurfaceControl != null && getHasBeenVisible(); } private void sendTaskAppeared() { Loading @@ -4420,9 +4437,9 @@ class Task extends WindowContainer<WindowContainer> { } } private void sendTaskVanished() { if (mTaskOrganizer != null) { mAtmService.mTaskOrganizerController.onTaskVanished(mTaskOrganizer, this); private void sendTaskVanished(ITaskOrganizer organizer) { if (organizer != null) { mAtmService.mTaskOrganizerController.onTaskVanished(organizer, this); } } Loading @@ -4431,9 +4448,13 @@ class Task extends WindowContainer<WindowContainer> { if (mTaskOrganizer == organizer) { return false; } // Let the old organizer know it has lost control. sendTaskVanished(); ITaskOrganizer previousOrganizer = mTaskOrganizer; // Update the new task organizer before calling sendTaskVanished since it could result in // a new SurfaceControl getting created that would notify the old organizer about it. mTaskOrganizer = organizer; // Let the old organizer know it has lost control. sendTaskVanished(previousOrganizer); if (mTaskOrganizer != null) { sendTaskAppeared(); Loading
services/core/java/com/android/server/wm/TaskOrganizerController.java +1 −0 Original line number Diff line number Diff line Loading @@ -211,6 +211,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { void removeTask(Task t) { if (t.mTaskAppearedSent) { t.migrateToNewSurfaceControl(); t.mTaskAppearedSent = false; mOrganizer.onTaskVanished(t); } Loading