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

Commit 47dc082e authored by Wei Sheng Shih's avatar Wei Sheng Shih Committed by Automerger Merge Worker
Browse files

Merge "Get starting window background color directly." into sc-dev am: a9a86113

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15020163

Change-Id: Ie972597bfe9e2d9ba342977992945bfa93c2ed25
parents d43fe279 a9a86113
Loading
Loading
Loading
Loading
+22 −7
Original line number Original line Diff line number Diff line
@@ -127,11 +127,13 @@ public class SplashscreenContentDrawer {
     * parallel.
     * parallel.
     *
     *
     * @param suggestType Suggest type to create the splash screen view.
     * @param suggestType Suggest type to create the splash screen view.
     * @param consumer Receiving the SplashScreenView object, which will also be executed
     * @param splashScreenViewConsumer Receiving the SplashScreenView object, which will also be
     *                 on splash screen thread. Note that the view can be null if failed.
     *                                 executed on splash screen thread. Note that the view can be
     *                                 null if failed.
     * @param bgColorConsumer Receiving the background color once it's estimated complete.
     */
     */
    void createContentView(Context context, @StartingWindowType int suggestType, ActivityInfo info,
    void createContentView(Context context, @StartingWindowType int suggestType, ActivityInfo info,
            int taskId, Consumer<SplashScreenView> consumer) {
            int taskId, Consumer<SplashScreenView> splashScreenViewConsumer) {
        mSplashscreenWorkerHandler.post(() -> {
        mSplashscreenWorkerHandler.post(() -> {
            SplashScreenView contentView;
            SplashScreenView contentView;
            try {
            try {
@@ -143,7 +145,7 @@ public class SplashscreenContentDrawer {
                        + taskId, e);
                        + taskId, e);
                contentView = null;
                contentView = null;
            }
            }
            consumer.accept(contentView);
            splashScreenViewConsumer.accept(contentView);
        });
        });
    }
    }


@@ -160,7 +162,10 @@ public class SplashscreenContentDrawer {
                com.android.wm.shell.R.dimen.starting_surface_exit_animation_window_shift_length);
                com.android.wm.shell.R.dimen.starting_surface_exit_animation_window_shift_length);
    }
    }


    private static int getSystemBGColor() {
    /**
     * @return Current system background color.
     */
    public static int getSystemBGColor() {
        final Context systemContext = ActivityThread.currentApplication();
        final Context systemContext = ActivityThread.currentApplication();
        if (systemContext == null) {
        if (systemContext == null) {
            Slog.e(TAG, "System context does not exist!");
            Slog.e(TAG, "System context does not exist!");
@@ -170,12 +175,22 @@ public class SplashscreenContentDrawer {
        return res.getColor(com.android.wm.shell.R.color.splash_window_background_default);
        return res.getColor(com.android.wm.shell.R.color.splash_window_background_default);
    }
    }


    /**
     * Estimate the background color of the app splash screen, this may take a while so use it only
     * if there is no starting window exists for that context.
     **/
    int estimateTaskBackgroundColor(Context context) {
        final SplashScreenWindowAttrs windowAttrs = new SplashScreenWindowAttrs();
        getWindowAttrs(context, windowAttrs);
        return peekWindowBGColor(context, windowAttrs);
    }

    private static Drawable createDefaultBackgroundDrawable() {
    private static Drawable createDefaultBackgroundDrawable() {
        return new ColorDrawable(getSystemBGColor());
        return new ColorDrawable(getSystemBGColor());
    }
    }


    /** Extract the window background color from {@code attrs}. */
    /** Extract the window background color from {@code attrs}. */
    public static int peekWindowBGColor(Context context, SplashScreenWindowAttrs attrs) {
    private static int peekWindowBGColor(Context context, SplashScreenWindowAttrs attrs) {
        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "peekWindowBGColor");
        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "peekWindowBGColor");
        final Drawable themeBGDrawable;
        final Drawable themeBGDrawable;
        if (attrs.mWindowBgColor != 0) {
        if (attrs.mWindowBgColor != 0) {
@@ -255,7 +270,7 @@ public class SplashscreenContentDrawer {
     * Get the {@link SplashScreenWindowAttrs} from {@code context} and fill them into
     * Get the {@link SplashScreenWindowAttrs} from {@code context} and fill them into
     * {@code attrs}.
     * {@code attrs}.
     */
     */
    public static void getWindowAttrs(Context context, SplashScreenWindowAttrs attrs) {
    private static void getWindowAttrs(Context context, SplashScreenWindowAttrs attrs) {
        final TypedArray typedArray = context.obtainStyledAttributes(
        final TypedArray typedArray = context.obtainStyledAttributes(
                com.android.internal.R.styleable.Window);
                com.android.internal.R.styleable.Window);
        attrs.mWindowBgResId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0);
        attrs.mWindowBgResId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0);
+9 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.wm.shell.startingsurface;
package com.android.wm.shell.startingsurface;


import android.app.TaskInfo;
import android.graphics.Color;
/**
/**
 * Interface to engage starting window feature.
 * Interface to engage starting window feature.
 */
 */
@@ -27,4 +29,11 @@ public interface StartingSurface {
    default IStartingWindow createExternalInterface() {
    default IStartingWindow createExternalInterface() {
        return null;
        return null;
    }
    }

    /**
     * Returns the background color for a starting window if existing.
     */
    default int getBackgroundColor(TaskInfo taskInfo) {
        return Color.BLACK;
    }
}
}
+61 −15
Original line number Original line Diff line number Diff line
@@ -26,17 +26,22 @@ 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;
import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager;
import android.app.ActivityThread;
import android.app.TaskInfo;
import android.content.Context;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Rect;
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;
import android.os.RemoteException;
import android.os.Trace;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.Slog;
import android.util.Slog;
@@ -149,6 +154,12 @@ public class StartingSurfaceDrawer {
        return context.createDisplayContext(targetDisplay);
        return context.createDisplayContext(targetDisplay);
    }
    }


    private int getSplashScreenTheme(int splashScreenThemeResId, ActivityInfo activityInfo) {
        return splashScreenThemeResId != 0
                ? splashScreenThemeResId
                : activityInfo.getThemeResource() != 0 ? activityInfo.getThemeResource()
                        : com.android.internal.R.style.Theme_DeviceDefault_DayNight;
    }
    /**
    /**
     * Called when a task need a splash screen starting window.
     * Called when a task need a splash screen starting window.
     *
     *
@@ -170,10 +181,7 @@ public class StartingSurfaceDrawer {
        final int taskId = taskInfo.taskId;
        final int taskId = taskInfo.taskId;
        Context context = mContext;
        Context context = mContext;
        // replace with the default theme if the application didn't set
        // replace with the default theme if the application didn't set
        final int theme = windowInfo.splashScreenThemeResId != 0
        final int theme = getSplashScreenTheme(windowInfo.splashScreenThemeResId, activityInfo);
                ? windowInfo.splashScreenThemeResId
                : activityInfo.getThemeResource() != 0 ? activityInfo.getThemeResource()
                        : 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
@@ -336,6 +344,10 @@ public class StartingSurfaceDrawer {
                // the window before first round relayoutWindow, which will happen after insets
                // the window before first round relayoutWindow, which will happen after insets
                // animation.
                // animation.
                mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null);
                mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null);
                // Block until we get the background color.
                final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
                final SplashScreenView contentView = viewSupplier.get();
                record.mBGColor = contentView.getInitBackgroundColor();
            }
            }
        } catch (RuntimeException e) {
        } catch (RuntimeException e) {
            // don't crash if something else bad happens, for example a
            // don't crash if something else bad happens, for example a
@@ -346,11 +358,11 @@ public class StartingSurfaceDrawer {
    }
    }


    int getStartingWindowBackgroundColorForTask(int taskId) {
    int getStartingWindowBackgroundColorForTask(int taskId) {
        StartingWindowRecord startingWindowRecord = mStartingWindowRecords.get(taskId);
        final StartingWindowRecord startingWindowRecord = mStartingWindowRecords.get(taskId);
        if (startingWindowRecord == null || startingWindowRecord.mContentView == null) {
        if (startingWindowRecord == null) {
            return 0;
            return Color.TRANSPARENT;
        }
        }
        return startingWindowRecord.mContentView.getInitBackgroundColor();
        return startingWindowRecord.mBGColor;
    }
    }


    private static class SplashScreenViewSupplier implements Supplier<SplashScreenView> {
    private static class SplashScreenViewSupplier implements Supplier<SplashScreenView> {
@@ -378,6 +390,43 @@ public class StartingSurfaceDrawer {
        }
        }
    }
    }


    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 a task need a snapshot starting window.
     * Called when a task need a snapshot starting window.
     */
     */
@@ -556,19 +605,16 @@ public class StartingSurfaceDrawer {
        private SplashScreenView mContentView;
        private SplashScreenView mContentView;
        private boolean mSetSplashScreen;
        private boolean mSetSplashScreen;
        private @StartingWindowType int mSuggestType;
        private @StartingWindowType int mSuggestType;

        private int mBGColor;
        StartingWindowRecord(IBinder appToken, View decorView,
                TaskSnapshotWindow taskSnapshotWindow) {
            mAppToken = appToken;
            mDecorView = decorView;
            mTaskSnapshotWindow = taskSnapshotWindow;
        }


        StartingWindowRecord(IBinder appToken, View decorView,
        StartingWindowRecord(IBinder appToken, View decorView,
                TaskSnapshotWindow taskSnapshotWindow, @StartingWindowType int suggestType) {
                TaskSnapshotWindow taskSnapshotWindow, @StartingWindowType int suggestType) {
            mAppToken = appToken;
            mAppToken = appToken;
            mDecorView = decorView;
            mDecorView = decorView;
            mTaskSnapshotWindow = taskSnapshotWindow;
            mTaskSnapshotWindow = taskSnapshotWindow;
            if (mTaskSnapshotWindow != null) {
                mBGColor = mTaskSnapshotWindow.getBackgroundColor();
            }
            mSuggestType = suggestType;
            mSuggestType = suggestType;
        }
        }


+45 −10
Original line number Original line Diff line number Diff line
@@ -18,18 +18,23 @@ 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_LEGACY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE;
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;


import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;


import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.TaskInfo;
import android.content.Context;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Rect;
import android.os.Build;
import android.os.IBinder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.Trace;
import android.os.Trace;
import android.util.Slog;
import android.util.Slog;
import android.util.SparseIntArray;
import android.view.SurfaceControl;
import android.view.SurfaceControl;
import android.window.StartingWindowInfo;
import android.window.StartingWindowInfo;
import android.window.StartingWindowInfo.StartingWindowType;
import android.window.StartingWindowInfo.StartingWindowType;
@@ -38,6 +43,7 @@ import android.window.TaskSnapshot;


import androidx.annotation.BinderThread;
import androidx.annotation.BinderThread;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.TriConsumer;
import com.android.internal.util.function.TriConsumer;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.ShellExecutor;
@@ -62,10 +68,11 @@ import com.android.wm.shell.common.TransactionPool;
public class StartingWindowController implements RemoteCallable<StartingWindowController> {
public class StartingWindowController implements RemoteCallable<StartingWindowController> {
    private static final String TAG = StartingWindowController.class.getSimpleName();
    private static final String TAG = StartingWindowController.class.getSimpleName();


    // TODO b/183150443 Keep this flag open for a while, several things might need to adjust.
    public static final boolean DEBUG_SPLASH_SCREEN = Build.isDebuggable();
    public static final boolean DEBUG_SPLASH_SCREEN = true;
    public static final boolean DEBUG_TASK_SNAPSHOT = false;
    public static final boolean DEBUG_TASK_SNAPSHOT = false;


    private static final long TASK_BG_COLOR_RETAIN_TIME_MS = 5000;

    private final StartingSurfaceDrawer mStartingSurfaceDrawer;
    private final StartingSurfaceDrawer mStartingSurfaceDrawer;
    private final StartingWindowTypeAlgorithm mStartingWindowTypeAlgorithm;
    private final StartingWindowTypeAlgorithm mStartingWindowTypeAlgorithm;


@@ -73,6 +80,11 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
    private final StartingSurfaceImpl mImpl = new StartingSurfaceImpl();
    private final StartingSurfaceImpl mImpl = new StartingSurfaceImpl();
    private final Context mContext;
    private final Context mContext;
    private final ShellExecutor mSplashScreenExecutor;
    private final ShellExecutor mSplashScreenExecutor;
    /**
     * Need guarded because it has exposed to StartingSurface
     */
    @GuardedBy("mTaskBackgroundColors")
    private final SparseIntArray mTaskBackgroundColors = new SparseIntArray();


    public StartingWindowController(Context context, ShellExecutor splashScreenExecutor,
    public StartingWindowController(Context context, ShellExecutor splashScreenExecutor,
            StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, TransactionPool pool) {
            StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, TransactionPool pool) {
@@ -125,14 +137,20 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
                final TaskSnapshot snapshot = windowInfo.mTaskSnapshot;
                final TaskSnapshot snapshot = windowInfo.mTaskSnapshot;
                mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, appToken,
                mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, appToken,
                        snapshot);
                        snapshot);
            } else /* suggestionType == STARTING_WINDOW_TYPE_NONE */ {
                // Don't add a staring window.
            }
            }
            if (mTaskLaunchingCallback != null && isSplashScreenType(suggestionType)) {
            if (suggestionType != STARTING_WINDOW_TYPE_NONE) {
                int taskId = runningTaskInfo.taskId;
                int taskId = runningTaskInfo.taskId;
                int color = mStartingSurfaceDrawer.getStartingWindowBackgroundColorForTask(taskId);
                int color = mStartingSurfaceDrawer
                        .getStartingWindowBackgroundColorForTask(taskId);
                if (color != Color.TRANSPARENT) {
                    synchronized (mTaskBackgroundColors) {
                        mTaskBackgroundColors.append(taskId, color);
                    }
                }
                if (mTaskLaunchingCallback != null && isSplashScreenType(suggestionType)) {
                    mTaskLaunchingCallback.accept(taskId, suggestionType, color);
                    mTaskLaunchingCallback.accept(taskId, suggestionType, color);
                }
                }
            }


            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        });
        });
@@ -163,9 +181,13 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
     */
     */
    public void removeStartingWindow(int taskId, SurfaceControl leash, Rect frame,
    public void removeStartingWindow(int taskId, SurfaceControl leash, Rect frame,
            boolean playRevealAnimation) {
            boolean playRevealAnimation) {
        mSplashScreenExecutor.execute(() -> {
        mSplashScreenExecutor.execute(() -> mStartingSurfaceDrawer.removeStartingWindow(
            mStartingSurfaceDrawer.removeStartingWindow(taskId, leash, frame, playRevealAnimation);
                taskId, leash, frame, playRevealAnimation));
        });
        mSplashScreenExecutor.executeDelayed(() -> {
            synchronized (mTaskBackgroundColors) {
                mTaskBackgroundColors.delete(taskId);
            }
        }, TASK_BG_COLOR_RETAIN_TIME_MS);
    }
    }


    /**
    /**
@@ -182,6 +204,19 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
            mIStartingWindow = new IStartingWindowImpl(StartingWindowController.this);
            mIStartingWindow = new IStartingWindowImpl(StartingWindowController.this);
            return mIStartingWindow;
            return mIStartingWindow;
        }
        }

        @Override
        public int getBackgroundColor(TaskInfo taskInfo) {
            synchronized (mTaskBackgroundColors) {
                final int index = mTaskBackgroundColors.indexOfKey(taskInfo.taskId);
                if (index >= 0) {
                    return mTaskBackgroundColors.valueAt(index);
                }
            }
            final int color = mStartingSurfaceDrawer.estimateTaskBackgroundColor(taskInfo);
            return color != Color.TRANSPARENT
                    ? color : SplashscreenContentDrawer.getSystemBGColor();
        }
    }
    }


    /**
    /**
+4 −0
Original line number Original line Diff line number Diff line
@@ -283,6 +283,10 @@ public class TaskSnapshotWindow {
        mClearWindowHandler = clearWindowHandler;
        mClearWindowHandler = clearWindowHandler;
    }
    }


    int getBackgroundColor() {
        return mBackgroundPaint.getColor();
    }

    /**
    /**
     * Ask system bar background painter to draw status bar background.
     * Ask system bar background painter to draw status bar background.
     * @hide
     * @hide
Loading