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

Commit 2be72d03 authored by Vadim Caen's avatar Vadim Caen Committed by Android (Google) Code Review
Browse files

Merge "Implement the legacy splash screen behavior" into sc-dev

parents 52a1d139 f08dae31
Loading
Loading
Loading
Loading
+18 −1
Original line number Original line Diff line number Diff line
@@ -133,6 +133,8 @@ public final class SplashScreenView extends FrameLayout {
        private @ColorInt int mIconBackground;
        private @ColorInt int mIconBackground;
        private Bitmap mParceledIconBitmap;
        private Bitmap mParceledIconBitmap;
        private Drawable mIconDrawable;
        private Drawable mIconDrawable;
        // It is only set for legacy splash screen which won't be sent across processes.
        private Drawable mOverlayDrawable;
        private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
        private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
        private RemoteCallback mClientCallback;
        private RemoteCallback mClientCallback;
        private int mBrandingImageWidth;
        private int mBrandingImageWidth;
@@ -192,6 +194,14 @@ public final class SplashScreenView extends FrameLayout {
            return this;
            return this;
        }
        }


        /**
         * Set the Drawable object to fill entire view
         */
        public Builder setOverlayDrawable(@Nullable Drawable drawable) {
            mOverlayDrawable = drawable;
            return this;
        }

        /**
        /**
         * Set the Drawable object to fill the center view.
         * Set the Drawable object to fill the center view.
         */
         */
@@ -236,7 +246,11 @@ public final class SplashScreenView extends FrameLayout {
                    layoutInflater.inflate(R.layout.splash_screen_view, null, false);
                    layoutInflater.inflate(R.layout.splash_screen_view, null, false);
            view.mInitBackgroundColor = mBackgroundColor;
            view.mInitBackgroundColor = mBackgroundColor;
            view.mInitIconBackgroundColor = mIconBackground;
            view.mInitIconBackgroundColor = mIconBackground;
            if (mOverlayDrawable != null) {
                view.setBackground(mOverlayDrawable);
            } else {
                view.setBackgroundColor(mBackgroundColor);
                view.setBackgroundColor(mBackgroundColor);
            }
            view.mClientCallback = mClientCallback;
            view.mClientCallback = mClientCallback;


            view.mBrandingImageView = view.findViewById(R.id.splashscreen_branding_view);
            view.mBrandingImageView = view.findViewById(R.id.splashscreen_branding_view);
@@ -261,6 +275,9 @@ public final class SplashScreenView extends FrameLayout {
                    }
                    }
                }
                }
            }
            }
            if (mOverlayDrawable != null || mIconDrawable == null) {
                view.setNotCopyable();
            }


            if (mParceledIconBitmap != null) {
            if (mParceledIconBitmap != null) {
                view.mParceledIconBitmap = mParceledIconBitmap;
                view.mParceledIconBitmap = mParceledIconBitmap;
+12 −2
Original line number Original line Diff line number Diff line
@@ -55,6 +55,9 @@ public final class StartingWindowInfo implements Parcelable {
     */
     */
    public static final int STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN = 3;
    public static final int STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN = 3;


    /** @hide **/
    public static final int STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN = 4;

    /**
    /**
     * @hide
     * @hide
     */
     */
@@ -62,7 +65,8 @@ public final class StartingWindowInfo implements Parcelable {
            STARTING_WINDOW_TYPE_NONE,
            STARTING_WINDOW_TYPE_NONE,
            STARTING_WINDOW_TYPE_SPLASH_SCREEN,
            STARTING_WINDOW_TYPE_SPLASH_SCREEN,
            STARTING_WINDOW_TYPE_SNAPSHOT,
            STARTING_WINDOW_TYPE_SNAPSHOT,
            STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
            STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN,
            STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN
    })
    })
    public @interface StartingWindowType {}
    public @interface StartingWindowType {}


@@ -103,7 +107,8 @@ public final class StartingWindowInfo implements Parcelable {
            TYPE_PARAMETER_PROCESS_RUNNING,
            TYPE_PARAMETER_PROCESS_RUNNING,
            TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT,
            TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT,
            TYPE_PARAMETER_ACTIVITY_CREATED,
            TYPE_PARAMETER_ACTIVITY_CREATED,
            TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN
            TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN,
            TYPE_PARAMETER_LEGACY_SPLASH_SCREEN
    })
    })
    public @interface StartingTypeParams {}
    public @interface StartingTypeParams {}


@@ -122,6 +127,11 @@ public final class StartingWindowInfo implements Parcelable {
    public static final int TYPE_PARAMETER_ACTIVITY_CREATED = 0x00000010;
    public static final int TYPE_PARAMETER_ACTIVITY_CREATED = 0x00000010;
    /** @hide */
    /** @hide */
    public static final int TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN = 0x00000020;
    public static final int TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN = 0x00000020;
    /**
     * Application is allowed to use the legacy splash screen
     * @hide
     */
    public static final int TYPE_PARAMETER_LEGACY_SPLASH_SCREEN = 0x80000000;


    /**
    /**
     * The parameters which effect the starting window type.
     * The parameters which effect the starting window type.
+66 −28
Original line number Original line Diff line number Diff line
@@ -18,6 +18,9 @@ package com.android.wm.shell.startingsurface;


import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;


import android.annotation.ColorInt;
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.NonNull;
@@ -47,6 +50,7 @@ import android.util.Slog;
import android.view.SurfaceControl;
import android.view.SurfaceControl;
import android.view.View;
import android.view.View;
import android.window.SplashScreenView;
import android.window.SplashScreenView;
import android.window.StartingWindowInfo.StartingWindowType;


import com.android.internal.R;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
@@ -122,17 +126,17 @@ public class SplashscreenContentDrawer {
     * view on background thread so the view and the drawable can be create and pre-draw in
     * view on background thread so the view and the drawable can be create and pre-draw in
     * parallel.
     * parallel.
     *
     *
     * @param emptyView Create a splash screen view without icon on it.
     * @param suggestType Suggest type to create the splash screen view.
     * @param consumer Receiving the SplashScreenView object, which will also be executed
     * @param consumer Receiving the SplashScreenView object, which will also be executed
     *                 on splash screen thread. Note that the view can be null if failed.
     *                 on splash screen thread. Note that the view can be null if failed.
     */
     */
    void createContentView(Context context, boolean emptyView, ActivityInfo info, int taskId,
    void createContentView(Context context, @StartingWindowType int suggestType, ActivityInfo info,
            Consumer<SplashScreenView> consumer) {
            int taskId, Consumer<SplashScreenView> consumer) {
        mSplashscreenWorkerHandler.post(() -> {
        mSplashscreenWorkerHandler.post(() -> {
            SplashScreenView contentView;
            SplashScreenView contentView;
            try {
            try {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "makeSplashScreenContentView");
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "makeSplashScreenContentView");
                contentView = makeSplashScreenContentView(context, info, emptyView);
                contentView = makeSplashScreenContentView(context, info, suggestType);
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            } catch (RuntimeException e) {
            } catch (RuntimeException e) {
                Slog.w(TAG, "failed creating starting window content at taskId: "
                Slog.w(TAG, "failed creating starting window content at taskId: "
@@ -199,22 +203,45 @@ public class SplashscreenContentDrawer {
        }
        }
    }
    }


    private static Drawable peekLegacySplashscreenContent(Context context,
            SplashScreenWindowAttrs attrs) {
        final TypedArray a = context.obtainStyledAttributes(R.styleable.Window);
        final int resId = safeReturnAttrDefault((def) ->
                a.getResourceId(R.styleable.Window_windowSplashscreenContent, def), 0);
        a.recycle();
        if (resId != 0) {
            return context.getDrawable(resId);
        }
        if (attrs.mWindowBgResId != 0) {
            return context.getDrawable(attrs.mWindowBgResId);
        }
        return null;
    }

    private SplashScreenView makeSplashScreenContentView(Context context, ActivityInfo ai,
    private SplashScreenView makeSplashScreenContentView(Context context, ActivityInfo ai,
            boolean emptyView) {
            @StartingWindowType int suggestType) {
        updateDensity();
        updateDensity();


        getWindowAttrs(context, mTmpAttrs);
        getWindowAttrs(context, mTmpAttrs);
        mLastPackageContextConfigHash = context.getResources().getConfiguration().hashCode();
        mLastPackageContextConfigHash = context.getResources().getConfiguration().hashCode();
        final int themeBGColor = mColorCache.getWindowColor(ai.packageName,

                mLastPackageContextConfigHash, mTmpAttrs.mWindowBgColor, mTmpAttrs.mWindowBgResId,
        final Drawable legacyDrawable = suggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN
                () -> peekWindowBGColor(context, mTmpAttrs)).mBgColor;
                ? peekLegacySplashscreenContent(context, mTmpAttrs) : null;
        // TODO (b/173975965) Tracking the performance on improved splash screen.
        final int themeBGColor = legacyDrawable != null
                ? getBGColorFromCache(ai, () -> estimateWindowBGColor(legacyDrawable))
                : getBGColorFromCache(ai, () -> peekWindowBGColor(context, mTmpAttrs));
        return new StartingWindowViewBuilder(context, ai)
        return new StartingWindowViewBuilder(context, ai)
                .setWindowBGColor(themeBGColor)
                .setWindowBGColor(themeBGColor)
                .makeEmptyView(emptyView)
                .overlayDrawable(legacyDrawable)
                .chooseStyle(suggestType)
                .build();
                .build();
    }
    }


    private int getBGColorFromCache(ActivityInfo ai, IntSupplier windowBgColorSupplier) {
        return mColorCache.getWindowColor(ai.packageName, mLastPackageContextConfigHash,
                mTmpAttrs.mWindowBgColor, mTmpAttrs.mWindowBgResId, windowBgColorSupplier).mBgColor;
    }

    private static <T> T safeReturnAttrDefault(UnaryOperator<T> getMethod, T def) {
    private static <T> T safeReturnAttrDefault(UnaryOperator<T> getMethod, T def) {
        try {
        try {
            return getMethod.apply(def);
            return getMethod.apply(def);
@@ -267,7 +294,8 @@ public class SplashscreenContentDrawer {
        private final Context mContext;
        private final Context mContext;
        private final ActivityInfo mActivityInfo;
        private final ActivityInfo mActivityInfo;


        private boolean mEmptyView;
        private Drawable mOverlayDrawable;
        private int mSuggestType;
        private int mThemeColor;
        private int mThemeColor;
        private Drawable mFinalIconDrawable;
        private Drawable mFinalIconDrawable;
        private int mFinalIconSize = mIconSize;
        private int mFinalIconSize = mIconSize;
@@ -282,16 +310,22 @@ public class SplashscreenContentDrawer {
            return this;
            return this;
        }
        }


        StartingWindowViewBuilder makeEmptyView(boolean empty) {
        StartingWindowViewBuilder overlayDrawable(Drawable overlay) {
            mEmptyView = empty;
            mOverlayDrawable = overlay;
            return this;
        }

        StartingWindowViewBuilder chooseStyle(int suggestType) {
            mSuggestType = suggestType;
            return this;
            return this;
        }
        }


        SplashScreenView build() {
        SplashScreenView build() {
            Drawable iconDrawable;
            Drawable iconDrawable;
            final int animationDuration;
            final int animationDuration;
            if (mEmptyView) {
            if (mSuggestType == STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
                // empty splash screen case
                    || mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
                // empty or legacy splash screen case
                animationDuration = 0;
                animationDuration = 0;
                mFinalIconSize = 0;
                mFinalIconSize = 0;
            } else if (mTmpAttrs.mSplashScreenIcon != null) {
            } else if (mTmpAttrs.mSplashScreenIcon != null) {
@@ -403,13 +437,15 @@ public class SplashscreenContentDrawer {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon");
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon");
            final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext);
            final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext);
            builder.setBackgroundColor(mThemeColor);
            builder.setBackgroundColor(mThemeColor);
            builder.setOverlayDrawable(mOverlayDrawable);
            if (iconDrawable != null) {
            if (iconDrawable != null) {
                builder.setIconSize(iconSize)
                builder.setIconSize(iconSize)
                        .setIconBackground(mTmpAttrs.mIconBgColor)
                        .setIconBackground(mTmpAttrs.mIconBgColor)
                        .setCenterViewDrawable(iconDrawable)
                        .setCenterViewDrawable(iconDrawable)
                        .setAnimationDurationMillis(animationDuration);
                        .setAnimationDurationMillis(animationDuration);
            }
            }
            if (mTmpAttrs.mBrandingImage != null) {
            if (mSuggestType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
                    && mTmpAttrs.mBrandingImage != null) {
                builder.setBrandingDrawable(mTmpAttrs.mBrandingImage, mBrandingImageWidth,
                builder.setBrandingDrawable(mTmpAttrs.mBrandingImage, mBrandingImageWidth,
                        mBrandingImageHeight);
                        mBrandingImageHeight);
            }
            }
@@ -417,13 +453,13 @@ public class SplashscreenContentDrawer {
            if (DEBUG) {
            if (DEBUG) {
                Slog.d(TAG, "fillViewWithIcon surfaceWindowView " + splashScreenView);
                Slog.d(TAG, "fillViewWithIcon surfaceWindowView " + splashScreenView);
            }
            }
            if (mEmptyView) {
            if (mSuggestType != STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
                splashScreenView.setNotCopyable();
                splashScreenView.addOnAttachStateChangeListener(
            }
                        new View.OnAttachStateChangeListener() {
            splashScreenView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
                            @Override
                            @Override
                            public void onViewAttachedToWindow(View v) {
                            public void onViewAttachedToWindow(View v) {
                    SplashScreenView.applySystemBarsContrastColor(v.getWindowInsetsController(),
                                SplashScreenView.applySystemBarsContrastColor(
                                        v.getWindowInsetsController(),
                                        splashScreenView.getInitBackgroundColor());
                                        splashScreenView.getInitBackgroundColor());
                            }
                            }


@@ -431,6 +467,8 @@ public class SplashscreenContentDrawer {
                            public void onViewDetachedFromWindow(View v) {
                            public void onViewDetachedFromWindow(View v) {
                            }
                            }
                        });
                        });
            }

            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            return splashScreenView;
            return splashScreenView;
        }
        }
+47 −21
Original line number Original line Diff line number Diff line
@@ -20,6 +20,8 @@ import static android.content.Context.CONTEXT_RESTRICTED;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Choreographer.CALLBACK_INSETS_ANIMATION;
import static android.view.Choreographer.CALLBACK_INSETS_ANIMATION;
import static android.view.Display.DEFAULT_DISPLAY;
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.Nullable;
import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.RunningTaskInfo;
@@ -32,7 +34,6 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteCallback;
@@ -50,6 +51,7 @@ import android.widget.FrameLayout;
import android.window.SplashScreenView;
import android.window.SplashScreenView;
import android.window.SplashScreenView.SplashScreenViewParcelable;
import android.window.SplashScreenView.SplashScreenViewParcelable;
import android.window.StartingWindowInfo;
import android.window.StartingWindowInfo;
import android.window.StartingWindowInfo.StartingWindowType;
import android.window.TaskSnapshot;
import android.window.TaskSnapshot;


import com.android.internal.R;
import com.android.internal.R;
@@ -149,10 +151,11 @@ public class StartingSurfaceDrawer {


    /**
    /**
     * Called when a task need a splash screen starting window.
     * Called when a task need a splash screen starting window.
     * @param emptyView Whether drawing an empty frame without anything on it.
     *
     * @param suggestType The suggestion type to draw the splash screen.
     */
     */
    void addSplashScreenStartingWindow(StartingWindowInfo windowInfo, IBinder appToken,
    void addSplashScreenStartingWindow(StartingWindowInfo windowInfo, IBinder appToken,
            boolean emptyView) {
            @StartingWindowType int suggestType) {
        final RunningTaskInfo taskInfo = windowInfo.taskInfo;
        final RunningTaskInfo taskInfo = windowInfo.taskInfo;
        final ActivityInfo activityInfo = taskInfo.topActivityInfo;
        final ActivityInfo activityInfo = taskInfo.topActivityInfo;
        if (activityInfo == null) {
        if (activityInfo == null) {
@@ -173,7 +176,8 @@ public class StartingSurfaceDrawer {
                        : com.android.internal.R.style.Theme_DeviceDefault_DayNight;
                        : com.android.internal.R.style.Theme_DeviceDefault_DayNight;
        if (DEBUG_SPLASH_SCREEN) {
        if (DEBUG_SPLASH_SCREEN) {
            Slog.d(TAG, "addSplashScreen " + activityInfo.packageName
            Slog.d(TAG, "addSplashScreen " + activityInfo.packageName
                    + " theme=" + Integer.toHexString(theme) + " task= " + taskInfo.taskId);
                    + " theme=" + Integer.toHexString(theme) + " task=" + taskInfo.taskId
                    + " suggestType=" + suggestType);
        }
        }


        // Obtain proper context to launch on the right display.
        // Obtain proper context to launch on the right display.
@@ -231,13 +235,19 @@ public class StartingSurfaceDrawer {
        params.setFitInsetsTypes(0);
        params.setFitInsetsTypes(0);
        params.format = PixelFormat.TRANSLUCENT;
        params.format = PixelFormat.TRANSLUCENT;
        int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
        int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
                | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
        final TypedArray a = context.obtainStyledAttributes(R.styleable.Window);
        final TypedArray a = context.obtainStyledAttributes(R.styleable.Window);
        if (a.getBoolean(R.styleable.Window_windowShowWallpaper, false)) {
        if (a.getBoolean(R.styleable.Window_windowShowWallpaper, false)) {
            windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
            windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
        }
        }
        if (suggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
            if (a.getBoolean(R.styleable.Window_windowDrawsSystemBarBackgrounds, false)) {
                windowFlags |= WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
            }
        } else {
            windowFlags |= WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
        }
        params.layoutInDisplayCutoutMode = a.getInt(
        params.layoutInDisplayCutoutMode = a.getInt(
                R.styleable.Window_windowLayoutInDisplayCutoutMode,
                R.styleable.Window_windowLayoutInDisplayCutoutMode,
                params.layoutInDisplayCutoutMode);
                params.layoutInDisplayCutoutMode);
@@ -311,12 +321,12 @@ public class StartingSurfaceDrawer {
            }
            }
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        };
        };
        mSplashscreenContentDrawer.createContentView(context, emptyView, activityInfo, taskId,
        mSplashscreenContentDrawer.createContentView(context, suggestType, activityInfo, taskId,
                viewSupplier::setView);
                viewSupplier::setView);


        try {
        try {
            final WindowManager wm = context.getSystemService(WindowManager.class);
            final WindowManager wm = context.getSystemService(WindowManager.class);
            if (addWindow(taskId, appToken, rootLayout, wm, params)) {
            if (addWindow(taskId, appToken, rootLayout, wm, params, suggestType)) {
                // We use the splash screen worker thread to create SplashScreenView while adding
                // We use the splash screen worker thread to create SplashScreenView while adding
                // the window, as otherwise Choreographer#doFrame might be delayed on this thread.
                // the window, as otherwise Choreographer#doFrame might be delayed on this thread.
                // And since Choreographer#doFrame won't happen immediately after adding the window,
                // And since Choreographer#doFrame won't happen immediately after adding the window,
@@ -336,8 +346,10 @@ public class StartingSurfaceDrawer {


    int getStartingWindowBackgroundColorForTask(int taskId) {
    int getStartingWindowBackgroundColorForTask(int taskId) {
        StartingWindowRecord startingWindowRecord = mStartingWindowRecords.get(taskId);
        StartingWindowRecord startingWindowRecord = mStartingWindowRecords.get(taskId);
        if (startingWindowRecord == null || startingWindowRecord.mContentView == null) return 0;
        if (startingWindowRecord == null || startingWindowRecord.mContentView == null) {
        return ((ColorDrawable) startingWindowRecord.mContentView.getBackground()).getColor();
            return 0;
        }
        return startingWindowRecord.mContentView.getInitBackgroundColor();
    }
    }


    private static class SplashScreenViewSupplier implements Supplier<SplashScreenView> {
    private static class SplashScreenViewSupplier implements Supplier<SplashScreenView> {
@@ -379,7 +391,7 @@ public class StartingSurfaceDrawer {
            return;
            return;
        }
        }
        final StartingWindowRecord tView = new StartingWindowRecord(appToken,
        final StartingWindowRecord tView = new StartingWindowRecord(appToken,
                null/* decorView */, surface);
                null/* decorView */, surface, STARTING_WINDOW_TYPE_SNAPSHOT);
        mStartingWindowRecords.put(taskId, tView);
        mStartingWindowRecords.put(taskId, tView);
    }
    }


@@ -449,7 +461,7 @@ public class StartingSurfaceDrawer {
    }
    }


    protected boolean addWindow(int taskId, IBinder appToken, View view, WindowManager wm,
    protected boolean addWindow(int taskId, IBinder appToken, View view, WindowManager wm,
            WindowManager.LayoutParams params) {
            WindowManager.LayoutParams params, @StartingWindowType int suggestType) {
        boolean shouldSaveView = true;
        boolean shouldSaveView = true;
        try {
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addRootView");
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addRootView");
@@ -469,14 +481,15 @@ public class StartingSurfaceDrawer {
        }
        }
        if (shouldSaveView) {
        if (shouldSaveView) {
            removeWindowNoAnimate(taskId);
            removeWindowNoAnimate(taskId);
            saveSplashScreenRecord(appToken, taskId, view);
            saveSplashScreenRecord(appToken, taskId, view, suggestType);
        }
        }
        return shouldSaveView;
        return shouldSaveView;
    }
    }


    private void saveSplashScreenRecord(IBinder appToken, int taskId, View view) {
    private void saveSplashScreenRecord(IBinder appToken, int taskId, View view,
            @StartingWindowType int suggestType) {
        final StartingWindowRecord tView = new StartingWindowRecord(appToken, view,
        final StartingWindowRecord tView = new StartingWindowRecord(appToken, view,
                null/* TaskSnapshotWindow */);
                null/* TaskSnapshotWindow */, suggestType);
        mStartingWindowRecords.put(taskId, tView);
        mStartingWindowRecords.put(taskId, tView);
    }
    }


@@ -493,6 +506,9 @@ public class StartingSurfaceDrawer {
                    Slog.v(TAG, "Removing splash screen window for task: " + taskId);
                    Slog.v(TAG, "Removing splash screen window for task: " + taskId);
                }
                }
                if (record.mContentView != null) {
                if (record.mContentView != null) {
                    if (record.mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
                        removeWindowInner(record.mDecorView, false);
                    } else {
                        if (playRevealAnimation) {
                        if (playRevealAnimation) {
                            mSplashscreenContentDrawer.applyExitAnimation(record.mContentView,
                            mSplashscreenContentDrawer.applyExitAnimation(record.mContentView,
                                    leash, frame,
                                    leash, frame,
@@ -502,6 +518,7 @@ public class StartingSurfaceDrawer {
                            // default exit animation
                            // default exit animation
                            removeWindowInner(record.mDecorView, true);
                            removeWindowInner(record.mDecorView, true);
                        }
                        }
                    }
                } else {
                } else {
                    // shouldn't happen
                    // shouldn't happen
                    Slog.e(TAG, "Found empty splash screen, remove!");
                    Slog.e(TAG, "Found empty splash screen, remove!");
@@ -537,6 +554,7 @@ public class StartingSurfaceDrawer {
        private final TaskSnapshotWindow mTaskSnapshotWindow;
        private final TaskSnapshotWindow mTaskSnapshotWindow;
        private SplashScreenView mContentView;
        private SplashScreenView mContentView;
        private boolean mSetSplashScreen;
        private boolean mSetSplashScreen;
        private @StartingWindowType int mSuggestType;


        StartingWindowRecord(IBinder appToken, View decorView,
        StartingWindowRecord(IBinder appToken, View decorView,
                TaskSnapshotWindow taskSnapshotWindow) {
                TaskSnapshotWindow taskSnapshotWindow) {
@@ -545,6 +563,14 @@ public class StartingSurfaceDrawer {
            mTaskSnapshotWindow = taskSnapshotWindow;
            mTaskSnapshotWindow = taskSnapshotWindow;
        }
        }


        StartingWindowRecord(IBinder appToken, View decorView,
                TaskSnapshotWindow taskSnapshotWindow, @StartingWindowType int suggestType) {
            mAppToken = appToken;
            mDecorView = decorView;
            mTaskSnapshotWindow = taskSnapshotWindow;
            mSuggestType = suggestType;
        }

        private void setSplashScreenView(SplashScreenView splashScreenView) {
        private void setSplashScreenView(SplashScreenView splashScreenView) {
            if (mSetSplashScreen) {
            if (mSetSplashScreen) {
                return;
                return;
+11 −10
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.wm.shell.startingsurface;


import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;


@@ -31,6 +32,7 @@ import android.os.Trace;
import android.util.Slog;
import android.util.Slog;
import android.view.SurfaceControl;
import android.view.SurfaceControl;
import android.window.StartingWindowInfo;
import android.window.StartingWindowInfo;
import android.window.StartingWindowInfo.StartingWindowType;
import android.window.TaskOrganizer;
import android.window.TaskOrganizer;
import android.window.TaskSnapshot;
import android.window.TaskSnapshot;


@@ -106,10 +108,6 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
        mTaskLaunchingCallback = listener;
        mTaskLaunchingCallback = listener;
    }
    }


    private boolean shouldSendToListener(int suggestionType) {
        return suggestionType != STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
    }

    /**
    /**
     * Called when a task need a starting window.
     * Called when a task need a starting window.
     */
     */
@@ -120,12 +118,9 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
            final int suggestionType = mStartingWindowTypeAlgorithm.getSuggestedWindowType(
            final int suggestionType = mStartingWindowTypeAlgorithm.getSuggestedWindowType(
                    windowInfo);
                    windowInfo);
            final RunningTaskInfo runningTaskInfo = windowInfo.taskInfo;
            final RunningTaskInfo runningTaskInfo = windowInfo.taskInfo;
            if (suggestionType == STARTING_WINDOW_TYPE_SPLASH_SCREEN) {
            if (isSplashScreenType(suggestionType)) {
                mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, appToken,
                        false /* emptyView */);
            } else if (suggestionType == STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN) {
                mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, appToken,
                mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, appToken,
                        true /* emptyView */);
                        suggestionType);
            } else if (suggestionType == STARTING_WINDOW_TYPE_SNAPSHOT) {
            } else if (suggestionType == STARTING_WINDOW_TYPE_SNAPSHOT) {
                final TaskSnapshot snapshot = windowInfo.mTaskSnapshot;
                final TaskSnapshot snapshot = windowInfo.mTaskSnapshot;
                mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, appToken,
                mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, appToken,
@@ -133,7 +128,7 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
            } else /* suggestionType == STARTING_WINDOW_TYPE_NONE */ {
            } else /* suggestionType == STARTING_WINDOW_TYPE_NONE */ {
                // Don't add a staring window.
                // Don't add a staring window.
            }
            }
            if (mTaskLaunchingCallback != null && shouldSendToListener(suggestionType)) {
            if (mTaskLaunchingCallback != null && isSplashScreenType(suggestionType)) {
                int taskId = runningTaskInfo.taskId;
                int taskId = runningTaskInfo.taskId;
                int color = mStartingSurfaceDrawer.getStartingWindowBackgroundColorForTask(taskId);
                int color = mStartingSurfaceDrawer.getStartingWindowBackgroundColorForTask(taskId);
                mTaskLaunchingCallback.accept(taskId, suggestionType, color);
                mTaskLaunchingCallback.accept(taskId, suggestionType, color);
@@ -143,6 +138,12 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
        });
        });
    }
    }


    private static boolean isSplashScreenType(@StartingWindowType int suggestionType) {
        return suggestionType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
                || suggestionType == STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
                || suggestionType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
    }

    public void copySplashScreenView(int taskId) {
    public void copySplashScreenView(int taskId) {
        mSplashScreenExecutor.execute(() -> {
        mSplashScreenExecutor.execute(() -> {
            mStartingSurfaceDrawer.copySplashScreenView(taskId);
            mStartingSurfaceDrawer.copySplashScreenView(taskId);
Loading