diff --git a/core/proto/android/server/appwindowthumbnail.proto b/core/proto/android/server/windowcontainerthumbnail.proto similarity index 89% rename from core/proto/android/server/appwindowthumbnail.proto rename to core/proto/android/server/windowcontainerthumbnail.proto index f22cdc5411581..9f8ea60ca122f 100644 --- a/core/proto/android/server/appwindowthumbnail.proto +++ b/core/proto/android/server/windowcontainerthumbnail.proto @@ -23,9 +23,9 @@ package com.android.server.wm; option java_multiple_files = true; /** - * Represents a {@link com.android.server.wm.AppWindowThumbnail} object. + * Represents a {@link com.android.server.wm.WindowContainerThumbnailProto} object. */ -message AppWindowThumbnailProto { +message WindowContainerThumbnailProto { option (.android.msg_privacy).dest = DEST_AUTOMATIC; optional int32 width = 1; diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto index 69e67d154d273..c9a18296a292a 100644 --- a/core/proto/android/server/windowmanagerservice.proto +++ b/core/proto/android/server/windowmanagerservice.proto @@ -20,7 +20,7 @@ import "frameworks/base/core/proto/android/app/statusbarmanager.proto"; import "frameworks/base/core/proto/android/content/activityinfo.proto"; import "frameworks/base/core/proto/android/content/configuration.proto"; import "frameworks/base/core/proto/android/graphics/rect.proto"; -import "frameworks/base/core/proto/android/server/appwindowthumbnail.proto"; +import "frameworks/base/core/proto/android/server/windowcontainerthumbnail.proto"; import "frameworks/base/core/proto/android/server/surfaceanimator.proto"; import "frameworks/base/core/proto/android/view/displaycutout.proto"; import "frameworks/base/core/proto/android/view/displayinfo.proto"; @@ -232,7 +232,7 @@ message AppWindowTokenProto { optional bool last_surface_showing = 3; optional bool is_waiting_for_transition_start = 4; optional bool is_animating = 5; - optional AppWindowThumbnailProto thumbnail = 6; + optional WindowContainerThumbnailProto thumbnail = 6; optional bool fills_parent = 7; optional bool app_stopped = 8; optional bool hidden_requested = 9; diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index ecdf5373f24fc..7099b6f79be21 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -301,12 +301,6 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, - "-1483752006": { - "message": " THUMBNAIL %s: CREATE", - "level": "INFO", - "group": "WM_SHOW_TRANSACTIONS", - "at": "com\/android\/server\/wm\/AppWindowThumbnail.java" - }, "-1471946192": { "message": "Marking app token %s with replacing child windows.", "level": "DEBUG", @@ -1303,6 +1297,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", "at": "com\/android\/server\/wm\/AppTransition.java" }, + "531242746": { + "message": " THUMBNAIL %s: CREATE", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowContainerThumbnail.java" + }, "539077569": { "message": "Clear freezing of %s force=%b", "level": "VERBOSE", diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 76ac5392fa768..95f76daac6fdc 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -5814,7 +5814,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mWmService.mTaskSnapshotController.createTaskSnapshot( task, 1 /* scaleFraction */); if (snapshot != null) { - mThumbnail = new AppWindowThumbnail(mWmService.mSurfaceFactory, t, this, + mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory, t, this, snapshot.getGraphicBuffer(), true /* relative */); } } @@ -5923,8 +5923,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } clearThumbnail(); - mThumbnail = new AppWindowThumbnail(mWmService.mSurfaceFactory, getPendingTransaction(), - this, thumbnailHeader); + mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory, + getPendingTransaction(), this, thumbnailHeader); mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader)); } @@ -5952,7 +5952,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (thumbnail == null) { return; } - mThumbnail = new AppWindowThumbnail(mWmService.mSurfaceFactory, + mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory, getPendingTransaction(), this, thumbnail); final Animation animation = getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked( @@ -6100,7 +6100,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } @VisibleForTesting - AppWindowThumbnail getThumbnail() { + WindowContainerThumbnail getThumbnail() { return mThumbnail; } diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index cb9a200e6010f..cd7c21685e14a 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -1922,11 +1922,13 @@ public class AppTransition implements Dump { if (taskId < 0) { return null; } - ArrayList tasks = new ArrayList<>(); + final ArrayList tasks = new ArrayList<>(); mDisplayContent.forAllTasks(task -> { if (task.mTaskId == taskId) { tasks.add(task); + return true; } + return false; }); return tasks.size() == 1 ? tasks.get(0) : null; } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 92ff2dc96ab3f..4b54a4d86266f 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -56,6 +56,7 @@ import android.view.Surface; import android.view.SurfaceControl; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.ToBooleanFunction; import java.io.PrintWriter; import java.util.function.Consumer; @@ -764,6 +765,11 @@ class Task extends WindowContainer implements ConfigurationConta callback.accept(this); } + @Override + boolean forAllTasks(ToBooleanFunction callback) { + return callback.apply(this); + } + /** * @param canAffectSystemUiFlags If false, all windows in this task can not affect SystemUI * flags. See {@link WindowState#canAffectSystemUiFlags()}. diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 7ce2b5eb727bc..84533974a3f7a 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -237,7 +237,7 @@ class WindowContainer extends ConfigurationContainer< * This gets used during some open/close transitions as well as during a change transition * where it represents the starting-state snapshot. */ - AppWindowThumbnail mThumbnail; + WindowContainerThumbnail mThumbnail; final Rect mTransitStartRect = new Rect(); final Point mTmpPoint = new Point(); protected final Rect mTmpRect = new Rect(); @@ -1121,6 +1121,21 @@ class WindowContainer extends ConfigurationContainer< } } + /** + * For all tasks at or below this container call the callback. + * + * @param callback Calls the {@link ToBooleanFunction#apply} method for each task found and + * stops the search if {@link ToBooleanFunction#apply} returns {@code true}. + */ + boolean forAllTasks(ToBooleanFunction callback) { + for (int i = mChildren.size() - 1; i >= 0; --i) { + if (mChildren.get(i).forAllTasks(callback)) { + return true; + } + } + return false; + } + WindowState getWindow(Predicate callback) { for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowState w = mChildren.get(i).getWindow(callback); @@ -1520,8 +1535,8 @@ class WindowContainer extends ConfigurationContainer< try { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WC#applyAnimation"); if (okToAnimate()) { - Pair adapters = getAnimationAdapter(lp, transit, - enter, isVoiceInteraction); + final Pair adapters = getAnimationAdapter(lp, + transit, enter, isVoiceInteraction); AnimationAdapter adapter = adapters.first; AnimationAdapter thumbnailAdapter = adapters.second; if (adapter != null) { @@ -1580,18 +1595,16 @@ class WindowContainer extends ConfigurationContainer< final DisplayInfo displayInfo = getDisplayContent().getDisplayInfo(); mTmpRect.offsetTo(mTmpPoint.x, mTmpPoint.y); - AnimationAdapter adapter = new LocalAnimationAdapter( + final AnimationAdapter adapter = new LocalAnimationAdapter( new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect, displayInfo, durationScale, true /* isAppAnimation */, false /* isThumbnail */), getSurfaceAnimationRunner()); - AnimationAdapter thumbnailAdapter = null; - if (mThumbnail != null) { - thumbnailAdapter = new LocalAnimationAdapter( - new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect, displayInfo, - durationScale, true /* isAppAnimation */, true /* isThumbnail */), - getSurfaceAnimationRunner()); - } + final AnimationAdapter thumbnailAdapter = mThumbnail != null + ? new LocalAnimationAdapter(new WindowChangeAnimationSpec(mTransitStartRect, + mTmpRect, displayInfo, durationScale, true /* isAppAnimation */, + true /* isThumbnail */), getSurfaceAnimationRunner()) + : null; resultAdapters = new Pair<>(adapter, thumbnailAdapter); mTransit = transit; mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags(); diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java similarity index 66% rename from services/core/java/com/android/server/wm/AppWindowThumbnail.java rename to services/core/java/com/android/server/wm/WindowContainerThumbnail.java index acd96e916fa89..604eae6a54275 100644 --- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java +++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java @@ -11,7 +11,7 @@ * 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 + * limitations under the License. */ package com.android.server.wm; @@ -19,10 +19,10 @@ package com.android.server.wm; import static android.view.SurfaceControl.METADATA_OWNER_UID; import static android.view.SurfaceControl.METADATA_WINDOW_TYPE; -import static com.android.server.wm.AppWindowThumbnailProto.HEIGHT; -import static com.android.server.wm.AppWindowThumbnailProto.SURFACE_ANIMATOR; -import static com.android.server.wm.AppWindowThumbnailProto.WIDTH; import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; +import static com.android.server.wm.WindowContainerThumbnailProto.HEIGHT; +import static com.android.server.wm.WindowContainerThumbnailProto.SURFACE_ANIMATOR; +import static com.android.server.wm.WindowContainerThumbnailProto.WIDTH; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION; @@ -30,7 +30,7 @@ import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION; import android.graphics.GraphicBuffer; import android.graphics.PixelFormat; import android.graphics.Point; -import android.os.Binder; +import android.os.Process; import android.util.proto.ProtoOutputStream; import android.view.Surface; import android.view.SurfaceControl; @@ -44,39 +44,40 @@ import com.android.server.wm.SurfaceAnimator.Animatable; import java.util.function.Supplier; /** - * Represents a surface that is displayed over an {@link ActivityRecord} + * Represents a surface that is displayed over a subclass of {@link WindowContainer} */ -class AppWindowThumbnail implements Animatable { +class WindowContainerThumbnail implements Animatable { - private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowThumbnail" : TAG_WM; + private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowContainerThumbnail" : TAG_WM; - private final ActivityRecord mActivityRecord; + private final WindowContainer mWindowContainer; private SurfaceControl mSurfaceControl; private final SurfaceAnimator mSurfaceAnimator; private final int mWidth; private final int mHeight; private final boolean mRelative; - AppWindowThumbnail(Supplier surfaceFactory, Transaction t, ActivityRecord activity, - GraphicBuffer thumbnailHeader) { - this(surfaceFactory, t, activity, thumbnailHeader, false /* relative */); + WindowContainerThumbnail(Supplier surfaceFactory, Transaction t, + WindowContainer container, GraphicBuffer thumbnailHeader) { + this(surfaceFactory, t, container, thumbnailHeader, false /* relative */); } /** * @param t Transaction to create the thumbnail in. - * @param activity {@link ActivityRecord} to associate this thumbnail with. + * @param container The sub-class of {@link WindowContainer} to associate this thumbnail with. * @param thumbnailHeader A thumbnail or placeholder for thumbnail to initialize with. - * @param relative Whether this thumbnail will be a child of activity (and thus positioned + * @param relative Whether this thumbnail will be a child of the container (and thus positioned * relative to it) or not. */ - AppWindowThumbnail(Supplier surfaceFactory, Transaction t, ActivityRecord activity, - GraphicBuffer thumbnailHeader, boolean relative) { - this(t, activity, thumbnailHeader, relative, surfaceFactory.get(), null); + WindowContainerThumbnail(Supplier surfaceFactory, Transaction t, + WindowContainer container, GraphicBuffer thumbnailHeader, boolean relative) { + this(t, container, thumbnailHeader, relative, surfaceFactory.get(), null); } - AppWindowThumbnail(Transaction t, ActivityRecord activity, GraphicBuffer thumbnailHeader, - boolean relative, Surface drawSurface, SurfaceAnimator animator) { - mActivityRecord = activity; + WindowContainerThumbnail(Transaction t, WindowContainer container, + GraphicBuffer thumbnailHeader, boolean relative, Surface drawSurface, + SurfaceAnimator animator) { + mWindowContainer = container; mRelative = relative; if (animator != null) { mSurfaceAnimator = animator; @@ -84,24 +85,21 @@ class AppWindowThumbnail implements Animatable { // We can't use a delegating constructor since we need to // reference this::onAnimationFinished mSurfaceAnimator = - new SurfaceAnimator(this, this::onAnimationFinished, activity.mWmService); + new SurfaceAnimator(this, this::onAnimationFinished, container.mWmService); } mWidth = thumbnailHeader.getWidth(); mHeight = thumbnailHeader.getHeight(); // Create a new surface for the thumbnail - WindowState window = mActivityRecord.findMainWindow(); - // TODO: This should be attached as a child to the app token, once the thumbnail animations // use relative coordinates. Once we start animating task we can also consider attaching // this to the task. - mSurfaceControl = mActivityRecord.makeSurface() - .setName("thumbnail anim: " + mActivityRecord.toString()) + mSurfaceControl = mWindowContainer.makeSurface() + .setName("thumbnail anim: " + mWindowContainer.toString()) .setBufferSize(mWidth, mHeight) .setFormat(PixelFormat.TRANSLUCENT) - .setMetadata(METADATA_WINDOW_TYPE, mActivityRecord.windowType) - .setMetadata(METADATA_OWNER_UID, - window != null ? window.mOwnerUid : Binder.getCallingUid()) + .setMetadata(METADATA_WINDOW_TYPE, mWindowContainer.getWindowingMode()) + .setMetadata(METADATA_OWNER_UID, Process.myUid()) .build(); ProtoLog.i(WM_SHOW_TRANSACTIONS, " THUMBNAIL %s: CREATE", mSurfaceControl); @@ -112,11 +110,11 @@ class AppWindowThumbnail implements Animatable { drawSurface.release(); t.show(mSurfaceControl); - // We parent the thumbnail to the task, and just place it on top of anything else in the - // task. + // We parent the thumbnail to the container, and just place it on top of anything else in + // the container. t.setLayer(mSurfaceControl, Integer.MAX_VALUE); if (relative) { - t.reparent(mSurfaceControl, mActivityRecord.getSurfaceControl()); + t.reparent(mSurfaceControl, mWindowContainer.getSurfaceControl()); } } @@ -126,12 +124,12 @@ class AppWindowThumbnail implements Animatable { void startAnimation(Transaction t, Animation anim, Point position) { anim.restrictDuration(MAX_ANIMATION_DURATION); - anim.scaleCurrentDuration(mActivityRecord.mWmService.getTransitionAnimationScaleLocked()); + anim.scaleCurrentDuration(mWindowContainer.mWmService.getTransitionAnimationScaleLocked()); mSurfaceAnimator.startAnimation(t, new LocalAnimationAdapter( new WindowAnimationSpec(anim, position, - mActivityRecord.getDisplayContent().mAppTransition.canSkipFirstFrame(), - mActivityRecord.getDisplayContent().getWindowCornerRadius()), - mActivityRecord.mWmService.mSurfaceAnimationRunner), false /* hidden */); + mWindowContainer.getDisplayContent().mAppTransition.canSkipFirstFrame(), + mWindowContainer.getDisplayContent().getWindowCornerRadius()), + mWindowContainer.mWmService.mSurfaceAnimationRunner), false /* hidden */); } /** @@ -161,10 +159,11 @@ class AppWindowThumbnail implements Animatable { /** * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link - * com.android.server.wm.AppWindowThumbnailProto}. + * com.android.server.wm.WindowContainerThumbnailProto}. * - * @param proto Stream to write the AppWindowThumbnail object to. - * @param fieldId Field Id of the AppWindowThumbnail as defined in the parent message. + * @param proto Stream to write the WindowContainerThumbnailProto object to. + * @param fieldId Field Id of the WindowContainerThumbnailProto as defined in the parent + * message. * @hide */ void writeToProto(ProtoOutputStream proto, long fieldId) { @@ -179,19 +178,19 @@ class AppWindowThumbnail implements Animatable { @Override public Transaction getPendingTransaction() { - return mActivityRecord.getPendingTransaction(); + return mWindowContainer.getPendingTransaction(); } @Override public void commitPendingTransaction() { - mActivityRecord.commitPendingTransaction(); + mWindowContainer.commitPendingTransaction(); } @Override public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) { t.setLayer(leash, Integer.MAX_VALUE); if (mRelative) { - t.reparent(leash, mActivityRecord.getSurfaceControl()); + t.reparent(leash, mWindowContainer.getSurfaceControl()); } } @@ -205,7 +204,7 @@ class AppWindowThumbnail implements Animatable { @Override public Builder makeAnimationLeash() { - return mActivityRecord.makeSurface(); + return mWindowContainer.makeSurface(); } @Override @@ -215,12 +214,12 @@ class AppWindowThumbnail implements Animatable { @Override public SurfaceControl getAnimationLeashParent() { - return mActivityRecord.getAppAnimationLayer(); + return mWindowContainer.getAnimationLeashParent(); } @Override public SurfaceControl getParentSurfaceControl() { - return mActivityRecord.getParentSurfaceControl(); + return mWindowContainer.getParentSurfaceControl(); } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java similarity index 86% rename from services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java rename to services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java index 8520d212c4ea5..b8de3ca4ea1cd 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java @@ -37,27 +37,27 @@ import org.junit.runner.RunWith; * Test class for {@link TaskSnapshotSurface}. * * Build/Install/Run: - * atest FrameworksServicesTest:AppWindowThumbnailTest + * atest WmTests:WindowContainerThumbnailTest * */ @SmallTest @Presubmit @RunWith(WindowTestRunner.class) -public class AppWindowThumbnailTest extends WindowTestsBase { - private AppWindowThumbnail buildThumbnail() { +public class WindowContainerThumbnailTest extends WindowTestsBase { + private WindowContainerThumbnail buildThumbnail() { final GraphicBuffer buffer = GraphicBuffer.create(1, 1, PixelFormat.RGBA_8888, GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER); final ActivityRecord mockAr = mock(ActivityRecord.class); when(mockAr.getPendingTransaction()).thenReturn(new StubTransaction()); when(mockAr.makeSurface()).thenReturn(new MockSurfaceControlBuilder()); - return new AppWindowThumbnail(new StubTransaction(), mockAr, + return new WindowContainerThumbnail(new StubTransaction(), mockAr, buffer, false, mock(Surface.class), mock(SurfaceAnimator.class)); } @Test @FlakyTest(bugId = 131005232) public void testDestroy_nullsSurface() { - final AppWindowThumbnail t = buildThumbnail(); + final WindowContainerThumbnail t = buildThumbnail(); assertNotNull(t.getSurfaceControl()); t.destroy(); assertNull(t.getSurfaceControl());