Cache constant values from CRAS

Cache constant values from CRAS to avoid redundant IPC calls.

BUG=b:267718096, chromium:1307680

Change-Id: I7167d5c656f0d9e7c8c79985ec06b8672747add9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4248820
Reviewed-by: Per Ã…hgren <peah@chromium.org>
Reviewed-by: Olga Sharonova <olka@chromium.org>
Commit-Queue: Yu-Hsuan Hsu <yuhsuan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1106053}
diff --git a/media/audio/cras/audio_manager_cras.cc b/media/audio/cras/audio_manager_cras.cc
index e51b1a20..c6e3f98 100644
--- a/media/audio/cras/audio_manager_cras.cc
+++ b/media/audio/cras/audio_manager_cras.cc
@@ -204,7 +204,6 @@
   // Rephrase the field aec_supported to properly reflect its meaning in this
   // context (since it currently signals whether an CrAS APM with tuned settings
   // is available).
-  // TODO(crbug.com/1307680): add unit tests and caching cras_util_ results.
   const bool tuned_system_apm_available = cras_util_->CrasGetAecSupported();
 
   // Don't use the system AEC if it is deactivated for this group ID. Also never
diff --git a/media/audio/cras/cras_util.cc b/media/audio/cras/cras_util.cc
index cb1b41a..ba57bd63 100644
--- a/media/audio/cras/cras_util.cc
+++ b/media/audio/cras/cras_util.cc
@@ -180,10 +180,35 @@
   old_dev.active |= new_dev.active;
 }
 
-CrasUtil::CrasUtil() = default;
+CrasUtil::CrasUtil() {
+  cras_effects_cached_ = CacheEffects();
+}
 
 CrasUtil::~CrasUtil() = default;
 
+bool CrasUtil::CacheEffects() {
+  libcras_client* client = CrasConnect();
+  if (!client) {
+    LOG(ERROR) << "Failed to cache effects";
+    return false;
+  }
+  if (libcras_client_get_aec_supported(client, &aec_supported_) < 0) {
+    LOG(ERROR) << "Fail to query AEC supported";
+    aec_supported_ = false;
+  }
+  if (libcras_client_get_aec_group_id(client, &aec_group_id_) < 0) {
+    LOG(ERROR) << "Fail to query AEC group ID";
+    aec_group_id_ = -1;  // The default group ID is -1
+  }
+  if (libcras_client_get_default_output_buffer_size(
+          client, &default_output_buffer_size_) < 0) {
+    LOG(ERROR) << "Fail to query default output buffer size";
+    default_output_buffer_size_ = 0;
+  }
+  CrasDisconnect(&client);
+  return true;
+}
+
 std::vector<CrasDevice> CrasUtil::CrasGetAudioDevices(DeviceType type) {
   std::vector<CrasDevice> devices;
 
@@ -236,42 +261,24 @@
 }
 
 int CrasUtil::CrasGetAecSupported() {
-  libcras_client* client = CrasConnect();
-  if (!client) {
-    return 0;
+  if (!cras_effects_cached_) {
+    cras_effects_cached_ = CacheEffects();
   }
-
-  int supported;
-  libcras_client_get_aec_supported(client, &supported);
-  CrasDisconnect(&client);
-
-  return supported;
+  return aec_supported_;
 }
 
 int CrasUtil::CrasGetAecGroupId() {
-  libcras_client* client = CrasConnect();
-  if (!client) {
-    return -1;
+  if (!cras_effects_cached_) {
+    cras_effects_cached_ = CacheEffects();
   }
-
-  int id;
-  int rc = libcras_client_get_aec_group_id(client, &id);
-  CrasDisconnect(&client);
-
-  return rc < 0 ? rc : id;
+  return aec_group_id_;
 }
 
 int CrasUtil::CrasGetDefaultOutputBufferSize() {
-  libcras_client* client = CrasConnect();
-  if (!client) {
-    return -1;
+  if (!cras_effects_cached_) {
+    cras_effects_cached_ = CacheEffects();
   }
-
-  int size;
-  int rc = libcras_client_get_default_output_buffer_size(client, &size);
-  CrasDisconnect(&client);
-
-  return rc < 0 ? rc : size;
+  return default_output_buffer_size_;
 }
 
 }  // namespace media
diff --git a/media/audio/cras/cras_util.h b/media/audio/cras/cras_util.h
index f76e1ce93..4711095 100644
--- a/media/audio/cras/cras_util.h
+++ b/media/audio/cras/cras_util.h
@@ -48,17 +48,30 @@
   virtual ~CrasUtil();
 
   // Enumerates all devices of |type|.
+  // Virtual for testing.
   virtual std::vector<CrasDevice> CrasGetAudioDevices(DeviceType type);
 
   // Returns if system AEC is supported in CRAS.
+  // Virtual for testing.
   virtual int CrasGetAecSupported();
 
   // Returns the system AEC group ID. If no group ID is specified, -1 is
   // returned.
+  // Virtual for testing.
   virtual int CrasGetAecGroupId();
 
   // Returns the default output buffer size.
+  // Virtual for testing.
   virtual int CrasGetDefaultOutputBufferSize();
+
+ private:
+  int aec_supported_ = false;
+  int aec_group_id_ = -1;
+  int default_output_buffer_size_ = 0;
+  bool cras_effects_cached_ = false;
+
+  // Caches constant effect config from CRAS.
+  bool CacheEffects();
 };
 
 }  // namespace media