Camera NDK: fix release image failure during destructor

Test: new CTS test that close reader with images in
      acquired state
Bug: 65839749

Change-Id: Iac9d2b1a3298ca619f2ab71a02641052f9a51f2e
diff --git a/media/ndk/NdkImage.cpp b/media/ndk/NdkImage.cpp
index 6d28d1b..87b649a 100644
--- a/media/ndk/NdkImage.cpp
+++ b/media/ndk/NdkImage.cpp
@@ -53,21 +53,25 @@
 
 void
 AImage::close(int releaseFenceFd) {
+    lockReader();
     Mutex::Autolock _l(mLock);
     if (mIsClosed) {
         return;
     }
     sp<AImageReader> reader = mReader.promote();
-    if (reader == nullptr) {
-        LOG_ALWAYS_FATAL("Error: AImage not closed before AImageReader close!");
-        return;
+    if (reader != nullptr) {
+        reader->releaseImageLocked(this, releaseFenceFd);
+    } else if (mBuffer != nullptr) {
+        LOG_ALWAYS_FATAL("%s: parent AImageReader closed without releasing image %p",
+                __FUNCTION__, this);
     }
-    reader->releaseImageLocked(this, releaseFenceFd);
+
     // Should have been set to nullptr in releaseImageLocked
     // Set to nullptr here for extra safety only
     mBuffer = nullptr;
     mLockedBuffer = nullptr;
     mIsClosed = true;
+    unlockReader();
 }
 
 void
@@ -618,9 +622,7 @@
 void AImage_deleteAsync(AImage* image, int releaseFenceFd) {
     ALOGV("%s", __FUNCTION__);
     if (image != nullptr) {
-        image->lockReader();
         image->close(releaseFenceFd);
-        image->unlockReader();
         if (!image->isClosed()) {
             LOG_ALWAYS_FATAL("Image close failed!");
         }
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index a450dd3..e90783d 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -349,6 +349,7 @@
     for (auto it = mAcquiredImages.begin();
               it != mAcquiredImages.end(); it++) {
         AImage* image = *it;
+        releaseImageLocked(image, /*releaseFenceFd*/-1);
         image->close();
     }