Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +22 −45 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.wm.shell.splitscreen; import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_BACK; Loading Loading @@ -515,7 +513,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSideStage.removeAllTasks(wct, childrenToTop == mSideStage); mMainStage.deactivate(wct, childrenToTop == mMainStage); mTaskOrganizer.applyTransaction(wct); // Reset divider position. // Hide divider and reset its position. setDividerVisibility(false); mSplitLayout.resetDividerPosition(); mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED; if (childrenToTop != null) { Loading Loading @@ -649,10 +648,15 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void onStageVisibilityChanged(StageListenerImpl stageListener) { final boolean sideStageVisible = mSideStageListener.mVisible; final boolean mainStageVisible = mMainStageListener.mVisible; // Divider is only visible if both the main stage and side stages are visible setDividerVisibility(isSplitScreenVisible()); final boolean bothStageVisible = sideStageVisible && mainStageVisible; final boolean sameVisibility = sideStageVisible == mainStageVisible; // Only add or remove divider when both visible or both invisible to avoid sometimes we only // got one stage visibility changed for a moment and it will cause flicker. if (sameVisibility) { setDividerVisibility(bothStageVisible); } if (!mainStageVisible && !sideStageVisible) { if (!bothStageVisible) { if (mExitSplitScreenOnHide // Don't dismiss staged split when both stages are not visible due to sleeping display, // like the cases keyguard showing or screen off. Loading @@ -669,59 +673,32 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, exitSplitScreen(toTop, SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED_SHOW_ON_TOP); } // When both stage's visibility changed to visible, main stage might receives visibility // changed before side stage if it has higher z-order than side stage. Make sure we only // update main stage's windowing mode with the visibility changed of side stage to prevent // stacking multiple windowing mode transactions which result to flicker issue. if (mainStageVisible && stageListener == mSideStageListener) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (sideStageVisible) { // The main stage configuration should to follow split layout when side stage is // visible. mMainStage.updateConfiguration( WINDOWING_MODE_MULTI_WINDOW, getMainStageBounds(), wct); } else if (!mSideStage.mRootTaskInfo.isSleeping) { // We want the main stage configuration to be fullscreen when the side stage isn't // visible. // We should not do it when side stage are not visible due to sleeping display too. mMainStage.updateConfiguration(WINDOWING_MODE_FULLSCREEN, null, wct); } // TODO: Change to `mSyncQueue.queue(wct)` once BLAST is stable. mTaskOrganizer.applyTransaction(wct); } mSyncQueue.runInSync(t -> { final SurfaceControl sideStageLeash = mSideStage.mRootLeash; final SurfaceControl mainStageLeash = mMainStage.mRootLeash; if (sideStageVisible) { final Rect sideStageBounds = getSideStageBounds(); t.show(sideStageLeash) .setPosition(sideStageLeash, t.setPosition(sideStageLeash, sideStageBounds.left, sideStageBounds.top) .setWindowCrop(sideStageLeash, sideStageBounds.width(), sideStageBounds.height()); } else { t.hide(sideStageLeash); } if (mainStageVisible) { final Rect mainStageBounds = getMainStageBounds(); t.show(mainStageLeash); if (sideStageVisible) { t.setPosition(mainStageLeash, mainStageBounds.left, mainStageBounds.top) .setWindowCrop(mainStageLeash, mainStageBounds.width(), mainStageBounds.height()); } else { // Clear window crop and position if side stage isn't visible. t.setPosition(mainStageLeash, 0, 0) .setWindowCrop(mainStageLeash, null); } } else { t.hide(mainStageLeash); } // Same above, we only set root tasks and divider leash visibility when both stage // change to visible or invisible to avoid flicker. if (sameVisibility) { t.setVisibility(sideStageLeash, bothStageVisible) .setVisibility(mainStageLeash, bothStageVisible); applyDividerVisibility(t); } }); } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +22 −45 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.wm.shell.splitscreen; import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_BACK; Loading Loading @@ -515,7 +513,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSideStage.removeAllTasks(wct, childrenToTop == mSideStage); mMainStage.deactivate(wct, childrenToTop == mMainStage); mTaskOrganizer.applyTransaction(wct); // Reset divider position. // Hide divider and reset its position. setDividerVisibility(false); mSplitLayout.resetDividerPosition(); mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED; if (childrenToTop != null) { Loading Loading @@ -649,10 +648,15 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void onStageVisibilityChanged(StageListenerImpl stageListener) { final boolean sideStageVisible = mSideStageListener.mVisible; final boolean mainStageVisible = mMainStageListener.mVisible; // Divider is only visible if both the main stage and side stages are visible setDividerVisibility(isSplitScreenVisible()); final boolean bothStageVisible = sideStageVisible && mainStageVisible; final boolean sameVisibility = sideStageVisible == mainStageVisible; // Only add or remove divider when both visible or both invisible to avoid sometimes we only // got one stage visibility changed for a moment and it will cause flicker. if (sameVisibility) { setDividerVisibility(bothStageVisible); } if (!mainStageVisible && !sideStageVisible) { if (!bothStageVisible) { if (mExitSplitScreenOnHide // Don't dismiss staged split when both stages are not visible due to sleeping display, // like the cases keyguard showing or screen off. Loading @@ -669,59 +673,32 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, exitSplitScreen(toTop, SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED_SHOW_ON_TOP); } // When both stage's visibility changed to visible, main stage might receives visibility // changed before side stage if it has higher z-order than side stage. Make sure we only // update main stage's windowing mode with the visibility changed of side stage to prevent // stacking multiple windowing mode transactions which result to flicker issue. if (mainStageVisible && stageListener == mSideStageListener) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (sideStageVisible) { // The main stage configuration should to follow split layout when side stage is // visible. mMainStage.updateConfiguration( WINDOWING_MODE_MULTI_WINDOW, getMainStageBounds(), wct); } else if (!mSideStage.mRootTaskInfo.isSleeping) { // We want the main stage configuration to be fullscreen when the side stage isn't // visible. // We should not do it when side stage are not visible due to sleeping display too. mMainStage.updateConfiguration(WINDOWING_MODE_FULLSCREEN, null, wct); } // TODO: Change to `mSyncQueue.queue(wct)` once BLAST is stable. mTaskOrganizer.applyTransaction(wct); } mSyncQueue.runInSync(t -> { final SurfaceControl sideStageLeash = mSideStage.mRootLeash; final SurfaceControl mainStageLeash = mMainStage.mRootLeash; if (sideStageVisible) { final Rect sideStageBounds = getSideStageBounds(); t.show(sideStageLeash) .setPosition(sideStageLeash, t.setPosition(sideStageLeash, sideStageBounds.left, sideStageBounds.top) .setWindowCrop(sideStageLeash, sideStageBounds.width(), sideStageBounds.height()); } else { t.hide(sideStageLeash); } if (mainStageVisible) { final Rect mainStageBounds = getMainStageBounds(); t.show(mainStageLeash); if (sideStageVisible) { t.setPosition(mainStageLeash, mainStageBounds.left, mainStageBounds.top) .setWindowCrop(mainStageLeash, mainStageBounds.width(), mainStageBounds.height()); } else { // Clear window crop and position if side stage isn't visible. t.setPosition(mainStageLeash, 0, 0) .setWindowCrop(mainStageLeash, null); } } else { t.hide(mainStageLeash); } // Same above, we only set root tasks and divider leash visibility when both stage // change to visible or invisible to avoid flicker. if (sameVisibility) { t.setVisibility(sideStageLeash, bothStageVisible) .setVisibility(mainStageLeash, bothStageVisible); applyDividerVisibility(t); } }); } Loading