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

Commit 76d20eed 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: I46ebb85f40dab8cd27f520fbdac81656fea52d51
parents dc66de53 a9a86113
Loading
Loading
Loading
Loading
+22 −7
Original line number Diff line number Diff line
@@ -127,11 +127,13 @@ public class SplashscreenContentDrawer {
     * parallel.
     *
     * @param suggestType Suggest type to create the splash screen view.
     * @param consumer Receiving the SplashScreenView object, which will also be executed
     *                 on splash screen thread. Note that the view can be null if failed.
     * @param splashScreenViewConsumer Receiving the SplashScreenView object, which will also be
     *                                 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,
            int taskId, Consumer<SplashScreenView> consumer) {
            int taskId, Consumer<SplashScreenView> splashScreenViewConsumer) {
        mSplashscreenWorkerHandler.post(() -> {
            SplashScreenView contentView;
            try {
@@ -143,7 +145,7 @@ public class SplashscreenContentDrawer {
                        + taskId, e);
                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);
    }

    private static int getSystemBGColor() {
    /**
     * @return Current system background color.
     */
    public static int getSystemBGColor() {
        final Context systemContext = ActivityThread.currentApplication();
        if (systemContext == null) {
            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);
    }

    /**
     * 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() {
        return new ColorDrawable(getSystemBGColor());
    }

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

package com.android.wm.shell.startingsurface;

import android.app.TaskInfo;
import android.graphics.Color;
/**
 * Interface to engage starting window feature.
 */
@@ -27,4 +29,11 @@ public interface StartingSurface {
    default IStartingWindow createExternalInterface() {
        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 Diff line number Diff line
@@ -26,17 +26,22 @@ import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
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.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
import android.util.Slog;
@@ -149,6 +154,12 @@ public class StartingSurfaceDrawer {
        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.
     *
@@ -170,10 +181,7 @@ public class StartingSurfaceDrawer {
        final int taskId = taskInfo.taskId;
        Context context = mContext;
        // replace with the default theme if the application didn't set
        final int theme = windowInfo.splashScreenThemeResId != 0
                ? windowInfo.splashScreenThemeResId
                : activityInfo.getThemeResource() != 0 ? activityInfo.getThemeResource()
                        : com.android.internal.R.style.Theme_DeviceDefault_DayNight;
        final int theme = getSplashScreenTheme(windowInfo.splashScreenThemeResId, activityInfo);
        if (DEBUG_SPLASH_SCREEN) {
            Slog.d(TAG, "addSplashScreen " + activityInfo.packageName
                    + " 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
                // animation.
                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) {
            // don't crash if something else bad happens, for example a
@@ -346,11 +358,11 @@ public class StartingSurfaceDrawer {
    }

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

    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.
     */
@@ -556,19 +605,16 @@ public class StartingSurfaceDrawer {
        private SplashScreenView mContentView;
        private boolean mSetSplashScreen;
        private @StartingWindowType int mSuggestType;

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

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

+45 −10
Original line number 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.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_NONE;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;

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

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

import androidx.annotation.BinderThread;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.TriConsumer;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
@@ -62,10 +68,11 @@ import com.android.wm.shell.common.TransactionPool;
public class StartingWindowController implements RemoteCallable<StartingWindowController> {
    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 = true;
    public static final boolean DEBUG_SPLASH_SCREEN = Build.isDebuggable();
    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 StartingWindowTypeAlgorithm mStartingWindowTypeAlgorithm;

@@ -73,6 +80,11 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
    private final StartingSurfaceImpl mImpl = new StartingSurfaceImpl();
    private final Context mContext;
    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,
            StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, TransactionPool pool) {
@@ -125,14 +137,20 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
                final TaskSnapshot snapshot = windowInfo.mTaskSnapshot;
                mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, appToken,
                        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 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);
                }
            }

            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,
            boolean playRevealAnimation) {
        mSplashScreenExecutor.execute(() -> {
            mStartingSurfaceDrawer.removeStartingWindow(taskId, leash, frame, playRevealAnimation);
        });
        mSplashScreenExecutor.execute(() -> mStartingSurfaceDrawer.removeStartingWindow(
                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);
            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 Diff line number Diff line
@@ -283,6 +283,10 @@ public class TaskSnapshotWindow {
        mClearWindowHandler = clearWindowHandler;
    }

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

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