Merge "Revert "Introduce Windowless starting window."" into udc-dev
diff --git a/core/java/android/window/ITaskOrganizer.aidl b/core/java/android/window/ITaskOrganizer.aidl
index bf9d3c2..fd86769 100644
--- a/core/java/android/window/ITaskOrganizer.aidl
+++ b/core/java/android/window/ITaskOrganizer.aidl
@@ -34,8 +34,9 @@
      * has create a starting window for the Task.
      *
      * @param info The information about the Task that's available
+     * @param appToken Token of the application being started.
      */
-    void addStartingWindow(in StartingWindowInfo info);
+    void addStartingWindow(in StartingWindowInfo info, IBinder appToken);
 
     /**
      * Called when the Task want to remove the starting window.
diff --git a/core/java/android/window/IWindowlessStartingSurfaceCallback.aidl b/core/java/android/window/IWindowlessStartingSurfaceCallback.aidl
deleted file mode 100644
index a081356..0000000
--- a/core/java/android/window/IWindowlessStartingSurfaceCallback.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.window;
-
-import android.view.SurfaceControl;
-
-/**
- * Interface to be invoked when a windowless starting surface added.
- *
- * @param addedSurface The starting surface.
- * {@hide}
- */
-interface IWindowlessStartingSurfaceCallback {
-    void onSurfaceAdded(in SurfaceControl addedSurface);
-}
diff --git a/core/java/android/window/SnapshotDrawerUtils.java b/core/java/android/window/SnapshotDrawerUtils.java
index 071c20f..1a58fd5 100644
--- a/core/java/android/window/SnapshotDrawerUtils.java
+++ b/core/java/android/window/SnapshotDrawerUtils.java
@@ -329,21 +329,6 @@
     }
 
     /**
-     * Get or create a TaskDescription from a RunningTaskInfo.
-     */
-    public static ActivityManager.TaskDescription getOrCreateTaskDescription(
-            ActivityManager.RunningTaskInfo runningTaskInfo) {
-        final ActivityManager.TaskDescription taskDescription;
-        if (runningTaskInfo.taskDescription != null) {
-            taskDescription = runningTaskInfo.taskDescription;
-        } else {
-            taskDescription = new ActivityManager.TaskDescription();
-            taskDescription.setBackgroundColor(WHITE);
-        }
-        return taskDescription;
-    }
-
-    /**
      * Help method to draw the snapshot on a surface.
      */
     public static void drawSnapshotOnSurface(StartingWindowInfo info, WindowManager.LayoutParams lp,
@@ -359,8 +344,13 @@
 
         final WindowManager.LayoutParams attrs = info.topOpaqueWindowLayoutParams;
         final ActivityManager.RunningTaskInfo runningTaskInfo = info.taskInfo;
-        final ActivityManager.TaskDescription taskDescription =
-                getOrCreateTaskDescription(runningTaskInfo);
+        final ActivityManager.TaskDescription taskDescription;
+        if (runningTaskInfo.taskDescription != null) {
+            taskDescription = runningTaskInfo.taskDescription;
+        } else {
+            taskDescription = new ActivityManager.TaskDescription();
+            taskDescription.setBackgroundColor(WHITE);
+        }
         drawSurface.initiateSystemBarPainter(lp.flags, lp.privateFlags,
                 attrs.insetsFlags.appearance, taskDescription, info.requestedVisibleTypes);
         final Rect systemBarInsets = getSystemBarInsets(windowBounds, topWindowInsetsState);
diff --git a/core/java/android/window/StartingWindowInfo.java b/core/java/android/window/StartingWindowInfo.java
index 451acbe..1b64e61 100644
--- a/core/java/android/window/StartingWindowInfo.java
+++ b/core/java/android/window/StartingWindowInfo.java
@@ -22,12 +22,9 @@
 import android.app.ActivityManager;
 import android.app.TaskInfo;
 import android.content.pm.ActivityInfo;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.RemoteException;
 import android.view.InsetsState;
-import android.view.SurfaceControl;
 import android.view.WindowInsets;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowManager;
@@ -62,8 +59,6 @@
     /** @hide **/
     public static final int STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN = 4;
 
-    public static final int STARTING_WINDOW_TYPE_WINDOWLESS = 5;
-
     /**
      * @hide
      */
@@ -72,8 +67,7 @@
             STARTING_WINDOW_TYPE_SPLASH_SCREEN,
             STARTING_WINDOW_TYPE_SNAPSHOT,
             STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN,
-            STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN,
-            STARTING_WINDOW_TYPE_WINDOWLESS
+            STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN
     })
     public @interface StartingWindowType {}
 
@@ -124,7 +118,6 @@
             TYPE_PARAMETER_ACTIVITY_CREATED,
             TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN,
             TYPE_PARAMETER_ALLOW_HANDLE_SOLID_COLOR_SCREEN,
-            TYPE_PARAMETER_WINDOWLESS,
             TYPE_PARAMETER_LEGACY_SPLASH_SCREEN
     })
     public @interface StartingTypeParams {}
@@ -158,12 +151,6 @@
      * @hide
      */
     public static final int TYPE_PARAMETER_ALLOW_HANDLE_SOLID_COLOR_SCREEN = 0x00000080;
-
-    /**
-     * Windowless surface
-     */
-    public static final int TYPE_PARAMETER_WINDOWLESS = 0x00000100;
-
     /**
      * Application is allowed to use the legacy splash screen
      * @hide
@@ -195,33 +182,7 @@
      */
     public TaskSnapshot taskSnapshot;
 
-    @InsetsType public int requestedVisibleTypes = WindowInsets.Type.defaultVisible();
-
-    /**
-     * App token where the starting window should add to.
-     */
-    public IBinder appToken;
-
-    public IWindowlessStartingSurfaceCallback windowlessStartingSurfaceCallback;
-
-    /**
-     * The root surface where windowless surface should attach on.
-     */
-    public SurfaceControl rootSurface;
-
-    /**
-     * Notify windowless surface is created.
-     * @param addedSurface Created surface.
-     */
-    public void notifyAddComplete(SurfaceControl addedSurface) {
-        if (windowlessStartingSurfaceCallback != null) {
-            try {
-                windowlessStartingSurfaceCallback.onSurfaceAdded(addedSurface);
-            } catch (RemoteException e) {
-                //
-            }
-        }
-    }
+    public @InsetsType int requestedVisibleTypes = WindowInsets.Type.defaultVisible();
 
     public StartingWindowInfo() {
 
@@ -255,9 +216,6 @@
         dest.writeBoolean(isKeyguardOccluded);
         dest.writeTypedObject(taskSnapshot, flags);
         dest.writeInt(requestedVisibleTypes);
-        dest.writeStrongBinder(appToken);
-        dest.writeStrongInterface(windowlessStartingSurfaceCallback);
-        dest.writeTypedObject(rootSurface, flags);
     }
 
     void readFromParcel(@NonNull Parcel source) {
@@ -272,10 +230,6 @@
         isKeyguardOccluded = source.readBoolean();
         taskSnapshot = source.readTypedObject(TaskSnapshot.CREATOR);
         requestedVisibleTypes = source.readInt();
-        appToken = source.readStrongBinder();
-        windowlessStartingSurfaceCallback = IWindowlessStartingSurfaceCallback.Stub
-                .asInterface(source.readStrongBinder());
-        rootSurface = source.readTypedObject(SurfaceControl.CREATOR);
     }
 
     @Override
diff --git a/core/java/android/window/StartingWindowRemovalInfo.java b/core/java/android/window/StartingWindowRemovalInfo.java
index 5181236..384dacf 100644
--- a/core/java/android/window/StartingWindowRemovalInfo.java
+++ b/core/java/android/window/StartingWindowRemovalInfo.java
@@ -67,16 +67,6 @@
      */
     public float roundedCornerRadius;
 
-    /**
-     * Remove windowless surface.
-     */
-    public boolean windowlessSurface;
-
-    /**
-     * Remove immediately.
-     */
-    public boolean removeImmediately;
-
     public StartingWindowRemovalInfo() {
 
     }
@@ -97,8 +87,6 @@
         playRevealAnimation = source.readBoolean();
         deferRemoveForIme = source.readBoolean();
         roundedCornerRadius = source.readFloat();
-        windowlessSurface = source.readBoolean();
-        removeImmediately = source.readBoolean();
     }
 
     @Override
@@ -109,8 +97,6 @@
         dest.writeBoolean(playRevealAnimation);
         dest.writeBoolean(deferRemoveForIme);
         dest.writeFloat(roundedCornerRadius);
-        dest.writeBoolean(windowlessSurface);
-        dest.writeBoolean(removeImmediately);
     }
 
     @Override
@@ -119,9 +105,7 @@
                 + " frame=" + mainFrame
                 + " playRevealAnimation=" + playRevealAnimation
                 + " roundedCornerRadius=" + roundedCornerRadius
-                + " deferRemoveForIme=" + deferRemoveForIme
-                + " windowlessSurface=" + windowlessSurface
-                + " removeImmediately=" + removeImmediately + "}";
+                + " deferRemoveForIme=" + deferRemoveForIme + "}";
     }
 
     public static final @android.annotation.NonNull Creator<StartingWindowRemovalInfo> CREATOR =
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index d4728c1..02878f8 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -92,10 +92,13 @@
      * has create a starting window for the Task.
      *
      * @param info The information about the Task that's available
+     * @param appToken Token of the application being started.
+     *        context to for resources
      * @hide
      */
     @BinderThread
-    public void addStartingWindow(@NonNull StartingWindowInfo info) {}
+    public void addStartingWindow(@NonNull StartingWindowInfo info,
+            @NonNull IBinder appToken) {}
 
     /**
      * Called when the Task want to remove the starting window.
@@ -294,8 +297,9 @@
 
     private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() {
         @Override
-        public void addStartingWindow(StartingWindowInfo windowInfo) {
-            mExecutor.execute(() -> TaskOrganizer.this.addStartingWindow(windowInfo));
+        public void addStartingWindow(StartingWindowInfo windowInfo,
+                IBinder appToken) {
+            mExecutor.execute(() -> TaskOrganizer.this.addStartingWindow(windowInfo, appToken));
         }
 
         @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index b6fd0bb..585f81c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -428,9 +428,9 @@
     }
 
     @Override
-    public void addStartingWindow(StartingWindowInfo info) {
+    public void addStartingWindow(StartingWindowInfo info, IBinder appToken) {
         if (mStartingWindow != null) {
-            mStartingWindow.addStartingWindow(info);
+            mStartingWindow.addStartingWindow(info, appToken);
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/AbsSplashWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/AbsSplashWindowCreator.java
deleted file mode 100644
index 1ddd8f9..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/AbsSplashWindowCreator.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.startingsurface;
-
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.hardware.display.DisplayManager;
-import android.view.Display;
-
-import com.android.wm.shell.common.ShellExecutor;
-
-// abstract class to create splash screen window(or windowless window)
-abstract class AbsSplashWindowCreator {
-    protected static final String TAG = StartingWindowController.TAG;
-    protected final SplashscreenContentDrawer mSplashscreenContentDrawer;
-    protected final Context mContext;
-    protected final DisplayManager mDisplayManager;
-    protected final ShellExecutor mSplashScreenExecutor;
-    protected final StartingSurfaceDrawer.StartingWindowRecordManager mStartingWindowRecordManager;
-
-    private StartingSurface.SysuiProxy mSysuiProxy;
-
-    AbsSplashWindowCreator(SplashscreenContentDrawer contentDrawer, Context context,
-            ShellExecutor splashScreenExecutor, DisplayManager displayManager,
-            StartingSurfaceDrawer.StartingWindowRecordManager startingWindowRecordManager) {
-        mSplashscreenContentDrawer = contentDrawer;
-        mContext = context;
-        mSplashScreenExecutor = splashScreenExecutor;
-        mDisplayManager = displayManager;
-        mStartingWindowRecordManager = startingWindowRecordManager;
-    }
-
-    int getSplashScreenTheme(int splashScreenThemeResId, ActivityInfo activityInfo) {
-        return splashScreenThemeResId != 0
-                ? splashScreenThemeResId
-                : activityInfo.getThemeResource() != 0 ? activityInfo.getThemeResource()
-                        : com.android.internal.R.style.Theme_DeviceDefault_DayNight;
-    }
-
-    protected Display getDisplay(int displayId) {
-        return mDisplayManager.getDisplay(displayId);
-    }
-
-    void setSysuiProxy(StartingSurface.SysuiProxy sysuiProxy) {
-        mSysuiProxy = sysuiProxy;
-    }
-
-    protected void requestTopUi(boolean requestTopUi) {
-        if (mSysuiProxy != null) {
-            mSysuiProxy.requestTopUi(requestTopUi, TAG);
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java
deleted file mode 100644
index 20c4d5a..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.startingsurface;
-
-import android.window.StartingWindowInfo;
-import android.window.TaskSnapshot;
-
-import com.android.wm.shell.common.ShellExecutor;
-
-class SnapshotWindowCreator {
-    private final ShellExecutor mMainExecutor;
-    private final StartingSurfaceDrawer.StartingWindowRecordManager
-            mStartingWindowRecordManager;
-
-    SnapshotWindowCreator(ShellExecutor mainExecutor,
-            StartingSurfaceDrawer.StartingWindowRecordManager startingWindowRecordManager) {
-        mMainExecutor = mainExecutor;
-        mStartingWindowRecordManager = startingWindowRecordManager;
-    }
-
-    void makeTaskSnapshotWindow(StartingWindowInfo startingWindowInfo, TaskSnapshot snapshot) {
-        final int taskId = startingWindowInfo.taskInfo.taskId;
-        // Remove any existing starting window for this task before adding.
-        mStartingWindowRecordManager.removeWindow(taskId, true);
-        final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo,
-                startingWindowInfo.appToken, snapshot, mMainExecutor,
-                () -> mStartingWindowRecordManager.removeWindow(taskId, true));
-        if (surface != null) {
-            final SnapshotWindowRecord tView = new SnapshotWindowRecord(surface,
-                    startingWindowInfo.taskInfo.topActivityType, mMainExecutor);
-            mStartingWindowRecordManager.addRecord(taskId, tView);
-        }
-    }
-
-    private static class SnapshotWindowRecord extends StartingSurfaceDrawer.SnapshotRecord {
-        private final TaskSnapshotWindow mTaskSnapshotWindow;
-
-        SnapshotWindowRecord(TaskSnapshotWindow taskSnapshotWindow,
-                int activityType, ShellExecutor removeExecutor) {
-            super(activityType, removeExecutor);
-            mTaskSnapshotWindow = taskSnapshotWindow;
-            mBGColor = mTaskSnapshotWindow.getBackgroundColor();
-        }
-
-        @Override
-        protected void removeImmediately() {
-            super.removeImmediately();
-            mTaskSnapshotWindow.removeImmediately();
-        }
-
-        @Override
-        protected boolean hasImeSurface() {
-            return mTaskSnapshotWindow.hasImeSurface();
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 79cd891..ebb957b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -24,6 +24,9 @@
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
 
+import static com.android.wm.shell.startingsurface.StartingSurfaceDrawer.MAX_ANIMATION_DURATION;
+import static com.android.wm.shell.startingsurface.StartingSurfaceDrawer.MINIMAL_ANIMATION_DURATION;
+
 import android.annotation.ColorInt;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -93,25 +96,6 @@
 public class SplashscreenContentDrawer {
     private static final String TAG = StartingWindowController.TAG;
 
-    /**
-     * The minimum duration during which the splash screen is shown when the splash screen icon is
-     * animated.
-     */
-    static final long MINIMAL_ANIMATION_DURATION = 400L;
-
-    /**
-     * Allow the icon style splash screen to be displayed for longer to give time for the animation
-     * to finish, i.e. the extra buffer time to keep the splash screen if the animation is slightly
-     * longer than the {@link #MINIMAL_ANIMATION_DURATION} duration.
-     */
-    static final long TIME_WINDOW_DURATION = 100L;
-
-    /**
-     * The maximum duration during which the splash screen will be shown if the application is ready
-     * to show before the icon animation finishes.
-     */
-    static final long MAX_ANIMATION_DURATION = MINIMAL_ANIMATION_DURATION + TIME_WINDOW_DURATION;
-
     // The acceptable area ratio of foreground_icon_area/background_icon_area, if there is an
     // icon which it's non-transparent foreground area is similar to it's background area, then
     // do not enlarge the foreground drawable.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
deleted file mode 100644
index 4db81e2..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.startingsurface;
-
-import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.view.Choreographer.CALLBACK_INSETS_ANIMATION;
-import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
-
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
-import android.app.ActivityThread;
-import android.app.TaskInfo;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.hardware.display.DisplayManager;
-import android.os.IBinder;
-import android.os.RemoteCallback;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.Trace;
-import android.os.UserHandle;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.view.Choreographer;
-import android.view.Display;
-import android.view.SurfaceControlViewHost;
-import android.view.View;
-import android.view.WindowInsetsController;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.widget.FrameLayout;
-import android.window.SplashScreenView;
-import android.window.StartingWindowInfo;
-import android.window.StartingWindowRemovalInfo;
-
-import com.android.internal.R;
-import com.android.internal.protolog.common.ProtoLog;
-import com.android.internal.util.ContrastColorUtil;
-import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.protolog.ShellProtoLogGroup;
-
-import java.util.function.Supplier;
-
-/**
- * A class which able to draw splash screen as the starting window for a task.
- *
- * In order to speed up, there will use two threads to creating a splash screen in parallel.
- * Right now we are still using PhoneWindow to create splash screen window, so the view is added to
- * the ViewRootImpl, and those view won't be draw immediately because the ViewRootImpl will call
- * scheduleTraversal to register a callback from Choreographer, so the drawing result of the view
- * can synchronize on each frame.
- *
- * The bad thing is that we cannot decide when would Choreographer#doFrame happen, and drawing
- * the AdaptiveIconDrawable object can be time consuming, so we use the splash-screen background
- * thread to draw the AdaptiveIconDrawable object to a Bitmap and cache it to a BitmapShader after
- * the SplashScreenView just created, once we get the BitmapShader then the #draw call can be very
- * quickly.
- *
- * So basically we are using the spare time to prepare the SplashScreenView while splash screen
- * thread is waiting for
- * 1. WindowManager#addView(binder call to WM),
- * 2. Choreographer#doFrame happen(uncertain time for next frame, depends on device),
- * 3. Session#relayout(another binder call to WM which under Choreographer#doFrame, but will
- * always happen before #draw).
- * Because above steps are running on splash-screen thread, so pre-draw the BitmapShader on
- * splash-screen background tread can make they execute in parallel, which ensure it is faster then
- * to draw the AdaptiveIconDrawable when receive callback from Choreographer#doFrame.
- *
- * Here is the sequence to compare the difference between using single and two thread.
- *
- * Single thread:
- * => makeSplashScreenContentView -> WM#addView .. waiting for Choreographer#doFrame -> relayout
- * -> draw -> AdaptiveIconDrawable#draw
- *
- * Two threads:
- * => makeSplashScreenContentView -> cachePaint(=AdaptiveIconDrawable#draw)
- * => WM#addView -> .. waiting for Choreographer#doFrame -> relayout -> draw -> (draw the Paint
- * directly).
- */
-class SplashscreenWindowCreator extends AbsSplashWindowCreator {
-    private static final int LIGHT_BARS_MASK =
-            WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
-                    | WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
-
-    private final WindowManagerGlobal mWindowManagerGlobal;
-    private Choreographer mChoreographer;
-
-    /**
-     * Records of {@link SurfaceControlViewHost} where the splash screen icon animation is
-     * rendered and that have not yet been removed by their client.
-     */
-    private final SparseArray<SurfaceControlViewHost> mAnimatedSplashScreenSurfaceHosts =
-            new SparseArray<>(1);
-
-    SplashscreenWindowCreator(SplashscreenContentDrawer contentDrawer, Context context,
-            ShellExecutor splashScreenExecutor, DisplayManager displayManager,
-            StartingSurfaceDrawer.StartingWindowRecordManager startingWindowRecordManager) {
-        super(contentDrawer, context, splashScreenExecutor, displayManager,
-                startingWindowRecordManager);
-        mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance());
-        mWindowManagerGlobal = WindowManagerGlobal.getInstance();
-    }
-
-    void addSplashScreenStartingWindow(StartingWindowInfo windowInfo,
-            @StartingWindowInfo.StartingWindowType int suggestType) {
-        final ActivityManager.RunningTaskInfo taskInfo = windowInfo.taskInfo;
-        final ActivityInfo activityInfo = windowInfo.targetActivityInfo != null
-                ? windowInfo.targetActivityInfo
-                : taskInfo.topActivityInfo;
-        if (activityInfo == null || activityInfo.packageName == null) {
-            return;
-        }
-        // replace with the default theme if the application didn't set
-        final int theme = getSplashScreenTheme(windowInfo.splashScreenThemeResId, activityInfo);
-        final Context context = SplashscreenContentDrawer.createContext(mContext, windowInfo, theme,
-                suggestType, mDisplayManager);
-        if (context == null) {
-            return;
-        }
-        final WindowManager.LayoutParams params = SplashscreenContentDrawer.createLayoutParameters(
-                context, windowInfo, suggestType, activityInfo.packageName,
-                suggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN
-                        ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT, windowInfo.appToken);
-
-        final int displayId = taskInfo.displayId;
-        final int taskId = taskInfo.taskId;
-        final Display display = getDisplay(displayId);
-
-        // TODO(b/173975965) tracking performance
-        // Prepare the splash screen content view on splash screen worker thread in parallel, so the
-        // content view won't be blocked by binder call like addWindow and relayout.
-        // 1. Trigger splash screen worker thread to create SplashScreenView before/while
-        // Session#addWindow.
-        // 2. Synchronize the SplashscreenView to splash screen thread before Choreographer start
-        // traversal, which will call Session#relayout on splash screen thread.
-        // 3. Pre-draw the BitmapShader if the icon is immobile on splash screen worker thread, at
-        // the same time the splash screen thread should be executing Session#relayout. Blocking the
-        // traversal -> draw on splash screen thread until the BitmapShader of the icon is ready.
-
-        // Record whether create splash screen view success, notify to current thread after
-        // create splash screen view finished.
-        final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier();
-        final FrameLayout rootLayout = new FrameLayout(
-                mSplashscreenContentDrawer.createViewContextWrapper(context));
-        rootLayout.setPadding(0, 0, 0, 0);
-        rootLayout.setFitsSystemWindows(false);
-        final Runnable setViewSynchronized = () -> {
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addSplashScreenView");
-            // waiting for setContentView before relayoutWindow
-            SplashScreenView contentView = viewSupplier.get();
-            final StartingSurfaceDrawer.StartingWindowRecord sRecord =
-                    mStartingWindowRecordManager.getRecord(taskId);
-            final SplashWindowRecord record = sRecord instanceof SplashWindowRecord
-                    ? (SplashWindowRecord) sRecord : null;
-            // If record == null, either the starting window added fail or removed already.
-            // Do not add this view if the token is mismatch.
-            if (record != null && windowInfo.appToken == record.mAppToken) {
-                // if view == null then creation of content view was failed.
-                if (contentView != null) {
-                    try {
-                        rootLayout.addView(contentView);
-                    } catch (RuntimeException e) {
-                        Slog.w(TAG, "failed set content view to starting window "
-                                + "at taskId: " + taskId, e);
-                        contentView = null;
-                    }
-                }
-                record.setSplashScreenView(contentView);
-            }
-            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-        };
-        requestTopUi(true);
-        mSplashscreenContentDrawer.createContentView(context, suggestType, windowInfo,
-                viewSupplier::setView, viewSupplier::setUiThreadInitTask);
-        try {
-            if (addWindow(taskId, windowInfo.appToken, rootLayout, display, params, suggestType)) {
-                // We use the splash screen worker thread to create SplashScreenView while adding
-                // the window, as otherwise Choreographer#doFrame might be delayed on this thread.
-                // And since Choreographer#doFrame won't happen immediately after adding the window,
-                // if the view is not added to the PhoneWindow on the first #doFrame, the view will
-                // not be rendered on the first frame. So here we need to synchronize the view on
-                // the window before first round relayoutWindow, which will happen after insets
-                // animation.
-                mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null);
-                final SplashWindowRecord record =
-                        (SplashWindowRecord) mStartingWindowRecordManager.getRecord(taskId);
-                if (record != null) {
-                    record.parseAppSystemBarColor(context);
-                    // Block until we get the background color.
-                    final SplashScreenView contentView = viewSupplier.get();
-                    if (suggestType != STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
-                        contentView.addOnAttachStateChangeListener(
-                                new View.OnAttachStateChangeListener() {
-                                    @Override
-                                    public void onViewAttachedToWindow(View v) {
-                                        final int lightBarAppearance =
-                                                ContrastColorUtil.isColorLight(
-                                                        contentView.getInitBackgroundColor())
-                                                        ? LIGHT_BARS_MASK : 0;
-                                        contentView.getWindowInsetsController()
-                                                .setSystemBarsAppearance(
-                                                lightBarAppearance, LIGHT_BARS_MASK);
-                                    }
-
-                                    @Override
-                                    public void onViewDetachedFromWindow(View v) {
-                                    }
-                                });
-                    }
-                }
-            } else {
-                // release the icon view host
-                final SplashScreenView contentView = viewSupplier.get();
-                if (contentView.getSurfaceHost() != null) {
-                    SplashScreenView.releaseIconHost(contentView.getSurfaceHost());
-                }
-            }
-        } catch (RuntimeException e) {
-            // don't crash if something else bad happens, for example a
-            // failure loading resources because we are loading from an app
-            // on external storage that has been unmounted.
-            Slog.w(TAG, "failed creating starting window at taskId: " + taskId, e);
-        }
-    }
-
-    int estimateTaskBackgroundColor(TaskInfo taskInfo) {
-        if (taskInfo.topActivityInfo == null) {
-            return Color.TRANSPARENT;
-        }
-        final ActivityInfo activityInfo = taskInfo.topActivityInfo;
-        final String packageName = activityInfo.packageName;
-        final int userId = taskInfo.userId;
-        final Context windowContext;
-        try {
-            windowContext = mContext.createPackageContextAsUser(
-                    packageName, Context.CONTEXT_RESTRICTED, UserHandle.of(userId));
-        } catch (PackageManager.NameNotFoundException e) {
-            Slog.w(TAG, "Failed creating package context with package name "
-                    + packageName + " for user " + taskInfo.userId, e);
-            return Color.TRANSPARENT;
-        }
-        try {
-            final IPackageManager packageManager = ActivityThread.getPackageManager();
-            final String splashScreenThemeName = packageManager.getSplashScreenTheme(packageName,
-                    userId);
-            final int splashScreenThemeId = splashScreenThemeName != null
-                    ? windowContext.getResources().getIdentifier(splashScreenThemeName, null, null)
-                    : 0;
-
-            final int theme = getSplashScreenTheme(splashScreenThemeId, activityInfo);
-
-            if (theme != windowContext.getThemeResId()) {
-                windowContext.setTheme(theme);
-            }
-            return mSplashscreenContentDrawer.estimateTaskBackgroundColor(windowContext);
-        } catch (RuntimeException | RemoteException e) {
-            Slog.w(TAG, "failed get starting window background color at taskId: "
-                    + taskInfo.taskId, e);
-        }
-        return Color.TRANSPARENT;
-    }
-
-    /**
-     * Called when the Task wants to copy the splash screen.
-     */
-    public void copySplashScreenView(int taskId) {
-        final StartingSurfaceDrawer.StartingWindowRecord record =
-                mStartingWindowRecordManager.getRecord(taskId);
-        final SplashWindowRecord preView = record instanceof SplashWindowRecord
-                ? (SplashWindowRecord) record : null;
-        SplashScreenView.SplashScreenViewParcelable parcelable;
-        SplashScreenView splashScreenView = preView != null ? preView.mSplashView : null;
-        if (splashScreenView != null && splashScreenView.isCopyable()) {
-            parcelable = new SplashScreenView.SplashScreenViewParcelable(splashScreenView);
-            parcelable.setClientCallback(
-                    new RemoteCallback((bundle) -> mSplashScreenExecutor.execute(
-                            () -> onAppSplashScreenViewRemoved(taskId, false))));
-            splashScreenView.onCopied();
-            mAnimatedSplashScreenSurfaceHosts.append(taskId, splashScreenView.getSurfaceHost());
-        } else {
-            parcelable = null;
-        }
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
-                "Copying splash screen window view for task: %d with parcelable %b",
-                taskId, parcelable != null);
-        ActivityTaskManager.getInstance().onSplashScreenViewCopyFinished(taskId, parcelable);
-    }
-
-    /**
-     * Called when the {@link SplashScreenView} is removed from the client Activity view's hierarchy
-     * or when the Activity is clean up.
-     *
-     * @param taskId The Task id on which the splash screen was attached
-     */
-    public void onAppSplashScreenViewRemoved(int taskId) {
-        onAppSplashScreenViewRemoved(taskId, true /* fromServer */);
-    }
-
-    /**
-     * @param fromServer If true, this means the removal was notified by the server. This is only
-     *                   used for debugging purposes.
-     * @see #onAppSplashScreenViewRemoved(int)
-     */
-    private void onAppSplashScreenViewRemoved(int taskId, boolean fromServer) {
-        SurfaceControlViewHost viewHost =
-                mAnimatedSplashScreenSurfaceHosts.get(taskId);
-        if (viewHost == null) {
-            return;
-        }
-        mAnimatedSplashScreenSurfaceHosts.remove(taskId);
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
-                "%s the splash screen. Releasing SurfaceControlViewHost for task: %d",
-                fromServer ? "Server cleaned up" : "App removed", taskId);
-        SplashScreenView.releaseIconHost(viewHost);
-    }
-
-    protected boolean addWindow(int taskId, IBinder appToken, View view, Display display,
-            WindowManager.LayoutParams params,
-            @StartingWindowInfo.StartingWindowType int suggestType) {
-        boolean shouldSaveView = true;
-        final Context context = view.getContext();
-        try {
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addRootView");
-            mWindowManagerGlobal.addView(view, params, display,
-                    null /* parentWindow */, context.getUserId());
-        } catch (WindowManager.BadTokenException e) {
-            // ignore
-            Slog.w(TAG, appToken + " already running, starting window not displayed. "
-                    + e.getMessage());
-            shouldSaveView = false;
-        } finally {
-            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-            if (view.getParent() == null) {
-                Slog.w(TAG, "view not successfully added to wm, removing view");
-                mWindowManagerGlobal.removeView(view, true /* immediate */);
-                shouldSaveView = false;
-            }
-        }
-        if (shouldSaveView) {
-            mStartingWindowRecordManager.removeWindow(taskId, true);
-            saveSplashScreenRecord(appToken, taskId, view, suggestType);
-        }
-        return shouldSaveView;
-    }
-
-    private void saveSplashScreenRecord(IBinder appToken, int taskId, View view,
-            @StartingWindowInfo.StartingWindowType int suggestType) {
-        final SplashWindowRecord tView =
-                new SplashWindowRecord(appToken, view, suggestType);
-        mStartingWindowRecordManager.addRecord(taskId, tView);
-    }
-
-    private void removeWindowInner(View decorView, boolean hideView) {
-        requestTopUi(false);
-        if (hideView) {
-            decorView.setVisibility(View.GONE);
-        }
-        mWindowManagerGlobal.removeView(decorView, false /* immediate */);
-    }
-
-    private static class SplashScreenViewSupplier implements Supplier<SplashScreenView> {
-        private SplashScreenView mView;
-        private boolean mIsViewSet;
-        private Runnable mUiThreadInitTask;
-        void setView(SplashScreenView view) {
-            synchronized (this) {
-                mView = view;
-                mIsViewSet = true;
-                notify();
-            }
-        }
-
-        void setUiThreadInitTask(Runnable initTask) {
-            synchronized (this) {
-                mUiThreadInitTask = initTask;
-            }
-        }
-
-        @Override
-        @Nullable
-        public SplashScreenView get() {
-            synchronized (this) {
-                while (!mIsViewSet) {
-                    try {
-                        wait();
-                    } catch (InterruptedException ignored) {
-                    }
-                }
-                if (mUiThreadInitTask != null) {
-                    mUiThreadInitTask.run();
-                    mUiThreadInitTask = null;
-                }
-                return mView;
-            }
-        }
-    }
-
-    private class SplashWindowRecord extends StartingSurfaceDrawer.StartingWindowRecord {
-        private final IBinder mAppToken;
-        private final View mRootView;
-        @StartingWindowInfo.StartingWindowType private final int mSuggestType;
-        private final long mCreateTime;
-
-        private boolean mSetSplashScreen;
-        private SplashScreenView mSplashView;
-        private int mSystemBarAppearance;
-        private boolean mDrawsSystemBarBackgrounds;
-
-        SplashWindowRecord(IBinder appToken, View decorView,
-                @StartingWindowInfo.StartingWindowType int suggestType) {
-            mAppToken = appToken;
-            mRootView = decorView;
-            mSuggestType = suggestType;
-            mCreateTime = SystemClock.uptimeMillis();
-        }
-
-        void setSplashScreenView(SplashScreenView splashScreenView) {
-            if (mSetSplashScreen) {
-                return;
-            }
-            mSplashView = splashScreenView;
-            mBGColor = mSplashView.getInitBackgroundColor();
-            mSetSplashScreen = true;
-        }
-
-        void parseAppSystemBarColor(Context context) {
-            final TypedArray a = context.obtainStyledAttributes(R.styleable.Window);
-            mDrawsSystemBarBackgrounds = a.getBoolean(
-                    R.styleable.Window_windowDrawsSystemBarBackgrounds, false);
-            if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
-                mSystemBarAppearance |= WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
-            }
-            if (a.getBoolean(R.styleable.Window_windowLightNavigationBar, false)) {
-                mSystemBarAppearance |= WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
-            }
-            a.recycle();
-        }
-
-        // Reset the system bar color which set by splash screen, make it align to the app.
-        void clearSystemBarColor() {
-            if (mRootView == null || !mRootView.isAttachedToWindow()) {
-                return;
-            }
-            if (mRootView.getLayoutParams() instanceof WindowManager.LayoutParams) {
-                final WindowManager.LayoutParams lp =
-                        (WindowManager.LayoutParams) mRootView.getLayoutParams();
-                if (mDrawsSystemBarBackgrounds) {
-                    lp.flags |= WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-                } else {
-                    lp.flags &= ~WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-                }
-                mRootView.setLayoutParams(lp);
-            }
-            mRootView.getWindowInsetsController().setSystemBarsAppearance(
-                    mSystemBarAppearance, LIGHT_BARS_MASK);
-        }
-
-        @Override
-        public void removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
-            if (mRootView != null) {
-                if (mSplashView != null) {
-                    clearSystemBarColor();
-                    if (immediately
-                            || mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
-                        removeWindowInner(mRootView, false);
-                    } else {
-                        if (info.playRevealAnimation) {
-                            mSplashscreenContentDrawer.applyExitAnimation(mSplashView,
-                                    info.windowAnimationLeash, info.mainFrame,
-                                    () -> removeWindowInner(mRootView, true),
-                                    mCreateTime, info.roundedCornerRadius);
-                        } else {
-                            // the SplashScreenView has been copied to client, hide the view to skip
-                            // default exit animation
-                            removeWindowInner(mRootView, true);
-                        }
-                    }
-                } else {
-                    // shouldn't happen
-                    Slog.e(TAG, "Found empty splash screen, remove!");
-                    removeWindowInner(mRootView, false);
-                }
-            }
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index ff06db3..4f07bfe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -16,80 +16,169 @@
 
 package com.android.wm.shell.startingsurface;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.view.Choreographer.CALLBACK_INSETS_ANIMATION;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
+import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
 
-import android.annotation.CallSuper;
+import android.annotation.Nullable;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityTaskManager;
+import android.app.ActivityThread;
 import android.app.TaskInfo;
-import android.app.WindowConfiguration;
 import android.content.Context;
-import android.content.res.Configuration;
+import android.content.pm.ActivityInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.res.TypedArray;
 import android.graphics.Color;
+import android.graphics.PixelFormat;
 import android.hardware.display.DisplayManager;
+import android.os.IBinder;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.util.Slog;
 import android.util.SparseArray;
-import android.view.IWindow;
-import android.view.SurfaceControl;
-import android.view.SurfaceSession;
+import android.view.Choreographer;
+import android.view.Display;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+import android.view.WindowInsetsController;
 import android.view.WindowManager;
-import android.view.WindowlessWindowManager;
+import android.view.WindowManagerGlobal;
+import android.widget.FrameLayout;
 import android.window.SplashScreenView;
+import android.window.SplashScreenView.SplashScreenViewParcelable;
 import android.window.StartingWindowInfo;
 import android.window.StartingWindowInfo.StartingWindowType;
 import android.window.StartingWindowRemovalInfo;
 import android.window.TaskSnapshot;
 
+import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.util.ContrastColorUtil;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
+import java.util.function.Supplier;
+
 /**
  * A class which able to draw splash screen or snapshot as the starting window for a task.
+ *
+ * In order to speed up, there will use two threads to creating a splash screen in parallel.
+ * Right now we are still using PhoneWindow to create splash screen window, so the view is added to
+ * the ViewRootImpl, and those view won't be draw immediately because the ViewRootImpl will call
+ * scheduleTraversal to register a callback from Choreographer, so the drawing result of the view
+ * can synchronize on each frame.
+ *
+ * The bad thing is that we cannot decide when would Choreographer#doFrame happen, and drawing
+ * the AdaptiveIconDrawable object can be time consuming, so we use the splash-screen background
+ * thread to draw the AdaptiveIconDrawable object to a Bitmap and cache it to a BitmapShader after
+ * the SplashScreenView just created, once we get the BitmapShader then the #draw call can be very
+ * quickly.
+ *
+ * So basically we are using the spare time to prepare the SplashScreenView while splash screen
+ * thread is waiting for
+ * 1. WindowManager#addView(binder call to WM),
+ * 2. Choreographer#doFrame happen(uncertain time for next frame, depends on device),
+ * 3. Session#relayout(another binder call to WM which under Choreographer#doFrame, but will
+ * always happen before #draw).
+ * Because above steps are running on splash-screen thread, so pre-draw the BitmapShader on
+ * splash-screen background tread can make they execute in parallel, which ensure it is faster then
+ * to draw the AdaptiveIconDrawable when receive callback from Choreographer#doFrame.
+ *
+ * Here is the sequence to compare the difference between using single and two thread.
+ *
+ * Single thread:
+ * => makeSplashScreenContentView -> WM#addView .. waiting for Choreographer#doFrame -> relayout
+ * -> draw -> AdaptiveIconDrawable#draw
+ *
+ * Two threads:
+ * => makeSplashScreenContentView -> cachePaint(=AdaptiveIconDrawable#draw)
+ * => WM#addView -> .. waiting for Choreographer#doFrame -> relayout -> draw -> (draw the Paint
+ * directly).
  */
 @ShellSplashscreenThread
 public class StartingSurfaceDrawer {
+    private static final String TAG = StartingWindowController.TAG;
 
+    private final Context mContext;
+    private final DisplayManager mDisplayManager;
     private final ShellExecutor mSplashScreenExecutor;
     @VisibleForTesting
     final SplashscreenContentDrawer mSplashscreenContentDrawer;
-    @VisibleForTesting
-    final SplashscreenWindowCreator mSplashscreenWindowCreator;
-    private final SnapshotWindowCreator mSnapshotWindowCreator;
-    private final WindowlessSplashWindowCreator mWindowlessSplashWindowCreator;
-    private final WindowlessSnapshotWindowCreator mWindowlessSnapshotWindowCreator;
+    private Choreographer mChoreographer;
+    private final WindowManagerGlobal mWindowManagerGlobal;
+    private StartingSurface.SysuiProxy mSysuiProxy;
+    private final StartingWindowRemovalInfo mTmpRemovalInfo = new StartingWindowRemovalInfo();
 
-    @VisibleForTesting
-    final StartingWindowRecordManager mWindowRecords = new StartingWindowRecordManager();
-    // Windowless surface could co-exist with starting window in a task.
-    @VisibleForTesting
-    final StartingWindowRecordManager mWindowlessRecords = new StartingWindowRecordManager();
+    private static final int LIGHT_BARS_MASK =
+            WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
+                    | WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
+    /**
+     * The minimum duration during which the splash screen is shown when the splash screen icon is
+     * animated.
+     */
+    static final long MINIMAL_ANIMATION_DURATION = 400L;
+
+    /**
+     * Allow the icon style splash screen to be displayed for longer to give time for the animation
+     * to finish, i.e. the extra buffer time to keep the splash screen if the animation is slightly
+     * longer than the {@link #MINIMAL_ANIMATION_DURATION} duration.
+     */
+    static final long TIME_WINDOW_DURATION = 100L;
+
+    /**
+     * The maximum duration during which the splash screen will be shown if the application is ready
+     * to show before the icon animation finishes.
+     */
+    static final long MAX_ANIMATION_DURATION = MINIMAL_ANIMATION_DURATION + TIME_WINDOW_DURATION;
+
     /**
      * @param splashScreenExecutor The thread used to control add and remove starting window.
      */
     public StartingSurfaceDrawer(Context context, ShellExecutor splashScreenExecutor,
             IconProvider iconProvider, TransactionPool pool) {
+        mContext = context;
+        mDisplayManager = mContext.getSystemService(DisplayManager.class);
         mSplashScreenExecutor = splashScreenExecutor;
-        final DisplayManager displayManager = context.getSystemService(DisplayManager.class);
-        mSplashscreenContentDrawer = new SplashscreenContentDrawer(context, iconProvider, pool);
-        displayManager.getDisplay(DEFAULT_DISPLAY);
+        mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, iconProvider, pool);
+        mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance());
+        mWindowManagerGlobal = WindowManagerGlobal.getInstance();
+        mDisplayManager.getDisplay(DEFAULT_DISPLAY);
+    }
 
-        mSplashscreenWindowCreator = new SplashscreenWindowCreator(mSplashscreenContentDrawer,
-                context, splashScreenExecutor, displayManager, mWindowRecords);
-        mSnapshotWindowCreator = new SnapshotWindowCreator(splashScreenExecutor,
-                mWindowRecords);
-        mWindowlessSplashWindowCreator = new WindowlessSplashWindowCreator(
-                mSplashscreenContentDrawer, context, splashScreenExecutor, displayManager,
-                mWindowlessRecords, pool);
-        mWindowlessSnapshotWindowCreator = new WindowlessSnapshotWindowCreator(
-                mWindowlessRecords, context, displayManager, mSplashscreenContentDrawer, pool);
+    @VisibleForTesting
+    final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>();
+
+    /**
+     * Records of {@link SurfaceControlViewHost} where the splash screen icon animation is
+     * rendered and that have not yet been removed by their client.
+     */
+    private final SparseArray<SurfaceControlViewHost> mAnimatedSplashScreenSurfaceHosts =
+            new SparseArray<>(1);
+
+    private Display getDisplay(int displayId) {
+        return mDisplayManager.getDisplay(displayId);
+    }
+
+    int getSplashScreenTheme(int splashScreenThemeResId, ActivityInfo activityInfo) {
+        return splashScreenThemeResId != 0
+                ? splashScreenThemeResId
+                : activityInfo.getThemeResource() != 0 ? activityInfo.getThemeResource()
+                        : com.android.internal.R.style.Theme_DeviceDefault_DayNight;
     }
 
     void setSysuiProxy(StartingSurface.SysuiProxy sysuiProxy) {
-        mSplashscreenWindowCreator.setSysuiProxy(sysuiProxy);
-        mWindowlessSplashWindowCreator.setSysuiProxy(sysuiProxy);
+        mSysuiProxy = sysuiProxy;
     }
 
     /**
@@ -97,55 +186,231 @@
      *
      * @param suggestType The suggestion type to draw the splash screen.
      */
-    void addSplashScreenStartingWindow(StartingWindowInfo windowInfo,
+    void addSplashScreenStartingWindow(StartingWindowInfo windowInfo, IBinder appToken,
             @StartingWindowType int suggestType) {
-        mSplashscreenWindowCreator.addSplashScreenStartingWindow(windowInfo, suggestType);
+        final RunningTaskInfo taskInfo = windowInfo.taskInfo;
+        final ActivityInfo activityInfo = windowInfo.targetActivityInfo != null
+                ? windowInfo.targetActivityInfo
+                : taskInfo.topActivityInfo;
+        if (activityInfo == null || activityInfo.packageName == null) {
+            return;
+        }
+        // replace with the default theme if the application didn't set
+        final int theme = getSplashScreenTheme(windowInfo.splashScreenThemeResId, activityInfo);
+        final Context context = SplashscreenContentDrawer.createContext(mContext, windowInfo, theme,
+                suggestType, mDisplayManager);
+        if (context == null) {
+            return;
+        }
+        final WindowManager.LayoutParams params = SplashscreenContentDrawer.createLayoutParameters(
+                context, windowInfo, suggestType, activityInfo.packageName,
+                suggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN
+                        ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT, appToken);
+
+        final int displayId = taskInfo.displayId;
+        final int taskId = taskInfo.taskId;
+        final Display display = getDisplay(displayId);
+
+        // TODO(b/173975965) tracking performance
+        // Prepare the splash screen content view on splash screen worker thread in parallel, so the
+        // content view won't be blocked by binder call like addWindow and relayout.
+        // 1. Trigger splash screen worker thread to create SplashScreenView before/while
+        // Session#addWindow.
+        // 2. Synchronize the SplashscreenView to splash screen thread before Choreographer start
+        // traversal, which will call Session#relayout on splash screen thread.
+        // 3. Pre-draw the BitmapShader if the icon is immobile on splash screen worker thread, at
+        // the same time the splash screen thread should be executing Session#relayout. Blocking the
+        // traversal -> draw on splash screen thread until the BitmapShader of the icon is ready.
+
+        // Record whether create splash screen view success, notify to current thread after
+        // create splash screen view finished.
+        final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier();
+        final FrameLayout rootLayout = new FrameLayout(
+                mSplashscreenContentDrawer.createViewContextWrapper(context));
+        rootLayout.setPadding(0, 0, 0, 0);
+        rootLayout.setFitsSystemWindows(false);
+        final Runnable setViewSynchronized = () -> {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addSplashScreenView");
+            // waiting for setContentView before relayoutWindow
+            SplashScreenView contentView = viewSupplier.get();
+            final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
+            // If record == null, either the starting window added fail or removed already.
+            // Do not add this view if the token is mismatch.
+            if (record != null && appToken == record.mAppToken) {
+                // if view == null then creation of content view was failed.
+                if (contentView != null) {
+                    try {
+                        rootLayout.addView(contentView);
+                    } catch (RuntimeException e) {
+                        Slog.w(TAG, "failed set content view to starting window "
+                                + "at taskId: " + taskId, e);
+                        contentView = null;
+                    }
+                }
+                record.setSplashScreenView(contentView);
+            }
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        };
+        if (mSysuiProxy != null) {
+            mSysuiProxy.requestTopUi(true, TAG);
+        }
+        mSplashscreenContentDrawer.createContentView(context, suggestType, windowInfo,
+                viewSupplier::setView, viewSupplier::setUiThreadInitTask);
+        try {
+            if (addWindow(taskId, appToken, rootLayout, display, params, suggestType)) {
+                // We use the splash screen worker thread to create SplashScreenView while adding
+                // the window, as otherwise Choreographer#doFrame might be delayed on this thread.
+                // And since Choreographer#doFrame won't happen immediately after adding the window,
+                // if the view is not added to the PhoneWindow on the first #doFrame, the view will
+                // not be rendered on the first frame. So here we need to synchronize the view on
+                // the window before first round relayoutWindow, which will happen after insets
+                // animation.
+                mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null);
+                final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
+                record.parseAppSystemBarColor(context);
+                // Block until we get the background color.
+                final SplashScreenView contentView = viewSupplier.get();
+                if (suggestType != STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
+                    contentView.addOnAttachStateChangeListener(
+                            new View.OnAttachStateChangeListener() {
+                                @Override
+                                public void onViewAttachedToWindow(View v) {
+                                    final int lightBarAppearance = ContrastColorUtil.isColorLight(
+                                            contentView.getInitBackgroundColor())
+                                            ? LIGHT_BARS_MASK : 0;
+                                    contentView.getWindowInsetsController().setSystemBarsAppearance(
+                                            lightBarAppearance, LIGHT_BARS_MASK);
+                                }
+
+                                @Override
+                                public void onViewDetachedFromWindow(View v) {
+                                }
+                            });
+                }
+                record.mBGColor = contentView.getInitBackgroundColor();
+            } else {
+                // release the icon view host
+                final SplashScreenView contentView = viewSupplier.get();
+                if (contentView.getSurfaceHost() != null) {
+                    SplashScreenView.releaseIconHost(contentView.getSurfaceHost());
+                }
+            }
+        } catch (RuntimeException e) {
+            // don't crash if something else bad happens, for example a
+            // failure loading resources because we are loading from an app
+            // on external storage that has been unmounted.
+            Slog.w(TAG, "failed creating starting window at taskId: " + taskId, e);
+        }
     }
 
     int getStartingWindowBackgroundColorForTask(int taskId) {
-        final StartingWindowRecord startingWindowRecord = mWindowRecords.getRecord(taskId);
+        final StartingWindowRecord startingWindowRecord = mStartingWindowRecords.get(taskId);
         if (startingWindowRecord == null) {
             return Color.TRANSPARENT;
         }
-        return startingWindowRecord.getBGColor();
+        return startingWindowRecord.mBGColor;
+    }
+
+    private static class SplashScreenViewSupplier implements Supplier<SplashScreenView> {
+        private SplashScreenView mView;
+        private boolean mIsViewSet;
+        private Runnable mUiThreadInitTask;
+        void setView(SplashScreenView view) {
+            synchronized (this) {
+                mView = view;
+                mIsViewSet = true;
+                notify();
+            }
+        }
+
+        void setUiThreadInitTask(Runnable initTask) {
+            synchronized (this) {
+                mUiThreadInitTask = initTask;
+            }
+        }
+
+        @Override
+        @Nullable
+        public SplashScreenView get() {
+            synchronized (this) {
+                while (!mIsViewSet) {
+                    try {
+                        wait();
+                    } catch (InterruptedException ignored) {
+                    }
+                }
+                if (mUiThreadInitTask != null) {
+                    mUiThreadInitTask.run();
+                    mUiThreadInitTask = null;
+                }
+                return mView;
+            }
+        }
     }
 
     int estimateTaskBackgroundColor(TaskInfo taskInfo) {
-        return mSplashscreenWindowCreator.estimateTaskBackgroundColor(taskInfo);
+        if (taskInfo.topActivityInfo == null) {
+            return Color.TRANSPARENT;
+        }
+        final ActivityInfo activityInfo = taskInfo.topActivityInfo;
+        final String packageName = activityInfo.packageName;
+        final int userId = taskInfo.userId;
+        final Context windowContext;
+        try {
+            windowContext = mContext.createPackageContextAsUser(
+                    packageName, Context.CONTEXT_RESTRICTED, UserHandle.of(userId));
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.w(TAG, "Failed creating package context with package name "
+                    + packageName + " for user " + taskInfo.userId, e);
+            return Color.TRANSPARENT;
+        }
+        try {
+            final IPackageManager packageManager = ActivityThread.getPackageManager();
+            final String splashScreenThemeName = packageManager.getSplashScreenTheme(packageName,
+                    userId);
+            final int splashScreenThemeId = splashScreenThemeName != null
+                    ? windowContext.getResources().getIdentifier(splashScreenThemeName, null, null)
+                    : 0;
+
+            final int theme = getSplashScreenTheme(splashScreenThemeId, activityInfo);
+
+            if (theme != windowContext.getThemeResId()) {
+                windowContext.setTheme(theme);
+            }
+            return mSplashscreenContentDrawer.estimateTaskBackgroundColor(windowContext);
+        } catch (RuntimeException | RemoteException e) {
+            Slog.w(TAG, "failed get starting window background color at taskId: "
+                    + taskInfo.taskId, e);
+        }
+        return Color.TRANSPARENT;
     }
 
     /**
      * Called when a task need a snapshot starting window.
      */
-    void makeTaskSnapshotWindow(StartingWindowInfo startingWindowInfo, TaskSnapshot snapshot) {
-        mSnapshotWindowCreator.makeTaskSnapshotWindow(startingWindowInfo, snapshot);
+    void makeTaskSnapshotWindow(StartingWindowInfo startingWindowInfo, IBinder appToken,
+            TaskSnapshot snapshot) {
+        final int taskId = startingWindowInfo.taskInfo.taskId;
+        // Remove any existing starting window for this task before adding.
+        removeWindowNoAnimate(taskId);
+        final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken,
+                snapshot, mSplashScreenExecutor, () -> removeWindowNoAnimate(taskId));
+        if (surface == null) {
+            return;
+        }
+        final StartingWindowRecord tView = new StartingWindowRecord(appToken,
+                null/* decorView */, surface, STARTING_WINDOW_TYPE_SNAPSHOT);
+        mStartingWindowRecords.put(taskId, tView);
     }
 
     /**
      * Called when the content of a task is ready to show, starting window can be removed.
      */
     public void removeStartingWindow(StartingWindowRemovalInfo removalInfo) {
-        if (removalInfo.windowlessSurface) {
-            mWindowlessRecords.removeWindow(removalInfo, removalInfo.removeImmediately);
-        } else {
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
-                    "Task start finish, remove starting surface for task: %d",
-                    removalInfo.taskId);
-            mWindowRecords.removeWindow(removalInfo, removalInfo.removeImmediately);
-        }
-    }
-
-    /**
-     * Create a windowless starting surface and attach to the root surface.
-     */
-    void addWindowlessStartingSurface(StartingWindowInfo windowInfo) {
-        if (windowInfo.taskSnapshot != null) {
-            mWindowlessSnapshotWindowCreator.makeTaskSnapshotWindow(windowInfo,
-                    windowInfo.rootSurface, windowInfo.taskSnapshot, mSplashScreenExecutor);
-        } else {
-            mWindowlessSplashWindowCreator.addSplashScreenStartingWindow(
-                    windowInfo, windowInfo.rootSurface);
-        }
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
+                "Task start finish, remove starting surface for task: %d",
+                removalInfo.taskId);
+        removeWindowSynced(removalInfo, false /* immediately */);
     }
 
     /**
@@ -154,15 +419,37 @@
     public void clearAllWindows() {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
                 "Clear all starting windows immediately");
-        mWindowRecords.clearAllWindows();
-        mWindowlessRecords.clearAllWindows();
+        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]);
+        }
     }
 
     /**
      * Called when the Task wants to copy the splash screen.
      */
     public void copySplashScreenView(int taskId) {
-        mSplashscreenWindowCreator.copySplashScreenView(taskId);
+        final StartingWindowRecord preView = mStartingWindowRecords.get(taskId);
+        SplashScreenViewParcelable parcelable;
+        SplashScreenView splashScreenView = preView != null ? preView.mContentView : null;
+        if (splashScreenView != null && splashScreenView.isCopyable()) {
+            parcelable = new SplashScreenViewParcelable(splashScreenView);
+            parcelable.setClientCallback(
+                    new RemoteCallback((bundle) -> mSplashScreenExecutor.execute(
+                            () -> onAppSplashScreenViewRemoved(taskId, false))));
+            splashScreenView.onCopied();
+            mAnimatedSplashScreenSurfaceHosts.append(taskId, splashScreenView.getSurfaceHost());
+        } else {
+            parcelable = null;
+        }
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
+                "Copying splash screen window view for task: %d with parcelable %b",
+                taskId, parcelable != null);
+        ActivityTaskManager.getInstance().onSplashScreenViewCopyFinished(taskId, parcelable);
     }
 
     /**
@@ -172,148 +459,195 @@
      * @param taskId The Task id on which the splash screen was attached
      */
     public void onAppSplashScreenViewRemoved(int taskId) {
-        mSplashscreenWindowCreator.onAppSplashScreenViewRemoved(taskId);
+        onAppSplashScreenViewRemoved(taskId, true /* fromServer */);
+    }
+
+    /**
+     * @param fromServer If true, this means the removal was notified by the server. This is only
+     *                   used for debugging purposes.
+     * @see #onAppSplashScreenViewRemoved(int)
+     */
+    private void onAppSplashScreenViewRemoved(int taskId, boolean fromServer) {
+        SurfaceControlViewHost viewHost =
+                mAnimatedSplashScreenSurfaceHosts.get(taskId);
+        if (viewHost == null) {
+            return;
+        }
+        mAnimatedSplashScreenSurfaceHosts.remove(taskId);
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
+                "%s the splash screen. Releasing SurfaceControlViewHost for task: %d",
+                fromServer ? "Server cleaned up" : "App removed", taskId);
+        SplashScreenView.releaseIconHost(viewHost);
+    }
+
+    protected boolean addWindow(int taskId, IBinder appToken, View view, Display display,
+            WindowManager.LayoutParams params, @StartingWindowType int suggestType) {
+        boolean shouldSaveView = true;
+        final Context context = view.getContext();
+        try {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addRootView");
+            mWindowManagerGlobal.addView(view, params, display,
+                    null /* parentWindow */, context.getUserId());
+        } catch (WindowManager.BadTokenException e) {
+            // ignore
+            Slog.w(TAG, appToken + " already running, starting window not displayed. "
+                    + e.getMessage());
+            shouldSaveView = false;
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+            if (view.getParent() == null) {
+                Slog.w(TAG, "view not successfully added to wm, removing view");
+                mWindowManagerGlobal.removeView(view, true /* immediate */);
+                shouldSaveView = false;
+            }
+        }
+        if (shouldSaveView) {
+            removeWindowNoAnimate(taskId);
+            saveSplashScreenRecord(appToken, taskId, view, suggestType);
+        }
+        return shouldSaveView;
+    }
+
+    @VisibleForTesting
+    void saveSplashScreenRecord(IBinder appToken, int taskId, View view,
+            @StartingWindowType int suggestType) {
+        final StartingWindowRecord tView = new StartingWindowRecord(appToken, view,
+                null/* TaskSnapshotWindow */, suggestType);
+        mStartingWindowRecords.put(taskId, tView);
+    }
+
+    private void removeWindowNoAnimate(int taskId) {
+        mTmpRemovalInfo.taskId = taskId;
+        removeWindowSynced(mTmpRemovalInfo, true /* immediately */);
     }
 
     void onImeDrawnOnTask(int taskId) {
-        onImeDrawnOnTask(mWindowRecords, taskId);
-        onImeDrawnOnTask(mWindowlessRecords, taskId);
-    }
-
-    private void onImeDrawnOnTask(StartingWindowRecordManager records, int taskId) {
-        final StartingSurfaceDrawer.StartingWindowRecord sRecord =
-                records.getRecord(taskId);
-        final SnapshotRecord record = sRecord instanceof SnapshotRecord
-                ? (SnapshotRecord) sRecord : null;
-        if (record != null && record.hasImeSurface()) {
-            records.removeWindow(taskId, true);
+        final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
+        if (record != null && record.mTaskSnapshotWindow != null
+                && record.mTaskSnapshotWindow.hasImeSurface()) {
+            removeWindowNoAnimate(taskId);
         }
     }
 
-    static class WindowlessStartingWindow extends WindowlessWindowManager {
-        SurfaceControl mChildSurface;
+    protected void removeWindowSynced(StartingWindowRemovalInfo removalInfo, boolean immediately) {
+        final int taskId = removalInfo.taskId;
+        final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
+        if (record != null) {
+            if (record.mDecorView != null) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
+                        "Removing splash screen window for task: %d", taskId);
+                if (record.mContentView != null) {
+                    record.clearSystemBarColor();
+                    if (immediately
+                            || record.mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
+                        removeWindowInner(record.mDecorView, false);
+                    } else {
+                        if (removalInfo.playRevealAnimation) {
+                            mSplashscreenContentDrawer.applyExitAnimation(record.mContentView,
+                                    removalInfo.windowAnimationLeash, removalInfo.mainFrame,
+                                    () -> removeWindowInner(record.mDecorView, true),
+                                    record.mCreateTime, removalInfo.roundedCornerRadius);
+                        } else {
+                            // the SplashScreenView has been copied to client, hide the view to skip
+                            // default exit animation
+                            removeWindowInner(record.mDecorView, true);
+                        }
+                    }
+                } else {
+                    // shouldn't happen
+                    Slog.e(TAG, "Found empty splash screen, remove!");
+                    removeWindowInner(record.mDecorView, false);
+                }
 
-        WindowlessStartingWindow(Configuration c, SurfaceControl rootSurface) {
-            super(c, rootSurface, null /* hostInputToken */);
-        }
-
-        @Override
-        protected SurfaceControl getParentSurface(IWindow window,
-                WindowManager.LayoutParams attrs) {
-            final SurfaceControl.Builder builder = new SurfaceControl.Builder(new SurfaceSession())
-                    .setContainerLayer()
-                    .setName("Windowless window")
-                    .setHidden(false)
-                    .setParent(mRootSurface)
-                    .setCallsite("WindowlessStartingWindow#attachToParentSurface");
-            mChildSurface = builder.build();
-            try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) {
-                t.setLayer(mChildSurface, Integer.MAX_VALUE);
-                t.apply();
             }
-            return mChildSurface;
-        }
-    }
-    abstract static class StartingWindowRecord {
-        protected int mBGColor;
-        abstract void removeIfPossible(StartingWindowRemovalInfo info, boolean immediately);
-        int getBGColor() {
-            return mBGColor;
-        }
-    }
-
-    abstract static class SnapshotRecord extends StartingWindowRecord {
-        private static final long DELAY_REMOVAL_TIME_GENERAL = 100;
-        /**
-         * The max delay time in milliseconds for removing the task snapshot window with IME
-         * visible.
-         * Ideally the delay time will be shorter when receiving
-         * {@link StartingSurfaceDrawer#onImeDrawnOnTask(int)}.
-         */
-        private static final long MAX_DELAY_REMOVAL_TIME_IME_VISIBLE = 600;
-        private final Runnable mScheduledRunnable = this::removeImmediately;
-
-        @WindowConfiguration.ActivityType protected final int mActivityType;
-        protected final ShellExecutor mRemoveExecutor;
-
-        SnapshotRecord(int activityType, ShellExecutor removeExecutor) {
-            mActivityType = activityType;
-            mRemoveExecutor = removeExecutor;
-        }
-
-        @Override
-        public final void removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
-            if (immediately) {
-                removeImmediately();
-            } else {
-                scheduleRemove(info.deferRemoveForIme);
+            if (record.mTaskSnapshotWindow != null) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
+                        "Removing task snapshot window for %d", taskId);
+                if (immediately) {
+                    record.mTaskSnapshotWindow.removeImmediately();
+                } else {
+                    record.mTaskSnapshotWindow.scheduleRemove(removalInfo.deferRemoveForIme);
+                }
             }
+            mStartingWindowRecords.remove(taskId);
+        }
+    }
+
+    private void removeWindowInner(View decorView, boolean hideView) {
+        if (mSysuiProxy != null) {
+            mSysuiProxy.requestTopUi(false, TAG);
+        }
+        if (hideView) {
+            decorView.setVisibility(View.GONE);
+        }
+        mWindowManagerGlobal.removeView(decorView, false /* immediate */);
+    }
+
+    /**
+     * Record the view or surface for a starting window.
+     */
+    private static class StartingWindowRecord {
+        private final IBinder mAppToken;
+        private final View mDecorView;
+        private final TaskSnapshotWindow mTaskSnapshotWindow;
+        private SplashScreenView mContentView;
+        private boolean mSetSplashScreen;
+        @StartingWindowType private int mSuggestType;
+        private int mBGColor;
+        private final long mCreateTime;
+        private int mSystemBarAppearance;
+        private boolean mDrawsSystemBarBackgrounds;
+
+        StartingWindowRecord(IBinder appToken, View decorView,
+                TaskSnapshotWindow taskSnapshotWindow, @StartingWindowType int suggestType) {
+            mAppToken = appToken;
+            mDecorView = decorView;
+            mTaskSnapshotWindow = taskSnapshotWindow;
+            if (mTaskSnapshotWindow != null) {
+                mBGColor = mTaskSnapshotWindow.getBackgroundColor();
+            }
+            mSuggestType = suggestType;
+            mCreateTime = SystemClock.uptimeMillis();
         }
 
-        void scheduleRemove(boolean deferRemoveForIme) {
-            // Show the latest content as soon as possible for unlocking to home.
-            if (mActivityType == ACTIVITY_TYPE_HOME) {
-                removeImmediately();
+        private void setSplashScreenView(SplashScreenView splashScreenView) {
+            if (mSetSplashScreen) {
                 return;
             }
-            mRemoveExecutor.removeCallbacks(mScheduledRunnable);
-            final long delayRemovalTime = hasImeSurface() && deferRemoveForIme
-                    ? MAX_DELAY_REMOVAL_TIME_IME_VISIBLE
-                    : DELAY_REMOVAL_TIME_GENERAL;
-            mRemoveExecutor.executeDelayed(mScheduledRunnable, delayRemovalTime);
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
-                    "Defer removing snapshot surface in %d", delayRemovalTime);
+            mContentView = splashScreenView;
+            mSetSplashScreen = true;
         }
 
-        protected abstract boolean hasImeSurface();
-
-        @CallSuper
-        protected void removeImmediately() {
-            mRemoveExecutor.removeCallbacks(mScheduledRunnable);
-        }
-    }
-
-    static class StartingWindowRecordManager {
-        private final StartingWindowRemovalInfo mTmpRemovalInfo = new StartingWindowRemovalInfo();
-        private final SparseArray<StartingWindowRecord> mStartingWindowRecords =
-                new SparseArray<>();
-
-        void clearAllWindows() {
-            final int taskSize = mStartingWindowRecords.size();
-            final int[] taskIds = new int[taskSize];
-            for (int i = taskSize - 1; i >= 0; --i) {
-                taskIds[i] = mStartingWindowRecords.keyAt(i);
+        private void parseAppSystemBarColor(Context context) {
+            final TypedArray a = context.obtainStyledAttributes(R.styleable.Window);
+            mDrawsSystemBarBackgrounds = a.getBoolean(
+                    R.styleable.Window_windowDrawsSystemBarBackgrounds, false);
+            if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
+                mSystemBarAppearance |= WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
             }
-            for (int i = taskSize - 1; i >= 0; --i) {
-                removeWindow(taskIds[i], true);
+            if (a.getBoolean(R.styleable.Window_windowLightNavigationBar, false)) {
+                mSystemBarAppearance |= WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
             }
+            a.recycle();
         }
 
-        void addRecord(int taskId, StartingWindowRecord record) {
-            mStartingWindowRecords.put(taskId, record);
-        }
-
-        void removeWindow(StartingWindowRemovalInfo removeInfo, boolean immediately) {
-            final int taskId = removeInfo.taskId;
-            final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
-            if (record != null) {
-                record.removeIfPossible(removeInfo, immediately);
-                mStartingWindowRecords.remove(taskId);
+        // Reset the system bar color which set by splash screen, make it align to the app.
+        private void clearSystemBarColor() {
+            if (mDecorView == null || !mDecorView.isAttachedToWindow()) {
+                return;
             }
-        }
-
-        void removeWindow(int taskId, boolean immediately) {
-            mTmpRemovalInfo.taskId = taskId;
-            removeWindow(mTmpRemovalInfo, immediately);
-        }
-
-        StartingWindowRecord getRecord(int taskId) {
-            return mStartingWindowRecords.get(taskId);
-        }
-
-        @VisibleForTesting
-        int recordSize() {
-            return mStartingWindowRecords.size();
+            if (mDecorView.getLayoutParams() instanceof WindowManager.LayoutParams) {
+                final WindowManager.LayoutParams lp =
+                        (WindowManager.LayoutParams) mDecorView.getLayoutParams();
+                if (mDrawsSystemBarBackgrounds) {
+                    lp.flags |= WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+                } else {
+                    lp.flags &= ~WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+                }
+                mDecorView.setLayoutParams(lp);
+            }
+            mDecorView.getWindowInsetsController().setSystemBarsAppearance(
+                    mSystemBarAppearance, LIGHT_BARS_MASK);
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
index bec4ba3..be2e793 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
@@ -21,7 +21,6 @@
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
-import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_WINDOWLESS;
 
 import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_STARTING_WINDOW;
@@ -30,6 +29,7 @@
 import android.app.TaskInfo;
 import android.content.Context;
 import android.graphics.Color;
+import android.os.IBinder;
 import android.os.Trace;
 import android.util.SparseIntArray;
 import android.window.StartingWindowInfo;
@@ -152,23 +152,22 @@
     /**
      * Called when a task need a starting window.
      */
-    public void addStartingWindow(StartingWindowInfo windowInfo) {
+    public void addStartingWindow(StartingWindowInfo windowInfo, IBinder appToken) {
         mSplashScreenExecutor.execute(() -> {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addStartingWindow");
 
             final int suggestionType = mStartingWindowTypeAlgorithm.getSuggestedWindowType(
                     windowInfo);
             final RunningTaskInfo runningTaskInfo = windowInfo.taskInfo;
-            if (suggestionType == STARTING_WINDOW_TYPE_WINDOWLESS) {
-                mStartingSurfaceDrawer.addWindowlessStartingSurface(windowInfo);
-            } else if (isSplashScreenType(suggestionType)) {
-                mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, suggestionType);
+            if (isSplashScreenType(suggestionType)) {
+                mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, appToken,
+                        suggestionType);
             } else if (suggestionType == STARTING_WINDOW_TYPE_SNAPSHOT) {
                 final TaskSnapshot snapshot = windowInfo.taskSnapshot;
-                mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, snapshot);
+                mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, appToken,
+                        snapshot);
             }
-            if (suggestionType != STARTING_WINDOW_TYPE_NONE
-                    && suggestionType != STARTING_WINDOW_TYPE_WINDOWLESS) {
+            if (suggestionType != STARTING_WINDOW_TYPE_NONE) {
                 int taskId = runningTaskInfo.taskId;
                 int color = mStartingSurfaceDrawer
                         .getStartingWindowBackgroundColorForTask(taskId);
@@ -219,13 +218,11 @@
     public void removeStartingWindow(StartingWindowRemovalInfo removalInfo) {
         mSplashScreenExecutor.execute(() -> mStartingSurfaceDrawer.removeStartingWindow(
                 removalInfo));
-        if (!removalInfo.windowlessSurface) {
-            mSplashScreenExecutor.executeDelayed(() -> {
-                synchronized (mTaskBackgroundColors) {
-                    mTaskBackgroundColors.delete(removalInfo.taskId);
-                }
-            }, TASK_BG_COLOR_RETAIN_TIME_MS);
-        }
+        mSplashScreenExecutor.executeDelayed(() -> {
+            synchronized (mTaskBackgroundColors) {
+                mTaskBackgroundColors.delete(removalInfo.taskId);
+            }
+        }, TASK_BG_COLOR_RETAIN_TIME_MS);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
index c964df1..a05ed4f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.startingsurface;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.graphics.Color.WHITE;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -62,14 +63,24 @@
     private static final String TAG = StartingWindowController.TAG;
     private static final String TITLE_FORMAT = "SnapshotStartingWindow for taskId=";
 
+    private static final long DELAY_REMOVAL_TIME_GENERAL = 100;
+    /**
+     * The max delay time in milliseconds for removing the task snapshot window with IME visible.
+     * Ideally the delay time will be shorter when receiving
+     * {@link StartingSurfaceDrawer#onImeDrawnOnTask(int)}.
+     */
+    private static final long MAX_DELAY_REMOVAL_TIME_IME_VISIBLE = 600;
+
     private final Window mWindow;
     private final Runnable mClearWindowHandler;
     private final ShellExecutor mSplashScreenExecutor;
     private final IWindowSession mSession;
     private boolean mHasDrawn;
     private final Paint mBackgroundPaint = new Paint();
+    private final int mActivityType;
     private final int mOrientationOnCreation;
 
+    private final Runnable mScheduledRunnable = this::removeImmediately;
     private final boolean mHasImeSurface;
 
     static TaskSnapshotWindow create(StartingWindowInfo info, IBinder appToken,
@@ -93,6 +104,7 @@
         final Point taskSize = snapshot.getTaskSize();
         final Rect taskBounds = new Rect(0, 0, taskSize.x, taskSize.y);
         final int orientation = snapshot.getOrientation();
+        final int activityType = runningTaskInfo.topActivityType;
         final int displayId = runningTaskInfo.displayId;
 
         final IWindowSession session = WindowManagerGlobal.getWindowSession();
@@ -102,11 +114,16 @@
         final InsetsSourceControl.Array tmpControls = new InsetsSourceControl.Array();
         final MergedConfiguration tmpMergedConfiguration = new MergedConfiguration();
 
-        final TaskDescription taskDescription =
-                SnapshotDrawerUtils.getOrCreateTaskDescription(runningTaskInfo);
+        final TaskDescription taskDescription;
+        if (runningTaskInfo.taskDescription != null) {
+            taskDescription = runningTaskInfo.taskDescription;
+        } else {
+            taskDescription = new TaskDescription();
+            taskDescription.setBackgroundColor(WHITE);
+        }
 
         final TaskSnapshotWindow snapshotSurface = new TaskSnapshotWindow(
-                snapshot, taskDescription, orientation,
+                snapshot, taskDescription, orientation, activityType,
                 clearWindowHandler, splashScreenExecutor);
         final Window window = snapshotSurface.mWindow;
 
@@ -136,8 +153,6 @@
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         } catch (RemoteException e) {
             snapshotSurface.clearWindowSynced();
-            Slog.w(TAG, "Failed to relayout snapshot starting window");
-            return null;
         }
 
         SnapshotDrawerUtils.drawSnapshotOnSurface(info, layoutParams, surfaceControl, snapshot,
@@ -149,7 +164,7 @@
     }
 
     public TaskSnapshotWindow(TaskSnapshot snapshot, TaskDescription taskDescription,
-            int currentOrientation, Runnable clearWindowHandler,
+            int currentOrientation, int activityType, Runnable clearWindowHandler,
             ShellExecutor splashScreenExecutor) {
         mSplashScreenExecutor = splashScreenExecutor;
         mSession = WindowManagerGlobal.getWindowSession();
@@ -158,6 +173,7 @@
         int backgroundColor = taskDescription.getBackgroundColor();
         mBackgroundPaint.setColor(backgroundColor != 0 ? backgroundColor : WHITE);
         mOrientationOnCreation = currentOrientation;
+        mActivityType = activityType;
         mClearWindowHandler = clearWindowHandler;
         mHasImeSurface = snapshot.hasImeSurface();
     }
@@ -170,7 +186,23 @@
 	return mHasImeSurface;
     }
 
+    void scheduleRemove(boolean deferRemoveForIme) {
+        // Show the latest content as soon as possible for unlocking to home.
+        if (mActivityType == ACTIVITY_TYPE_HOME) {
+            removeImmediately();
+            return;
+        }
+        mSplashScreenExecutor.removeCallbacks(mScheduledRunnable);
+        final long delayRemovalTime = mHasImeSurface && deferRemoveForIme
+                ? MAX_DELAY_REMOVAL_TIME_IME_VISIBLE
+                : DELAY_REMOVAL_TIME_GENERAL;
+        mSplashScreenExecutor.executeDelayed(mScheduledRunnable, delayRemovalTime);
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
+                "Defer removing snapshot surface in %d", delayRemovalTime);
+    }
+
     void removeImmediately() {
+        mSplashScreenExecutor.removeCallbacks(mScheduledRunnable);
         try {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
                     "Removing taskSnapshot surface, mHasDrawn=%b", mHasDrawn);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java
deleted file mode 100644
index 1445478..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.startingsurface;
-
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.hardware.display.DisplayManager;
-import android.view.Display;
-import android.view.InsetsState;
-import android.view.SurfaceControl;
-import android.view.SurfaceControlViewHost;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.window.SnapshotDrawerUtils;
-import android.window.StartingWindowInfo;
-import android.window.TaskSnapshot;
-
-import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.TransactionPool;
-
-class WindowlessSnapshotWindowCreator {
-    private static final int DEFAULT_FADEOUT_DURATION = 233;
-    private final StartingSurfaceDrawer.StartingWindowRecordManager
-            mStartingWindowRecordManager;
-    private final DisplayManager mDisplayManager;
-    private final Context mContext;
-    private final SplashscreenContentDrawer mSplashscreenContentDrawer;
-    private final TransactionPool mTransactionPool;
-
-    WindowlessSnapshotWindowCreator(
-            StartingSurfaceDrawer.StartingWindowRecordManager startingWindowRecordManager,
-            Context context,
-            DisplayManager displayManager, SplashscreenContentDrawer splashscreenContentDrawer,
-            TransactionPool transactionPool) {
-        mStartingWindowRecordManager = startingWindowRecordManager;
-        mContext = context;
-        mDisplayManager = displayManager;
-        mSplashscreenContentDrawer = splashscreenContentDrawer;
-        mTransactionPool = transactionPool;
-    }
-
-    void makeTaskSnapshotWindow(StartingWindowInfo info, SurfaceControl rootSurface,
-            TaskSnapshot snapshot, ShellExecutor removeExecutor) {
-        final ActivityManager.RunningTaskInfo runningTaskInfo = info.taskInfo;
-        final int taskId = runningTaskInfo.taskId;
-        final String title = "Windowless Snapshot " + taskId;
-        final WindowManager.LayoutParams lp = SnapshotDrawerUtils.createLayoutParameters(
-                info, title, TYPE_APPLICATION_OVERLAY, snapshot.getHardwareBuffer().getFormat(),
-                null /* token */);
-        if (lp == null) {
-            return;
-        }
-        final Display display = mDisplayManager.getDisplay(runningTaskInfo.displayId);
-        final StartingSurfaceDrawer.WindowlessStartingWindow wlw =
-                new StartingSurfaceDrawer.WindowlessStartingWindow(
-                runningTaskInfo.configuration, rootSurface);
-        final SurfaceControlViewHost mViewHost = new SurfaceControlViewHost(
-                mContext, display, wlw, "WindowlessSnapshotWindowCreator");
-        final Point taskSize = snapshot.getTaskSize();
-        final Rect snapshotBounds = new Rect(0, 0, taskSize.x, taskSize.y);
-        final Rect windowBounds = runningTaskInfo.configuration.windowConfiguration.getBounds();
-        final InsetsState topWindowInsetsState = info.topOpaqueWindowInsetsState;
-        final FrameLayout rootLayout = new FrameLayout(
-                mSplashscreenContentDrawer.createViewContextWrapper(mContext));
-        mViewHost.setView(rootLayout, lp);
-        SnapshotDrawerUtils.drawSnapshotOnSurface(info, lp, wlw.mChildSurface, snapshot,
-                snapshotBounds, windowBounds, topWindowInsetsState, false /* releaseAfterDraw */);
-
-        final ActivityManager.TaskDescription taskDescription =
-                SnapshotDrawerUtils.getOrCreateTaskDescription(runningTaskInfo);
-
-        final SnapshotWindowRecord record = new SnapshotWindowRecord(mViewHost, wlw.mChildSurface,
-                taskDescription.getBackgroundColor(), snapshot.hasImeSurface(),
-                runningTaskInfo.topActivityType, removeExecutor);
-        mStartingWindowRecordManager.addRecord(taskId, record);
-        info.notifyAddComplete(wlw.mChildSurface);
-    }
-
-    private class SnapshotWindowRecord extends StartingSurfaceDrawer.SnapshotRecord {
-        private SurfaceControlViewHost mViewHost;
-        private SurfaceControl mChildSurface;
-        private final boolean mHasImeSurface;
-
-        SnapshotWindowRecord(SurfaceControlViewHost viewHost, SurfaceControl childSurface,
-                int bgColor, boolean hasImeSurface, int activityType,
-                ShellExecutor removeExecutor) {
-            super(activityType, removeExecutor);
-            mViewHost = viewHost;
-            mChildSurface = childSurface;
-            mBGColor = bgColor;
-            mHasImeSurface = hasImeSurface;
-        }
-
-        @Override
-        protected void removeImmediately() {
-            super.removeImmediately();
-            fadeoutThenRelease();
-        }
-
-        void fadeoutThenRelease() {
-            final ValueAnimator fadeOutAnimator = ValueAnimator.ofFloat(1f, 0f);
-            fadeOutAnimator.setDuration(DEFAULT_FADEOUT_DURATION);
-            final SurfaceControl.Transaction t = mTransactionPool.acquire();
-            fadeOutAnimator.addUpdateListener(animation -> {
-                if (mChildSurface == null || !mChildSurface.isValid()) {
-                    fadeOutAnimator.cancel();
-                    return;
-                }
-                t.setAlpha(mChildSurface, (float) animation.getAnimatedValue());
-                t.apply();
-            });
-
-            fadeOutAnimator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    if (mChildSurface == null || !mChildSurface.isValid()) {
-                        fadeOutAnimator.cancel();
-                    }
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mTransactionPool.release(t);
-                    if (mChildSurface != null) {
-                        final SurfaceControl.Transaction t = mTransactionPool.acquire();
-                        t.remove(mChildSurface).apply();
-                        mTransactionPool.release(t);
-                        mChildSurface = null;
-                    }
-                    if (mViewHost != null) {
-                        mViewHost.release();
-                        mViewHost = null;
-                    }
-                }
-            });
-            fadeOutAnimator.start();
-        }
-
-        @Override
-        protected boolean hasImeSurface() {
-            return mHasImeSurface;
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java
deleted file mode 100644
index 12a0d40..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.startingsurface;
-
-import static android.graphics.Color.WHITE;
-import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.hardware.display.DisplayManager;
-import android.os.Binder;
-import android.os.SystemClock;
-import android.view.Display;
-import android.view.SurfaceControl;
-import android.view.SurfaceControlViewHost;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.window.SplashScreenView;
-import android.window.StartingWindowInfo;
-import android.window.StartingWindowRemovalInfo;
-
-import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.TransactionPool;
-
-class WindowlessSplashWindowCreator extends AbsSplashWindowCreator {
-
-    private final TransactionPool mTransactionPool;
-
-    WindowlessSplashWindowCreator(SplashscreenContentDrawer contentDrawer,
-            Context context,
-            ShellExecutor splashScreenExecutor,
-            DisplayManager displayManager,
-            StartingSurfaceDrawer.StartingWindowRecordManager startingWindowRecordManager,
-            TransactionPool pool) {
-        super(contentDrawer, context, splashScreenExecutor, displayManager,
-                startingWindowRecordManager);
-        mTransactionPool = pool;
-    }
-
-    void addSplashScreenStartingWindow(StartingWindowInfo windowInfo, SurfaceControl rootSurface) {
-        final ActivityManager.RunningTaskInfo taskInfo = windowInfo.taskInfo;
-        final ActivityInfo activityInfo = windowInfo.targetActivityInfo != null
-                ? windowInfo.targetActivityInfo
-                : taskInfo.topActivityInfo;
-        if (activityInfo == null || activityInfo.packageName == null) {
-            return;
-        }
-
-        final int displayId = taskInfo.displayId;
-        final Display display = mDisplayManager.getDisplay(displayId);
-        if (display == null) {
-            // Can't show splash screen on requested display, so skip showing at all.
-            return;
-        }
-        final Context myContext = SplashscreenContentDrawer.createContext(mContext, windowInfo,
-                0 /* theme */, STARTING_WINDOW_TYPE_SPLASH_SCREEN, mDisplayManager);
-        if (myContext == null) {
-            return;
-        }
-        final StartingSurfaceDrawer.WindowlessStartingWindow wlw =
-                new StartingSurfaceDrawer.WindowlessStartingWindow(
-                        taskInfo.configuration, rootSurface);
-        final SurfaceControlViewHost viewHost = new SurfaceControlViewHost(
-                myContext, display, wlw, "WindowlessSplashWindowCreator");
-        final String title = "Windowless Splash " + taskInfo.taskId;
-        final WindowManager.LayoutParams lp = SplashscreenContentDrawer.createLayoutParameters(
-                myContext, windowInfo, STARTING_WINDOW_TYPE_SPLASH_SCREEN, title,
-                PixelFormat.TRANSLUCENT, new Binder());
-        final Rect windowBounds = taskInfo.configuration.windowConfiguration.getBounds();
-        lp.width = windowBounds.width();
-        lp.height = windowBounds.height();
-        final ActivityManager.TaskDescription taskDescription;
-        if (taskInfo.taskDescription != null) {
-            taskDescription = taskInfo.taskDescription;
-        } else {
-            taskDescription = new ActivityManager.TaskDescription();
-            taskDescription.setBackgroundColor(WHITE);
-        }
-
-        final FrameLayout rootLayout = new FrameLayout(
-                mSplashscreenContentDrawer.createViewContextWrapper(mContext));
-        viewHost.setView(rootLayout, lp);
-
-        final int bgColor = taskDescription.getBackgroundColor();
-        final SplashScreenView splashScreenView = mSplashscreenContentDrawer
-                .makeSimpleSplashScreenContentView(myContext, windowInfo, bgColor);
-        rootLayout.addView(splashScreenView);
-        final SplashWindowRecord record = new SplashWindowRecord(viewHost, splashScreenView,
-                wlw.mChildSurface, bgColor);
-        mStartingWindowRecordManager.addRecord(taskInfo.taskId, record);
-        windowInfo.notifyAddComplete(wlw.mChildSurface);
-    }
-
-    private class SplashWindowRecord extends StartingSurfaceDrawer.StartingWindowRecord {
-        private SurfaceControlViewHost mViewHost;
-        private final long mCreateTime;
-        private SurfaceControl mChildSurface;
-        private final SplashScreenView mSplashView;
-
-        SplashWindowRecord(SurfaceControlViewHost viewHost, SplashScreenView splashView,
-                SurfaceControl childSurface, int bgColor) {
-            mViewHost = viewHost;
-            mSplashView = splashView;
-            mChildSurface = childSurface;
-            mBGColor = bgColor;
-            mCreateTime = SystemClock.uptimeMillis();
-        }
-
-        @Override
-        public void removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
-            if (!immediately) {
-                mSplashscreenContentDrawer.applyExitAnimation(mSplashView,
-                        info.windowAnimationLeash, info.mainFrame,
-                        this::release, mCreateTime, 0 /* roundedCornerRadius */);
-            } else {
-                release();
-            }
-        }
-
-        void release() {
-            if (mChildSurface != null) {
-                final SurfaceControl.Transaction t = mTransactionPool.acquire();
-                t.remove(mChildSurface).apply();
-                mTransactionPool.release(t);
-                mChildSurface = null;
-            }
-            if (mViewHost != null) {
-                mViewHost.release();
-                mViewHost = null;
-            }
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
index 72fc8686..bb43d7c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
@@ -22,7 +22,6 @@
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
-import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_WINDOWLESS;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_DRAWN;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT;
@@ -31,7 +30,6 @@
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN;
-import static android.window.StartingWindowInfo.TYPE_PARAMETER_WINDOWLESS;
 
 import android.window.StartingWindowInfo;
 
@@ -57,7 +55,6 @@
         final boolean legacySplashScreen =
                 ((parameter & TYPE_PARAMETER_LEGACY_SPLASH_SCREEN) != 0);
         final boolean activityDrawn = (parameter & TYPE_PARAMETER_ACTIVITY_DRAWN) != 0;
-        final boolean windowlessSurface = (parameter & TYPE_PARAMETER_WINDOWLESS) != 0;
         final boolean topIsHome = windowInfo.taskInfo.topActivityType == ACTIVITY_TYPE_HOME;
 
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
@@ -70,15 +67,10 @@
                         + "isSolidColorSplashScreen=%b, "
                         + "legacySplashScreen=%b, "
                         + "activityDrawn=%b, "
-                        + "windowless=%b, "
                         + "topIsHome=%b",
                 newTask, taskSwitch, processRunning, allowTaskSnapshot, activityCreated,
-                isSolidColorSplashScreen, legacySplashScreen, activityDrawn, windowlessSurface,
-                topIsHome);
+                isSolidColorSplashScreen, legacySplashScreen, activityDrawn, topIsHome);
 
-        if (windowlessSurface) {
-            return STARTING_WINDOW_TYPE_WINDOWLESS;
-        }
         if (!topIsHome) {
             if (!processRunning || newTask || (taskSwitch && !activityCreated)) {
                 return getSplashscreenType(isSolidColorSplashScreen, legacySplashScreen);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index bf62acf..11fda8b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -24,8 +24,8 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.wm.shell.startingsurface.SplashscreenContentDrawer.MAX_ANIMATION_DURATION;
-import static com.android.wm.shell.startingsurface.SplashscreenContentDrawer.MINIMAL_ANIMATION_DURATION;
+import static com.android.wm.shell.startingsurface.StartingSurfaceDrawer.MAX_ANIMATION_DURATION;
+import static com.android.wm.shell.startingsurface.StartingSurfaceDrawer.MINIMAL_ANIMATION_DURATION;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
@@ -56,9 +56,11 @@
 import android.os.Looper;
 import android.os.UserHandle;
 import android.testing.TestableContext;
+import android.view.Display;
 import android.view.IWindowSession;
 import android.view.InsetsState;
 import android.view.Surface;
+import android.view.View;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.WindowMetrics;
@@ -104,7 +106,36 @@
     private ShellExecutor mTestExecutor;
     private final TestableContext mTestContext = new TestContext(
             InstrumentationRegistry.getInstrumentation().getTargetContext());
-    StartingSurfaceDrawer mStartingSurfaceDrawer;
+    TestStartingSurfaceDrawer mStartingSurfaceDrawer;
+
+    static final class TestStartingSurfaceDrawer extends StartingSurfaceDrawer{
+        int mAddWindowForTask = 0;
+
+        TestStartingSurfaceDrawer(Context context, ShellExecutor splashScreenExecutor,
+                IconProvider iconProvider, TransactionPool pool) {
+            super(context, splashScreenExecutor, iconProvider, pool);
+        }
+
+        @Override
+        protected boolean addWindow(int taskId, IBinder appToken, View view, Display display,
+                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,
+                boolean immediately) {
+            // listen for removeView
+            if (mAddWindowForTask == removalInfo.taskId) {
+                mAddWindowForTask = 0;
+            }
+            mStartingWindowRecords.remove(removalInfo.taskId);
+        }
+    }
 
     private static class TestContext extends TestableContext {
         TestContext(Context context) {
@@ -134,51 +165,44 @@
         doReturn(metrics).when(mMockWindowManager).getMaximumWindowMetrics();
         doNothing().when(mMockWindowManager).addView(any(), any());
         mTestExecutor = new HandlerExecutor(mTestHandler);
-        mStartingSurfaceDrawer = new StartingSurfaceDrawer(mTestContext, mTestExecutor,
-                mIconProvider, mTransactionPool);
         mStartingSurfaceDrawer = spy(
-                new StartingSurfaceDrawer(mTestContext, mTestExecutor, mIconProvider,
+                new TestStartingSurfaceDrawer(mTestContext, mTestExecutor, mIconProvider,
                         mTransactionPool));
-        spyOn(mStartingSurfaceDrawer.mSplashscreenWindowCreator);
-        spyOn(mStartingSurfaceDrawer.mWindowRecords);
-        spyOn(mStartingSurfaceDrawer.mWindowlessRecords);
     }
 
     @Test
     public void testAddSplashScreenSurface() {
         final int taskId = 1;
         final StartingWindowInfo windowInfo =
-                createWindowInfo(taskId, android.R.style.Theme, mBinder);
-        mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo,
+                createWindowInfo(taskId, android.R.style.Theme);
+        mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, mBinder,
                 STARTING_WINDOW_TYPE_SPLASH_SCREEN);
         waitHandlerIdle(mTestHandler);
-        verify(mStartingSurfaceDrawer.mSplashscreenWindowCreator).addWindow(
-                eq(taskId), eq(mBinder), any(), any(), any(),
+        verify(mStartingSurfaceDrawer).addWindow(eq(taskId), eq(mBinder), any(), any(), any(),
                 eq(STARTING_WINDOW_TYPE_SPLASH_SCREEN));
+        assertEquals(mStartingSurfaceDrawer.mAddWindowForTask, taskId);
 
         StartingWindowRemovalInfo removalInfo = new StartingWindowRemovalInfo();
         removalInfo.taskId = windowInfo.taskInfo.taskId;
         mStartingSurfaceDrawer.removeStartingWindow(removalInfo);
         waitHandlerIdle(mTestHandler);
-        verify(mStartingSurfaceDrawer.mWindowRecords).removeWindow(any(), eq(false));
-        assertEquals(mStartingSurfaceDrawer.mWindowRecords.recordSize(), 0);
+        verify(mStartingSurfaceDrawer).removeWindowSynced(any(), eq(false));
+        assertEquals(mStartingSurfaceDrawer.mAddWindowForTask, 0);
     }
 
     @Test
     public void testFallbackDefaultTheme() {
         final int taskId = 1;
         final StartingWindowInfo windowInfo =
-                createWindowInfo(taskId, 0, mBinder);
+                createWindowInfo(taskId, 0);
         final int[] theme = new int[1];
         doAnswer(invocation -> theme[0] = (Integer) invocation.callRealMethod())
-                .when(mStartingSurfaceDrawer.mSplashscreenWindowCreator)
-                .getSplashScreenTheme(eq(0), any());
+                .when(mStartingSurfaceDrawer).getSplashScreenTheme(eq(0), any());
 
-        mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo,
+        mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, mBinder,
                 STARTING_WINDOW_TYPE_SPLASH_SCREEN);
         waitHandlerIdle(mTestHandler);
-        verify(mStartingSurfaceDrawer.mSplashscreenWindowCreator)
-                .getSplashScreenTheme(eq(0), any());
+        verify(mStartingSurfaceDrawer).getSplashScreenTheme(eq(0), any());
         assertNotEquals(theme[0], 0);
     }
 
@@ -217,7 +241,7 @@
     public void testRemoveTaskSnapshotWithImeSurfaceWhenOnImeDrawn() throws Exception {
         final int taskId = 1;
         final StartingWindowInfo windowInfo =
-                createWindowInfo(taskId, android.R.style.Theme, mBinder);
+                createWindowInfo(taskId, android.R.style.Theme);
         TaskSnapshot snapshot = createTaskSnapshot(100, 100, new Point(100, 100),
                 new Rect(0, 0, 0, 50), true /* hasImeSurface */);
         final IWindowSession session = WindowManagerGlobal.getWindowSession();
@@ -246,7 +270,7 @@
             when(TaskSnapshotWindow.create(eq(windowInfo), eq(mBinder), eq(snapshot), any(),
                     any())).thenReturn(mockSnapshotWindow);
             // Simulate a task snapshot window created with IME snapshot shown.
-            mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, snapshot);
+            mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, mBinder, snapshot);
             waitHandlerIdle(mTestHandler);
 
             // Verify the task snapshot with IME snapshot will be removed when received the real IME
@@ -254,36 +278,27 @@
             // makeTaskSnapshotWindow shall call removeWindowSynced before there add a new
             // StartingWindowRecord for the task.
             mStartingSurfaceDrawer.onImeDrawnOnTask(1);
-            verify(mStartingSurfaceDrawer.mWindowRecords, times(2))
-                    .removeWindow(any(), eq(true));
+            verify(mStartingSurfaceDrawer, times(2))
+                    .removeWindowSynced(any(), eq(true));
         }
     }
 
     @Test
     public void testClearAllWindows() {
         final int taskId = 1;
-        mStartingSurfaceDrawer.mWindowRecords.addRecord(taskId,
-                new StartingSurfaceDrawer.StartingWindowRecord() {
-                    @Override
-                    public void removeIfPossible(StartingWindowRemovalInfo info,
-                            boolean immediately) {
+        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.mWindowlessRecords.addRecord(taskId,
-                new StartingSurfaceDrawer.StartingWindowRecord() {
-                    @Override
-                    public void removeIfPossible(StartingWindowRemovalInfo info,
-                            boolean immediately) {
-
-                    }
-                });
         mStartingSurfaceDrawer.clearAllWindows();
         waitHandlerIdle(mTestHandler);
-        verify(mStartingSurfaceDrawer.mWindowRecords).removeWindow(any(), eq(true));
-        assertEquals(mStartingSurfaceDrawer.mWindowRecords.recordSize(), 0);
-        verify(mStartingSurfaceDrawer.mWindowlessRecords).removeWindow(any(), eq(true));
-        assertEquals(mStartingSurfaceDrawer.mWindowlessRecords.recordSize(), 0);
+        verify(mStartingSurfaceDrawer).removeWindowSynced(any(), eq(true));
+        assertEquals(mStartingSurfaceDrawer.mStartingWindowRecords.size(), 0);
     }
 
     @Test
@@ -336,7 +351,7 @@
                 longAppDuration, longAppDuration));
     }
 
-    private StartingWindowInfo createWindowInfo(int taskId, int themeResId, IBinder appToken) {
+    private StartingWindowInfo createWindowInfo(int taskId, int themeResId) {
         StartingWindowInfo windowInfo = new StartingWindowInfo();
         final ActivityInfo info = new ActivityInfo();
         info.applicationInfo = new ApplicationInfo();
@@ -345,7 +360,6 @@
         final ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
         taskInfo.topActivityInfo = info;
         taskInfo.taskId = taskId;
-        windowInfo.appToken = appToken;
         windowInfo.targetActivityInfo = info;
         windowInfo.taskInfo = taskInfo;
         windowInfo.topOpaqueWindowInsetsState = new InsetsState();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index cc81d52..0a833f4 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3512,10 +3512,7 @@
         info.isKeyguardOccluded =
             mAtmService.mKeyguardController.isDisplayOccluded(DEFAULT_DISPLAY);
 
-        info.startingWindowTypeParameter = activity.mStartingData != null
-                ? activity.mStartingData.mTypeParams
-                : (StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED
-                        | StartingWindowInfo.TYPE_PARAMETER_WINDOWLESS);
+        info.startingWindowTypeParameter = activity.mStartingData.mTypeParams;
         if ((info.startingWindowTypeParameter
                 & StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED) != 0) {
             final WindowState topMainWin = getWindow(w -> w.mAttrs.type == TYPE_BASE_APPLICATION);
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index b131365..3a30e4b 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.TaskInfo.cameraCompatControlStateToString;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
@@ -44,7 +43,6 @@
 import android.view.SurfaceControl;
 import android.window.ITaskOrganizer;
 import android.window.ITaskOrganizerController;
-import android.window.IWindowlessStartingSurfaceCallback;
 import android.window.SplashScreenView;
 import android.window.StartingWindowInfo;
 import android.window.StartingWindowRemovalInfo;
@@ -658,10 +656,9 @@
             info.splashScreenThemeResId = launchTheme;
         }
         info.taskSnapshot = taskSnapshot;
-        info.appToken = activity.token;
         // make this happen prior than prepare surface
         try {
-            lastOrganizer.addStartingWindow(info);
+            lastOrganizer.addStartingWindow(info, activity.token);
         } catch (RemoteException e) {
             Slog.e(TAG, "Exception sending onTaskStart callback", e);
             return false;
@@ -707,55 +704,6 @@
         }
     }
 
-    /**
-     * Create a starting surface which attach on a given surface.
-     * @param activity Target activity, this isn't necessary to be the top activity.
-     * @param root The root surface which the created surface will attach on.
-     * @param taskSnapshot Whether to draw snapshot.
-     * @param callback Called when surface is drawn and attached to the root surface.
-     * @return The taskId, this is a token and should be used to remove the surface, even if
-     *         the task was removed from hierarchy.
-     */
-    int addWindowlessStartingSurface(Task task, ActivityRecord activity, SurfaceControl root,
-            TaskSnapshot taskSnapshot, IWindowlessStartingSurfaceCallback callback) {
-        final Task rootTask = task.getRootTask();
-        if (rootTask == null) {
-            return INVALID_TASK_ID;
-        }
-        final ITaskOrganizer lastOrganizer = mTaskOrganizers.peekLast();
-        if (lastOrganizer == null) {
-            return INVALID_TASK_ID;
-        }
-        final StartingWindowInfo info = task.getStartingWindowInfo(activity);
-        info.taskInfo.taskDescription = activity.taskDescription;
-        info.taskSnapshot = taskSnapshot;
-        info.windowlessStartingSurfaceCallback = callback;
-        info.rootSurface = root;
-        try {
-            lastOrganizer.addStartingWindow(info);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Exception sending addWindowlessStartingSurface ", e);
-            return INVALID_TASK_ID;
-        }
-        return task.mTaskId;
-    }
-
-    void removeWindowlessStartingSurface(int taskId, boolean immediately) {
-        final ITaskOrganizer lastOrganizer = mTaskOrganizers.peekLast();
-        if (lastOrganizer == null || taskId == 0) {
-            return;
-        }
-        final StartingWindowRemovalInfo removalInfo = new StartingWindowRemovalInfo();
-        removalInfo.taskId = taskId;
-        removalInfo.windowlessSurface = true;
-        removalInfo.removeImmediately = immediately;
-        try {
-            lastOrganizer.removeStartingWindow(removalInfo);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Exception sending removeWindowlessStartingSurface ", e);
-        }
-    }
-
     boolean copySplashScreenView(Task task) {
         final Task rootTask = task.getRootTask();
         if (rootTask == null) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index d7e4c55..169586e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -1023,7 +1023,7 @@
         RunningTaskInfo mInfo;
 
         @Override
-        public void addStartingWindow(StartingWindowInfo info) { }
+        public void addStartingWindow(StartingWindowInfo info, IBinder appToken) { }
         @Override
         public void removeStartingWindow(StartingWindowRemovalInfo removalInfo) { }
         @Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index fafe90a..323894ca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -1583,10 +1583,10 @@
         }
 
         @Override
-        public void addStartingWindow(StartingWindowInfo info) {
+        public void addStartingWindow(StartingWindowInfo info, IBinder appToken) {
             synchronized (mWMService.mGlobalLock) {
                 final ActivityRecord activity = mWMService.mRoot.getActivityRecord(
-                        info.appToken);
+                        appToken);
                 IWindow iWindow = mock(IWindow.class);
                 doReturn(mock(IBinder.class)).when(iWindow).asBinder();
                 final WindowState window = WindowTestsBase.createWindow(null,
@@ -1596,8 +1596,8 @@
                         iWindow,
                         mPowerManagerWrapper);
                 activity.mStartingWindow = window;
-                mAppWindowMap.put(info.appToken, window);
-                mTaskAppMap.put(info.taskInfo.taskId, info.appToken);
+                mAppWindowMap.put(appToken, window);
+                mTaskAppMap.put(info.taskInfo.taskId, appToken);
             }
             if (mRunnableWhenAddingSplashScreen != null) {
                 mRunnableWhenAddingSplashScreen.run();