Let AppTransition has its own Handler.

The CL is for the preparation of per display AppTransition refectoring.

It includes:
- Add Handler for processing AppTransition related messages.
- Moving APP_TRANSITION_TIMEOUT & DO_ANIMATION_CALLBACK logics from
  WMS to AppTransition class.

Bug: 111362605
Test: go/wm-smoke
Test: atest ActivityManagerTransitionSelectionTests
Test: atest WindowSurfacePlacerTest AppTransitionTests
Test: atest BoundsAnimationControllerTests
Change-Id: Ifb6bcac794d8212d41eb6018526bd4633c19138d
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index d73606f..a9d0978 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -77,6 +77,7 @@
 import static com.android.server.wm.AppTransitionProto.LAST_USED_APP_TRANSITION;
 
 import android.annotation.DrawableRes;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.ComponentName;
@@ -93,6 +94,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Binder;
 import android.os.Debug;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
@@ -120,8 +122,8 @@
 
 import com.android.internal.R;
 import com.android.internal.util.DumpUtils.Dump;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.AttributeCache;
-import com.android.server.wm.WindowManagerService.H;
 import com.android.server.wm.animation.ClipRectLRAnimation;
 import com.android.server.wm.animation.ClipRectTBAnimation;
 import com.android.server.wm.animation.CurvedTranslateAnimation;
@@ -252,9 +254,13 @@
 
     private RemoteAnimationController mRemoteAnimationController;
 
+    final Handler mHandler;
+    final Runnable mHandleAppTransitionTimeoutRunnable = () -> handleAppTransitionTimeout();
+
     AppTransition(Context context, WindowManagerService service) {
         mContext = context;
         mService = service;
+        mHandler = new Handler(service.mH.getLooper());
         mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.linear_out_slow_in);
         mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -1349,7 +1355,8 @@
 
                 @Override
                 public void onAnimationEnd(Animation animation) {
-                    mService.mH.obtainMessage(H.DO_ANIMATION_CALLBACK, callback).sendToTarget();
+                    mHandler.sendMessage(PooledLambda.obtainMessage(
+                            AppTransition::doAnimationCallback, callback));
                 }
 
                 @Override
@@ -1756,7 +1763,7 @@
 
     void postAnimationCallback() {
         if (mNextAppTransitionCallback != null) {
-            mService.mH.sendMessage(mService.mH.obtainMessage(H.DO_ANIMATION_CALLBACK,
+            mHandler.sendMessage(PooledLambda.obtainMessage(AppTransition::doAnimationCallback,
                     mNextAppTransitionCallback));
             mNextAppTransitionCallback = null;
         }
@@ -1869,7 +1876,7 @@
             clear();
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE;
             mRemoteAnimationController = new RemoteAnimationController(mService,
-                    remoteAnimationAdapter, mService.mH);
+                    remoteAnimationAdapter, mHandler);
         }
     }
 
@@ -2162,8 +2169,8 @@
         }
         boolean prepared = prepare();
         if (isTransitionSet()) {
-            mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
-            mService.mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, APP_TRANSITION_TIMEOUT_MS);
+            removeAppTransitionTimeoutCallbacks();
+            mHandler.postDelayed(mHandleAppTransitionTimeoutRunnable, APP_TRANSITION_TIMEOUT_MS);
         }
         return prepared;
     }
@@ -2208,4 +2215,32 @@
         return mGridLayoutRecentsEnabled
                 || orientation == Configuration.ORIENTATION_PORTRAIT;
     }
+
+    private void handleAppTransitionTimeout() {
+        synchronized (mService.mWindowMap) {
+            if (isTransitionSet() || !mService.mOpeningApps.isEmpty()
+                    || !mService.mClosingApps.isEmpty()) {
+                if (DEBUG_APP_TRANSITIONS) {
+                    Slog.v(TAG_WM, "*** APP TRANSITION TIMEOUT."
+                            + " isTransitionSet()="
+                            + mService.mAppTransition.isTransitionSet()
+                            + " mOpeningApps.size()=" + mService.mOpeningApps.size()
+                            + " mClosingApps.size()=" + mService.mClosingApps.size());
+                }
+                setTimeout();
+                mService.mWindowPlacerLocked.performSurfacePlacement();
+            }
+        }
+    }
+
+    private static void doAnimationCallback(@NonNull IRemoteCallback callback) {
+        try {
+            ((IRemoteCallback) callback).sendResult(null);
+        } catch (RemoteException e) {
+        }
+    }
+
+    void removeAppTransitionTimeoutCallbacks() {
+        mHandler.removeCallbacks(mHandleAppTransitionTimeoutRunnable);
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7caa7ae..8f04097 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4536,7 +4536,6 @@
         public static final int REPORT_LOSING_FOCUS = 3;
         public static final int WINDOW_FREEZE_TIMEOUT = 11;
 
-        public static final int APP_TRANSITION_TIMEOUT = 13;
         public static final int PERSIST_ANIMATION_SCALE = 14;
         public static final int FORCE_GC = 15;
         public static final int ENABLE_SCREEN = 16;
@@ -4548,7 +4547,6 @@
         public static final int BOOT_TIMEOUT = 23;
         public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
         public static final int SHOW_STRICT_MODE_VIOLATION = 25;
-        public static final int DO_ANIMATION_CALLBACK = 26;
 
         public static final int CLIENT_FREEZE_TIMEOUT = 30;
         public static final int NOTIFY_ACTIVITY_DRAWN = 32;
@@ -4668,21 +4666,6 @@
                     break;
                 }
 
-                case APP_TRANSITION_TIMEOUT: {
-                    synchronized (mWindowMap) {
-                        if (mAppTransition.isTransitionSet() || !mOpeningApps.isEmpty()
-                                    || !mClosingApps.isEmpty()) {
-                            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "*** APP TRANSITION TIMEOUT."
-                                    + " isTransitionSet()=" + mAppTransition.isTransitionSet()
-                                    + " mOpeningApps.size()=" + mOpeningApps.size()
-                                    + " mClosingApps.size()=" + mClosingApps.size());
-                            mAppTransition.setTimeout();
-                            mWindowPlacerLocked.performSurfacePlacement();
-                        }
-                    }
-                    break;
-                }
-
                 case PERSIST_ANIMATION_SCALE: {
                     Settings.Global.putFloat(mContext.getContentResolver(),
                             Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
@@ -4835,14 +4818,6 @@
                     break;
                 }
 
-                case DO_ANIMATION_CALLBACK: {
-                    try {
-                        ((IRemoteCallback)msg.obj).sendResult(null);
-                    } catch (RemoteException e) {
-                    }
-                    break;
-                }
-
                 case NOTIFY_ACTIVITY_DRAWN:
                     try {
                         mActivityTaskManager.notifyActivityDrawn((IBinder) msg.obj);
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index c8d1a8b..04a69e1 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -69,7 +69,6 @@
 import android.view.animation.Animation;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.wm.WindowManagerService.H;
 
 import java.io.PrintWriter;
 import java.util.function.Predicate;
@@ -258,7 +257,7 @@
         mService.mSkipAppTransitionAnimation = false;
         mService.mNoAnimationNotifyOnTransitionFinished.clear();
 
-        mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
+        mService.mAppTransition.removeAppTransitionTimeoutCallbacks();
 
         final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
index 12be0b3..e6e08bb 100644
--- a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -90,7 +90,7 @@
         private AppTransitionListener mListener;
 
         MockAppTransition(Context context) {
-            super(context, null);
+            super(context, sWm);
         }
 
         @Override