Let windowSplashScreenBackground work independent from icon.

The API windowSplashScreenBackground should work even when starting
window controller request to create an empty icon splash screen.

Bug: 182759603
Test: atest SplashscreenTests
Change-Id: I0c8178f27663f92acfdd0da8d216ff7ae94db981
This commit is contained in:
wilsonshih
2021-04-12 22:57:45 +08:00
parent 07d522f307
commit 25ddb677b6
2 changed files with 44 additions and 35 deletions

View File

@@ -109,11 +109,12 @@ public class SplashscreenContentDrawer {
* view on background thread so the view and the drawable can be create and pre-draw in
* parallel.
*
* @param emptyView Create a splash screen view without icon on it.
* @param consumer Receiving the SplashScreenView object, which will also be executed
* on splash screen thread. Note that the view can be null if failed.
*/
void createContentView(Context context, int splashScreenResId, ActivityInfo info,
int taskId, Consumer<SplashScreenView> consumer) {
void createContentView(Context context, boolean emptyView, int splashScreenResId,
ActivityInfo info, int taskId, Consumer<SplashScreenView> consumer) {
mSplashscreenWorkerHandler.post(() -> {
SplashScreenView contentView;
try {
@@ -121,7 +122,11 @@ public class SplashscreenContentDrawer {
context, splashScreenResId);
if (contentView == null) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "makeSplashScreenContentView");
contentView = makeSplashScreenContentView(context, info);
if (emptyView) {
contentView = makeEmptySplashScreenContentView(context);
} else {
contentView = makeSplashScreenContentView(context, info);
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
} catch (RuntimeException e) {
@@ -190,6 +195,18 @@ public class SplashscreenContentDrawer {
}
}
private SplashScreenView makeEmptySplashScreenContentView(Context context) {
getWindowAttrs(context, mTmpAttrs);
final StartingWindowViewBuilder builder = new StartingWindowViewBuilder();
final int themeBGColor = peekWindowBGColor(context);
final SplashScreenView view = builder
.setContext(context)
.setWindowBGColor(themeBGColor)
.build();
view.setNotCopyable();
return view;
}
private SplashScreenView makeSplashScreenContentView(Context context, ActivityInfo ai) {
updateDensity();

View File

@@ -317,46 +317,38 @@ public class StartingSurfaceDrawer {
// 3. Pre-draw the BitmapShader if the icon is immobile on splash screen worker thread, at
// the same time the splash screen thread should be executing Session#relayout. Blocking the
// traversal -> draw on splash screen thread until the BitmapShader of the icon is ready.
final Runnable setViewSynchronized;
if (!emptyView) {
// Record whether create splash screen view success, notify to current thread after
// create splash screen view finished.
final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier();
setViewSynchronized = () -> {
// waiting for setContentView before relayoutWindow
SplashScreenView contentView = viewSupplier.get();
final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
// if record == null, either the starting window added fail or removed already.
if (record != null) {
// if view == null then creation of content view was failed.
if (contentView != null) {
try {
win.setContentView(contentView);
contentView.cacheRootWindow(win);
} catch (RuntimeException e) {
Slog.w(TAG, "failed set content view to starting window "
+ "at taskId: " + taskId, e);
contentView = null;
}
// Record whether create splash screen view success, notify to current thread after
// create splash screen view finished.
final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier();
final Runnable setViewSynchronized = () -> {
// waiting for setContentView before relayoutWindow
SplashScreenView contentView = viewSupplier.get();
final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
// if record == null, either the starting window added fail or removed already.
if (record != null) {
// if view == null then creation of content view was failed.
if (contentView != null) {
try {
win.setContentView(contentView);
contentView.cacheRootWindow(win);
} catch (RuntimeException e) {
Slog.w(TAG, "failed set content view to starting window "
+ "at taskId: " + taskId, e);
contentView = null;
}
record.setSplashScreenView(contentView);
}
};
mSplashscreenContentDrawer.createContentView(context,
splashscreenContentResId[0], activityInfo, taskId, viewSupplier::setView);
} else {
setViewSynchronized = null;
}
record.setSplashScreenView(contentView);
}
};
mSplashscreenContentDrawer.createContentView(context, emptyView,
splashscreenContentResId[0], activityInfo, taskId, viewSupplier::setView);
try {
final View view = win.getDecorView();
final WindowManager wm = mContext.getSystemService(WindowManager.class);
postAddWindow(taskId, appToken, view, wm, params);
// all done
if (emptyView) {
return;
}
// We use the splash screen worker thread to create SplashScreenView while adding the
// window, as otherwise Choreographer#doFrame might be delayed on this thread.
// And since Choreographer#doFrame won't happen immediately after adding the window, if