Camera: Account for any pending freed buffers during the offline switch

During offline session switches, pending buffer cache updates may not
have the ability to propagate to CameraHal due to absence of any
additional capture requests. This scenario will result in a delta between
the circulating buffers declared by Hal and the current buffer records in
camera service.
Try to detect and avoid possible switch failures in such cases.

Bug: 232892208
Test: Camera CTS
Change-Id: I835ec422131135eb884130a79642d5cb9952498b
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index de418da..f7fd5d6 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -4091,6 +4091,26 @@
         // Verify buffer caches
         std::vector<uint64_t> bufIds(offlineStream.circulatingBufferIds.begin(),
                 offlineStream.circulatingBufferIds.end());
+        {
+            // Due to timing it is possible that we may not have any remaining pending capture
+            // requests that can update the caches on Hal side. This can result in buffer cache
+            // mismatch between the service and the Hal and must be accounted for.
+            std::lock_guard<std::mutex> l(mFreedBuffersLock);
+            for (const auto& it : mFreedBuffers) {
+                if (it.first == id) {
+                    ALOGV("%s: stream ID %d buffer id %" PRIu64 " cache removal still pending",
+                            __FUNCTION__, id, it.second);
+                    const auto& cachedEntry = std::find(bufIds.begin(), bufIds.end(), it.second);
+                    if (cachedEntry != bufIds.end()) {
+                        bufIds.erase(cachedEntry);
+                    } else {
+                        ALOGE("%s: stream ID %d buffer id %" PRIu64 " cache removal still pending "
+                                "however buffer is no longer in the offline stream info!",
+                                __FUNCTION__, id, it.second);
+                    }
+                }
+            }
+        }
         if (!verifyBufferIds(id, bufIds)) {
             ALOGE("%s: stream ID %d buffer cache records mismatch!", __FUNCTION__, id);
             return UNKNOWN_ERROR;