Merge "Generalized AppWindowThumbnail as WindowContainerThumbnail"

This commit is contained in:
TreeHugger Robot
2019-11-06 22:16:20 +00:00
committed by Android (Google) Code Review
9 changed files with 96 additions and 76 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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",
@@ -1297,6 +1291,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",

View File

@@ -5757,7 +5757,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 */);
}
}
@@ -5866,8 +5866,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));
}
@@ -5895,7 +5895,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(
@@ -6043,7 +6043,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
@VisibleForTesting
AppWindowThumbnail getThumbnail() {
WindowContainerThumbnail getThumbnail() {
return mThumbnail;
}

View File

@@ -1922,11 +1922,13 @@ public class AppTransition implements Dump {
if (taskId < 0) {
return null;
}
ArrayList<Task> tasks = new ArrayList<>();
final ArrayList<Task> 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;
}

View File

@@ -58,6 +58,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;
@@ -718,6 +719,11 @@ class Task extends WindowContainer<ActivityRecord> implements ConfigurationConta
callback.accept(this);
}
@Override
boolean forAllTasks(ToBooleanFunction<Task> callback) {
return callback.apply(this);
}
/**
* @param canAffectSystemUiFlags If false, all windows in this task can not affect SystemUI
* flags. See {@link WindowState#canAffectSystemUiFlags()}.

View File

@@ -237,7 +237,7 @@ class WindowContainer<E extends 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<E extends 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<Task> callback) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
if (mChildren.get(i).forAllTasks(callback)) {
return true;
}
}
return false;
}
WindowState getWindow(Predicate<WindowState> callback) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowState w = mChildren.get(i).getWindow(callback);
@@ -1520,8 +1535,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WC#applyAnimation");
if (okToAnimate()) {
Pair<AnimationAdapter, AnimationAdapter> adapters = getAnimationAdapter(lp, transit,
enter, isVoiceInteraction);
final Pair<AnimationAdapter, AnimationAdapter> adapters = getAnimationAdapter(lp,
transit, enter, isVoiceInteraction);
AnimationAdapter adapter = adapters.first;
AnimationAdapter thumbnailAdapter = adapters.second;
if (adapter != null) {
@@ -1580,18 +1595,16 @@ class WindowContainer<E extends 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();

View File

@@ -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<Surface> surfaceFactory, Transaction t, ActivityRecord activity,
GraphicBuffer thumbnailHeader) {
this(surfaceFactory, t, activity, thumbnailHeader, false /* relative */);
WindowContainerThumbnail(Supplier<Surface> 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<Surface> surfaceFactory, Transaction t, ActivityRecord activity,
GraphicBuffer thumbnailHeader, boolean relative) {
this(t, activity, thumbnailHeader, relative, surfaceFactory.get(), null);
WindowContainerThumbnail(Supplier<Surface> 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

View File

@@ -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());