OSDN Git Service

Improve animation dump/logging
authorJorim Jaggi <jjaggi@google.com>
Tue, 27 Feb 2018 14:05:21 +0000 (15:05 +0100)
committerJorim Jaggi <jjaggi@google.com>
Tue, 13 Mar 2018 13:06:08 +0000 (14:06 +0100)
Bug: 74220420
Test: go/wm-smoke
Test: adb shell dumpsys window during animation
Change-Id: Ib8bddb4f38ad4fe7a80315d3bfdac0a80aea4cc8

12 files changed:
core/java/android/view/RemoteAnimationTarget.java
core/proto/android/server/animationadapter.proto [new file with mode: 0644]
core/proto/android/server/surfaceanimator.proto
core/proto/android/view/remote_animation_target.proto [new file with mode: 0644]
services/core/java/com/android/server/wm/AnimationAdapter.java
services/core/java/com/android/server/wm/Dimmer.java
services/core/java/com/android/server/wm/LocalAnimationAdapter.java
services/core/java/com/android/server/wm/RecentsAnimationController.java
services/core/java/com/android/server/wm/RemoteAnimationController.java
services/core/java/com/android/server/wm/SurfaceAnimator.java
services/core/java/com/android/server/wm/WindowAnimationSpec.java
services/core/java/com/android/server/wm/WindowState.java

index 75cdd49..5b2cc81 100644 (file)
 
 package android.view;
 
+import static android.app.RemoteAnimationTargetProto.CLIP_RECT;
+import static android.app.RemoteAnimationTargetProto.CONTENT_INSETS;
+import static android.app.RemoteAnimationTargetProto.IS_TRANSLUCENT;
+import static android.app.RemoteAnimationTargetProto.LEASH;
+import static android.app.RemoteAnimationTargetProto.MODE;
+import static android.app.RemoteAnimationTargetProto.POSITION;
+import static android.app.RemoteAnimationTargetProto.PREFIX_ORDER_INDEX;
+import static android.app.RemoteAnimationTargetProto.SOURCE_CONTAINER_BOUNDS;
+import static android.app.RemoteAnimationTargetProto.TASK_ID;
+import static android.app.RemoteAnimationTargetProto.WINDOW_CONFIGURATION;
+
 import android.annotation.IntDef;
 import android.app.WindowConfiguration;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.proto.ProtoOutputStream;
 
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -164,6 +177,35 @@ public class RemoteAnimationTarget implements Parcelable {
         dest.writeBoolean(isNotInRecents);
     }
 
+    public void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.print("mode="); pw.print(mode);
+        pw.print(" taskId="); pw.print(taskId);
+        pw.print(" isTranslucent="); pw.print(isTranslucent);
+        pw.print(" clipRect="); clipRect.printShortString(pw);
+        pw.print(" contentInsets="); contentInsets.printShortString(pw);
+        pw.print(" prefixOrderIndex="); pw.print(prefixOrderIndex);
+        pw.print(" position="); position.printShortString(pw);
+        pw.print(" sourceContainerBounds="); sourceContainerBounds.printShortString(pw);
+        pw.println();
+        pw.print(prefix); pw.print("windowConfiguration="); pw.println(windowConfiguration);
+        pw.print(prefix); pw.print("leash="); pw.println(leash);
+    }
+
+    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+        final long token = proto.start(fieldId);
+        proto.write(TASK_ID, taskId);
+        proto.write(MODE, mode);
+        leash.writeToProto(proto, LEASH);
+        proto.write(IS_TRANSLUCENT, isTranslucent);
+        clipRect.writeToProto(proto, CLIP_RECT);
+        contentInsets.writeToProto(proto, CONTENT_INSETS);
+        proto.write(PREFIX_ORDER_INDEX, prefixOrderIndex);
+        position.writeToProto(proto, POSITION);
+        sourceContainerBounds.writeToProto(proto, SOURCE_CONTAINER_BOUNDS);
+        windowConfiguration.writeToProto(proto, WINDOW_CONFIGURATION);
+        proto.end(token);
+    }
+
     public static final Creator<RemoteAnimationTarget> CREATOR
             = new Creator<RemoteAnimationTarget>() {
         public RemoteAnimationTarget createFromParcel(Parcel in) {
diff --git a/core/proto/android/server/animationadapter.proto b/core/proto/android/server/animationadapter.proto
new file mode 100644 (file)
index 0000000..c4ffe8c
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+syntax = "proto2";
+
+import "frameworks/base/core/proto/android/graphics/point.proto";
+import "frameworks/base/core/proto/android/view/remote_animation_target.proto";
+import "frameworks/base/libs/incident/proto/android/privacy.proto";
+
+package com.android.server.wm.proto;
+option java_multiple_files = true;
+
+message AnimationAdapterProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional LocalAnimationAdapterProto local = 1;
+  optional RemoteAnimationAdapterWrapperProto remote = 2;
+}
+
+/* represents RemoteAnimationAdapterWrapper */
+message RemoteAnimationAdapterWrapperProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional .android.view.RemoteAnimationTargetProto target = 1;
+}
+
+/* represents LocalAnimationAdapter */
+message LocalAnimationAdapterProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional AnimationSpecProto animation_spec = 1;
+}
+
+message AnimationSpecProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional WindowAnimationSpecProto window = 1;
+  optional MoveAnimationSpecProto move = 2;
+  optional AlphaAnimationSpecProto alpha = 3;
+}
+
+/* represents WindowAnimationSpec */
+message WindowAnimationSpecProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional string animation = 1;
+}
+
+/* represents MoveAnimationSpec*/
+message MoveAnimationSpecProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional .android.graphics.PointProto from = 1;
+  optional .android.graphics.PointProto to = 2;
+  optional int64 duration = 3;
+}
+
+/* represents AlphaAnimationSpec */
+message AlphaAnimationSpecProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional float from = 1;
+  optional float to = 2;
+  optional int64 duration = 3;
+}
\ No newline at end of file
index 7f7839e..dcc2b34 100644 (file)
@@ -16,6 +16,7 @@
 
 syntax = "proto2";
 
+import "frameworks/base/core/proto/android/server/animationadapter.proto";
 import "frameworks/base/core/proto/android/view/surfacecontrol.proto";
 import "frameworks/base/libs/incident/proto/android/privacy.proto";
 
@@ -28,7 +29,8 @@ option java_multiple_files = true;
 message SurfaceAnimatorProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
-  optional string animation_adapter = 1;
+  reserved 1; // Was string animation_adapter = 1
   optional .android.view.SurfaceControlProto leash = 2;
   optional bool animation_start_delayed = 3;
+  optional AnimationAdapterProto animation_adapter = 4;
 }
\ No newline at end of file
diff --git a/core/proto/android/view/remote_animation_target.proto b/core/proto/android/view/remote_animation_target.proto
new file mode 100644 (file)
index 0000000..d5da0a9
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+syntax = "proto2";
+option java_package = "android.app";
+option java_multiple_files = true;
+
+package android.view;
+
+import "frameworks/base/core/proto/android/app/window_configuration.proto";
+import "frameworks/base/core/proto/android/graphics/point.proto";
+import "frameworks/base/core/proto/android/graphics/rect.proto";
+import "frameworks/base/core/proto/android/view/surfacecontrol.proto";
+import "frameworks/base/libs/incident/proto/android/privacy.proto";
+
+/** Proto representation for RemoteAnimationTarget.java class. */
+message RemoteAnimationTargetProto {
+  option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional int32 task_id = 1;
+  optional int32 mode = 2;
+  optional .android.view.SurfaceControlProto leash = 3;
+  optional bool is_translucent = 4;
+  optional .android.graphics.RectProto clip_rect = 5;
+  optional .android.graphics.RectProto contentInsets = 6;
+  optional int32 prefix_order_index = 7;
+  optional .android.graphics.PointProto position = 8;
+  optional .android.graphics.RectProto source_container_bounds = 9;
+  optional .android.app.WindowConfigurationProto window_configuration = 10;
+}
index 64f77a2..00e3050 100644 (file)
 package com.android.server.wm;
 
 import android.annotation.ColorInt;
-import android.graphics.Point;
+import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
 import android.view.animation.Animation;
 
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
+import java.io.PrintWriter;
+
 /**
  * Interface that describes an animation and bridges the animation start to the component
  * responsible for running the animation.
@@ -83,4 +85,14 @@ interface AnimationAdapter {
      * @return the desired start time of the status bar transition, in uptime millis
      */
     long getStatusBarTransitionsStartTime();
+
+    void dump(PrintWriter pw, String prefix);
+
+    default void writeToProto(ProtoOutputStream proto, long fieldId) {
+        final long token = proto.start(fieldId);
+        writeToProto(proto);
+        proto.end(token);
+    }
+
+    void writeToProto(ProtoOutputStream proto);
 }
index a180a3a..5c62987 100644 (file)
 
 package com.android.server.wm;
 
-import android.view.SurfaceControl;
+import static com.android.server.wm.proto.AlphaAnimationSpecProto.DURATION;
+import static com.android.server.wm.proto.AlphaAnimationSpecProto.FROM;
+import static com.android.server.wm.proto.AlphaAnimationSpecProto.TO;
+import static com.android.server.wm.proto.AnimationSpecProto.ALPHA;
+
 import android.graphics.Rect;
+import android.util.proto.ProtoOutputStream;
+import android.view.SurfaceControl;
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.io.PrintWriter;
+
 /**
  * Utility class for use by a WindowContainer implementation to add "DimLayer" support, that is
  * black layers of varying opacity at various Z-levels which create the effect of a Dim.
@@ -334,5 +342,21 @@ class Dimmer {
                     + mFromAlpha;
             t.setAlpha(sc, alpha);
         }
+
+        @Override
+        public void dump(PrintWriter pw, String prefix) {
+            pw.print(prefix); pw.print("from="); pw.print(mFromAlpha);
+            pw.print(" to="); pw.print(mToAlpha);
+            pw.print(" duration="); pw.println(mDuration);
+        }
+
+        @Override
+        public void writeToProtoInner(ProtoOutputStream proto) {
+            final long token = proto.start(ALPHA);
+            proto.write(FROM, mFromAlpha);
+            proto.write(TO, mToAlpha);
+            proto.write(DURATION, mDuration);
+            proto.end(token);
+        }
     }
 }
index 1b41cb8..3f1fde9 100644 (file)
 
 package com.android.server.wm;
 
+import static com.android.server.wm.proto.AnimationAdapterProto.LOCAL;
+import static com.android.server.wm.proto.LocalAnimationAdapterProto.ANIMATION_SPEC;
+
 import android.os.SystemClock;
+import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
 
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
+import java.io.PrintWriter;
+
 /**
  * Animation that can be executed without holding the window manager lock. See
  * {@link SurfaceAnimationRunner}.
@@ -74,6 +80,18 @@ class LocalAnimationAdapter implements AnimationAdapter {
         return mSpec.calculateStatusBarTransitionStartTime();
     }
 
+    @Override
+    public void dump(PrintWriter pw, String prefix) {
+        mSpec.dump(pw, prefix);
+    }
+
+    @Override
+    public void writeToProto(ProtoOutputStream proto) {
+        final long token = proto.start(LOCAL);
+        mSpec.writeToProto(proto, ANIMATION_SPEC);
+        proto.end(token);
+    }
+
     /**
      * Describes how to apply an animation.
      */
@@ -127,5 +145,15 @@ class LocalAnimationAdapter implements AnimationAdapter {
         default boolean canSkipFirstFrame() {
             return false;
         }
+
+        void dump(PrintWriter pw, String prefix);
+
+        default void writeToProto(ProtoOutputStream proto, long fieldId) {
+            final long token = proto.start(fieldId);
+            writeToProtoInner(proto);
+            proto.end(token);
+        }
+
+        void writeToProtoInner(ProtoOutputStream proto);
     }
 }
index 39b886d..59bec74 100644 (file)
@@ -23,6 +23,8 @@ import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 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.proto.RemoteAnimationAdapterWrapperProto.TARGET;
+import static com.android.server.wm.proto.AnimationAdapterProto.REMOTE;
 
 import android.app.ActivityManager.TaskSnapshot;
 import android.app.WindowConfiguration;
@@ -33,18 +35,21 @@ import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.Slog;
+import android.util.Slog;import android.util.proto.ProtoOutputStream;
 import android.util.SparseBooleanArray;
+import android.util.proto.ProtoOutputStream;
 import android.view.IRecentsAnimationController;
 import android.view.IRecentsAnimationRunner;
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
-import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
 import com.google.android.collect.Sets;
+
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
-
 /**
  * Controls a single instance of the remote driven recents animation. In particular, this allows
  * the calling SystemUI to animate the visible task windows as a part of the transition. The remote
@@ -348,6 +353,7 @@ public class RecentsAnimationController {
         private SurfaceControl mCapturedLeash;
         private OnAnimationFinishedCallback mCapturedFinishCallback;
         private final boolean mIsRecentTaskInvisible;
+        private RemoteAnimationTarget mTarget;
 
         TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) {
             mTask = task;
@@ -361,10 +367,11 @@ public class RecentsAnimationController {
             container.getRelativePosition(position);
             container.getBounds(bounds);
             final WindowState mainWindow = mTask.getTopVisibleAppMainWindow();
-            return new RemoteAnimationTarget(mTask.mTaskId, MODE_CLOSING, mCapturedLeash,
+            mTarget = new RemoteAnimationTarget(mTask.mTaskId, MODE_CLOSING, mCapturedLeash,
                     !mTask.fillsParent(), mainWindow.mWinAnimator.mLastClipRect,
                     mainWindow.mContentInsets, mTask.getPrefixOrderIndex(), position, bounds,
                     mTask.getWindowConfiguration(), mIsRecentTaskInvisible);
+            return mTarget;
         }
 
         @Override
@@ -403,6 +410,26 @@ public class RecentsAnimationController {
         public long getStatusBarTransitionsStartTime() {
             return SystemClock.uptimeMillis();
         }
+
+        @Override
+        public void dump(PrintWriter pw, String prefix) {
+            pw.print(prefix); pw.println("task=" + mTask);
+            if (mTarget != null) {
+                pw.print(prefix); pw.println("Target:");
+                mTarget.dump(pw, prefix + "  ");
+            } else {
+                pw.print(prefix); pw.println("Target: null");
+            }
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream proto) {
+            final long token = proto.start(REMOTE);
+            if (mTarget != null) {
+                mTarget.writeToProto(proto, TARGET);
+            }
+            proto.end(token);
+        }
     }
 
     public void dump(PrintWriter pw, String prefix) {
index 169d65e..d645110 100644 (file)
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 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.proto.AnimationAdapterProto.REMOTE;
+import static com.android.server.wm.proto.RemoteAnimationAdapterWrapperProto.TARGET;
 
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -25,16 +28,18 @@ import android.os.Handler;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
 import android.view.IRemoteAnimationFinishedCallback;
-import android.view.IRemoteAnimationFinishedCallback.Stub;
 import android.view.RemoteAnimationAdapter;
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
 
+import com.android.internal.util.FastPrintWriter;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
-import java.lang.ref.WeakReference;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.ArrayList;
 
 /**
@@ -104,6 +109,20 @@ class RemoteAnimationController {
             }
         });
         sendRunningRemoteAnimation(true);
+        if (DEBUG_APP_TRANSITIONS) {
+            writeStartDebugStatement();
+        }
+    }
+
+    private void writeStartDebugStatement() {
+        Slog.i(TAG, "Starting remote animation");
+        final StringWriter sw = new StringWriter();
+        final FastPrintWriter pw = new FastPrintWriter(sw);
+        for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
+            mPendingAnimations.get(i).dump(pw, "");
+        }
+        pw.close();
+        Slog.i(TAG, sw.toString());
     }
 
     private RemoteAnimationTarget[] createAnimations() {
@@ -133,6 +152,7 @@ class RemoteAnimationController {
             }
         }
         sendRunningRemoteAnimation(false);
+        if (DEBUG_APP_TRANSITIONS) Slog.i(TAG, "Finishing remote animation");
     }
 
     private void invokeAnimationCancelled() {
@@ -193,6 +213,7 @@ class RemoteAnimationController {
         private OnAnimationFinishedCallback mCapturedFinishCallback;
         private final Point mPosition = new Point();
         private final Rect mStackBounds = new Rect();
+        private RemoteAnimationTarget mTarget;
 
         RemoteAnimationAdapterWrapper(AppWindowToken appWindowToken, Point position,
                 Rect stackBounds) {
@@ -210,11 +231,12 @@ class RemoteAnimationController {
             if (mainWindow == null) {
                 return null;
             }
-            return new RemoteAnimationTarget(task.mTaskId, getMode(),
+            mTarget = new RemoteAnimationTarget(task.mTaskId, getMode(),
                     mCapturedLeash, !mAppWindowToken.fillsParent(),
                     mainWindow.mWinAnimator.mLastClipRect, mainWindow.mContentInsets,
                     mAppWindowToken.getPrefixOrderIndex(), mPosition, mStackBounds,
                     task.getWindowConfiguration(), false /*isNotInRecents*/);
+            return mTarget;
         }
 
         private int getMode() {
@@ -275,5 +297,25 @@ class RemoteAnimationController {
             return SystemClock.uptimeMillis()
                     + mRemoteAnimationAdapter.getStatusBarTransitionDelay();
         }
+
+        @Override
+        public void dump(PrintWriter pw, String prefix) {
+            pw.print(prefix); pw.print("token="); pw.println(mAppWindowToken);
+            if (mTarget != null) {
+                pw.print(prefix); pw.println("Target:");
+                mTarget.dump(pw, prefix + "  ");
+            } else {
+                pw.print(prefix); pw.println("Target: null");
+            }
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream proto) {
+            final long token = proto.start(REMOTE);
+            if (mTarget != null) {
+                mTarget.writeToProto(proto, TARGET);
+            }
+            proto.end(token);
+        }
     }
 }
index 76f5396..c06caaf 100644 (file)
@@ -313,7 +313,9 @@ class SurfaceAnimator {
      */
     void writeToProto(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
-        proto.write(ANIMATION_ADAPTER, mAnimation != null ? mAnimation.toString() : "null");
+        if (mAnimation != null) {
+            mAnimation.writeToProto(proto, ANIMATION_ADAPTER);
+        }
         if (mLeash != null){
             mLeash.writeToProto(proto, LEASH);
         }
@@ -322,8 +324,18 @@ class SurfaceAnimator {
     }
 
     void dump(PrintWriter pw, String prefix) {
-        pw.print(prefix); pw.print("mAnimation="); pw.print(mAnimation);
-        pw.print(" mLeash="); pw.println(mLeash);
+        pw.print(prefix); pw.print("mLeash="); pw.print(mLeash);
+        if (mAnimationStartDelayed) {
+            pw.print(" mAnimationStartDelayed="); pw.println(mAnimationStartDelayed);
+        } else {
+            pw.println();
+        }
+        pw.print(prefix); pw.println("Animation:");
+        if (mAnimation != null) {
+            mAnimation.dump(pw, prefix + "  ");
+        } else {
+            pw.print(prefix); pw.println("null");
+        }
     }
 
     /**
index 43fa3d5..a41eba8 100644 (file)
@@ -19,10 +19,13 @@ package com.android.server.wm;
 import static com.android.server.wm.AnimationAdapter.STATUS_BAR_TRANSITION_DURATION;
 import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
 import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
+import static com.android.server.wm.proto.AnimationSpecProto.WINDOW;
+import static com.android.server.wm.proto.WindowAnimationSpecProto.ANIMATION;
 
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.SystemClock;
+import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
 import android.view.animation.Animation;
@@ -33,6 +36,8 @@ import android.view.animation.TranslateAnimation;
 
 import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
 
+import java.io.PrintWriter;
+
 /**
  * Animation spec for regular window animations.
  */
@@ -129,6 +134,18 @@ public class WindowAnimationSpec implements AnimationSpec {
         return mCanSkipFirstFrame;
     }
 
+    @Override
+    public void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.println(mAnimation);
+    }
+
+    @Override
+    public void writeToProtoInner(ProtoOutputStream proto) {
+        final long token = proto.start(WINDOW);
+        proto.write(ANIMATION, mAnimation.toString());
+        proto.end(token);
+    }
+
     /**
      * Tries to find a {@link TranslateAnimation} inside the {@code animation}.
      *
index f01dc20..297e067 100644 (file)
@@ -113,6 +113,10 @@ import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
 import static com.android.server.wm.proto.IdentifierProto.HASH_CODE;
 import static com.android.server.wm.proto.IdentifierProto.TITLE;
 import static com.android.server.wm.proto.IdentifierProto.USER_ID;
+import static com.android.server.wm.proto.AnimationSpecProto.MOVE;
+import static com.android.server.wm.proto.MoveAnimationSpecProto.DURATION;
+import static com.android.server.wm.proto.MoveAnimationSpecProto.FROM;
+import static com.android.server.wm.proto.MoveAnimationSpecProto.TO;
 import static com.android.server.wm.proto.WindowStateProto.ANIMATING_EXIT;
 import static com.android.server.wm.proto.WindowStateProto.ANIMATOR;
 import static com.android.server.wm.proto.WindowStateProto.ATTRIBUTES;
@@ -4724,5 +4728,21 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
             t.setPosition(leash, mFrom.x + (mTo.x - mFrom.x) * v,
                     mFrom.y + (mTo.y - mFrom.y) * v);
         }
+
+        @Override
+        public void dump(PrintWriter pw, String prefix) {
+            pw.print(prefix); pw.print("from="); pw.print(mFrom);
+            pw.print(" to="); pw.print(mTo);
+            pw.print(" duration="); pw.println(mDuration);
+        }
+
+        @Override
+        public void writeToProtoInner(ProtoOutputStream proto) {
+            final long token = proto.start(MOVE);
+            mFrom.writeToProto(proto, FROM);
+            mTo.writeToProto(proto, TO);
+            proto.write(DURATION, mDuration);
+            proto.end(token);
+        }
     }
 }