Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 205cd648 authored by wilsonshih's avatar wilsonshih Committed by Wei Sheng Shih
Browse files

Clear all starting window while unregister organizer.

The starting window view might left in client's ShellTaskOrganizer,
clear all of the starting windows view while unregister task organizer
to preventing those views from left.
Consolidating the remove window methods together.

Bug: 207175662
Test: build/flash
Test: atest StartingSurfaceDrawerTests SplashscreenTests
Change-Id: I93e4862b7f866c7c73d9b3999a74e03784848058
Merged-In: I93e4862b7f866c7c73d9b3999a74e03784848058
parent ab529ab9
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -200,6 +200,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());
+32 −10
Original line number Diff line number Diff line
@@ -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
@@ -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]);
        }
    }

    /**
@@ -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);
@@ -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) {
@@ -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) {
@@ -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);
                }
            }
        }
    }
+12 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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.
     */
+28 −3
Original line number Diff line number Diff line
@@ -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;

@@ -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);
        }
    }

@@ -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);
    }

@@ -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();