Loading libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +8 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,14 @@ public class ShellTaskOrganizer extends TaskOrganizer implements } } @Override public void unregisterOrganizer() { super.unregisterOrganizer(); if (mStartingWindow != null) { mStartingWindow.clearAllWindows(); } } public void createRootTask(int displayId, int windowingMode, TaskListener listener) { ProtoLog.v(WM_SHELL_TASK_ORG, "createRootTask() displayId=%d winMode=%d listener=%s", displayId, windowingMode, listener.toString()); Loading libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +32 −10 Original line number Diff line number Diff line Loading @@ -134,7 +134,8 @@ public class StartingSurfaceDrawer { mDisplayManager.getDisplay(DEFAULT_DISPLAY); } private final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>(); @VisibleForTesting final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>(); /** * Records of {@link SurfaceControlViewHost} where the splash screen icon animation is Loading Loading @@ -464,8 +465,24 @@ public class StartingSurfaceDrawer { Slog.d(TAG, "Task start finish, remove starting surface for task " + removalInfo.taskId); } removeWindowSynced(removalInfo); removeWindowSynced(removalInfo, false /* immediately */); } /** * Clear all starting windows immediately. */ public void clearAllWindows() { if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { Slog.d(TAG, "Clear all starting windows immediately"); } final int taskSize = mStartingWindowRecords.size(); final int[] taskIds = new int[taskSize]; for (int i = taskSize - 1; i >= 0; --i) { taskIds[i] = mStartingWindowRecords.keyAt(i); } for (int i = taskSize - 1; i >= 0; --i) { removeWindowNoAnimate(taskIds[i]); } } /** Loading Loading @@ -550,7 +567,8 @@ public class StartingSurfaceDrawer { return shouldSaveView; } private void saveSplashScreenRecord(IBinder appToken, int taskId, View view, @VisibleForTesting void saveSplashScreenRecord(IBinder appToken, int taskId, View view, @StartingWindowType int suggestType) { final StartingWindowRecord tView = new StartingWindowRecord(appToken, view, null/* TaskSnapshotWindow */, suggestType); Loading @@ -559,19 +577,18 @@ public class StartingSurfaceDrawer { private void removeWindowNoAnimate(int taskId) { mTmpRemovalInfo.taskId = taskId; removeWindowSynced(mTmpRemovalInfo); removeWindowSynced(mTmpRemovalInfo, true /* immediately */); } void onImeDrawnOnTask(int taskId) { final StartingWindowRecord record = mStartingWindowRecords.get(taskId); if (record != null && record.mTaskSnapshotWindow != null && record.mTaskSnapshotWindow.hasImeSurface()) { record.mTaskSnapshotWindow.removeImmediately(); removeWindowNoAnimate(taskId); } mStartingWindowRecords.remove(taskId); } protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo) { protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo, boolean immediately) { final int taskId = removalInfo.taskId; final StartingWindowRecord record = mStartingWindowRecords.get(taskId); if (record != null) { Loading @@ -580,7 +597,8 @@ public class StartingSurfaceDrawer { Slog.v(TAG, "Removing splash screen window for task: " + taskId); } if (record.mContentView != null) { if (record.mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) { if (immediately || record.mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) { removeWindowInner(record.mDecorView, false); } else { if (removalInfo.playRevealAnimation) { Loading @@ -604,8 +622,12 @@ public class StartingSurfaceDrawer { if (DEBUG_TASK_SNAPSHOT) { Slog.v(TAG, "Removing task snapshot window for " + taskId); } record.mTaskSnapshotWindow.scheduleRemove( () -> mStartingWindowRecords.remove(taskId), removalInfo.deferRemoveForIme); if (immediately) { record.mTaskSnapshotWindow.removeImmediately(); } else { record.mTaskSnapshotWindow.scheduleRemove(() -> mStartingWindowRecords.remove(taskId), removalInfo.deferRemoveForIme); } } } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java +12 −2 Original line number Diff line number Diff line Loading @@ -29,9 +29,7 @@ import android.app.TaskInfo; import android.content.Context; import android.graphics.Color; import android.os.IBinder; import android.os.RemoteException; import android.os.Trace; import android.util.Slog; import android.util.SparseIntArray; import android.window.StartingWindowInfo; import android.window.StartingWindowInfo.StartingWindowType; Loading Loading @@ -198,6 +196,18 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo }, TASK_BG_COLOR_RETAIN_TIME_MS); } /** * Clear all starting window immediately, called this method when releasing the task organizer. */ public void clearAllWindows() { mSplashScreenExecutor.execute(() -> { mStartingSurfaceDrawer.clearAllWindows(); synchronized (mTaskBackgroundColors) { mTaskBackgroundColors.clear(); } }); } /** * The interface for calls from outside the Shell, within the host process. */ Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java +28 −3 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -117,16 +118,19 @@ public class StartingSurfaceDrawerTests { WindowManager.LayoutParams params, int suggestType) { // listen for addView mAddWindowForTask = taskId; saveSplashScreenRecord(appToken, taskId, view, suggestType); // Do not wait for background color return false; } @Override protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo) { protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo, boolean immediately) { // listen for removeView if (mAddWindowForTask == removalInfo.taskId) { mAddWindowForTask = 0; } mStartingWindowRecords.remove(removalInfo.taskId); } } Loading Loading @@ -179,7 +183,7 @@ public class StartingSurfaceDrawerTests { removalInfo.taskId = windowInfo.taskInfo.taskId; mStartingSurfaceDrawer.removeStartingWindow(removalInfo); waitHandlerIdle(mTestHandler); verify(mStartingSurfaceDrawer).removeWindowSynced(any()); verify(mStartingSurfaceDrawer).removeWindowSynced(any(), eq(false)); assertEquals(mStartingSurfaceDrawer.mAddWindowForTask, 0); } Loading Loading @@ -267,11 +271,32 @@ public class StartingSurfaceDrawerTests { // Verify the task snapshot with IME snapshot will be removed when received the real IME // drawn callback. // makeTaskSnapshotWindow shall call removeWindowSynced before there add a new // StartingWindowRecord for the task. mStartingSurfaceDrawer.onImeDrawnOnTask(1); verify(mockSnapshotWindow).removeImmediately(); verify(mStartingSurfaceDrawer, times(2)) .removeWindowSynced(any(), eq(true)); } } @Test public void testClearAllWindows() { final int taskId = 1; final StartingWindowInfo windowInfo = createWindowInfo(taskId, android.R.style.Theme); mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, mBinder, STARTING_WINDOW_TYPE_SPLASH_SCREEN); waitHandlerIdle(mTestHandler); verify(mStartingSurfaceDrawer).addWindow(eq(taskId), eq(mBinder), any(), any(), any(), eq(STARTING_WINDOW_TYPE_SPLASH_SCREEN)); assertEquals(mStartingSurfaceDrawer.mAddWindowForTask, taskId); mStartingSurfaceDrawer.clearAllWindows(); waitHandlerIdle(mTestHandler); verify(mStartingSurfaceDrawer).removeWindowSynced(any(), eq(true)); assertEquals(mStartingSurfaceDrawer.mStartingWindowRecords.size(), 0); } private StartingWindowInfo createWindowInfo(int taskId, int themeResId) { StartingWindowInfo windowInfo = new StartingWindowInfo(); final ActivityInfo info = new ActivityInfo(); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +8 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,14 @@ public class ShellTaskOrganizer extends TaskOrganizer implements } } @Override public void unregisterOrganizer() { super.unregisterOrganizer(); if (mStartingWindow != null) { mStartingWindow.clearAllWindows(); } } public void createRootTask(int displayId, int windowingMode, TaskListener listener) { ProtoLog.v(WM_SHELL_TASK_ORG, "createRootTask() displayId=%d winMode=%d listener=%s", displayId, windowingMode, listener.toString()); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +32 −10 Original line number Diff line number Diff line Loading @@ -134,7 +134,8 @@ public class StartingSurfaceDrawer { mDisplayManager.getDisplay(DEFAULT_DISPLAY); } private final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>(); @VisibleForTesting final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>(); /** * Records of {@link SurfaceControlViewHost} where the splash screen icon animation is Loading Loading @@ -464,8 +465,24 @@ public class StartingSurfaceDrawer { Slog.d(TAG, "Task start finish, remove starting surface for task " + removalInfo.taskId); } removeWindowSynced(removalInfo); removeWindowSynced(removalInfo, false /* immediately */); } /** * Clear all starting windows immediately. */ public void clearAllWindows() { if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { Slog.d(TAG, "Clear all starting windows immediately"); } final int taskSize = mStartingWindowRecords.size(); final int[] taskIds = new int[taskSize]; for (int i = taskSize - 1; i >= 0; --i) { taskIds[i] = mStartingWindowRecords.keyAt(i); } for (int i = taskSize - 1; i >= 0; --i) { removeWindowNoAnimate(taskIds[i]); } } /** Loading Loading @@ -550,7 +567,8 @@ public class StartingSurfaceDrawer { return shouldSaveView; } private void saveSplashScreenRecord(IBinder appToken, int taskId, View view, @VisibleForTesting void saveSplashScreenRecord(IBinder appToken, int taskId, View view, @StartingWindowType int suggestType) { final StartingWindowRecord tView = new StartingWindowRecord(appToken, view, null/* TaskSnapshotWindow */, suggestType); Loading @@ -559,19 +577,18 @@ public class StartingSurfaceDrawer { private void removeWindowNoAnimate(int taskId) { mTmpRemovalInfo.taskId = taskId; removeWindowSynced(mTmpRemovalInfo); removeWindowSynced(mTmpRemovalInfo, true /* immediately */); } void onImeDrawnOnTask(int taskId) { final StartingWindowRecord record = mStartingWindowRecords.get(taskId); if (record != null && record.mTaskSnapshotWindow != null && record.mTaskSnapshotWindow.hasImeSurface()) { record.mTaskSnapshotWindow.removeImmediately(); removeWindowNoAnimate(taskId); } mStartingWindowRecords.remove(taskId); } protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo) { protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo, boolean immediately) { final int taskId = removalInfo.taskId; final StartingWindowRecord record = mStartingWindowRecords.get(taskId); if (record != null) { Loading @@ -580,7 +597,8 @@ public class StartingSurfaceDrawer { Slog.v(TAG, "Removing splash screen window for task: " + taskId); } if (record.mContentView != null) { if (record.mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) { if (immediately || record.mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) { removeWindowInner(record.mDecorView, false); } else { if (removalInfo.playRevealAnimation) { Loading @@ -604,8 +622,12 @@ public class StartingSurfaceDrawer { if (DEBUG_TASK_SNAPSHOT) { Slog.v(TAG, "Removing task snapshot window for " + taskId); } record.mTaskSnapshotWindow.scheduleRemove( () -> mStartingWindowRecords.remove(taskId), removalInfo.deferRemoveForIme); if (immediately) { record.mTaskSnapshotWindow.removeImmediately(); } else { record.mTaskSnapshotWindow.scheduleRemove(() -> mStartingWindowRecords.remove(taskId), removalInfo.deferRemoveForIme); } } } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java +12 −2 Original line number Diff line number Diff line Loading @@ -29,9 +29,7 @@ import android.app.TaskInfo; import android.content.Context; import android.graphics.Color; import android.os.IBinder; import android.os.RemoteException; import android.os.Trace; import android.util.Slog; import android.util.SparseIntArray; import android.window.StartingWindowInfo; import android.window.StartingWindowInfo.StartingWindowType; Loading Loading @@ -198,6 +196,18 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo }, TASK_BG_COLOR_RETAIN_TIME_MS); } /** * Clear all starting window immediately, called this method when releasing the task organizer. */ public void clearAllWindows() { mSplashScreenExecutor.execute(() -> { mStartingSurfaceDrawer.clearAllWindows(); synchronized (mTaskBackgroundColors) { mTaskBackgroundColors.clear(); } }); } /** * The interface for calls from outside the Shell, within the host process. */ Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java +28 −3 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -117,16 +118,19 @@ public class StartingSurfaceDrawerTests { WindowManager.LayoutParams params, int suggestType) { // listen for addView mAddWindowForTask = taskId; saveSplashScreenRecord(appToken, taskId, view, suggestType); // Do not wait for background color return false; } @Override protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo) { protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo, boolean immediately) { // listen for removeView if (mAddWindowForTask == removalInfo.taskId) { mAddWindowForTask = 0; } mStartingWindowRecords.remove(removalInfo.taskId); } } Loading Loading @@ -179,7 +183,7 @@ public class StartingSurfaceDrawerTests { removalInfo.taskId = windowInfo.taskInfo.taskId; mStartingSurfaceDrawer.removeStartingWindow(removalInfo); waitHandlerIdle(mTestHandler); verify(mStartingSurfaceDrawer).removeWindowSynced(any()); verify(mStartingSurfaceDrawer).removeWindowSynced(any(), eq(false)); assertEquals(mStartingSurfaceDrawer.mAddWindowForTask, 0); } Loading Loading @@ -267,11 +271,32 @@ public class StartingSurfaceDrawerTests { // Verify the task snapshot with IME snapshot will be removed when received the real IME // drawn callback. // makeTaskSnapshotWindow shall call removeWindowSynced before there add a new // StartingWindowRecord for the task. mStartingSurfaceDrawer.onImeDrawnOnTask(1); verify(mockSnapshotWindow).removeImmediately(); verify(mStartingSurfaceDrawer, times(2)) .removeWindowSynced(any(), eq(true)); } } @Test public void testClearAllWindows() { final int taskId = 1; final StartingWindowInfo windowInfo = createWindowInfo(taskId, android.R.style.Theme); mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, mBinder, STARTING_WINDOW_TYPE_SPLASH_SCREEN); waitHandlerIdle(mTestHandler); verify(mStartingSurfaceDrawer).addWindow(eq(taskId), eq(mBinder), any(), any(), any(), eq(STARTING_WINDOW_TYPE_SPLASH_SCREEN)); assertEquals(mStartingSurfaceDrawer.mAddWindowForTask, taskId); mStartingSurfaceDrawer.clearAllWindows(); waitHandlerIdle(mTestHandler); verify(mStartingSurfaceDrawer).removeWindowSynced(any(), eq(true)); assertEquals(mStartingSurfaceDrawer.mStartingWindowRecords.size(), 0); } private StartingWindowInfo createWindowInfo(int taskId, int themeResId) { StartingWindowInfo windowInfo = new StartingWindowInfo(); final ActivityInfo info = new ActivityInfo(); Loading