SurfaceFlinger: Remove removeLayer

We remove explicit layer destruction and replace it
with reparent->null, completing the transition to
a reference counted model.

Test: Manual
Bug: 62536731
Bug: 111373437
Bug: 111297488

Change-Id: I8ac7c5c5125e1c8daf84b42db00e1dd93a544bb5
diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp
index 384f21f..34886a9 100644
--- a/cmds/surfacereplayer/replayer/Replayer.cpp
+++ b/cmds/surfacereplayer/replayer/Replayer.cpp
@@ -286,10 +286,6 @@
             std::thread(&Replayer::createSurfaceControl, this, increment.surface_creation(), event)
                     .detach();
         } break;
-        case increment.kSurfaceDeletion: {
-            std::thread(&Replayer::deleteSurfaceControl, this, increment.surface_deletion(), event)
-                    .detach();
-        } break;
         case increment.kBufferUpdate: {
             std::lock_guard<std::mutex> lock1(mLayerLock);
             std::lock_guard<std::mutex> lock2(mBufferQueueSchedulerLock);
@@ -628,47 +624,10 @@
     return NO_ERROR;
 }
 
-status_t Replayer::deleteSurfaceControl(
-        const SurfaceDeletion& delete_, const std::shared_ptr<Event>& event) {
-    ALOGV("Deleting %d Surface Control", delete_.id());
-    event->readyToExecute();
-
-    std::lock_guard<std::mutex> lock1(mPendingLayersLock);
-
-    mLayersPendingRemoval.push_back(delete_.id());
-
-    const auto& iterator = mBufferQueueSchedulers.find(delete_.id());
-    if (iterator != mBufferQueueSchedulers.end()) {
-        (*iterator).second->stopScheduling();
-    }
-
-    std::lock_guard<std::mutex> lock2(mLayerLock);
-    if (mLayers[delete_.id()] != nullptr) {
-        mComposerClient->destroySurface(mLayers[delete_.id()]->getHandle());
-    }
-
-    return NO_ERROR;
-}
-
-void Replayer::doDeleteSurfaceControls() {
-    std::lock_guard<std::mutex> lock1(mPendingLayersLock);
-    std::lock_guard<std::mutex> lock2(mLayerLock);
-    if (!mLayersPendingRemoval.empty()) {
-        for (int id : mLayersPendingRemoval) {
-            mLayers.erase(id);
-            mColors.erase(id);
-            mBufferQueueSchedulers.erase(id);
-        }
-        mLayersPendingRemoval.clear();
-    }
-}
-
 status_t Replayer::injectVSyncEvent(
         const VSyncEvent& vSyncEvent, const std::shared_ptr<Event>& event) {
     ALOGV("Injecting VSync Event");
 
-    doDeleteSurfaceControls();
-
     event->readyToExecute();
 
     SurfaceComposerClient::injectVSync(vSyncEvent.when());
diff --git a/cmds/surfacereplayer/replayer/Replayer.h b/cmds/surfacereplayer/replayer/Replayer.h
index 120dd9b..ad807ee 100644
--- a/cmds/surfacereplayer/replayer/Replayer.h
+++ b/cmds/surfacereplayer/replayer/Replayer.h
@@ -70,8 +70,6 @@
     status_t doTransaction(const Transaction& transaction, const std::shared_ptr<Event>& event);
     status_t createSurfaceControl(const SurfaceCreation& create,
             const std::shared_ptr<Event>& event);
-    status_t deleteSurfaceControl(const SurfaceDeletion& delete_,
-            const std::shared_ptr<Event>& event);
     status_t injectVSyncEvent(const VSyncEvent& vsyncEvent, const std::shared_ptr<Event>& event);
     void createDisplay(const DisplayCreation& create, const std::shared_ptr<Event>& event);
     void deleteDisplay(const DisplayDeletion& delete_, const std::shared_ptr<Event>& event);
@@ -120,7 +118,6 @@
     void setDisplayProjection(SurfaceComposerClient::Transaction& t,
             display_id id, const ProjectionChange& pc);
 
-    void doDeleteSurfaceControls();
     void waitUntilTimestamp(int64_t timestamp);
     void waitUntilDeferredTransactionLayerExists(
             const DeferredTransactionChange& dtc, std::unique_lock<std::mutex>& lock);
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index a6890ee..369f523 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -31,7 +31,6 @@
 
 enum class Tag : uint32_t {
     CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
-    DESTROY_SURFACE,
     CLEAR_LAYER_FRAME_STATS,
     GET_LAYER_FRAME_STATS,
     LAST = GET_LAYER_FRAME_STATS,
@@ -57,11 +56,6 @@
                                                                             handle, gbp);
     }
 
-    status_t destroySurface(const sp<IBinder>& handle) override {
-        return callRemote<decltype(&ISurfaceComposerClient::destroySurface)>(Tag::DESTROY_SURFACE,
-                                                                             handle);
-    }
-
     status_t clearLayerFrameStats(const sp<IBinder>& handle) const override {
         return callRemote<decltype(
                 &ISurfaceComposerClient::clearLayerFrameStats)>(Tag::CLEAR_LAYER_FRAME_STATS,
@@ -92,8 +86,6 @@
     switch (tag) {
         case Tag::CREATE_SURFACE:
             return callLocal(data, reply, &ISurfaceComposerClient::createSurface);
-        case Tag::DESTROY_SURFACE:
-            return callLocal(data, reply, &ISurfaceComposerClient::destroySurface);
         case Tag::CLEAR_LAYER_FRAME_STATS:
             return callLocal(data, reply, &ISurfaceComposerClient::clearLayerFrameStats);
         case Tag::GET_LAYER_FRAME_STATS:
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 824e43f..6c39d6f 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -205,6 +205,22 @@
     return *this;
 }
 
+void SurfaceComposerClient::doDropReferenceTransaction(const sp<IBinder>& handle,
+        const sp<ISurfaceComposerClient>& client) {
+    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+    Vector<ComposerState> composerStates;
+    Vector<DisplayState> displayStates;
+
+    ComposerState s;
+    s.client = client;
+    s.state.surface = handle;
+    s.state.what |= layer_state_t::eReparent;
+    s.state.parentHandleForChild = nullptr;
+
+    composerStates.add(s);
+    sf->setTransactionState(composerStates, displayStates, 0, nullptr, {});
+}
+
 status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
     if (mStatus != NO_ERROR) {
         return mStatus;
@@ -819,17 +835,6 @@
 
 #endif
 
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::destroySurface(
-        const sp<SurfaceControl>& sc) {
-    layer_state_t* s = getLayerState(sc);
-    if (!s) {
-        mStatus = BAD_INDEX;
-        return *this;
-    }
-    s->what |= layer_state_t::eDestroySurface;
-    return *this;
-}
-
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorTransform(
     const sp<SurfaceControl>& sc, const mat3& matrix, const vec3& translation) {
     layer_state_t* s = getLayerState(sc);
@@ -1004,13 +1009,6 @@
     return err;
 }
 
-status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) {
-    if (mStatus != NO_ERROR)
-        return mStatus;
-    status_t err = mClient->destroySurface(sid);
-    return err;
-}
-
 status_t SurfaceComposerClient::clearLayerFrameStats(const sp<IBinder>& token) const {
     if (mStatus != NO_ERROR) {
         return mStatus;
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index b6ef286..8e500a4 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -63,7 +63,13 @@
 
 SurfaceControl::~SurfaceControl()
 {
-    destroy();
+    if (mClient != nullptr && mHandle != nullptr && mOwned) {
+        SurfaceComposerClient::doDropReferenceTransaction(mHandle, mClient->getClient());
+    }
+    mClient.clear();
+    mHandle.clear();
+    mGraphicBufferProducer.clear();
+    IPCThreadState::self()->flushCommands();
 }
 
 void SurfaceControl::destroy()
@@ -71,7 +77,7 @@
     // Avoid destroying the server-side surface if we are not the owner of it, meaning that we
     // retrieved it from another process.
     if (isValid() && mOwned) {
-        mClient->destroySurface(mHandle);
+        SurfaceComposerClient::Transaction().reparent(this, nullptr).apply();
     }
     // clear all references and trigger an IPC now, to make sure things
     // happen without delay, since these resources are quite heavy.
diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
index 82b01b8..56ca197 100644
--- a/libs/gui/include/gui/ISurfaceComposerClient.h
+++ b/libs/gui/include/gui/ISurfaceComposerClient.h
@@ -58,11 +58,6 @@
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
      */
-    virtual status_t destroySurface(const sp<IBinder>& handle) = 0;
-
-    /*
-     * Requires ACCESS_SURFACE_FLINGER permission
-     */
     virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const = 0;
 
     /*
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 4a8e01b..e0cbb70 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -145,6 +145,13 @@
                                              ui::Dataspace* wideColorGamutDataspace,
                                              ui::PixelFormat* wideColorGamutPixelFormat);
 
+    /**
+     * Called from SurfaceControl d'tor to 'destroy' the surface (or rather, reparent it
+     * to null), but without needing an sp<SurfaceControl> to avoid infinite ressurection.
+     */
+    static void doDropReferenceTransaction(const sp<IBinder>& handle,
+            const sp<ISurfaceComposerClient>& client);
+
     // ------------------------------------------------------------------------
     // surface creation / destruction
 
@@ -338,8 +345,6 @@
         Transaction& transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
 #endif
 
-        Transaction& destroySurface(const sp<SurfaceControl>& sc);
-
         // Set a color transform matrix on the given layer on the built-in display.
         Transaction& setColorTransform(const sp<SurfaceControl>& sc, const mat3& matrix,
                                        const vec3& translation);
@@ -368,8 +373,6 @@
         void setEarlyWakeup();
     };
 
-    status_t    destroySurface(const sp<IBinder>& id);
-
     status_t clearLayerFrameStats(const sp<IBinder>& token) const;
     status_t getLayerFrameStats(const sp<IBinder>& token, FrameStats* outStats) const;
     static status_t clearAnimationFrameStats();
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index ee4ec50..4f6fb1c 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -39,26 +39,6 @@
 {
 }
 
-Client::~Client()
-{
-    // We need to post a message to remove our remaining layers rather than
-    // do so directly by acquiring the SurfaceFlinger lock. If we were to
-    // attempt to directly call the lock it becomes effectively impossible
-    // to use sp<Client> while holding the SF lock as descoping it could
-    // then trigger a dead-lock.
-
-    const size_t count = mLayers.size();
-    for (size_t i=0 ; i<count ; i++) {
-        sp<Layer> l = mLayers.valueAt(i).promote();
-        if (l == nullptr) {
-            continue;
-        }
-        mFlinger->postMessageAsync(new LambdaMessage([flinger = mFlinger, l]() {
-            flinger->removeLayer(l);
-        }));
-    }
-}
-
 status_t Client::initCheck() const {
     return NO_ERROR;
 }
@@ -115,10 +95,6 @@
                                  ownerUid, handle, gbp, &parent);
 }
 
-status_t Client::destroySurface(const sp<IBinder>& handle) {
-    return mFlinger->onLayerRemoved(this, handle);
-}
-
 status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
     sp<Layer> layer = getLayerUser(handle);
     if (layer == nullptr) {
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 4a74739..d0051de 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -39,13 +39,12 @@
 {
 public:
     explicit Client(const sp<SurfaceFlinger>& flinger);
-    ~Client();
+    ~Client() = default;
 
     status_t initCheck() const;
 
     // protected by SurfaceFlinger::mStateLock
     void attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer);
-
     void detachLayer(const Layer* layer);
 
     sp<Layer> getLayerUser(const sp<IBinder>& handle) const;
@@ -59,8 +58,6 @@
             sp<IBinder>* handle,
             sp<IGraphicBufferProducer>* gbp);
 
-    virtual status_t destroySurface(const sp<IBinder>& handle);
-
     virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const;
 
     virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index b1827c1..3f2d10a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -179,6 +179,8 @@
     for (const auto& child : mCurrentChildren) {
         child->onRemovedFromCurrentState();
     }
+
+    mFlinger->markLayerPendingRemovalLocked(this);
 }
 
 void Layer::addToCurrentState() {
@@ -1571,6 +1573,7 @@
 
 ssize_t Layer::removeChild(const sp<Layer>& layer) {
     layer->setParent(nullptr);
+
     return mCurrentChildren.remove(layer);
 }
 
@@ -1605,14 +1608,14 @@
 }
 
 bool Layer::reparent(const sp<IBinder>& newParentHandle) {
-    if (newParentHandle == nullptr) {
-        return false;
-    }
+    bool callSetTransactionFlags = false;
 
-    auto handle = static_cast<Handle*>(newParentHandle.get());
-    sp<Layer> newParent = handle->owner.promote();
-    if (newParent == nullptr) {
-        ALOGE("Unable to promote Layer handle");
+    // While layers are detached, we allow most operations
+    // and simply halt performing the actual transaction. However
+    // for reparent != null we would enter the mRemovedFromCurrentState
+    // state, regardless of whether doTransaction was called, and
+    // so we need to prevent the update here.
+    if (mLayerDetached && newParentHandle == nullptr) {
         return false;
     }
 
@@ -1620,17 +1623,31 @@
     if (parent != nullptr) {
         parent->removeChild(this);
     }
-    newParent->addChild(this);
 
-    if (!newParent->isRemovedFromCurrentState()) {
-        addToCurrentState();
+    if (newParentHandle != nullptr) {
+        auto handle = static_cast<Handle*>(newParentHandle.get());
+        sp<Layer> newParent = handle->owner.promote();
+        if (newParent == nullptr) {
+            ALOGE("Unable to promote Layer handle");
+            return false;
+        }
+
+        newParent->addChild(this);
+        if (!newParent->isRemovedFromCurrentState()) {
+            addToCurrentState();
+        } else {
+            onRemovedFromCurrentState();
+        }
+
+        if (mLayerDetached) {
+            mLayerDetached = false;
+            callSetTransactionFlags = true;
+        }
+    } else {
+        onRemovedFromCurrentState();
     }
 
-    if (mLayerDetached) {
-        mLayerDetached = false;
-        setTransactionFlags(eTransactionNeeded);
-    }
-    if (attachChildren()) {
+    if (callSetTransactionFlags || attachChildren()) {
         setTransactionFlags(eTransactionNeeded);
     }
     return true;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fd25abf..3648be4 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2799,10 +2799,8 @@
             // showing at its last configured state until we eventually
             // abandon the buffer queue.
             if (l->isRemovedFromCurrentState()) {
-                l->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* child) {
-                    child->destroyHwcLayersForAllDisplays();
-                    latchAndReleaseBuffer(child);
-                });
+                l->destroyHwcLayersForAllDisplays();
+                latchAndReleaseBuffer(l);
             }
         }
         mLayersPendingRemoval.clear();
@@ -3276,30 +3274,6 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
-    Mutex::Autolock _l(mStateLock);
-    return removeLayerLocked(mStateLock, layer);
-}
-
-status_t SurfaceFlinger::removeLayerLocked(const Mutex& lock, const sp<Layer>& layer) {
-    if (layer->isLayerDetached()) {
-        return NO_ERROR;
-    }
-
-    const auto& p = layer->getParent();
-    ssize_t index;
-    if (p != nullptr) {
-        index = p->removeChild(layer);
-    } else {
-        index = mCurrentState.layersSortedByZ.remove(layer);
-    }
-
-    layer->onRemovedFromCurrentState();
-
-    markLayerPendingRemovalLocked(lock, layer);
-    return NO_ERROR;
-}
-
 uint32_t SurfaceFlinger::peekTransactionFlags() {
     return mTransactionFlags;
 }
@@ -3434,14 +3408,6 @@
     }
     transactionFlags |= clientStateFlags;
 
-    // Iterate through all layers again to determine if any need to be destroyed. Marking layers
-    // as destroyed should only occur after setting all other states. This is to allow for a
-    // child re-parent to happen before marking its original parent as destroyed (which would
-    // then mark the child as destroyed).
-    for (const ComposerState& state : states) {
-        setDestroyStateLocked(state);
-    }
-
     transactionFlags |= addInputWindowCommands(inputWindowCommands);
 
     // If a synchronous transaction is explicitly requested without any changes, force a transaction
@@ -3767,20 +3733,6 @@
     return flags;
 }
 
-void SurfaceFlinger::setDestroyStateLocked(const ComposerState& composerState) {
-    const layer_state_t& state = composerState.state;
-    sp<Client> client(static_cast<Client*>(composerState.client.get()));
-
-    sp<Layer> layer(client->getLayerUser(state.surface));
-    if (layer == nullptr) {
-        return;
-    }
-
-    if (state.what & layer_state_t::eDestroySurface) {
-        removeLayerLocked(mStateLock, layer);
-    }
-}
-
 uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
     uint32_t flags = 0;
     if (!inputWindowCommands.transferTouchFocusCommands.empty()) {
@@ -3960,21 +3912,7 @@
 }
 
 
-status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
-{
-    // called by a client when it wants to remove a Layer
-    status_t err = NO_ERROR;
-    sp<Layer> l(client->getLayerUser(handle));
-    if (l != nullptr) {
-        mInterceptor->saveSurfaceDeletion(l);
-        err = removeLayer(l);
-        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
-                "error removing layer=%p (%s)", l.get(), strerror(-err));
-    }
-    return err;
-}
-
-void SurfaceFlinger::markLayerPendingRemovalLocked(const Mutex&, const sp<Layer>& layer) {
+void SurfaceFlinger::markLayerPendingRemovalLocked(const sp<Layer>& layer) {
     mLayersPendingRemoval.add(layer);
     mLayersRemoved = true;
     setTransactionFlags(eTransactionNeeded);
@@ -3983,7 +3921,14 @@
 void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer)
 {
     Mutex::Autolock lock(mStateLock);
-    markLayerPendingRemovalLocked(mStateLock, layer);
+    // If a layer has a parent, we allow it to out-live it's handle
+    // with the idea that the parent holds a reference and will eventually
+    // be cleaned up. However no one cleans up the top-level so we do so
+    // here.
+    if (layer->getParent() == nullptr) {
+        mCurrentState.layersSortedByZ.remove(layer);
+    }
+    markLayerPendingRemovalLocked(layer);
     layer.clear();
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index bfc87a0..b8bfcf1 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -569,7 +569,6 @@
     bool composerStateContainsUnsignaledFences(const Vector<ComposerState>& states);
     uint32_t setClientStateLocked(const ComposerState& composerState);
     uint32_t setDisplayStateLocked(const DisplayState& s);
-    void setDestroyStateLocked(const ComposerState& composerState);
     uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands);
 
     /* ------------------------------------------------------------------------
@@ -599,20 +598,11 @@
 
     String8 getUniqueLayerName(const String8& name);
 
-    // called in response to the window-manager calling
-    // ISurfaceComposerClient::destroySurface()
-    status_t onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle);
-
-    void markLayerPendingRemovalLocked(const Mutex& /* mStateLock */, const sp<Layer>& layer);
-
     // called when all clients have released all their references to
     // this layer meaning it is entirely safe to destroy all
     // resources associated to this layer.
     void onHandleDestroyed(sp<Layer>& layer);
-
-    // remove a layer from SurfaceFlinger immediately
-    status_t removeLayer(const sp<Layer>& layer);
-    status_t removeLayerLocked(const Mutex&, const sp<Layer>& layer);
+    void markLayerPendingRemovalLocked(const sp<Layer>& layer);
 
     // add a layer to SurfaceFlinger
     status_t addClientLayer(const sp<Client>& client,
diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp
index 3e1be8e..89c26f4 100644
--- a/services/surfaceflinger/tests/Stress_test.cpp
+++ b/services/surfaceflinger/tests/Stress_test.cpp
@@ -34,7 +34,7 @@
             auto surf = client->createSurface(String8("t"), 100, 100,
                     PIXEL_FORMAT_RGBA_8888, 0);
             ASSERT_TRUE(surf != nullptr);
-            client->destroySurface(surf->getHandle());
+            surf->clear();
         }
     };
 
diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
index e506757..8ec3e15 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -806,18 +806,6 @@
             Increment::IncrementCase::kSurfaceCreation);
 }
 
-TEST_F(SurfaceInterceptorTest, InterceptSurfaceDeletionWorks) {
-    enableInterceptor();
-    sp<SurfaceControl> layerToDelete = mComposerClient->createSurface(String8(LAYER_NAME),
-            SIZE_UPDATE, SIZE_UPDATE, PIXEL_FORMAT_RGBA_8888, 0);
-    mComposerClient->destroySurface(layerToDelete->getHandle());
-    disableInterceptor();
-
-    Trace capturedTrace;
-    ASSERT_EQ(NO_ERROR, readProtoFile(&capturedTrace));
-    ASSERT_TRUE(singleIncrementFound(capturedTrace, Increment::IncrementCase::kSurfaceDeletion));
-}
-
 TEST_F(SurfaceInterceptorTest, InterceptDisplayCreationWorks) {
     captureTest(&SurfaceInterceptorTest::displayCreation,
             Increment::IncrementCase::kDisplayCreation);
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index d118ad6..991ea36 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -1023,7 +1023,7 @@
             .setRelativeLayer(layerG, layerR->getHandle(), 1)
             .apply();
 
-    mClient->destroySurface(layerG->getHandle());
+    layerG->clear();
     // layerG should have been removed
     screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
 }
@@ -4030,9 +4030,9 @@
     asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
     {
         mCapture = screenshot();
-        // Nothing should have changed.
+        // The surface should now be offscreen.
         mCapture->expectFGColor(64, 64);
-        mCapture->expectChildColor(74, 74);
+        mCapture->expectFGColor(74, 74);
         mCapture->expectFGColor(84, 84);
     }
 }
@@ -4610,7 +4610,7 @@
     ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
 
     auto redLayerHandle = redLayer->getHandle();
-    mClient->destroySurface(redLayerHandle);
+    redLayer->clear();
     SurfaceComposerClient::Transaction().apply(true);
 
     sp<GraphicBuffer> outBuffer;