mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-01 08:16:49 +00:00
152 lines
6.3 KiB
Java
152 lines
6.3 KiB
Java
|
|
/*
|
||
|
|
* Copyright (C) 2023 The Android Open Source Project
|
||
|
|
*
|
||
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
* you may not use this file except in compliance with the License.
|
||
|
|
* You may obtain a copy of the License at
|
||
|
|
*
|
||
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
*
|
||
|
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
* See the License for the specific language governing permissions and
|
||
|
|
* limitations under the License.
|
||
|
|
*/
|
||
|
|
|
||
|
|
package com.android.wm.shell.startingsurface;
|
||
|
|
|
||
|
|
import static android.graphics.Color.WHITE;
|
||
|
|
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
|
||
|
|
|
||
|
|
import android.app.ActivityManager;
|
||
|
|
import android.content.Context;
|
||
|
|
import android.content.pm.ActivityInfo;
|
||
|
|
import android.graphics.PixelFormat;
|
||
|
|
import android.graphics.Rect;
|
||
|
|
import android.hardware.display.DisplayManager;
|
||
|
|
import android.os.Binder;
|
||
|
|
import android.os.SystemClock;
|
||
|
|
import android.view.Display;
|
||
|
|
import android.view.SurfaceControl;
|
||
|
|
import android.view.SurfaceControlViewHost;
|
||
|
|
import android.view.WindowManager;
|
||
|
|
import android.widget.FrameLayout;
|
||
|
|
import android.window.SplashScreenView;
|
||
|
|
import android.window.StartingWindowInfo;
|
||
|
|
import android.window.StartingWindowRemovalInfo;
|
||
|
|
|
||
|
|
import com.android.wm.shell.common.ShellExecutor;
|
||
|
|
import com.android.wm.shell.common.TransactionPool;
|
||
|
|
|
||
|
|
class WindowlessSplashWindowCreator extends AbsSplashWindowCreator {
|
||
|
|
|
||
|
|
private final TransactionPool mTransactionPool;
|
||
|
|
|
||
|
|
WindowlessSplashWindowCreator(SplashscreenContentDrawer contentDrawer,
|
||
|
|
Context context,
|
||
|
|
ShellExecutor splashScreenExecutor,
|
||
|
|
DisplayManager displayManager,
|
||
|
|
StartingSurfaceDrawer.StartingWindowRecordManager startingWindowRecordManager,
|
||
|
|
TransactionPool pool) {
|
||
|
|
super(contentDrawer, context, splashScreenExecutor, displayManager,
|
||
|
|
startingWindowRecordManager);
|
||
|
|
mTransactionPool = pool;
|
||
|
|
}
|
||
|
|
|
||
|
|
void addSplashScreenStartingWindow(StartingWindowInfo windowInfo, SurfaceControl rootSurface) {
|
||
|
|
final ActivityManager.RunningTaskInfo taskInfo = windowInfo.taskInfo;
|
||
|
|
final ActivityInfo activityInfo = windowInfo.targetActivityInfo != null
|
||
|
|
? windowInfo.targetActivityInfo
|
||
|
|
: taskInfo.topActivityInfo;
|
||
|
|
if (activityInfo == null || activityInfo.packageName == null) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
final int displayId = taskInfo.displayId;
|
||
|
|
final Display display = mDisplayManager.getDisplay(displayId);
|
||
|
|
if (display == null) {
|
||
|
|
// Can't show splash screen on requested display, so skip showing at all.
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
final Context myContext = SplashscreenContentDrawer.createContext(mContext, windowInfo,
|
||
|
|
0 /* theme */, STARTING_WINDOW_TYPE_SPLASH_SCREEN, mDisplayManager);
|
||
|
|
if (myContext == null) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
final StartingSurfaceDrawer.WindowlessStartingWindow wlw =
|
||
|
|
new StartingSurfaceDrawer.WindowlessStartingWindow(
|
||
|
|
taskInfo.configuration, rootSurface);
|
||
|
|
final SurfaceControlViewHost viewHost = new SurfaceControlViewHost(
|
||
|
|
myContext, display, wlw, "WindowlessSplashWindowCreator");
|
||
|
|
final String title = "Windowless Splash " + taskInfo.taskId;
|
||
|
|
final WindowManager.LayoutParams lp = SplashscreenContentDrawer.createLayoutParameters(
|
||
|
|
myContext, windowInfo, STARTING_WINDOW_TYPE_SPLASH_SCREEN, title,
|
||
|
|
PixelFormat.TRANSLUCENT, new Binder());
|
||
|
|
final Rect windowBounds = taskInfo.configuration.windowConfiguration.getBounds();
|
||
|
|
lp.width = windowBounds.width();
|
||
|
|
lp.height = windowBounds.height();
|
||
|
|
final ActivityManager.TaskDescription taskDescription;
|
||
|
|
if (taskInfo.taskDescription != null) {
|
||
|
|
taskDescription = taskInfo.taskDescription;
|
||
|
|
} else {
|
||
|
|
taskDescription = new ActivityManager.TaskDescription();
|
||
|
|
taskDescription.setBackgroundColor(WHITE);
|
||
|
|
}
|
||
|
|
|
||
|
|
final FrameLayout rootLayout = new FrameLayout(
|
||
|
|
mSplashscreenContentDrawer.createViewContextWrapper(mContext));
|
||
|
|
viewHost.setView(rootLayout, lp);
|
||
|
|
|
||
|
|
final int bgColor = taskDescription.getBackgroundColor();
|
||
|
|
final SplashScreenView splashScreenView = mSplashscreenContentDrawer
|
||
|
|
.makeSimpleSplashScreenContentView(myContext, windowInfo, bgColor);
|
||
|
|
rootLayout.addView(splashScreenView);
|
||
|
|
final SplashWindowRecord record = new SplashWindowRecord(viewHost, splashScreenView,
|
||
|
|
wlw.mChildSurface, bgColor);
|
||
|
|
mStartingWindowRecordManager.addRecord(taskInfo.taskId, record);
|
||
|
|
windowInfo.notifyAddComplete(wlw.mChildSurface);
|
||
|
|
}
|
||
|
|
|
||
|
|
private class SplashWindowRecord extends StartingSurfaceDrawer.StartingWindowRecord {
|
||
|
|
private SurfaceControlViewHost mViewHost;
|
||
|
|
private final long mCreateTime;
|
||
|
|
private SurfaceControl mChildSurface;
|
||
|
|
private final SplashScreenView mSplashView;
|
||
|
|
|
||
|
|
SplashWindowRecord(SurfaceControlViewHost viewHost, SplashScreenView splashView,
|
||
|
|
SurfaceControl childSurface, int bgColor) {
|
||
|
|
mViewHost = viewHost;
|
||
|
|
mSplashView = splashView;
|
||
|
|
mChildSurface = childSurface;
|
||
|
|
mBGColor = bgColor;
|
||
|
|
mCreateTime = SystemClock.uptimeMillis();
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public boolean removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
|
||
|
|
if (!immediately) {
|
||
|
|
mSplashscreenContentDrawer.applyExitAnimation(mSplashView,
|
||
|
|
info.windowAnimationLeash, info.mainFrame,
|
||
|
|
this::release, mCreateTime, 0 /* roundedCornerRadius */);
|
||
|
|
} else {
|
||
|
|
release();
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void release() {
|
||
|
|
if (mChildSurface != null) {
|
||
|
|
final SurfaceControl.Transaction t = mTransactionPool.acquire();
|
||
|
|
t.remove(mChildSurface).apply();
|
||
|
|
mTransactionPool.release(t);
|
||
|
|
mChildSurface = null;
|
||
|
|
}
|
||
|
|
if (mViewHost != null) {
|
||
|
|
mViewHost.release();
|
||
|
|
mViewHost = null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|