audio: Avoid possible crashes [1/3]

PD#OTT-70004

Problem:
When the sound card is busy, a crash will occur
when it is used again.

Solution:
Perform the checking and print the necessary log

Verify:
zapper

Change-Id: I07f617464cb7f7b6a249bd36b18a1fbc9c3032d4
Signed-off-by: haiyang.ren <haiyang.ren@amlogic.com>
diff --git a/audio_hal/audio_hw.c b/audio_hal/audio_hw.c
index 6117b46..1ea81be 100644
--- a/audio_hal/audio_hw.c
+++ b/audio_hal/audio_hw.c
@@ -6320,7 +6320,7 @@
       closed anymore, because its ref is bigger than 0.
       Now we add this patch to make sure the alsa will be closed.
     */
-    if ((!adev->useSubMix && (!ms12->dolby_ms12_enable && (eDolbyMS12Lib == adev->dolby_lib_type)))) {
+    if ((!adev->useSubMix || (!ms12->dolby_ms12_enable && (eDolbyMS12Lib == adev->dolby_lib_type)))) {
         ALOGI("%s aml_out(%p)standby close", __func__, aml_out);
         aml_audio_pcm_out_close(adev);
     }
diff --git a/utils/tinyalsa/pcm.c b/utils/tinyalsa/pcm.c
index ae87aa2..a3b5724 100644
--- a/utils/tinyalsa/pcm.c
+++ b/utils/tinyalsa/pcm.c
@@ -127,11 +127,54 @@
 #endif
 };
 
+#define PCM_ERROR_MAX 128
+
+struct pcm {
+    int fd;
+    unsigned int flags;
+    int running:1;
+    int prepared:1;
+    int underruns;
+    unsigned int buffer_size;
+    unsigned int boundary;
+    char error[PCM_ERROR_MAX];
+    struct pcm_config config;
+    struct snd_pcm_mmap_status *mmap_status;
+    struct snd_pcm_mmap_control *mmap_control;
+    struct snd_pcm_sync_ptr *sync_ptr;
+    void *mmap_buffer;
+    unsigned int noirq_frames_per_msec;
+    int wait_for_avail_min;
+    unsigned int subdevice;
+};
+
 /* refer to SNDRV_PCM_SUBFORMAT_##index in sound/asound.h. */
 static const char * const subformat_lookup[] = {
         "STD",
 };
 
+static int oops(struct pcm *pcm, int e, const char *fmt, ...)
+{
+    va_list ap;
+    int sz;
+
+    if (NULL == pcm) {
+        ALOGE("pcm was null pinter!");
+        return -1;
+    }
+
+    va_start(ap, fmt);
+    vsnprintf(pcm->error, PCM_ERROR_MAX, fmt, ap);
+    va_end(ap);
+    sz = strlen(pcm->error);
+
+    if (e)
+        snprintf(pcm->error + sz, PCM_ERROR_MAX - sz,
+                 ": %s", strerror(e));
+    return -1;
+}
+
+
 static inline int param_is_mask(int p)
 {
     return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
@@ -242,66 +285,44 @@
     p->info = ~0U;
 }
 
-#define PCM_ERROR_MAX 128
-
-struct pcm {
-    int fd;
-    unsigned int flags;
-    int running:1;
-    int prepared:1;
-    int underruns;
-    unsigned int buffer_size;
-    unsigned int boundary;
-    char error[PCM_ERROR_MAX];
-    struct pcm_config config;
-    struct snd_pcm_mmap_status *mmap_status;
-    struct snd_pcm_mmap_control *mmap_control;
-    struct snd_pcm_sync_ptr *sync_ptr;
-    void *mmap_buffer;
-    unsigned int noirq_frames_per_msec;
-    int wait_for_avail_min;
-    unsigned int subdevice;
-};
-
 unsigned int pcm_get_buffer_size(struct pcm *pcm)
 {
+    if (NULL == pcm) {
+        ALOGE("pcm was null pinter!");
+        return 0;
+    }
+
     return pcm->buffer_size;
 }
 
 int pcm_get_config(struct pcm *pcm, struct pcm_config *config) {
-    if (pcm == NULL) {
-        return -1;
-    }
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     *config = pcm->config;
     return 0;
 }
 
 const char* pcm_get_error(struct pcm *pcm)
 {
+    if (NULL == pcm) {
+        ALOGE("pcm was null pinter!");
+        return NULL;
+    }
+
     return pcm->error;
 }
 
 unsigned int pcm_get_subdevice(struct pcm *pcm)
 {
+    if (NULL == pcm) {
+        ALOGE("pcm was null pinter!");
+        return 0;
+    }
+
     return pcm->subdevice;
 }
 
-static int oops(struct pcm *pcm, int e, const char *fmt, ...)
-{
-    va_list ap;
-    int sz;
-
-    va_start(ap, fmt);
-    vsnprintf(pcm->error, PCM_ERROR_MAX, fmt, ap);
-    va_end(ap);
-    sz = strlen(pcm->error);
-
-    if (e)
-        snprintf(pcm->error + sz, PCM_ERROR_MAX - sz,
-                 ": %s", strerror(e));
-    return -1;
-}
-
 static unsigned int pcm_format_to_alsa(enum pcm_format format)
 {
     switch (format) {
@@ -335,12 +356,22 @@
 
 unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes)
 {
+    if (NULL == pcm) {
+        ALOGE("pcm was null pinter!");
+        return 0;
+    }
+
     return bytes / (pcm->config.channels *
         (pcm_format_to_bits(pcm->config.format) >> 3));
 }
 
 unsigned int pcm_frames_to_bytes(struct pcm *pcm, unsigned int frames)
 {
+    if (NULL == pcm) {
+        ALOGE("pcm was null pinter!");
+        return 0;
+    }
+
     return frames * pcm->config.channels *
         (pcm_format_to_bits(pcm->config.format) >> 3);
 }
@@ -539,6 +570,10 @@
     int frames;
     int rc;
 
+    if (NULL == pcm) {
+        return oops(pcm, 0, "");
+    }
+
     if (pcm == NULL || hw_ptr == NULL || tstamp == NULL)
         return oops(pcm, EINVAL, "pcm %p, hw_ptr %p, tstamp %p", pcm, hw_ptr, tstamp);
 
@@ -569,6 +604,9 @@
 {
     struct snd_xferi x;
 
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     if (pcm->flags & PCM_IN)
         return -EINVAL;
 
@@ -608,6 +646,9 @@
 {
     struct snd_xferi x;
 
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     if (!(pcm->flags & PCM_IN))
         return -EINVAL;
 
@@ -915,7 +956,7 @@
 
 int pcm_close(struct pcm *pcm)
 {
-    if (pcm == &bad_pcm)
+    if (NULL == pcm || pcm == &bad_pcm)
         return 0;
 
     pcm_hw_munmap_status(pcm);
@@ -1123,11 +1164,19 @@
 
 int pcm_is_ready(struct pcm *pcm)
 {
-    return pcm->fd >= 0;
+    if (pcm) {
+        return pcm->fd >= 0;
+    } else {
+        ALOGE("pcm is not ready now!");
+        return 0;
+    }
 }
 
 int pcm_prepare(struct pcm *pcm)
 {
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     if (pcm->prepared)
         return 0;
 
@@ -1156,6 +1205,9 @@
 
 int pcm_stop(struct pcm *pcm)
 {
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_DROP) < 0)
         return oops(pcm, errno, "cannot stop channel");
     ALOGI("pcm_stop handle(%p)", pcm);
@@ -1188,6 +1240,9 @@
 
 int pcm_mmap_avail(struct pcm *pcm)
 {
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_HWSYNC);
     if (pcm->flags & PCM_IN)
         return pcm_mmap_capture_avail(pcm);
@@ -1211,6 +1266,9 @@
 {
     unsigned int continuous, copy_frames, avail;
 
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     /* return the mmap buffer */
     *areas = pcm->mmap_buffer;
 
@@ -1235,6 +1293,9 @@
 
 int pcm_mmap_commit(struct pcm *pcm, unsigned int offset __attribute__((unused)), unsigned int frames)
 {
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     /* update the application pointer in userspace and kernel */
     pcm_mmap_appl_forward(pcm, frames);
     pcm_sync_ptr(pcm, 0);
@@ -1244,12 +1305,18 @@
 
 int pcm_avail_update(struct pcm *pcm)
 {
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     pcm_sync_ptr(pcm, 0);
     return pcm_mmap_avail(pcm);
 }
 
 int pcm_state(struct pcm *pcm)
 {
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     int err = pcm_sync_ptr(pcm, 0);
     if (err < 0)
         return err;
@@ -1259,6 +1326,9 @@
 
 int pcm_set_avail_min(struct pcm *pcm, int avail_min)
 {
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     if ((~pcm->flags) & (PCM_MMAP | PCM_NOIRQ))
         return -ENOSYS;
 
@@ -1271,6 +1341,9 @@
     struct pollfd pfd;
     int err;
 
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     pfd.fd = pcm->fd;
     pfd.events = POLLOUT | POLLERR | POLLNVAL;
 
@@ -1309,6 +1382,9 @@
 
 int pcm_get_poll_fd(struct pcm *pcm)
 {
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     return pcm->fd;
 }
 
@@ -1317,6 +1393,9 @@
     int err = 0, frames, avail;
     unsigned int offset = 0, count;
 
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     if (bytes == 0)
         return 0;
 
@@ -1402,6 +1481,9 @@
 
 int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count)
 {
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     if ((~pcm->flags) & (PCM_OUT | PCM_MMAP))
         return -ENOSYS;
 
@@ -1410,6 +1492,9 @@
 
 int pcm_mmap_read(struct pcm *pcm, void *data, unsigned int count)
 {
+    if (NULL == pcm)
+        return oops(pcm, 0, "");
+
     if ((~pcm->flags) & (PCM_IN | PCM_MMAP))
         return -ENOSYS;