audio_hw: close mmap file descriptor to fix leak

The file descriptor for MMAP shared memory was created
and passed to AudioFlinger but never closed.
Now the FD is closed when the stream is goes to standby.

Bug: 134381208
Test: Get HAL pid.
Test:     adb shell ps | grep audio
Test:     adb shell ls -l /proc/{halpid}/fd | wc
Test: Run Oboetester or other app that uses MMAP
Test: Completely close the app.
Test:     adb shell ls -l /proc/{halpid}/fd | wc
Test: Count should NOT grow each time.
Change-Id: Ieaaf1c6bdc96e7ecf01cee23215fb39f79662111
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 5d611c6..0d918d9 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2817,6 +2817,14 @@
             if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP) {
                 do_stop = out->playback_started;
                 out->playback_started = false;
+
+                if (out->mmap_shared_memory_fd >= 0) {
+                    ALOGV("%s: closing mmap_shared_memory_fd = %d",
+                          __func__, out->mmap_shared_memory_fd);
+                    close(out->mmap_shared_memory_fd);
+                    out->mmap_shared_memory_fd = -1;
+                }
+
             }
         } else {
             stop_compressed_output_l(out);
@@ -3989,6 +3997,9 @@
         // Fall back to non exclusive mode
         info->shared_memory_fd = pcm_get_poll_fd(out->pcm);
     } else {
+        out->mmap_shared_memory_fd = info->shared_memory_fd; // for closing later
+        ALOGV("%s: opened mmap_shared_memory_fd = %d", __func__, out->mmap_shared_memory_fd);
+
         if (mmap_size < buffer_size) {
             step = "mmap";
             goto exit;
@@ -4122,6 +4133,14 @@
         if (in->usecase == USECASE_AUDIO_RECORD_MMAP) {
             do_stop = in->capture_started;
             in->capture_started = false;
+
+            if (in->mmap_shared_memory_fd >= 0) {
+                ALOGV("%s: closing mmap_shared_memory_fd = %d",
+                      __func__, in->mmap_shared_memory_fd);
+                close(in->mmap_shared_memory_fd);
+                in->mmap_shared_memory_fd = -1;
+            }
+
         }
         if (in->pcm) {
             pcm_close(in->pcm);
@@ -4718,6 +4737,9 @@
         // Fall back to non exclusive mode
         info->shared_memory_fd = pcm_get_poll_fd(in->pcm);
     } else {
+        in->mmap_shared_memory_fd = info->shared_memory_fd; // for closing later
+        ALOGV("%s: opened mmap_shared_memory_fd = %d", __func__, in->mmap_shared_memory_fd);
+
         if (mmap_size < buffer_size) {
             step = "mmap";
             goto exit;
@@ -4930,6 +4952,7 @@
     out->dev = adev;
     out->handle = handle;
     out->a2dp_compress_mute = false;
+    out->mmap_shared_memory_fd = -1; // not open
 
     /* Init use case and pcm_config */
     if ((is_hdmi || is_usb_dev) &&
@@ -5893,6 +5916,7 @@
     in->flags = flags;
     in->direction = MIC_DIRECTION_UNSPECIFIED;
     in->zoom = 0;
+    in->mmap_shared_memory_fd = -1; // not open
     list_init(&in->aec_list);
     list_init(&in->ns_list);
 
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 54ee72c..15cfa60 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -234,6 +234,7 @@
     bool muted;
     uint64_t written; /* total frames written, not cleared when entering standby */
     int64_t mmap_time_offset_nanos; /* fudge factor to correct inaccuracies in DSP */
+    int     mmap_shared_memory_fd; /* file descriptor associated with MMAP NOIRQ shared memory */
     audio_io_handle_t handle;
 
     int non_blocking;
@@ -293,6 +294,7 @@
     int64_t frames_read; /* total frames read, not cleared when entering standby */
     int64_t frames_muted; /* total frames muted, not cleared when entering standby */
     int64_t mmap_time_offset_nanos; /* fudge factor to correct inaccuracies in DSP */
+    int     mmap_shared_memory_fd; /* file descriptor associated with MMAP NOIRQ shared memory */
 
     audio_io_handle_t capture_handle;
     audio_input_flags_t flags;