Camera: Exit PreviewStreamSpacer when disconnecting stream

- Call requestExit() during Camera3OutputStream disconnect.
- Remove requestExitAndWait() from the PreviewStreamSpacer
  destructor.
- Return false if exitPending() is true in threadLoop.
- Use wp<> when accessing parent from PreviewStreamSpacer.

Test: Camera CTS, and vendor testing
Bug: 232046746
Bug: 232829166
Change-Id: I136a93fee37cd6fbdb8050cacea1511170e03ee6
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 1ce7108..4a9b259 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -689,7 +689,7 @@
             mSyncToDisplay = true;
             mTotalBufferCount += kDisplaySyncExtraBuffer;
         } else if (defaultToSpacer) {
-            mPreviewFrameSpacer = new PreviewFrameSpacer(*this, mConsumer);
+            mPreviewFrameSpacer = new PreviewFrameSpacer(this, mConsumer);
             mTotalBufferCount ++;
             res = mPreviewFrameSpacer->run(String8::format("PreviewSpacer-%d", mId).string());
             if (res != OK) {
@@ -970,6 +970,10 @@
 
     returnPrefetchedBuffersLocked();
 
+    if (mPreviewFrameSpacer != nullptr) {
+        mPreviewFrameSpacer->requestExit();
+    }
+
     ALOGV("%s: disconnecting stream %d from native window", __FUNCTION__, getId());
 
     res = native_window_api_disconnect(mConsumer.get(),
diff --git a/services/camera/libcameraservice/device3/PreviewFrameSpacer.cpp b/services/camera/libcameraservice/device3/PreviewFrameSpacer.cpp
index 496580f..0439501 100644
--- a/services/camera/libcameraservice/device3/PreviewFrameSpacer.cpp
+++ b/services/camera/libcameraservice/device3/PreviewFrameSpacer.cpp
@@ -27,13 +27,12 @@
 
 namespace camera3 {
 
-PreviewFrameSpacer::PreviewFrameSpacer(Camera3OutputStream& parent, sp<Surface> consumer) :
+PreviewFrameSpacer::PreviewFrameSpacer(wp<Camera3OutputStream> parent, sp<Surface> consumer) :
         mParent(parent),
         mConsumer(consumer) {
 }
 
 PreviewFrameSpacer::~PreviewFrameSpacer() {
-    Thread::requestExitAndWait();
 }
 
 status_t PreviewFrameSpacer::queuePreviewBuffer(nsecs_t timestamp, nsecs_t readoutTimestamp,
@@ -51,7 +50,11 @@
     Mutex::Autolock l(mLock);
     if (mPendingBuffers.size() == 0) {
         mBufferCond.waitRelative(mLock, kWaitDuration);
-        return true;
+        if (exitPending()) {
+            return false;
+        } else {
+            return true;
+        }
     }
 
     nsecs_t currentTime = systemTime();
@@ -71,7 +74,7 @@
     if (frameWaitTime > 0 && mPendingBuffers.size() < 2) {
         mBufferCond.waitRelative(mLock, frameWaitTime);
         if (exitPending()) {
-            return true;
+            return false;
         }
         currentTime = systemTime();
     }
@@ -92,7 +95,13 @@
 
 void PreviewFrameSpacer::queueBufferToClientLocked(
         const BufferHolder& bufferHolder, nsecs_t currentTime) {
-    mParent.setTransform(bufferHolder.transform, true/*mayChangeMirror*/);
+    sp<Camera3OutputStream> parent = mParent.promote();
+    if (parent == nullptr) {
+        ALOGV("%s: Parent camera3 output stream was destroyed", __FUNCTION__);
+        return;
+    }
+
+    parent->setTransform(bufferHolder.transform, true/*mayChangeMirror*/);
 
     status_t res = native_window_set_buffers_timestamp(mConsumer.get(), bufferHolder.timestamp);
     if (res != OK) {
@@ -101,13 +110,13 @@
     }
 
     Camera3Stream::queueHDRMetadata(bufferHolder.anwBuffer.get()->handle, mConsumer,
-            mParent.getDynamicRangeProfile());
+            parent->getDynamicRangeProfile());
 
     res = mConsumer->queueBuffer(mConsumer.get(), bufferHolder.anwBuffer.get(),
             bufferHolder.releaseFence);
     if (res != OK) {
         close(bufferHolder.releaseFence);
-        if (mParent.shouldLogError(res)) {
+        if (parent->shouldLogError(res)) {
             ALOGE("%s: Failed to queue buffer to client: %s(%d)", __FUNCTION__,
                     strerror(-res), res);
         }
diff --git a/services/camera/libcameraservice/device3/PreviewFrameSpacer.h b/services/camera/libcameraservice/device3/PreviewFrameSpacer.h
index fb0a563..e165768 100644
--- a/services/camera/libcameraservice/device3/PreviewFrameSpacer.h
+++ b/services/camera/libcameraservice/device3/PreviewFrameSpacer.h
@@ -49,7 +49,7 @@
  */
 class PreviewFrameSpacer : public Thread {
   public:
-    explicit PreviewFrameSpacer(Camera3OutputStream& parent, sp<Surface> consumer);
+    explicit PreviewFrameSpacer(wp<Camera3OutputStream> parent, sp<Surface> consumer);
     virtual ~PreviewFrameSpacer();
 
     // Queue preview buffer locally
@@ -75,8 +75,7 @@
 
     void queueBufferToClientLocked(const BufferHolder& bufferHolder, nsecs_t currentTime);
 
-
-    Camera3OutputStream& mParent;
+    wp<Camera3OutputStream> mParent;
     sp<ANativeWindow> mConsumer;
     mutable Mutex mLock;
     Condition mBufferCond;