APM: Adding more explicit handling of failures in the json config data

This CL creates a new API for the parser of APM json config that
that provides an explicit way for the user to know when there has
been an issue in the parsing of the json config data.

Bug: webrtc:9921
Change-Id: Idd8f40529f40ab6871efb5b356c0fd2cea21b7d9
Reviewed-on: https://webrtc-review.googlesource.com/c/107841
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Commit-Queue: Per Åhgren <peah@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25355}
diff --git a/api/audio/echo_canceller3_config_json.cc b/api/audio/echo_canceller3_config_json.cc
index 784f928..d039c8b 100644
--- a/api/audio/echo_canceller3_config_json.cc
+++ b/api/audio/echo_canceller3_config_json.cc
@@ -109,21 +109,29 @@
 }
 }  // namespace
 
-EchoCanceller3Config Aec3ConfigFromJsonString(absl::string_view json_string) {
-  EchoCanceller3Config cfg;
+void Aec3ConfigFromJsonString(absl::string_view json_string,
+                              EchoCanceller3Config* config,
+                              bool* parsing_successful) {
+  RTC_DCHECK(config);
+  RTC_DCHECK(parsing_successful);
+  EchoCanceller3Config& cfg = *config;
+  cfg = EchoCanceller3Config();
+  *parsing_successful = true;
 
   Json::Value root;
   bool success = Json::Reader().parse(std::string(json_string), root);
   if (!success) {
     RTC_LOG(LS_ERROR) << "Incorrect JSON format: " << json_string;
-    return EchoCanceller3Config();
+    *parsing_successful = false;
+    return;
   }
 
   Json::Value aec3_root;
   success = rtc::GetValueFromJsonObject(root, "aec3", &aec3_root);
   if (!success) {
     RTC_LOG(LS_ERROR) << "Missing AEC3 config field: " << json_string;
-    return EchoCanceller3Config();
+    *parsing_successful = false;
+    return;
   }
 
   Json::Value section;
@@ -325,6 +333,12 @@
     ReadParam(section, "enforce_empty_higher_bands",
               &cfg.suppressor.enforce_empty_higher_bands);
   }
+}
+
+EchoCanceller3Config Aec3ConfigFromJsonString(absl::string_view json_string) {
+  EchoCanceller3Config cfg;
+  bool not_used;
+  Aec3ConfigFromJsonString(json_string, &cfg, &not_used);
   return cfg;
 }
 
diff --git a/api/audio/echo_canceller3_config_json.h b/api/audio/echo_canceller3_config_json.h
index 3c8b975..8973650 100644
--- a/api/audio/echo_canceller3_config_json.h
+++ b/api/audio/echo_canceller3_config_json.h
@@ -20,6 +20,16 @@
 namespace webrtc {
 // Parses a JSON-encoded string into an Aec3 config. Fields corresponds to
 // substruct names, with the addition that there must be a top-level node
+// "aec3". Produces default config values for anything that cannot be parsed
+// from the string. If any error was found in the parsing, parsing_successful is
+// set to false.
+RTC_EXPORT void Aec3ConfigFromJsonString(absl::string_view json_string,
+                                         EchoCanceller3Config* config,
+                                         bool* parsing_successful);
+
+// To be deprecated.
+// Parses a JSON-encoded string into an Aec3 config. Fields corresponds to
+// substruct names, with the addition that there must be a top-level node
 // "aec3". Returns default config values for anything that cannot be parsed from
 // the string.
 RTC_EXPORT EchoCanceller3Config
diff --git a/modules/audio_processing/test/audio_processing_simulator.cc b/modules/audio_processing/test/audio_processing_simulator.cc
index e4ac57b..aae9363 100644
--- a/modules/audio_processing/test/audio_processing_simulator.cc
+++ b/modules/audio_processing/test/audio_processing_simulator.cc
@@ -48,7 +48,17 @@
   while (std::getline(f, s)) {
     json_string += s;
   }
-  return Aec3ConfigFromJsonString(json_string);
+
+  bool parsing_successful;
+  EchoCanceller3Config cfg;
+  Aec3ConfigFromJsonString(json_string, &cfg, &parsing_successful);
+  if (!parsing_successful) {
+    std::cout << "Parsing of json string failed: " << std::endl
+              << json_string << std::endl;
+    RTC_CHECK(false);
+  }
+
+  return cfg;
 }
 
 void CopyFromAudioFrame(const AudioFrame& src, ChannelBuffer<float>* dest) {