summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/SplashScreenView.java53
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java15
4 files changed, 79 insertions, 19 deletions
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index 6a875d1be65d..f14294ee512e 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -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;
@@ -232,6 +234,15 @@ public final class SplashScreenView extends FrameLayout {
}
/**
+ * 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.
*/
public Builder setBrandingDrawable(@Nullable Drawable branding, int width, int height) {
@@ -262,7 +273,11 @@ public final class SplashScreenView extends FrameLayout {
// center icon
if (mIconDrawable instanceof SplashScreenView.IconAnimateListener
|| mSurfacePackage != null) {
- view.mIconView = createSurfaceView(view);
+ 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,17 +549,14 @@ public final class SplashScreenView extends FrameLayout {
private void releaseAnimationSurfaceHost() {
if (mSurfaceHost != null && !mIsCopied) {
- final SurfaceControlViewHost finalSurfaceHost = mSurfaceHost;
+ if (DEBUG) {
+ Log.d(TAG,
+ "Shell removed splash screen."
+ + " Releasing SurfaceControlViewHost on thread #"
+ + Thread.currentThread().getId());
+ }
+ releaseIconHost(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);
@@ -550,6 +564,18 @@ public final class SplashScreenView extends FrameLayout {
}
/**
+ * 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();
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 3db33f3f1216..8df7cbb27807 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -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) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
index 951b97e791c9..f0685a81d25f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
@@ -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) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 645b881558fb..debe6d56dd92 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -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,