audio: Fix usecase list access am: 67486e2767
am: 50cdcc2f36

Change-Id: Idd416d12aa48bafd7447d8414802487ff893fc76
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index e5a8854..767798c 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -49,7 +49,6 @@
 #include <audio_effects/effect_aec.h>
 #include <audio_effects/effect_ns.h>
 #include <audio_utils/clock.h>
-#include <audio_utils/power.h>
 #include "audio_hw.h"
 #include "audio_extn.h"
 #include "platform_api.h"
@@ -98,6 +97,7 @@
 #define MMAP_PERIOD_COUNT_MAX 512
 #define MMAP_PERIOD_COUNT_DEFAULT (MMAP_PERIOD_COUNT_MAX)
 
+static const int64_t NANOS_PER_SECOND = 1000000000;
 
 /* This constant enables extended precision handling.
  * TODO The flag is off until more testing is done.
@@ -310,14 +310,6 @@
 //cache last MBDRC cal step level
 static int last_known_cal_step = -1 ;
 
-// TODO: Consider moving this to a pthread_once() if we have more
-// static initialization required.
-static bool is_userdebug_or_eng_build() {
-    char value[PROPERTY_VALUE_MAX];
-    (void)property_get("ro.build.type", value, "unknown"); // ignore actual length
-    return strcmp(value, "userdebug") == 0 || strcmp(value, "eng") == 0;
-}
-
 static bool may_use_noirq_mode(struct audio_device *adev, audio_usecase_t uc_id,
                                int flags __unused)
 {
@@ -2070,9 +2062,7 @@
     // dump error info
     (void)error_log_dump(
             out->error_log, fd, "      " /* prefix */, 0 /* lines */, 0 /* limit_ns */);
-    // dump power info (out->power_log may be null)
-    (void)power_log_dump(
-            out->power_log, fd, "      " /* prefix */, POWER_LOG_LINES, 0 /* limit_ns */);
+
     return 0;
 }
 
@@ -2468,7 +2458,8 @@
 
     lock_output_stream(out);
     // this is always nonzero
-    const int frame_size = audio_stream_out_frame_size(stream);
+    const size_t frame_size = audio_stream_out_frame_size(stream);
+    const size_t frames = bytes / frame_size;
 
     if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP) {
         error_code = ERROR_CODE_WRITE;
@@ -2559,22 +2550,16 @@
 exit:
     // For PCM we always consume the buffer and return #bytes regardless of ret.
     if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
-        out->written += bytes / (out->config.channels * sizeof(short));
+        out->written += frames;
     }
     long long sleeptime_us = 0;
 
-    // only get time if needed for logging, as it is a system call on 32 bit devices.
-    // TODO: Consider always enabling for 64 bit vDSO using compile time check on __LP64__.
-    const int64_t now_ns = out->power_log != 0 || (ret != 0 && out->error_log != 0)
-            ? audio_utils_get_real_time_ns() : 0;
-
     if (ret != 0) {
-        error_log_log(out->error_log, error_code, now_ns);
+        error_log_log(out->error_log, error_code, audio_utils_get_real_time_ns());
         if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
             ALOGE_IF(out->pcm != NULL,
                     "%s: error %zd - %s", __func__, ret, pcm_get_error(out->pcm));
-            sleeptime_us = bytes * 1000000LL / frame_size /
-                out_get_sample_rate(&out->stream.common);
+            sleeptime_us = frames * 1000000LL / out_get_sample_rate(&out->stream.common);
             // usleep not guaranteed for values over 1 second but we don't limit here.
         }
     }
@@ -2585,9 +2570,6 @@
         out_on_error(&out->stream.common);
         if (sleeptime_us != 0)
             usleep(sleeptime_us);
-    } else {
-        // only log if the data is properly written (out->power_log may be null)
-        power_log_log(out->power_log, buffer, bytes / frame_size, now_ns);
     }
     return bytes;
 }
@@ -2997,8 +2979,25 @@
     return status;
 }
 
-static int in_dump(const struct audio_stream *stream __unused, int fd __unused)
+static int in_dump(const struct audio_stream *stream, int fd)
 {
+    struct stream_in *in = (struct stream_in *)stream;
+
+    // We try to get the lock for consistency,
+    // but it isn't necessary for these variables.
+    // If we're not in standby, we may be blocked on a read.
+    const bool locked = (pthread_mutex_trylock(&in->lock) == 0);
+    dprintf(fd, "      Standby: %s\n", in->standby ? "yes" : "no");
+    dprintf(fd, "      Frames read: %lld\n", (long long)in->frames_read);
+    dprintf(fd, "      Frames muted: %lld\n", (long long)in->frames_muted);
+
+    if (locked) {
+        pthread_mutex_unlock(&in->lock);
+    }
+
+    // dump error info
+    (void)error_log_dump(
+            in->error_log, fd, "      " /* prefix */, 0 /* lines */, 0 /* limit_ns */);
     return 0;
 }
 
@@ -3131,8 +3130,11 @@
     struct audio_device *adev = in->dev;
     int i, ret = -1;
     int *int_buf_stream = NULL;
+    int error_code = ERROR_CODE_STANDBY; // initial errors are considered coming out of standby.
 
     lock_input_stream(in);
+    const size_t frame_size = audio_stream_in_frame_size(stream);
+    const size_t frames = bytes / frame_size;
 
     if (in->is_st_session) {
         ALOGVV(" %s: reading on st session bytes=%zu", __func__, bytes);
@@ -3157,6 +3159,9 @@
         in->standby = 0;
     }
 
+    // errors that occur here are read errors.
+    error_code = ERROR_CODE_READ;
+
     //what's the duration requested by the client?
     long ns = pcm_bytes_to_frames(in->pcm, bytes)*1000000000LL/
                                                 in->config.rate;
@@ -3195,21 +3200,24 @@
      * to always provide zeroes when muted.
      * No need to acquire adev->lock to read mic_muted here as we don't change its state.
      */
-    if (ret == 0 && adev->mic_muted && in->usecase != USECASE_AUDIO_RECORD_AFE_PROXY)
+    if (ret == 0 && adev->mic_muted && in->usecase != USECASE_AUDIO_RECORD_AFE_PROXY) {
         memset(buffer, 0, bytes);
+        in->frames_muted += frames;
+    }
 
 exit:
     pthread_mutex_unlock(&in->lock);
 
     if (ret != 0) {
+        error_log_log(in->error_log, error_code, audio_utils_get_real_time_ns());
         in_standby(&in->stream.common);
         ALOGV("%s: read failed - sleeping for buffer duration", __func__);
-        usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
-               in_get_sample_rate(&in->stream.common));
+        usleep(frames * 1000000LL / in_get_sample_rate(&in->stream.common));
         memset(buffer, 0, bytes); // clear return data
+        in->frames_muted += frames;
     }
     if (bytes > 0) {
-        in->frames_read += bytes / audio_stream_in_frame_size(stream);
+        in->frames_read += frames;
     }
     return bytes;
 }
@@ -3743,20 +3751,6 @@
             ERROR_LOG_ENTRIES,
             1000000000 /* aggregate consecutive identical errors within one second in ns */);
 
-    // power_log may be null if the format is not supported
-    // or not a userdebug or eng build.
-    if (false /* is_userdebug_or_eng_build() */) {
-        const size_t POWER_LOG_FRAMES_PER_ENTRY =
-                (long long)config->sample_rate * POWER_LOG_SAMPLING_INTERVAL_MS / 1000;
-
-        out->power_log = power_log_create(
-                config->sample_rate,
-                audio_channel_count_from_out_mask(config->channel_mask),
-                config->format,
-                POWER_LOG_ENTRIES,
-                POWER_LOG_FRAMES_PER_ENTRY);
-    }
-
     /*
        By locking output stream before registering, we allow the callback
        to update stream's state only after stream's initial state is set to
@@ -3805,9 +3799,6 @@
     if (adev->voice_tx_output == out)
         adev->voice_tx_output = NULL;
 
-    power_log_destroy(out->power_log);
-    out->power_log = NULL;
-
     error_log_destroy(out->error_log);
     out->error_log = NULL;
 
@@ -4300,6 +4291,10 @@
     in->config.channels = channel_count;
     in->sample_rate  = in->config.rate;
 
+    in->error_log = error_log_create(
+            ERROR_LOG_ENTRIES,
+            NANOS_PER_SECOND /* aggregate consecutive identical errors within one second */);
+
     /* This stream could be for sound trigger lab,
        get sound trigger pcm if present */
     audio_extn_sound_trigger_check_and_get_session(in);
@@ -4326,12 +4321,17 @@
 static void adev_close_input_stream(struct audio_hw_device *dev __unused,
                                     struct audio_stream_in *stream)
 {
+    struct stream_in *in = (struct stream_in *)stream;
     ALOGV("%s", __func__);
 
     // must deregister from sndmonitor first to prevent races
     // between the callback and close_stream
     audio_extn_snd_mon_unregister_listener(stream);
     in_standby(&stream->common);
+
+    error_log_destroy(in->error_log);
+    in->error_log = NULL;
+
     free(stream);
 
     return;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 46384a2..a588eef 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -26,7 +26,6 @@
 
 #include <audio_route/audio_route.h>
 #include <audio_utils/ErrorLog.h>
-#include <audio_utils/PowerLog.h>
 #include "voice.h"
 
 // dlopen() does not go through default library path search if there is a "/" in the library name.
@@ -57,15 +56,11 @@
 
 #define ERROR_LOG_ENTRIES 16
 
-#define POWER_LOG_LINES 40
-#define POWER_LOG_SAMPLING_INTERVAL_MS 50
-#define POWER_LOG_ENTRIES (1 /* minutes */ * 60 /* seconds */ * 1000 /* msec */ \
-                           / POWER_LOG_SAMPLING_INTERVAL_MS)
-
 /* Error types for the error log */
 enum {
     ERROR_CODE_STANDBY = 1,
     ERROR_CODE_WRITE,
+    ERROR_CODE_READ,
 };
 
 typedef enum card_status_t {
@@ -223,7 +218,6 @@
     card_status_t card_status;
 
     error_log_t *error_log;
-    power_log_t *power_log;
 
     struct stream_app_type_cfg app_type_cfg;
 };
@@ -244,6 +238,7 @@
     bool enable_aec;
     bool enable_ns;
     int64_t frames_read; /* total frames read, not cleared when entering standby */
+    int64_t frames_muted; /* total frames muted, not cleared when entering standby */
 
     audio_io_handle_t capture_handle;
     audio_input_flags_t flags;
@@ -263,6 +258,8 @@
     audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
     audio_format_t supported_formats[MAX_SUPPORTED_FORMATS + 1];
     uint32_t supported_sample_rates[MAX_SUPPORTED_SAMPLE_RATES + 1];
+
+    error_log_t *error_log;
 };
 
 typedef enum usecase_type_t {
diff --git a/post_proc/Android.mk b/post_proc/Android.mk
index 493f2cc..f1174a0 100644
--- a/post_proc/Android.mk
+++ b/post_proc/Android.mk
@@ -30,6 +30,8 @@
 	external/tinyalsa/include \
 	$(call include-path-for, audio-effects)
 
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
 include $(BUILD_SHARED_LIBRARY)
 endif
 
@@ -60,6 +62,8 @@
         hardware/qcom/audio/hal \
 	$(call include-path-for, audio-effects)
 
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
 include $(BUILD_SHARED_LIBRARY)
 
 endif
diff --git a/visualizer/Android.mk b/visualizer/Android.mk
index e318214..29a093e 100644
--- a/visualizer/Android.mk
+++ b/visualizer/Android.mk
@@ -36,4 +36,5 @@
 	external/tinyalsa/include \
 	$(call include-path-for, audio-effects)
 
+LOCAL_HEADER_LIBRARIES += libsystem_headers
 include $(BUILD_SHARED_LIBRARY)
diff --git a/voice_processing/Android.mk b/voice_processing/Android.mk
index e8878ee..7ebeb70 100644
--- a/voice_processing/Android.mk
+++ b/voice_processing/Android.mk
@@ -23,4 +23,5 @@
 
 LOCAL_CFLAGS += -fvisibility=hidden
 
+LOCAL_HEADER_LIBRARIES += libhardware_headers
 include $(BUILD_SHARED_LIBRARY)