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

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

Merge "Adding the SurfaceView on splash screen thread." into sc-v2-dev am: 50c8b2d9

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

Change-Id: I0ef863bf3695473081885eb875f952a2aaf2f71d
parents 929a3921 50c8b2d9
Loading
Loading
Loading
Loading
+42 −11
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import com.android.internal.util.ContrastColorUtil;

import java.time.Duration;
import java.time.Instant;
import java.util.function.Consumer;

/**
 * <p>The view which allows an activity to customize its splash screen exit animation.</p>
@@ -144,6 +145,7 @@ public final class SplashScreenView extends FrameLayout {
        private Bitmap mParceledBrandingBitmap;
        private Instant mIconAnimationStart;
        private Duration mIconAnimationDuration;
        private Consumer<Runnable> mUiThreadInitTask;

        public Builder(@NonNull Context context) {
            mContext = context;
@@ -231,6 +233,15 @@ public final class SplashScreenView extends FrameLayout {
            return this;
        }

        /**
         * Set the Runnable that can receive the task which should be executed on UI thread.
         * @param uiThreadInitTask
         */
        public Builder setUiThreadInitConsumer(Consumer<Runnable> uiThreadInitTask) {
            mUiThreadInitTask = uiThreadInitTask;
            return this;
        }

        /**
         * Set the Drawable object and size for the branding view.
         */
@@ -262,7 +273,11 @@ public final class SplashScreenView extends FrameLayout {
            // center icon
            if (mIconDrawable instanceof SplashScreenView.IconAnimateListener
                    || mSurfacePackage != null) {
                if (mUiThreadInitTask != null) {
                    mUiThreadInitTask.accept(() -> view.mIconView = createSurfaceView(view));
                } else {
                    view.mIconView = createSurfaceView(view);
                }
                view.initIconAnimation(mIconDrawable,
                        mIconAnimationDuration != null ? mIconAnimationDuration.toMillis() : 0);
                view.mIconAnimationStart = mIconAnimationStart;
@@ -316,6 +331,7 @@ public final class SplashScreenView extends FrameLayout {
        }

        private SurfaceView createSurfaceView(@NonNull SplashScreenView view) {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "SplashScreenView#createSurfaceView");
            final Context viewContext = view.getContext();
            final SurfaceView surfaceView = new SurfaceView(viewContext);
            surfaceView.setPadding(0, 0, 0, 0);
@@ -361,6 +377,7 @@ public final class SplashScreenView extends FrameLayout {

            view.addView(surfaceView);
            view.mSurfaceView = surfaceView;
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            return surfaceView;
        }
    }
@@ -532,23 +549,32 @@ public final class SplashScreenView extends FrameLayout {

    private void releaseAnimationSurfaceHost() {
        if (mSurfaceHost != null && !mIsCopied) {
            final SurfaceControlViewHost finalSurfaceHost = mSurfaceHost;
            mSurfaceHost = null;
            finalSurfaceHost.getView().post(() -> {
            if (DEBUG) {
                Log.d(TAG,
                        "Shell removed splash screen."
                                + " Releasing SurfaceControlViewHost on thread #"
                                + Thread.currentThread().getId());
            }
                finalSurfaceHost.release();
            });
            releaseIconHost(mSurfaceHost);
            mSurfaceHost = null;
        } else if (mSurfacePackage != null && mSurfaceHost == null) {
            mSurfacePackage = null;
            mClientCallback.sendResult(null);
        }
    }

    /**
     * Release the host which hold the SurfaceView of the icon.
     * @hide
     */
    public static void releaseIconHost(SurfaceControlViewHost host) {
        final Drawable background = host.getView().getBackground();
        if (background instanceof SplashScreenView.IconAnimateListener) {
            ((SplashScreenView.IconAnimateListener) background).stopAnimation();
        }
        host.release();
    }

    /**
     * Called when this view is attached to an activity. This also makes SystemUI colors
     * transparent so the content of splash screen view can draw fully.
@@ -640,6 +666,11 @@ public final class SplashScreenView extends FrameLayout {
         * @return true if this drawable object can also be animated and it can be played now.
         */
        boolean prepareAnimate(long duration, Runnable startListener);

        /**
         * Stop animation.
         */
        void stopAnimation();
    }

    /**
+17 −6
Original line number Diff line number Diff line
@@ -138,12 +138,14 @@ public class SplashscreenContentDrawer {
     *                                 null if failed.
     */
    void createContentView(Context context, @StartingWindowType int suggestType, ActivityInfo info,
            int taskId, Consumer<SplashScreenView> splashScreenViewConsumer) {
            int taskId, Consumer<SplashScreenView> splashScreenViewConsumer,
            Consumer<Runnable> uiThreadInitConsumer) {
        mSplashscreenWorkerHandler.post(() -> {
            SplashScreenView contentView;
            try {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "makeSplashScreenContentView");
                contentView = makeSplashScreenContentView(context, info, suggestType);
                contentView = makeSplashScreenContentView(context, info, suggestType,
                        uiThreadInitConsumer);
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            } catch (RuntimeException e) {
                Slog.w(TAG, "failed creating starting window content at taskId: "
@@ -239,7 +241,7 @@ public class SplashscreenContentDrawer {
    }

    private SplashScreenView makeSplashScreenContentView(Context context, ActivityInfo ai,
            @StartingWindowType int suggestType) {
            @StartingWindowType int suggestType, Consumer<Runnable> uiThreadInitConsumer) {
        updateDensity();

        getWindowAttrs(context, mTmpAttrs);
@@ -254,6 +256,7 @@ public class SplashscreenContentDrawer {
                .setWindowBGColor(themeBGColor)
                .overlayDrawable(legacyDrawable)
                .chooseStyle(suggestType)
                .setUiThreadInitConsumer(uiThreadInitConsumer)
                .build();
    }

@@ -324,6 +327,7 @@ public class SplashscreenContentDrawer {
        private int mThemeColor;
        private Drawable[] mFinalIconDrawables;
        private int mFinalIconSize = mIconSize;
        private Consumer<Runnable> mUiThreadInitTask;

        StartingWindowViewBuilder(@NonNull Context context, @NonNull ActivityInfo aInfo) {
            mContext = context;
@@ -345,6 +349,11 @@ public class SplashscreenContentDrawer {
            return this;
        }

        StartingWindowViewBuilder setUiThreadInitConsumer(Consumer<Runnable> uiThreadInitTask) {
            mUiThreadInitTask = uiThreadInitTask;
            return this;
        }

        SplashScreenView build() {
            Drawable iconDrawable;
            final int animationDuration;
@@ -391,7 +400,8 @@ public class SplashscreenContentDrawer {
                animationDuration = 0;
            }

            return fillViewWithIcon(mFinalIconSize, mFinalIconDrawables, animationDuration);
            return fillViewWithIcon(mFinalIconSize, mFinalIconDrawables, animationDuration,
                    mUiThreadInitTask);
        }

        private class ShapeIconFactory extends BaseIconFactory {
@@ -469,7 +479,7 @@ public class SplashscreenContentDrawer {
        }

        private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable,
                int animationDuration) {
                int animationDuration, Consumer<Runnable> uiThreadInitTask) {
            Drawable foreground = null;
            Drawable background = null;
            if (iconDrawable != null) {
@@ -485,7 +495,8 @@ public class SplashscreenContentDrawer {
                    .setIconSize(iconSize)
                    .setIconBackground(background)
                    .setCenterViewDrawable(foreground)
                    .setAnimationDurationMillis(animationDuration);
                    .setAnimationDurationMillis(animationDuration)
                    .setUiThreadInitConsumer(uiThreadInitTask);

            if (mSuggestType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
                    && mTmpAttrs.mBrandingImage != null) {
+7 −0
Original line number Diff line number Diff line
@@ -304,6 +304,13 @@ public class SplashscreenIconDrawableFactory {
            return true;
        }

        @Override
        public void stopAnimation() {
            if (mIconAnimator != null) {
                mIconAnimator.end();
            }
        }

        private final Callback mCallback = new Callback() {
            @Override
            public void invalidateDrawable(@NonNull Drawable who) {
+13 −2
Original line number Diff line number Diff line
@@ -332,7 +332,7 @@ public class StartingSurfaceDrawer {
            mSysuiProxy.requestTopUi(true, TAG);
        }
        mSplashscreenContentDrawer.createContentView(context, suggestType, activityInfo, taskId,
                viewSupplier::setView);
                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
@@ -367,6 +367,7 @@ public class StartingSurfaceDrawer {
    private static class SplashScreenViewSupplier implements Supplier<SplashScreenView> {
        private SplashScreenView mView;
        private boolean mIsViewSet;
        private Runnable mUiThreadInitTask;
        void setView(SplashScreenView view) {
            synchronized (this) {
                mView = view;
@@ -375,6 +376,12 @@ public class StartingSurfaceDrawer {
            }
        }

        void setUiThreadInitTask(Runnable initTask) {
            synchronized (this) {
                mUiThreadInitTask = initTask;
            }
        }

        @Override
        public @Nullable SplashScreenView get() {
            synchronized (this) {
@@ -384,6 +391,10 @@ public class StartingSurfaceDrawer {
                    } catch (InterruptedException ignored) {
                    }
                }
                if (mUiThreadInitTask != null) {
                    mUiThreadInitTask.run();
                    mUiThreadInitTask = null;
                }
                return mView;
            }
        }
@@ -506,7 +517,7 @@ public class StartingSurfaceDrawer {
            Slog.v(TAG, reason + "the splash screen. Releasing SurfaceControlViewHost for task:"
                    + taskId);
        }
        viewHost.getView().post(viewHost::release);
        SplashScreenView.releaseIconHost(viewHost);
    }

    protected boolean addWindow(int taskId, IBinder appToken, View view, Display display,