Merge cherrypicks of [15873636, 15873851, 15873852, 15873654, 15873655, 15873656, 15873657, 15873637, 15873638, 15873639, 15873339, 15873340, 15873341, 15873342, 15873343, 15873344, 15873345, 15873346, 15873947, 15873948, 15873949, 15873950, 15873951, 15873952, 15873953, 15873954, 15873955, 15873956, 15873957, 15873958, 15873959, 15873960, 15873961, 15873642, 15873122, 15873323, 15873123, 15873324, 15872698, 15872700, 15873987, 15873962, 15873963, 15873964, 15873965, 15873557, 15873558, 15873816, 15873643, 15873817, 15873660, 15873559, 15873988, 15873644, 15873645, 15873646, 15873325, 15873661, 15873662, 15873663, 15874027, 15874028, 15874029, 15874030, 15874031, 15874032, 15874033, 15874034, 15874035, 15874036, 15874037, 15874038, 15874039, 15874040, 15874041, 15874042, 15873560, 15873561, 15873854, 15873855, 15873562, 15873563, 15873564, 15873565, 15873566, 15874047, 15874048, 15873326, 15873124, 15874043, 15872622, 15872623, 15873857, 15872701, 15872702] into sc-d1-release

Change-Id: I3aa3b6e8913f904e66a222cf7909d5859929d1d1
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 56a9683..f7ec8ef 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -630,7 +630,10 @@
 
 class BBQSurface : public Surface {
 private:
+    std::mutex mMutex;
     sp<BLASTBufferQueue> mBbq;
+    bool mDestroyed = false;
+
 public:
     BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp,
                const sp<IBinder>& scHandle, const sp<BLASTBufferQueue>& bbq)
@@ -650,6 +653,10 @@
 
     status_t setFrameRate(float frameRate, int8_t compatibility,
                           int8_t changeFrameRateStrategy) override {
+        std::unique_lock _lock{mMutex};
+        if (mDestroyed) {
+            return DEAD_OBJECT;
+        }
         if (!ValidateFrameRate(frameRate, compatibility, changeFrameRateStrategy,
                                "BBQSurface::setFrameRate")) {
             return BAD_VALUE;
@@ -658,8 +665,20 @@
     }
 
     status_t setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) override {
+        std::unique_lock _lock{mMutex};
+        if (mDestroyed) {
+            return DEAD_OBJECT;
+        }
         return mBbq->setFrameTimelineInfo(frameTimelineInfo);
     }
+
+    void destroy() override {
+        Surface::destroy();
+
+        std::unique_lock _lock{mMutex};
+        mDestroyed = true;
+        mBbq = nullptr;
+    }
 };
 
 // TODO: Can we coalesce this with frame updates? Need to confirm
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 2edb4e4..353a91d 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -2622,4 +2622,14 @@
     return composerService()->setFrameTimelineInfo(mGraphicBufferProducer, frameTimelineInfo);
 }
 
+sp<IBinder> Surface::getSurfaceControlHandle() const {
+    Mutex::Autolock lock(mMutex);
+    return mSurfaceControlHandle;
+}
+
+void Surface::destroy() {
+    Mutex::Autolock lock(mMutex);
+    mSurfaceControlHandle = nullptr;
+}
+
 }; // namespace android
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 7e4143b..e540351 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -99,7 +99,7 @@
      */
     sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;
 
-    sp<IBinder> getSurfaceControlHandle() const { return mSurfaceControlHandle; }
+    sp<IBinder> getSurfaceControlHandle() const;
 
     /* convenience function to check that the given surface is non NULL as
      * well as its IGraphicBufferProducer */
@@ -333,6 +333,7 @@
     virtual int connect(
             int api, bool reportBufferRemoval,
             const sp<SurfaceListener>& sListener);
+    virtual void destroy();
 
     // When client connects to Surface with reportBufferRemoval set to true, any buffers removed
     // from this Surface will be collected and returned here. Once this method returns, these