Remove getLeash from WindowContainerToken

If the WindowContainer was revoked from a registered organizer, the
client could still call getLeash to system server and control the leash
for the WindowContainer. Instead, pass the leash back to the client in
onTaskAppeared and onDisplayAreaAppeared. Once the WindowContainer is
revoked from the client, the leash will reference the old
WindowContainer SurfaceControl and will not be able to control the
WindowContainer anymore.

Test: Split screen
Test: DisplayAreaOrganizerTest
Test: WindowOrganizerTest
Bug: 154558563
Change-Id: I1f6eb987a2a3fecfef912a3009ee52989c85ff4b
diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
index 2c8c820..b6c71bb 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
@@ -21,6 +21,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.view.SurfaceControl;
 import android.window.IDisplayAreaOrganizer;
 import android.window.IDisplayAreaOrganizerController;
 
@@ -113,7 +114,8 @@
 
     void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) {
         try {
-            organizer.onDisplayAreaAppeared(da.getDisplayAreaInfo());
+            SurfaceControl outSurfaceControl = new SurfaceControl(da.getSurfaceControl());
+            organizer.onDisplayAreaAppeared(da.getDisplayAreaInfo(), outSurfaceControl);
         } catch (RemoteException e) {
             // Oh well...
         }
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 9d229df..83105c2 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -36,6 +36,7 @@
 import android.os.RemoteException;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.SurfaceControl;
 import android.window.ITaskOrganizer;
 import android.window.ITaskOrganizerController;
 import android.window.WindowContainerToken;
@@ -112,7 +113,8 @@
             final RunningTaskInfo taskInfo = task.getTaskInfo();
             mDeferTaskOrgCallbacksConsumer.accept(() -> {
                 try {
-                    mTaskOrganizer.onTaskAppeared(taskInfo);
+                    SurfaceControl outSurfaceControl = new SurfaceControl(task.getSurfaceControl());
+                    mTaskOrganizer.onTaskAppeared(taskInfo, outSurfaceControl);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "Exception sending onTaskAppeared callback", e);
                 }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 1155bb8..3f8d7b5 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -2557,16 +2557,6 @@
             return (RemoteToken) binder;
         }
 
-        @Override
-        public SurfaceControl getLeash() {
-            final WindowContainer wc = getContainer();
-            if (wc == null) return null;
-            // We need to copy the SurfaceControl instead of returning the original
-            // because the Parcel FLAGS PARCELABLE_WRITE_RETURN_VALUE cause SurfaceControls
-            // to release themselves.
-            return new SurfaceControl(wc.getSurfaceControl());
-        }
-
         WindowContainerToken toWindowContainerToken() {
             if (mWindowContainerToken == null) {
                 mWindowContainerToken = new WindowContainerToken(this);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 0700f9f..2991859 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -49,6 +49,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.service.voice.IVoiceInteractionSession;
+import android.view.SurfaceControl;
 import android.window.ITaskOrganizer;
 import android.window.WindowContainerToken;
 
@@ -552,7 +553,7 @@
             mMoveToSecondaryOnEnter = move;
         }
         @Override
-        public void onTaskAppeared(ActivityManager.RunningTaskInfo info) {
+        public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
         }
         @Override
         public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java
index 307b40f..6a1f50d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java
@@ -27,6 +27,8 @@
 import android.os.Binder;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
+import android.view.SurfaceControl;
+import android.window.DisplayAreaInfo;
 import android.window.IDisplayAreaOrganizer;
 
 import androidx.test.filters.SmallTest;
@@ -74,7 +76,8 @@
     @Test
     public void testAppearedVanished() throws RemoteException {
         IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST);
-        verify(organizer).onDisplayAreaAppeared(any());
+        verify(organizer)
+                .onDisplayAreaAppeared(any(DisplayAreaInfo.class), any(SurfaceControl.class));
 
         unregisterMockOrganizer(organizer);
         verify(organizer).onDisplayAreaVanished(any());
@@ -83,7 +86,8 @@
     @Test
     public void testChanged() throws RemoteException {
         IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST);
-        verify(organizer).onDisplayAreaAppeared(any());
+        verify(organizer)
+                .onDisplayAreaAppeared(any(DisplayAreaInfo.class), any(SurfaceControl.class));
 
         mDisplayContent.setBounds(new Rect(0, 0, 1000, 1000));
         verify(organizer).onDisplayAreaInfoChanged(any());
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 7d2e880..aa68c69 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -65,6 +65,7 @@
 import android.util.ArrayMap;
 import android.util.Rational;
 import android.view.Display;
+import android.view.SurfaceControl;
 import android.window.ITaskOrganizer;
 import android.window.WindowContainerTransaction;
 
@@ -133,7 +134,8 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
 
         task.setTaskOrganizer(organizer);
-        verify(organizer).onTaskAppeared(any());
+        verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
+
 
         task.removeImmediately();
         verify(organizer).onTaskVanished(any());
@@ -147,11 +149,12 @@
 
         task.setTaskOrganizer(organizer);
 
-        verify(organizer, never()).onTaskAppeared(any());
+        verify(organizer, never())
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         task.setHasBeenVisible(true);
         assertTrue(stack.getHasBeenVisible());
 
-        verify(organizer).onTaskAppeared(any());
+        verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
 
         task.removeImmediately();
         verify(organizer).onTaskVanished(any());
@@ -167,7 +170,8 @@
         // that even though a TaskOrganizer is set remove doesn't emit
         // a vanish callback, because we never emitted appear.
         task.setTaskOrganizer(organizer);
-        verify(organizer, never()).onTaskAppeared(any());
+        verify(organizer, never())
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         task.removeImmediately();
         verify(organizer, never()).onTaskVanished(any());
     }
@@ -180,10 +184,10 @@
         final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED);
 
         task.setTaskOrganizer(organizer);
-        verify(organizer).onTaskAppeared(any());
+        verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         task.setTaskOrganizer(organizer2);
         verify(organizer).onTaskVanished(any());
-        verify(organizer2).onTaskAppeared(any());
+        verify(organizer2).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
     }
 
     @Test
@@ -194,10 +198,10 @@
         final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED);
 
         stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
-        verify(organizer).onTaskAppeared(any());
+        verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         stack.setWindowingMode(WINDOWING_MODE_PINNED);
         verify(organizer).onTaskVanished(any());
-        verify(organizer2).onTaskAppeared(any());
+        verify(organizer2).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
     }
 
     @Test
@@ -207,7 +211,8 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
 
         stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
-        verify(organizer, never()).onTaskAppeared(any());
+        verify(organizer, never())
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         assertTrue(stack.isOrganized());
 
         mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer);
@@ -222,7 +227,7 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
 
         stack.setTaskOrganizer(organizer);
-        verify(organizer).onTaskAppeared(any());
+        verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         assertTrue(stack.isOrganized());
 
         stack.setTaskOrganizer(null);
@@ -237,7 +242,7 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
 
         stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
-        verify(organizer).onTaskAppeared(any());
+        verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         assertTrue(stack.isOrganized());
 
         mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer);
@@ -257,7 +262,8 @@
 
         // First organizer is registered, verify a task appears when changing windowing mode
         stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
-        verify(organizer, times(1)).onTaskAppeared(any());
+        verify(organizer, times(1))
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         assertTrue(stack.isOrganized());
 
         // Now we replace the registration and1 verify the new organizer receives tasks
@@ -265,7 +271,8 @@
         final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);
         stack2.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         // One each for task and task2
-        verify(organizer2, times(2)).onTaskAppeared(any());
+        verify(organizer2, times(2))
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         verify(organizer2, times(0)).onTaskVanished(any());
         // One for task
         verify(organizer).onTaskVanished(any());
@@ -274,11 +281,13 @@
         // Now we unregister the second one, the first one should automatically be reregistered
         // so we verify that it's now seeing changes.
         mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer2);
-        verify(organizer, times(3)).onTaskAppeared(any());
+        verify(organizer, times(3))
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         verify(organizer2, times(2)).onTaskVanished(any());
 
         stack3.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
-        verify(organizer, times(4)).onTaskAppeared(any());
+        verify(organizer, times(4))
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
         verify(organizer2, times(2)).onTaskVanished(any());
         assertTrue(stack3.isOrganized());
     }
@@ -291,7 +300,8 @@
         final Task task = createTask(stack);
         final Task task2 = createTask(stack);
         stack.setWindowingMode(WINDOWING_MODE_PINNED);
-        verify(organizer, times(1)).onTaskAppeared(any());
+        verify(organizer, times(1))
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
 
         stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
         verify(organizer, times(1)).onTaskVanished(any());
@@ -304,7 +314,8 @@
         stack.setWindowingMode(WINDOWING_MODE_PINNED);
 
         final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_PINNED);
-        verify(organizer, times(1)).onTaskAppeared(any());
+        verify(organizer, times(1))
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
     }
 
     @Test
@@ -459,7 +470,7 @@
     public void testTileAddRemoveChild() {
         ITaskOrganizer listener = new ITaskOrganizer.Stub() {
             @Override
-            public void onTaskAppeared(RunningTaskInfo taskInfo) { }
+            public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { }
 
             @Override
             public void onTaskVanished(RunningTaskInfo container) { }
@@ -515,7 +526,7 @@
         final boolean[] called = {false};
         ITaskOrganizer listener = new ITaskOrganizer.Stub() {
             @Override
-            public void onTaskAppeared(RunningTaskInfo taskInfo) { }
+            public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { }
 
             @Override
             public void onTaskVanished(RunningTaskInfo container) { }
@@ -577,7 +588,7 @@
         final ArrayMap<IBinder, RunningTaskInfo> lastReportedTiles = new ArrayMap<>();
         ITaskOrganizer listener = new ITaskOrganizer.Stub() {
             @Override
-            public void onTaskAppeared(RunningTaskInfo taskInfo) { }
+            public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { }
 
             @Override
             public void onTaskVanished(RunningTaskInfo container) { }
@@ -804,7 +815,7 @@
         RunningTaskInfo mInfo;
 
         @Override
-        public void onTaskAppeared(RunningTaskInfo info) {
+        public void onTaskAppeared(RunningTaskInfo info, SurfaceControl leash) {
             mInfo = info;
         }
         @Override
@@ -907,12 +918,14 @@
         task.setTaskOrganizer(organizer);
         // setHasBeenVisible was already called once by the set-up code.
         task.setHasBeenVisible(true);
-        verify(organizer, times(1)).onTaskAppeared(any());
+        verify(organizer, times(1))
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
 
         task.setTaskOrganizer(null);
         verify(organizer, times(1)).onTaskVanished(any());
         task.setTaskOrganizer(organizer);
-        verify(organizer, times(2)).onTaskAppeared(any());
+        verify(organizer, times(2))
+                .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
 
         task.removeImmediately();
         verify(organizer, times(2)).onTaskVanished(any());