Move error logging to audio_utils
Test: dumpsys media.audio_flinger (instrumented)
Bug: 30572472
Change-Id: I7b00214bafa2abc2b95c022753d6dbeb58ed5c3e
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 0277ec4..badc889 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -389,58 +389,6 @@
adev->adm_abandon_focus(adev->adm_data, in->capture_handle);
}
-// Log errors: consecutive errors with the same code will
-// be aggregated if they occur within one second.
-// A mutual exclusion lock must be held before calling.
-static void log_error_l(struct error_log *log, int code) {
- ++log->errors;
-
- const int64_t now = audio_utils_get_real_time_ns();
-
- // Within 1 second, cluster the same error codes together.
- const int one_second = 1000000000;
- if (code == log->entries[log->idx].code &&
- now - log->entries[log->idx].last_time < one_second) {
- log->entries[log->idx].count++;
- log->entries[log->idx].last_time = now;
- return;
- }
-
- // Add new error entry.
- if (++log->idx >= ARRAY_SIZE(log->entries)) {
- log->idx = 0;
- }
- log->entries[log->idx].count = 1;
- log->entries[log->idx].code = code;
- log->entries[log->idx].first_time = now;
- log->entries[log->idx].last_time = now;
-}
-
-// Dump information in the error log. A mutual exclusion lock
-// should be held, but if that cannot be obtained, one should
-// make a copy of the error log before calling -- the call is
-// still safe, but there might be some misinterpreted data.
-static void log_dump_l(const struct error_log *log, int fd)
-{
- dprintf(fd, " Errors: %u\n", log->errors);
- if (log->errors == 0)
- return;
-
- dprintf(fd, " Index Code Freq First time Last time\n");
- for (size_t i = 0; i < ARRAY_SIZE(log->entries); ++i) {
- if (log->entries[i].count != 0) {
- char first_time[32];
- char last_time[32];
- audio_utils_ns_to_string(log->entries[i].first_time, first_time, sizeof(first_time));
- audio_utils_ns_to_string(log->entries[i].last_time, last_time, sizeof(last_time));
- dprintf(fd, " %c%4zu %4d %5d %s %s\n",
- i == log->idx ? '*' : ' ', // mark head position
- i, log->entries[i].code, log->entries[i].count,
- first_time, last_time);
- }
- }
-}
-
static int parse_snd_card_status(struct str_parms * parms, int * card,
card_status_t * status)
{
@@ -1970,13 +1918,12 @@
dprintf(fd, " Frames written: %lld\n", (long long)out->written);
if (locked) {
- log_dump_l(&out->error_log, fd);
pthread_mutex_unlock(&out->lock);
- } else {
- // We don't have the lock here, copy for safety.
- struct error_log log = out->error_log;
- log_dump_l(&log, fd);
}
+
+ // 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, POWER_LOG_LINES, 0 /* limitNs */);
return 0;
@@ -2333,7 +2280,7 @@
out->offload_state = OFFLOAD_STATE_PLAYING;
}
if (ret < 0) {
- log_error_l(&out->error_log, ERROR_CODE_WRITE);
+ error_log_log(out->error_log, ERROR_CODE_WRITE, audio_utils_get_real_time_ns());
}
pthread_mutex_unlock(&out->lock);
// TODO: consider logging offload pcm
@@ -2371,7 +2318,7 @@
const int64_t now_ns = audio_utils_get_real_time_ns();
if (ret != 0) {
- log_error_l(&out->error_log, error_code);
+ error_log_log(out->error_log, error_code, now_ns);
if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
ALOGE_IF(out->pcm != NULL,
"%s: error %zd - %s", __func__, ret, pcm_get_error(out->pcm));
@@ -3470,6 +3417,10 @@
config->channel_mask = out->stream.common.get_channels(&out->stream.common);
config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
+ out->error_log = error_log_create(
+ ERROR_LOG_ENTRIES,
+ 1000000000 /* aggregate consecutive identical errors within one second in ns */);
+
const size_t POWER_LOG_FRAMES_PER_ENTRY =
config->sample_rate * POWER_LOG_SAMPLING_INTERVAL_MS / 1000;
// power_log may be null if the format is not supported
@@ -3529,6 +3480,9 @@
power_log_destroy(out->power_log);
out->power_log = NULL;
+ error_log_destroy(out->error_log);
+ out->error_log = NULL;
+
pthread_cond_destroy(&out->cond);
pthread_mutex_destroy(&out->lock);
free(stream);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index a612599..03f1587 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -25,6 +25,7 @@
#include <tinycompress/tinycompress.h>
#include <audio_route/audio_route.h>
+#include <audio_utils/ErrorLog.h>
#include <audio_utils/PowerLog.h>
#include "voice.h"
@@ -61,6 +62,12 @@
#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,
+};
+
typedef enum card_status_t {
CARD_STATUS_OFFLINE,
CARD_STATUS_ONLINE
@@ -160,24 +167,6 @@
int data[];
};
-enum {
- ERROR_CODE_STANDBY,
- ERROR_CODE_WRITE,
-};
-
-struct error_log_entry {
- int32_t code;
- int32_t count;
- int64_t first_time;
- int64_t last_time;
-};
-
-struct error_log {
- uint32_t errors;
- uint32_t idx;
- struct error_log_entry entries[ERROR_LOG_ENTRIES];
-};
-
struct stream_out {
struct audio_stream_out stream;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
@@ -219,7 +208,7 @@
struct audio_device *dev;
card_status_t card_status;
- struct error_log error_log;
+ error_log_t *error_log;
power_log_t *power_log;
};