diff options
Diffstat (limited to 'core/java/android/window/SplashScreenView.java')
| -rw-r--r-- | core/java/android/window/SplashScreenView.java | 64 |
1 files changed, 60 insertions, 4 deletions
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java index 6772afeb0270..4a3bf91645f2 100644 --- a/core/java/android/window/SplashScreenView.java +++ b/core/java/android/window/SplashScreenView.java @@ -34,8 +34,10 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import android.os.RemoteCallback; import android.os.Trace; import android.util.AttributeSet; import android.util.Log; @@ -76,7 +78,7 @@ import java.time.Instant; */ public final class SplashScreenView extends FrameLayout { private static final String TAG = SplashScreenView.class.getSimpleName(); - private static final boolean DEBUG = false; + private static final boolean DEBUG = Build.IS_DEBUGGABLE; private static final int LIGHT_BARS_MASK = WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS @@ -85,6 +87,7 @@ public final class SplashScreenView extends FrameLayout { | FLAG_TRANSLUCENT_NAVIGATION | FLAG_TRANSLUCENT_STATUS; private boolean mNotCopyable; + private boolean mIsCopied; private int mInitBackgroundColor; private int mInitIconBackgroundColor; private View mIconView; @@ -103,6 +106,10 @@ public final class SplashScreenView extends FrameLayout { private SurfaceControlViewHost.SurfacePackage mSurfacePackage; @Nullable private SurfaceView mSurfaceView; + @Nullable + private SurfaceControlViewHost mSurfaceHost; + @Nullable + private RemoteCallback mClientCallback; // cache original window and status private Window mWindow; @@ -127,6 +134,7 @@ public final class SplashScreenView extends FrameLayout { private Bitmap mParceledIconBitmap; private Drawable mIconDrawable; private SurfaceControlViewHost.SurfacePackage mSurfacePackage; + private RemoteCallback mClientCallback; private int mBrandingImageWidth; private int mBrandingImageHeight; private Drawable mBrandingDrawable; @@ -161,6 +169,7 @@ public final class SplashScreenView extends FrameLayout { } mIconAnimationStart = Instant.ofEpochMilli(parcelable.mIconAnimationStartMillis); mIconAnimationDuration = Duration.ofMillis(parcelable.mIconAnimationDurationMillis); + mClientCallback = parcelable.mClientCallback; if (DEBUG) { Log.d(TAG, String.format("Building from parcel drawable: %s", mIconDrawable)); } @@ -228,6 +237,7 @@ public final class SplashScreenView extends FrameLayout { view.mInitBackgroundColor = mBackgroundColor; view.mInitIconBackgroundColor = mIconBackground; view.setBackgroundColor(mBackgroundColor); + view.mClientCallback = mClientCallback; view.mBrandingImageView = view.findViewById(R.id.splashscreen_branding_view); @@ -285,7 +295,8 @@ public final class SplashScreenView extends FrameLayout { if (mSurfacePackage == null) { if (DEBUG) { Log.d(TAG, - "Creating Original SurfacePackage. SurfaceView: " + surfaceView); + "SurfaceControlViewHost created on thread " + + Thread.currentThread().getId()); } SurfaceControlViewHost viewHost = new SurfaceControlViewHost(mContext, @@ -297,6 +308,7 @@ public final class SplashScreenView extends FrameLayout { SurfaceControlViewHost.SurfacePackage surfacePackage = viewHost.getSurfacePackage(); surfaceView.setChildSurfacePackage(surfacePackage); view.mSurfacePackage = surfacePackage; + view.mSurfaceHost = viewHost; view.mSurfacePackageCopy = new SurfaceControlViewHost.SurfacePackage( surfacePackage); } else { @@ -357,6 +369,7 @@ public final class SplashScreenView extends FrameLayout { * @hide */ public void onCopied() { + mIsCopied = true; if (mSurfaceView == null) { return; } @@ -369,6 +382,12 @@ public final class SplashScreenView extends FrameLayout { mSurfacePackage = null; } + /** @hide **/ + @Nullable + public SurfaceControlViewHost getSurfaceHost() { + return mSurfaceHost; + } + @Override public void setAlpha(float alpha) { super.setAlpha(alpha); @@ -407,8 +426,7 @@ public final class SplashScreenView extends FrameLayout { if (DEBUG) { mSurfacePackage.getSurfaceControl().addOnReparentListener( (transaction, parent) -> Log.e(TAG, - String.format("SurfacePackage'surface reparented.\n Parent: %s", - parent), new Throwable())); + String.format("SurfacePackage'surface reparented to %s", parent))); Log.d(TAG, "Transferring surface " + mSurfaceView.toString()); } mSurfaceView.setChildSurfacePackage(mSurfacePackage); @@ -466,9 +484,36 @@ public final class SplashScreenView extends FrameLayout { mHasRemoved = true; } + /** @hide **/ + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + releaseAnimationSurfaceHost(); + } + + 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(); + }); + } else if (mSurfacePackage != null && mSurfaceHost == null) { + mSurfacePackage = null; + mClientCallback.sendResult(null); + } + } + /** * 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. + * * @hide */ public void attachHostActivityAndSetSystemUIColors(Activity activity, Window window) { @@ -585,6 +630,7 @@ public final class SplashScreenView extends FrameLayout { private long mIconAnimationDurationMillis; private SurfaceControlViewHost.SurfacePackage mSurfacePackage; + private RemoteCallback mClientCallback; public SplashScreenViewParcelable(SplashScreenView view) { mIconSize = view.mIconView.getWidth(); @@ -641,6 +687,7 @@ public final class SplashScreenView extends FrameLayout { mIconAnimationDurationMillis = source.readLong(); mIconBackground = source.readInt(); mSurfacePackage = source.readTypedObject(SurfaceControlViewHost.SurfacePackage.CREATOR); + mClientCallback = source.readTypedObject(RemoteCallback.CREATOR); } @Override @@ -660,6 +707,7 @@ public final class SplashScreenView extends FrameLayout { dest.writeLong(mIconAnimationDurationMillis); dest.writeInt(mIconBackground); dest.writeTypedObject(mSurfacePackage, flags); + dest.writeTypedObject(mClientCallback, flags); } public static final @NonNull Parcelable.Creator<SplashScreenViewParcelable> CREATOR = @@ -697,5 +745,13 @@ public final class SplashScreenView extends FrameLayout { int getIconBackground() { return mIconBackground; } + + /** + * Sets the {@link RemoteCallback} that will be called by the client to notify the shell + * of the removal of the {@link SplashScreenView}. + */ + public void setClientCallback(@NonNull RemoteCallback clientCallback) { + mClientCallback = clientCallback; + } } } |
