Parse ice_servers property from client handler

This will be used by both the client handler and the streamer

Bug: 280805814
Test: locally
Merged-In: I909be5bfaedf9f1ff67ba004086866846cc8ec46
Change-Id: I909be5bfaedf9f1ff67ba004086866846cc8ec46
(cherry picked from commit 6faafac01de8001bc894e74d5c1632fa896d46ba)
Skip-CP-To-Master: already in master
diff --git a/host/frontend/webrtc/lib/client_handler.cpp b/host/frontend/webrtc/lib/client_handler.cpp
index 9be1ca0..3fb7e64 100644
--- a/host/frontend/webrtc/lib/client_handler.cpp
+++ b/host/frontend/webrtc/lib/client_handler.cpp
@@ -457,6 +457,45 @@
                          msg_data + msg.size());
 }
 
+std::vector<webrtc::PeerConnectionInterface::IceServer>
+ClientHandler::ParseIceServersMessage(const Json::Value &message) {
+  std::vector<webrtc::PeerConnectionInterface::IceServer> ret;
+  if (!message.isMember("ice_servers") || !message["ice_servers"].isArray()) {
+    // Log as verbose since the ice_servers field is optional in some messages
+    LOG(VERBOSE) << "ice_servers field not present in json object or not an array";
+    return ret;
+  }
+  auto& servers = message["ice_servers"];
+  for (const auto& server: servers) {
+    webrtc::PeerConnectionInterface::IceServer ice_server;
+    if (!server.isMember("urls") || !server["urls"].isArray()) {
+      // The urls field is required
+      LOG(WARNING)
+          << "ICE server specification missing urls field or not an array: "
+          << server.toStyledString();
+      continue;
+    }
+    auto urls = server["urls"];
+    for (int url_idx = 0; url_idx < urls.size(); url_idx++) {
+      auto url = urls[url_idx];
+      if (!url.isString()) {
+        LOG(WARNING) << "Non string 'urls' field in ice server: "
+                     << url.toStyledString();
+        continue;
+      }
+      ice_server.urls.push_back(url.asString());
+    }
+    if (server.isMember("credential") && server["credential"].isString()) {
+      ice_server.password = server["credential"].asString();
+    }
+    if (server.isMember("username") && server["username"].isString()) {
+      ice_server.username = server["username"].asString();
+    }
+    ret.push_back(ice_server);
+  }
+  return ret;
+}
+
 std::shared_ptr<ClientHandler> ClientHandler::Create(
     int client_id, std::shared_ptr<ConnectionObserver> observer,
     std::function<void(const Json::Value &)> send_to_client_cb,
diff --git a/host/frontend/webrtc/lib/client_handler.h b/host/frontend/webrtc/lib/client_handler.h
index ea58552..841f3b5 100644
--- a/host/frontend/webrtc/lib/client_handler.h
+++ b/host/frontend/webrtc/lib/client_handler.h
@@ -46,6 +46,12 @@
 class ClientHandler : public webrtc::PeerConnectionObserver,
                       public std::enable_shared_from_this<ClientHandler> {
  public:
+  // Checks if the message contains an "ice_servers" array field and parses it
+  // into a vector of webrtc ICE servers. Returns an empty vector if the field
+  // isn't present.
+  static std::vector<webrtc::PeerConnectionInterface::IceServer>
+  ParseIceServersMessage(const Json::Value& message);
+
   static std::shared_ptr<ClientHandler> Create(
       int client_id, std::shared_ptr<ConnectionObserver> observer,
       std::function<void(const Json::Value&)> send_client_cb,
diff --git a/host/frontend/webrtc/lib/streamer.cpp b/host/frontend/webrtc/lib/streamer.cpp
index 088b25b..11a7b63 100644
--- a/host/frontend/webrtc/lib/streamer.cpp
+++ b/host/frontend/webrtc/lib/streamer.cpp
@@ -474,39 +474,8 @@
 void Streamer::Impl::HandleConfigMessage(const Json::Value& server_message) {
   CHECK(signal_thread_->IsCurrent())
       << __FUNCTION__ << " called from the wrong thread";
-  if (server_message.isMember("ice_servers") &&
-      server_message["ice_servers"].isArray()) {
-    auto servers = server_message["ice_servers"];
-    operator_config_.servers.clear();
-    for (int server_idx = 0; server_idx < servers.size(); server_idx++) {
-      auto server = servers[server_idx];
-      webrtc::PeerConnectionInterface::IceServer ice_server;
-      if (!server.isMember("urls") || !server["urls"].isArray()) {
-        // The urls field is required
-        LOG(WARNING)
-            << "Invalid ICE server specification obtained from server: "
-            << server.toStyledString();
-        continue;
-      }
-      auto urls = server["urls"];
-      for (int url_idx = 0; url_idx < urls.size(); url_idx++) {
-        auto url = urls[url_idx];
-        if (!url.isString()) {
-          LOG(WARNING) << "Non string 'urls' field in ice server: "
-                       << url.toStyledString();
-          continue;
-        }
-        ice_server.urls.push_back(url.asString());
-        if (server.isMember("credential") && server["credential"].isString()) {
-          ice_server.password = server["credential"].asString();
-        }
-        if (server.isMember("username") && server["username"].isString()) {
-          ice_server.username = server["username"].asString();
-        }
-        operator_config_.servers.push_back(ice_server);
-      }
-    }
-  }
+  operator_config_.servers =
+      ClientHandler::ParseIceServersMessage(server_message);
 }
 
 void Streamer::Impl::HandleClientMessage(const Json::Value& server_message) {