Use new ISurfaceComposer::destroyDisplay method

Bug: 10191053
Change-Id: I3ecc6880db4a4c77c6db4e8b50faa9b4021d17c6
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 6b530ef..dc31e0b 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -59,13 +59,14 @@
 
     private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
     private static native IBinder nativeCreateDisplay(String name, boolean secure);
+    private static native void nativeDestroyDisplay(IBinder displayToken);
     private static native void nativeSetDisplaySurface(
             IBinder displayToken, int nativeSurfaceObject);
     private static native void nativeSetDisplayLayerStack(
             IBinder displayToken, int layerStack);
     private static native void nativeSetDisplayProjection(
             IBinder displayToken, int orientation,
-            int l, int t, int r, int b, 
+            int l, int t, int r, int b,
             int L, int T, int R, int B);
     private static native boolean nativeGetDisplayInfo(
             IBinder displayToken, SurfaceControl.PhysicalDisplayInfo outInfo);
@@ -103,7 +104,7 @@
      * measures will be taken to disallow the surface's content to be copied
      * from another process. In particular, screenshots and VNC servers will
      * be disabled, but other measures can take place, for instance the
-     * surface might not be hardware accelerated. 
+     * surface might not be hardware accelerated.
      *
      */
     public static final int SECURE = 0x00000080;
@@ -247,10 +248,10 @@
             throw new OutOfResourcesException(
                     "Couldn't allocate SurfaceControl native object");
         }
-        
+
         mCloseGuard.open("release");
     }
-    
+
     @Override
     protected void finalize() throws Throwable {
         try {
@@ -300,7 +301,7 @@
         if (mNativeObject == 0) throw new NullPointerException(
                 "mNativeObject is null. Have you called release() already?");
     }
-    
+
     /*
      * set surface parameters.
      * needs to be inside open/closeTransaction block
@@ -369,7 +370,7 @@
     public void setWindowCrop(Rect crop) {
         checkNotReleased();
         if (crop != null) {
-            nativeSetWindowCrop(mNativeObject, 
+            nativeSetWindowCrop(mNativeObject,
                 crop.left, crop.top, crop.right, crop.bottom);
         } else {
             nativeSetWindowCrop(mNativeObject, 0, 0, 0, 0);
@@ -397,19 +398,19 @@
         public float xDpi;
         public float yDpi;
         public boolean secure;
-    
+
         public PhysicalDisplayInfo() {
         }
-    
+
         public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
             copyFrom(other);
         }
-    
+
         @Override
         public boolean equals(Object o) {
             return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
         }
-    
+
         public boolean equals(PhysicalDisplayInfo other) {
             return other != null
                     && width == other.width
@@ -420,12 +421,12 @@
                     && yDpi == other.yDpi
                     && secure == other.secure;
         }
-    
+
         @Override
         public int hashCode() {
             return 0; // don't care
         }
-    
+
         public void copyFrom(PhysicalDisplayInfo other) {
             width = other.width;
             height = other.height;
@@ -435,7 +436,7 @@
             yDpi = other.yDpi;
             secure = other.secure;
         }
-    
+
         // For debugging purposes
         @Override
         public String toString() {
@@ -481,7 +482,7 @@
             throw new IllegalArgumentException("displayRect must not be null");
         }
         nativeSetDisplayProjection(displayToken, orientation,
-                layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom, 
+                layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
                 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
     }
 
@@ -513,6 +514,13 @@
         return nativeCreateDisplay(name, secure);
     }
 
+    public static void destroyDisplay(IBinder displayToken) {
+        if (displayToken == null) {
+            throw new IllegalArgumentException("displayToken must not be null");
+        }
+        nativeDestroyDisplay(displayToken);
+    }
+
     public static IBinder getBuiltInDisplay(int builtInDisplayId) {
         return nativeGetBuiltInDisplay(builtInDisplayId);
     }
@@ -608,7 +616,7 @@
                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
         return nativeScreenshot(displayToken, width, height, 0, 0, true);
     }
-    
+
     private static void screenshot(IBinder display, Surface consumer,
             int width, int height, int minLayer, int maxLayer, boolean allLayers) {
         if (display == null) {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index e5e3a2f..19f56cd 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -333,6 +333,12 @@
     return javaObjectForIBinder(env, token);
 }
 
+static void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
+    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+    if (token == NULL) return;
+    SurfaceComposerClient::destroyDisplay(token);
+}
+
 static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
         jobject tokenObj, jint nativeSurfaceObject) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
@@ -441,6 +447,8 @@
             (void*)nativeGetBuiltInDisplay },
     {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
             (void*)nativeCreateDisplay },
+    {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
+            (void*)nativeDestroyDisplay },
     {"nativeSetDisplaySurface", "(Landroid/os/IBinder;I)V",
             (void*)nativeSetDisplaySurface },
     {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V",
diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java
index 4b3463c..659163c 100644
--- a/services/java/com/android/server/display/DisplayManagerService.java
+++ b/services/java/com/android/server/display/DisplayManagerService.java
@@ -154,9 +154,6 @@
     // List of all currently connected display devices.
     private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
 
-    // List of all removed display devices.
-    private final ArrayList<DisplayDevice> mRemovedDisplayDevices = new ArrayList<DisplayDevice>();
-
     // List of all logical displays indexed by logical display id.
     private final SparseArray<LogicalDisplay> mLogicalDisplays =
             new SparseArray<LogicalDisplay>();
@@ -798,7 +795,6 @@
 
         Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
 
-        mRemovedDisplayDevices.add(device);
         updateLogicalDisplaysLocked();
         scheduleTraversalLocked(false);
     }
@@ -900,14 +896,6 @@
     }
 
     private void performTraversalInTransactionLocked() {
-        // Perform one last traversal for each removed display device.
-        final int removedCount = mRemovedDisplayDevices.size();
-        for (int i = 0; i < removedCount; i++) {
-            DisplayDevice device = mRemovedDisplayDevices.get(i);
-            device.performTraversalInTransactionLocked();
-        }
-        mRemovedDisplayDevices.clear();
-
         // Clear all viewports before configuring displays so that we can keep
         // track of which ones we have configured.
         clearViewportsLocked();
diff --git a/services/java/com/android/server/display/OverlayDisplayAdapter.java b/services/java/com/android/server/display/OverlayDisplayAdapter.java
index ce402a5..007acf7 100644
--- a/services/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -211,11 +211,13 @@
             mSurfaceTexture = surfaceTexture;
         }
 
-        public void clearSurfaceTextureLocked() {
-            if (mSurfaceTexture != null) {
-                mSurfaceTexture = null;
+        public void destroyLocked() {
+            mSurfaceTexture = null;
+            if (mSurface != null) {
+                mSurface.release();
+                mSurface = null;
             }
-            sendTraversalRequestLocked();
+            SurfaceControl.destroyDisplay(getDisplayTokenLocked());
         }
 
         @Override
@@ -225,12 +227,6 @@
                     mSurface = new Surface(mSurfaceTexture);
                 }
                 setSurfaceInTransactionLocked(mSurface);
-            } else {
-                setSurfaceInTransactionLocked(null);
-                if (mSurface != null) {
-                    mSurface.destroy();
-                    mSurface = null;
-                }
             }
         }
 
@@ -307,7 +303,7 @@
         public void onWindowDestroyed() {
             synchronized (getSyncRoot()) {
                 if (mDevice != null) {
-                    mDevice.clearSurfaceTextureLocked();
+                    mDevice.destroyLocked();
                     sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_REMOVED);
                 }
             }
diff --git a/services/java/com/android/server/display/VirtualDisplayAdapter.java b/services/java/com/android/server/display/VirtualDisplayAdapter.java
index 3a71361..46d473c 100644
--- a/services/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -58,7 +58,7 @@
         try {
             appToken.linkToDeath(device, 0);
         } catch (RemoteException ex) {
-            device.releaseLocked();
+            device.destroyLocked();
             return null;
         }
 
@@ -72,6 +72,7 @@
     public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
         VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
         if (device != null) {
+            device.destroyLocked();
             appToken.unlinkToDeath(device, 0);
         }
 
@@ -85,6 +86,7 @@
         if (device != null) {
             Slog.i(TAG, "Virtual display device released because application token died: "
                     + device.mOwnerPackageName);
+            device.destroyLocked();
             sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_REMOVED);
         }
     }
@@ -100,7 +102,6 @@
         private final int mDensityDpi;
         private final int mFlags;
 
-        private boolean mReleased;
         private Surface mSurface;
         private DisplayDeviceInfo mInfo;
 
@@ -122,24 +123,25 @@
         @Override
         public void binderDied() {
             synchronized (getSyncRoot()) {
-                if (!mReleased) {
+                if (mSurface != null) {
                     handleBinderDiedLocked(mAppToken);
                 }
             }
         }
 
-        public void releaseLocked() {
-            mReleased = true;
-            sendTraversalRequestLocked();
+        public void destroyLocked() {
+            if (mSurface != null) {
+                mSurface.release();
+                mSurface = null;
+            }
+            SurfaceControl.destroyDisplay(getDisplayTokenLocked());
         }
 
         @Override
         public void performTraversalInTransactionLocked() {
-            if (mReleased && mSurface != null) {
-                mSurface.destroy();
-                mSurface = null;
+            if (mSurface != null) {
+                setSurfaceInTransactionLocked(mSurface);
             }
-            setSurfaceInTransactionLocked(mSurface);
         }
 
         @Override
diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java
index 11d3819..a9da30f 100644
--- a/services/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/java/com/android/server/display/WifiDisplayAdapter.java
@@ -374,7 +374,7 @@
 
     private void removeDisplayDeviceLocked() {
         if (mDisplayDevice != null) {
-            mDisplayDevice.clearSurfaceLocked();
+            mDisplayDevice.destroyLocked();
             sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
             mDisplayDevice = null;
 
@@ -633,9 +633,12 @@
             mSurface = surface;
         }
 
-        public void clearSurfaceLocked() {
-            mSurface = null;
-            sendTraversalRequestLocked();
+        public void destroyLocked() {
+            if (mSurface != null) {
+                mSurface.release();
+                mSurface = null;
+            }
+            SurfaceControl.destroyDisplay(getDisplayTokenLocked());
         }
 
         public void setNameLocked(String name) {
@@ -645,7 +648,9 @@
 
         @Override
         public void performTraversalInTransactionLocked() {
-            setSurfaceInTransactionLocked(mSurface);
+            if (mSurface != null) {
+                setSurfaceInTransactionLocked(mSurface);
+            }
         }
 
         @Override