Merge "Release the SurfacePackageViewHost on splash screen removed" into sc-dev
This commit is contained in:
@@ -3190,6 +3190,7 @@ package android.window {
|
|||||||
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]);
|
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]);
|
||||||
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public android.window.WindowContainerToken getImeTarget(int);
|
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public android.window.WindowContainerToken getImeTarget(int);
|
||||||
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getRootTasks(int, @NonNull int[]);
|
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getRootTasks(int, @NonNull int[]);
|
||||||
|
method @BinderThread public void onAppSplashScreenViewRemoved(int);
|
||||||
method @BinderThread public void onBackPressedOnTaskRoot(@NonNull android.app.ActivityManager.RunningTaskInfo);
|
method @BinderThread public void onBackPressedOnTaskRoot(@NonNull android.app.ActivityManager.RunningTaskInfo);
|
||||||
method @BinderThread public void onTaskAppeared(@NonNull android.app.ActivityManager.RunningTaskInfo, @NonNull android.view.SurfaceControl);
|
method @BinderThread public void onTaskAppeared(@NonNull android.app.ActivityManager.RunningTaskInfo, @NonNull android.view.SurfaceControl);
|
||||||
method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo);
|
method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo);
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ oneway interface ITaskOrganizer {
|
|||||||
*/
|
*/
|
||||||
void copySplashScreenView(int taskId);
|
void copySplashScreenView(int taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the Task removed the splash screen.
|
||||||
|
*/
|
||||||
|
void onAppSplashScreenViewRemoved(int taskId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback when the Task is available for the registered organizer. The client is responsible
|
* A callback when the Task is available for the registered organizer. The client is responsible
|
||||||
* for releasing the SurfaceControl in the callback. For non-root tasks, the leash may initially
|
* for releasing the SurfaceControl in the callback. For non-root tasks, the leash may initially
|
||||||
|
|||||||
@@ -34,8 +34,10 @@ import android.graphics.PixelFormat;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
import android.os.RemoteCallback;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -76,7 +78,7 @@ import java.time.Instant;
|
|||||||
*/
|
*/
|
||||||
public final class SplashScreenView extends FrameLayout {
|
public final class SplashScreenView extends FrameLayout {
|
||||||
private static final String TAG = SplashScreenView.class.getSimpleName();
|
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 =
|
private static final int LIGHT_BARS_MASK =
|
||||||
WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
|
WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
|
||||||
@@ -85,6 +87,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
| FLAG_TRANSLUCENT_NAVIGATION | FLAG_TRANSLUCENT_STATUS;
|
| FLAG_TRANSLUCENT_NAVIGATION | FLAG_TRANSLUCENT_STATUS;
|
||||||
|
|
||||||
private boolean mNotCopyable;
|
private boolean mNotCopyable;
|
||||||
|
private boolean mIsCopied;
|
||||||
private int mInitBackgroundColor;
|
private int mInitBackgroundColor;
|
||||||
private int mInitIconBackgroundColor;
|
private int mInitIconBackgroundColor;
|
||||||
private View mIconView;
|
private View mIconView;
|
||||||
@@ -103,6 +106,10 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
|
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
|
||||||
@Nullable
|
@Nullable
|
||||||
private SurfaceView mSurfaceView;
|
private SurfaceView mSurfaceView;
|
||||||
|
@Nullable
|
||||||
|
private SurfaceControlViewHost mSurfaceHost;
|
||||||
|
@Nullable
|
||||||
|
private RemoteCallback mClientCallback;
|
||||||
|
|
||||||
// cache original window and status
|
// cache original window and status
|
||||||
private Window mWindow;
|
private Window mWindow;
|
||||||
@@ -127,6 +134,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
private Bitmap mParceledIconBitmap;
|
private Bitmap mParceledIconBitmap;
|
||||||
private Drawable mIconDrawable;
|
private Drawable mIconDrawable;
|
||||||
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
|
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
|
||||||
|
private RemoteCallback mClientCallback;
|
||||||
private int mBrandingImageWidth;
|
private int mBrandingImageWidth;
|
||||||
private int mBrandingImageHeight;
|
private int mBrandingImageHeight;
|
||||||
private Drawable mBrandingDrawable;
|
private Drawable mBrandingDrawable;
|
||||||
@@ -161,6 +169,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
mIconAnimationStart = Instant.ofEpochMilli(parcelable.mIconAnimationStartMillis);
|
mIconAnimationStart = Instant.ofEpochMilli(parcelable.mIconAnimationStartMillis);
|
||||||
mIconAnimationDuration = Duration.ofMillis(parcelable.mIconAnimationDurationMillis);
|
mIconAnimationDuration = Duration.ofMillis(parcelable.mIconAnimationDurationMillis);
|
||||||
|
mClientCallback = parcelable.mClientCallback;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, String.format("Building from parcel drawable: %s", mIconDrawable));
|
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.mInitBackgroundColor = mBackgroundColor;
|
||||||
view.mInitIconBackgroundColor = mIconBackground;
|
view.mInitIconBackgroundColor = mIconBackground;
|
||||||
view.setBackgroundColor(mBackgroundColor);
|
view.setBackgroundColor(mBackgroundColor);
|
||||||
|
view.mClientCallback = mClientCallback;
|
||||||
|
|
||||||
view.mBrandingImageView = view.findViewById(R.id.splashscreen_branding_view);
|
view.mBrandingImageView = view.findViewById(R.id.splashscreen_branding_view);
|
||||||
|
|
||||||
@@ -285,7 +295,8 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
if (mSurfacePackage == null) {
|
if (mSurfacePackage == null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG,
|
Log.d(TAG,
|
||||||
"Creating Original SurfacePackage. SurfaceView: " + surfaceView);
|
"SurfaceControlViewHost created on thread "
|
||||||
|
+ Thread.currentThread().getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceControlViewHost viewHost = new SurfaceControlViewHost(mContext,
|
SurfaceControlViewHost viewHost = new SurfaceControlViewHost(mContext,
|
||||||
@@ -297,6 +308,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
SurfaceControlViewHost.SurfacePackage surfacePackage = viewHost.getSurfacePackage();
|
SurfaceControlViewHost.SurfacePackage surfacePackage = viewHost.getSurfacePackage();
|
||||||
surfaceView.setChildSurfacePackage(surfacePackage);
|
surfaceView.setChildSurfacePackage(surfacePackage);
|
||||||
view.mSurfacePackage = surfacePackage;
|
view.mSurfacePackage = surfacePackage;
|
||||||
|
view.mSurfaceHost = viewHost;
|
||||||
view.mSurfacePackageCopy = new SurfaceControlViewHost.SurfacePackage(
|
view.mSurfacePackageCopy = new SurfaceControlViewHost.SurfacePackage(
|
||||||
surfacePackage);
|
surfacePackage);
|
||||||
} else {
|
} else {
|
||||||
@@ -357,6 +369,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void onCopied() {
|
public void onCopied() {
|
||||||
|
mIsCopied = true;
|
||||||
if (mSurfaceView == null) {
|
if (mSurfaceView == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -369,6 +382,12 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
mSurfacePackage = null;
|
mSurfacePackage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hide **/
|
||||||
|
@Nullable
|
||||||
|
public SurfaceControlViewHost getSurfaceHost() {
|
||||||
|
return mSurfaceHost;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAlpha(float alpha) {
|
public void setAlpha(float alpha) {
|
||||||
super.setAlpha(alpha);
|
super.setAlpha(alpha);
|
||||||
@@ -407,8 +426,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
mSurfacePackage.getSurfaceControl().addOnReparentListener(
|
mSurfacePackage.getSurfaceControl().addOnReparentListener(
|
||||||
(transaction, parent) -> Log.e(TAG,
|
(transaction, parent) -> Log.e(TAG,
|
||||||
String.format("SurfacePackage'surface reparented.\n Parent: %s",
|
String.format("SurfacePackage'surface reparented to %s", parent)));
|
||||||
parent), new Throwable()));
|
|
||||||
Log.d(TAG, "Transferring surface " + mSurfaceView.toString());
|
Log.d(TAG, "Transferring surface " + mSurfaceView.toString());
|
||||||
}
|
}
|
||||||
mSurfaceView.setChildSurfacePackage(mSurfacePackage);
|
mSurfaceView.setChildSurfacePackage(mSurfacePackage);
|
||||||
@@ -466,9 +484,36 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
mHasRemoved = true;
|
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
|
* 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.
|
* transparent so the content of splash screen view can draw fully.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void attachHostActivityAndSetSystemUIColors(Activity activity, Window window) {
|
public void attachHostActivityAndSetSystemUIColors(Activity activity, Window window) {
|
||||||
@@ -585,6 +630,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
private long mIconAnimationDurationMillis;
|
private long mIconAnimationDurationMillis;
|
||||||
|
|
||||||
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
|
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
|
||||||
|
private RemoteCallback mClientCallback;
|
||||||
|
|
||||||
public SplashScreenViewParcelable(SplashScreenView view) {
|
public SplashScreenViewParcelable(SplashScreenView view) {
|
||||||
mIconSize = view.mIconView.getWidth();
|
mIconSize = view.mIconView.getWidth();
|
||||||
@@ -641,6 +687,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
mIconAnimationDurationMillis = source.readLong();
|
mIconAnimationDurationMillis = source.readLong();
|
||||||
mIconBackground = source.readInt();
|
mIconBackground = source.readInt();
|
||||||
mSurfacePackage = source.readTypedObject(SurfaceControlViewHost.SurfacePackage.CREATOR);
|
mSurfacePackage = source.readTypedObject(SurfaceControlViewHost.SurfacePackage.CREATOR);
|
||||||
|
mClientCallback = source.readTypedObject(RemoteCallback.CREATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -660,6 +707,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
dest.writeLong(mIconAnimationDurationMillis);
|
dest.writeLong(mIconAnimationDurationMillis);
|
||||||
dest.writeInt(mIconBackground);
|
dest.writeInt(mIconBackground);
|
||||||
dest.writeTypedObject(mSurfacePackage, flags);
|
dest.writeTypedObject(mSurfacePackage, flags);
|
||||||
|
dest.writeTypedObject(mClientCallback, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final @NonNull Parcelable.Creator<SplashScreenViewParcelable> CREATOR =
|
public static final @NonNull Parcelable.Creator<SplashScreenViewParcelable> CREATOR =
|
||||||
@@ -697,5 +745,13 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
int getIconBackground() {
|
int getIconBackground() {
|
||||||
return mIconBackground;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,16 @@ public class TaskOrganizer extends WindowOrganizer {
|
|||||||
@BinderThread
|
@BinderThread
|
||||||
public void copySplashScreenView(int taskId) {}
|
public void copySplashScreenView(int taskId) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the shell ({@link com.android.wm.shell.ShellTaskOrganizer} that the client has
|
||||||
|
* removed the splash screen view.
|
||||||
|
* @see com.android.wm.shell.ShellTaskOrganizer#onAppSplashScreenViewRemoved(int)
|
||||||
|
* @see SplashScreenView#remove()
|
||||||
|
*/
|
||||||
|
@BinderThread
|
||||||
|
public void onAppSplashScreenViewRemoved(int taskId) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a task with the registered windowing mode can be controlled by this task
|
* Called when a task with the registered windowing mode can be controlled by this task
|
||||||
* organizer. For non-root tasks, the leash may initially be hidden so it is up to the organizer
|
* organizer. For non-root tasks, the leash may initially be hidden so it is up to the organizer
|
||||||
@@ -236,10 +246,15 @@ public class TaskOrganizer extends WindowOrganizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void copySplashScreenView(int taskId) {
|
public void copySplashScreenView(int taskId) {
|
||||||
mExecutor.execute(() -> TaskOrganizer.this.copySplashScreenView(taskId));
|
mExecutor.execute(() -> TaskOrganizer.this.copySplashScreenView(taskId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAppSplashScreenViewRemoved(int taskId) {
|
||||||
|
mExecutor.execute(() -> TaskOrganizer.this.onAppSplashScreenViewRemoved(taskId));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
|
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
|
||||||
mExecutor.execute(() -> TaskOrganizer.this.onTaskAppeared(taskInfo, leash));
|
mExecutor.execute(() -> TaskOrganizer.this.onTaskAppeared(taskInfo, leash));
|
||||||
|
|||||||
@@ -961,6 +961,12 @@
|
|||||||
"group": "WM_DEBUG_APP_TRANSITIONS",
|
"group": "WM_DEBUG_APP_TRANSITIONS",
|
||||||
"at": "com\/android\/server\/wm\/AppTransitionController.java"
|
"at": "com\/android\/server\/wm\/AppTransitionController.java"
|
||||||
},
|
},
|
||||||
|
"-1003678883": {
|
||||||
|
"message": "Cleaning splash screen token=%s",
|
||||||
|
"level": "VERBOSE",
|
||||||
|
"group": "WM_DEBUG_STARTING_WINDOW",
|
||||||
|
"at": "com\/android\/server\/wm\/ActivityRecord.java"
|
||||||
|
},
|
||||||
"-1003060523": {
|
"-1003060523": {
|
||||||
"message": "Finish needs to pause: %s",
|
"message": "Finish needs to pause: %s",
|
||||||
"level": "VERBOSE",
|
"level": "VERBOSE",
|
||||||
|
|||||||
@@ -324,6 +324,13 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAppSplashScreenViewRemoved(int taskId) {
|
||||||
|
if (mStartingWindow != null) {
|
||||||
|
mStartingWindow.onAppSplashScreenViewRemoved(taskId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
|
public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import android.graphics.Rect;
|
|||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.RemoteCallback;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -42,6 +43,7 @@ import android.util.SparseArray;
|
|||||||
import android.view.Choreographer;
|
import android.view.Choreographer;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
|
import android.view.SurfaceControlViewHost;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
@@ -121,6 +123,13 @@ public class StartingSurfaceDrawer {
|
|||||||
|
|
||||||
private final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>();
|
private final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records of {@link SurfaceControlViewHost} where the splash screen icon animation is
|
||||||
|
* rendered and that have not yet been removed by their client.
|
||||||
|
*/
|
||||||
|
private final SparseArray<SurfaceControlViewHost> mAnimatedSplashScreenSurfaceHosts =
|
||||||
|
new SparseArray<>(1);
|
||||||
|
|
||||||
/** Obtain proper context for showing splash screen on the provided display. */
|
/** Obtain proper context for showing splash screen on the provided display. */
|
||||||
private Context getDisplayContext(Context context, int displayId) {
|
private Context getDisplayContext(Context context, int displayId) {
|
||||||
if (displayId == DEFAULT_DISPLAY) {
|
if (displayId == DEFAULT_DISPLAY) {
|
||||||
@@ -386,25 +395,58 @@ public class StartingSurfaceDrawer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the Task wants to copy the splash screen.
|
* Called when the Task wants to copy the splash screen.
|
||||||
* @param taskId
|
|
||||||
*/
|
*/
|
||||||
public void copySplashScreenView(int taskId) {
|
public void copySplashScreenView(int taskId) {
|
||||||
final StartingWindowRecord preView = mStartingWindowRecords.get(taskId);
|
final StartingWindowRecord preView = mStartingWindowRecords.get(taskId);
|
||||||
SplashScreenViewParcelable parcelable;
|
SplashScreenViewParcelable parcelable;
|
||||||
if (preView != null && preView.mContentView != null
|
SplashScreenView splashScreenView = preView != null ? preView.mContentView : null;
|
||||||
&& preView.mContentView.isCopyable()) {
|
if (splashScreenView != null && splashScreenView.isCopyable()) {
|
||||||
parcelable = new SplashScreenViewParcelable(preView.mContentView);
|
parcelable = new SplashScreenViewParcelable(splashScreenView);
|
||||||
preView.mContentView.onCopied();
|
parcelable.setClientCallback(
|
||||||
|
new RemoteCallback((bundle) -> mSplashScreenExecutor.execute(
|
||||||
|
() -> onAppSplashScreenViewRemoved(taskId, false))));
|
||||||
|
splashScreenView.onCopied();
|
||||||
|
mAnimatedSplashScreenSurfaceHosts.append(taskId, splashScreenView.getSurfaceHost());
|
||||||
} else {
|
} else {
|
||||||
parcelable = null;
|
parcelable = null;
|
||||||
}
|
}
|
||||||
if (DEBUG_SPLASH_SCREEN) {
|
if (DEBUG_SPLASH_SCREEN) {
|
||||||
Slog.v(TAG, "Copying splash screen window view for task: " + taskId
|
Slog.v(TAG, "Copying splash screen window view for task: " + taskId
|
||||||
+ " parcelable? " + parcelable);
|
+ " parcelable: " + parcelable);
|
||||||
}
|
}
|
||||||
ActivityTaskManager.getInstance().onSplashScreenViewCopyFinished(taskId, parcelable);
|
ActivityTaskManager.getInstance().onSplashScreenViewCopyFinished(taskId, parcelable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the {@link SplashScreenView} is removed from the client Activity view's hierarchy
|
||||||
|
* or when the Activity is clean up.
|
||||||
|
*
|
||||||
|
* @param taskId The Task id on which the splash screen was attached
|
||||||
|
*/
|
||||||
|
public void onAppSplashScreenViewRemoved(int taskId) {
|
||||||
|
onAppSplashScreenViewRemoved(taskId, true /* fromServer */);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fromServer If true, this means the removal was notified by the server. This is only
|
||||||
|
* used for debugging purposes.
|
||||||
|
* @see #onAppSplashScreenViewRemoved(int)
|
||||||
|
*/
|
||||||
|
private void onAppSplashScreenViewRemoved(int taskId, boolean fromServer) {
|
||||||
|
SurfaceControlViewHost viewHost =
|
||||||
|
mAnimatedSplashScreenSurfaceHosts.get(taskId);
|
||||||
|
if (viewHost == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mAnimatedSplashScreenSurfaceHosts.remove(taskId);
|
||||||
|
if (DEBUG_SPLASH_SCREEN) {
|
||||||
|
String reason = fromServer ? "Server cleaned up" : "App removed";
|
||||||
|
Slog.v(TAG, reason + "the splash screen. Releasing SurfaceControlViewHost for task:"
|
||||||
|
+ taskId);
|
||||||
|
}
|
||||||
|
viewHost.getView().post(viewHost::release);
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean addWindow(int taskId, IBinder appToken, View view, WindowManager wm,
|
protected boolean addWindow(int taskId, IBinder appToken, View view, WindowManager wm,
|
||||||
WindowManager.LayoutParams params) {
|
WindowManager.LayoutParams params) {
|
||||||
boolean shouldSaveView = true;
|
boolean shouldSaveView = true;
|
||||||
|
|||||||
@@ -149,6 +149,14 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see StartingSurfaceDrawer#onAppSplashScreenViewRemoved(int)
|
||||||
|
*/
|
||||||
|
public void onAppSplashScreenViewRemoved(int taskId) {
|
||||||
|
mSplashScreenExecutor.execute(
|
||||||
|
() -> mStartingSurfaceDrawer.onAppSplashScreenViewRemoved(taskId));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the content of a task is ready to show, starting window can be removed.
|
* Called when the content of a task is ready to show, starting window can be removed.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -309,6 +309,7 @@ import android.view.animation.Animation;
|
|||||||
import android.window.IRemoteTransition;
|
import android.window.IRemoteTransition;
|
||||||
import android.window.SizeConfigurationBuckets;
|
import android.window.SizeConfigurationBuckets;
|
||||||
import android.window.SplashScreen;
|
import android.window.SplashScreen;
|
||||||
|
import android.window.SplashScreenView;
|
||||||
import android.window.SplashScreenView.SplashScreenViewParcelable;
|
import android.window.SplashScreenView.SplashScreenViewParcelable;
|
||||||
import android.window.TaskSnapshot;
|
import android.window.TaskSnapshot;
|
||||||
import android.window.WindowContainerToken;
|
import android.window.WindowContainerToken;
|
||||||
@@ -716,25 +717,29 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
boolean startingMoved;
|
boolean startingMoved;
|
||||||
|
|
||||||
boolean mHandleExitSplashScreen;
|
boolean mHandleExitSplashScreen;
|
||||||
@TransferSplashScreenState int mTransferringSplashScreenState =
|
@TransferSplashScreenState
|
||||||
TRANSFER_SPLASH_SCREEN_IDLE;
|
int mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_IDLE;
|
||||||
|
|
||||||
// Idle, can be triggered to do transfer if needed.
|
/** Idle, can be triggered to do transfer if needed. */
|
||||||
static final int TRANSFER_SPLASH_SCREEN_IDLE = 0;
|
static final int TRANSFER_SPLASH_SCREEN_IDLE = 0;
|
||||||
// requesting a copy from shell.
|
|
||||||
|
/** Requesting a copy from shell. */
|
||||||
static final int TRANSFER_SPLASH_SCREEN_COPYING = 1;
|
static final int TRANSFER_SPLASH_SCREEN_COPYING = 1;
|
||||||
// attach the splash screen view to activity.
|
|
||||||
|
/** Attach the splash screen view to activity. */
|
||||||
static final int TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT = 2;
|
static final int TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT = 2;
|
||||||
// client has taken over splash screen view.
|
|
||||||
|
/** Client has taken over splash screen view. */
|
||||||
static final int TRANSFER_SPLASH_SCREEN_FINISH = 3;
|
static final int TRANSFER_SPLASH_SCREEN_FINISH = 3;
|
||||||
|
|
||||||
@IntDef(prefix = { "TRANSFER_SPLASH_SCREEN_" }, value = {
|
@IntDef(prefix = {"TRANSFER_SPLASH_SCREEN_"}, value = {
|
||||||
TRANSFER_SPLASH_SCREEN_IDLE,
|
TRANSFER_SPLASH_SCREEN_IDLE,
|
||||||
TRANSFER_SPLASH_SCREEN_COPYING,
|
TRANSFER_SPLASH_SCREEN_COPYING,
|
||||||
TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT,
|
TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT,
|
||||||
TRANSFER_SPLASH_SCREEN_FINISH,
|
TRANSFER_SPLASH_SCREEN_FINISH,
|
||||||
})
|
})
|
||||||
@interface TransferSplashScreenState {}
|
@interface TransferSplashScreenState {
|
||||||
|
}
|
||||||
|
|
||||||
// How long we wait until giving up transfer splash screen.
|
// How long we wait until giving up transfer splash screen.
|
||||||
private static final int TRANSFER_SPLASH_SCREEN_TIMEOUT = 2000;
|
private static final int TRANSFER_SPLASH_SCREEN_TIMEOUT = 2000;
|
||||||
@@ -2196,6 +2201,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
removeStartingWindowAnimation(false /* prepareAnimation */);
|
removeStartingWindowAnimation(false /* prepareAnimation */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the shell ({@link com.android.wm.shell.ShellTaskOrganizer} it should clean up any
|
||||||
|
* remaining reference to this {@link ActivityRecord}'s splash screen.
|
||||||
|
* @see com.android.wm.shell.ShellTaskOrganizer#onAppSplashScreenViewRemoved(int)
|
||||||
|
* @see SplashScreenView#remove()
|
||||||
|
*/
|
||||||
|
void cleanUpSplashScreen() {
|
||||||
|
// We only clean up the splash screen if we were supposed to handle it. If it was
|
||||||
|
// transferred to another activity, the next one will handle the clean up.
|
||||||
|
if (mHandleExitSplashScreen && !startingMoved
|
||||||
|
&& (mTransferringSplashScreenState == TRANSFER_SPLASH_SCREEN_FINISH
|
||||||
|
|| mTransferringSplashScreenState == TRANSFER_SPLASH_SCREEN_IDLE)) {
|
||||||
|
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Cleaning splash screen token=%s", this);
|
||||||
|
mAtmService.mTaskOrganizerController.onAppSplashScreenViewRemoved(getTask());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void removeStartingWindow() {
|
void removeStartingWindow() {
|
||||||
removeStartingWindowAnimation(true /* prepareAnimation */);
|
removeStartingWindowAnimation(true /* prepareAnimation */);
|
||||||
}
|
}
|
||||||
@@ -3343,6 +3365,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
task.cleanUpActivityReferences(this);
|
task.cleanUpActivityReferences(this);
|
||||||
clearLastParentBeforePip();
|
clearLastParentBeforePip();
|
||||||
|
|
||||||
|
// Clean up the splash screen if it was still displayed.
|
||||||
|
cleanUpSplashScreen();
|
||||||
|
|
||||||
deferRelaunchUntilPaused = false;
|
deferRelaunchUntilPaused = false;
|
||||||
frozenBeforeDestroy = false;
|
frozenBeforeDestroy = false;
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import android.util.proto.ProtoOutputStream;
|
|||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.window.ITaskOrganizer;
|
import android.window.ITaskOrganizer;
|
||||||
import android.window.ITaskOrganizerController;
|
import android.window.ITaskOrganizerController;
|
||||||
|
import android.window.SplashScreenView;
|
||||||
import android.window.StartingWindowInfo;
|
import android.window.StartingWindowInfo;
|
||||||
import android.window.TaskAppearedInfo;
|
import android.window.TaskAppearedInfo;
|
||||||
import android.window.TaskSnapshot;
|
import android.window.TaskSnapshot;
|
||||||
@@ -215,6 +216,14 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onAppSplashScreenViewRemoved(Task task) {
|
||||||
|
try {
|
||||||
|
mTaskOrganizer.onAppSplashScreenViewRemoved(task.mTaskId);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.e(TAG, "Exception sending onAppSplashScreenViewRemoved callback", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SurfaceControl prepareLeash(Task task, String reason) {
|
SurfaceControl prepareLeash(Task task, String reason) {
|
||||||
return new SurfaceControl(task.getSurfaceControl(), reason);
|
return new SurfaceControl(task.getSurfaceControl(), reason);
|
||||||
}
|
}
|
||||||
@@ -314,6 +323,10 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
|||||||
mOrganizer.copySplashScreenView(t);
|
mOrganizer.copySplashScreenView(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onAppSplashScreenViewRemoved(Task t) {
|
||||||
|
mOrganizer.onAppSplashScreenViewRemoved(t);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register this task with this state, but doesn't trigger the task appeared callback to
|
* Register this task with this state, but doesn't trigger the task appeared callback to
|
||||||
* the organizer.
|
* the organizer.
|
||||||
@@ -566,6 +579,22 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the shell ({@link com.android.wm.shell.ShellTaskOrganizer} that the client has
|
||||||
|
* removed the splash screen view.
|
||||||
|
* @see com.android.wm.shell.ShellTaskOrganizer#onAppSplashScreenViewRemoved(int)
|
||||||
|
* @see SplashScreenView#remove()
|
||||||
|
*/
|
||||||
|
public void onAppSplashScreenViewRemoved(Task task) {
|
||||||
|
final Task rootTask = task.getRootTask();
|
||||||
|
if (rootTask == null || rootTask.mTaskOrganizer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final TaskOrganizerState state =
|
||||||
|
mTaskOrganizerStates.get(rootTask.mTaskOrganizer.asBinder());
|
||||||
|
state.onAppSplashScreenViewRemoved(task);
|
||||||
|
}
|
||||||
|
|
||||||
void onTaskAppeared(ITaskOrganizer organizer, Task task) {
|
void onTaskAppeared(ITaskOrganizer organizer, Task task) {
|
||||||
final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
|
final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
|
||||||
if (state != null && state.addTask(task)) {
|
if (state != null && state.addTask(task)) {
|
||||||
|
|||||||
@@ -796,6 +796,9 @@ public class WindowOrganizerTests extends WindowTestsBase {
|
|||||||
@Override
|
@Override
|
||||||
public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {
|
public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public void onAppSplashScreenViewRemoved(int taskId) {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private ActivityRecord makePipableActivity() {
|
private ActivityRecord makePipableActivity() {
|
||||||
|
|||||||
Reference in New Issue
Block a user