Add Windows, Mac, Android support to low bandwidth audio test

BUG=webrtc:7229

Review-Url: https://codereview.webrtc.org/2767383005
Cr-Commit-Position: refs/heads/master@{#17470}
diff --git a/tools-webrtc/download_tools.py b/tools-webrtc/download_tools.py
index dc64ebf..123fd3a 100755
--- a/tools-webrtc/download_tools.py
+++ b/tools-webrtc/download_tools.py
@@ -20,6 +20,8 @@
 
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+# Needed to properly resolve PATH and executable extensions on Windows.
+USE_SHELL = sys.platform == 'win32'
 
 
 def main(directories):
@@ -37,7 +39,7 @@
       path,
     ]
     print 'Downloading precompiled tools...'
-    subprocess.check_call(cmd)
+    subprocess.check_call(cmd, shell=USE_SHELL)
 
 
 if __name__ == '__main__':
diff --git a/webrtc/BUILD.gn b/webrtc/BUILD.gn
index 0bc2eb3..1e8508a 100644
--- a/webrtc/BUILD.gn
+++ b/webrtc/BUILD.gn
@@ -321,7 +321,10 @@
         ]
       }
       if (rtc_enable_protobuf) {
-        deps += [ "logging:rtc_event_log2rtp_dump" ]
+        deps += [
+          "audio:low_bandwidth_audio_test",
+          "logging:rtc_event_log2rtp_dump",
+        ]
       }
     }
   }
diff --git a/webrtc/audio/BUILD.gn b/webrtc/audio/BUILD.gn
index 4858c46..0b4b580 100644
--- a/webrtc/audio/BUILD.gn
+++ b/webrtc/audio/BUILD.gn
@@ -78,9 +78,6 @@
       "//testing/gmock",
       "//testing/gtest",
     ]
-    if (rtc_enable_protobuf) {
-      deps += [ ":low_bandwidth_audio_test" ]
-    }
 
     if (!build_with_chromium && is_clang) {
       # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
@@ -89,7 +86,7 @@
   }
 
   if (rtc_enable_protobuf) {
-    rtc_executable("low_bandwidth_audio_test") {
+    rtc_test("low_bandwidth_audio_test") {
       testonly = true
 
       sources = [
@@ -101,7 +98,6 @@
         "../common_audio",
         "../system_wrappers",
         "../test:fake_audio_device",
-        "../test:run_test",
         "../test:test_common",
         "../test:test_main",
       ]
diff --git a/webrtc/audio/test/low_bandwidth_audio_test.cc b/webrtc/audio/test/low_bandwidth_audio_test.cc
index 50d7e67..de955f7 100644
--- a/webrtc/audio/test/low_bandwidth_audio_test.cc
+++ b/webrtc/audio/test/low_bandwidth_audio_test.cc
@@ -13,7 +13,6 @@
 #include "webrtc/audio/test/low_bandwidth_audio_test.h"
 #include "webrtc/common_audio/wav_file.h"
 #include "webrtc/test/gtest.h"
-#include "webrtc/test/run_test.h"
 #include "webrtc/system_wrappers/include/sleep.h"
 #include "webrtc/test/testsupport/fileutils.h"
 
@@ -109,7 +108,7 @@
 
   // Output information about the input and output audio files so that further
   // processing can be done by an external process.
-  printf("TEST %s %s:%s\n", test_info->name(),
+  printf("TEST %s %s %s\n", test_info->name(),
          AudioInputFile().c_str(), AudioOutputFile().c_str());
 }
 
diff --git a/webrtc/audio/test/low_bandwidth_audio_test.py b/webrtc/audio/test/low_bandwidth_audio_test.py
index 6482d3d..58243b1 100755
--- a/webrtc/audio/test/low_bandwidth_audio_test.py
+++ b/webrtc/audio/test/low_bandwidth_audio_test.py
@@ -18,6 +18,7 @@
 import logging
 import os
 import re
+import shutil
 import subprocess
 import sys
 
@@ -38,6 +39,9 @@
       help='Path to the build directory (e.g. out/Release).')
   parser.add_argument('--remove', action='store_true',
       help='Remove output audio files after testing.')
+  parser.add_argument('--android', action='store_true',
+      help='Perform the test on a connected Android device instead.')
+  parser.add_argument('--adb-path', help='Path to adb binary.', default='adb')
   args = parser.parse_args()
   return args
 
@@ -51,13 +55,6 @@
     return 'linux'
 
 
-def _GetExecutableExtension():
-  if sys.platform == 'win32':
-    return '.exe'
-  else:
-    return ''
-
-
 def _DownloadTools():
   tools_dir = os.path.join(SRC_DIR, 'tools-webrtc')
   toolchain_dir = os.path.join(tools_dir, 'audio_quality')
@@ -67,11 +64,24 @@
   command = [sys.executable, download_script, toolchain_dir]
   subprocess.check_call(_LogCommand(command))
 
-  pesq_path = os.path.join(toolchain_dir, _GetPlatform(),
-                           'pesq' + _GetExecutableExtension())
+  pesq_path = os.path.join(toolchain_dir, _GetPlatform(), 'pesq')
   return pesq_path
 
 
+def _GetFile(file_path, out_dir, android=False, adb_path=None):
+  out_file_name = os.path.basename(file_path)
+  out_file_path = os.path.join(out_dir, out_file_name)
+
+  if android:
+    # Pull the file from the connected Android device
+    adb_command = [adb_path, 'pull', file_path, out_dir]
+    subprocess.check_call(_LogCommand(adb_command))
+  elif os.path.abspath(file_path) != os.path.abspath(out_file_path):
+    shutil.copy(file_path, out_file_path)
+
+  return out_file_path
+
+
 def main():
   # pylint: disable=W0101
   logging.basicConfig(level=logging.INFO)
@@ -80,29 +90,41 @@
 
   pesq_path = _DownloadTools()
 
-  test_executable_path = os.path.join(args.build_dir,
-      'low_bandwidth_audio_test' + _GetExecutableExtension())
+  out_dir = os.path.join(args.build_dir, '..')
+  if args.android:
+    test_command = [os.path.join(args.build_dir, 'bin',
+                                 'run_low_bandwidth_audio_test'), '-v']
+  else:
+    test_command = [os.path.join(args.build_dir, 'low_bandwidth_audio_test')]
 
   # Start the test executable that produces audio files.
-  command = [test_executable_path]
-  test_process = subprocess.Popen(_LogCommand(command), stdout=subprocess.PIPE)
+  test_process = subprocess.Popen(_LogCommand(test_command),
+                                  stdout=subprocess.PIPE)
 
   for line in iter(test_process.stdout.readline, ''):
     # Echo the output to screen.
     sys.stdout.write(line)
 
     # Extract specific lines that contain information about produced files.
-    match = re.search(r'^TEST (\w+) ([^:]+?):([^:]+?)\n?$', line)
+    # Output from Android has a prefix, need to skip it.
+    match = re.search(r'^(?:I\b.+\b)?TEST (\w+) ([^ ]+?) ([^ ]+?)\s*$', line)
     if not match:
       continue
-    test_name, reference_file, degraded_file = match.groups()
+    test_name = match.group(1)
+    reference_file = _GetFile(match.group(2), out_dir,
+                              args.android, args.adb_path)
+    degraded_file = _GetFile(match.group(3), out_dir,
+                             args.android, args.adb_path)
 
-    # Analyze audio
-    command = [pesq_path, '+16000', reference_file, degraded_file]
-    pesq_output = subprocess.check_output(_LogCommand(command))
-
-    if args.remove:
-      os.remove(degraded_file)
+    # Analyze audio.
+    pesq_command = [pesq_path, '+16000',
+                    os.path.basename(reference_file),
+                    os.path.basename(degraded_file)]
+    # Need to provide paths in the current directory due to a bug in PESQ:
+    # On Mac, for some 'path/to/file.wav', if 'file.wav' is longer than
+    # 'path/to', PESQ crashes.
+    pesq_output = subprocess.check_output(_LogCommand(pesq_command),
+                                          cwd=out_dir)
 
     # Find the scores in stdout of pesq.
     match = re.search(
@@ -116,6 +138,10 @@
     else:
       logging.error('PESQ: %s', pesq_output.splitlines()[-1])
 
+    if args.remove:
+      os.remove(reference_file)
+      os.remove(degraded_file)
+
   return test_process.wait()