[autotest] chameleon: Allow line-out to be detected

The audio board is connected to chameleon line-in, so it is reasonable
for Cros device to detect a LineOut node when its audio jack is connected
to audio board.
Add 'LINEOUT' to CRAS output node types.
Accept 'LINEOUT' node type in check_audio_nodes when 'HEADPHONE' is
requested.
Fix the server side audio tests:
- audio_AudioBasicHeadphone and audio_MediaBasicVerification: They
  should use check_audio_nodes in audio_test_utils.
- Other BT and HDMI tests: they check whether headphone is plugged
  because in some Chameleon setup DUT is connected to audio board
  permanently. They should check either headphone or line-out.

BUG=chromium:710903
TEST=run audio_AudioBasicHeadphone and audio_MediaBasicVerification
tests.

Change-Id: Ic156f21c6683fc8de680768930ad7675a7755f5a
Reviewed-on: https://chromium-review.googlesource.com/487785
Commit-Ready: Cheng-Yi Chiang <cychiang@chromium.org>
Tested-by: Cheng-Yi Chiang <cychiang@chromium.org>
Reviewed-by: Wai-Hong Tam <waihong@google.com>
Reviewed-by: Kalin Stoyanov <kalin@chromium.org>
diff --git a/client/cros/audio/cras_utils.py b/client/cros/audio/cras_utils.py
index 94aca03..faf7ea7 100644
--- a/client/cros/audio/cras_utils.py
+++ b/client/cros/audio/cras_utils.py
@@ -283,7 +283,7 @@
 
 # Cras node types reported from Cras DBus control API.
 CRAS_OUTPUT_NODE_TYPES = ['HEADPHONE', 'INTERNAL_SPEAKER', 'HDMI', 'USB',
-                          'BLUETOOTH', 'UNKNOWN']
+                          'BLUETOOTH', 'LINEOUT', 'UNKNOWN']
 CRAS_INPUT_NODE_TYPES = ['MIC', 'INTERNAL_MIC', 'USB', 'BLUETOOTH',
                          'POST_DSP_LOOPBACK', 'POST_MIX_LOOPBACK', 'UNKNOWN',
                          'KEYBOARD_MIC', 'HOTWORD']
diff --git a/client/cros/chameleon/audio_test_utils.py b/client/cros/chameleon/audio_test_utils.py
index a6cfa4b..abead82 100644
--- a/client/cros/chameleon/audio_test_utils.py
+++ b/client/cros/chameleon/audio_test_utils.py
@@ -85,6 +85,13 @@
         sorted(curr_in_nodes) != sorted(in_audio_nodes)):
         raise error.TestFail('Wrong input node(s) selected %s '
                 'instead %s!' % (str(curr_in_nodes), str(in_audio_nodes)))
+
+    # Treat line-out node as headphone node in Chameleon test since some
+    # Cros devices detect audio board as lineout. This actually makes sense
+    # because 3.5mm audio jack is connected to LineIn port on Chameleon.
+    if (out_audio_nodes == ['HEADPHONE'] and curr_out_nodes == ['LINEOUT']):
+        return
+
     if (out_audio_nodes != None and
         sorted(curr_out_nodes) != sorted(out_audio_nodes)):
         raise error.TestFail('Wrong output node(s) selected %s '
diff --git a/server/site_tests/audio_AudioBasicBluetoothPlayback/audio_AudioBasicBluetoothPlayback.py b/server/site_tests/audio_AudioBasicBluetoothPlayback/audio_AudioBasicBluetoothPlayback.py
index 0a3e8c4..83c5285 100644
--- a/server/site_tests/audio_AudioBasicBluetoothPlayback/audio_AudioBasicBluetoothPlayback.py
+++ b/server/site_tests/audio_AudioBasicBluetoothPlayback/audio_AudioBasicBluetoothPlayback.py
@@ -133,7 +133,7 @@
             # For DUTs with permanently connected audio jack cable
             # Bluetooth output node should be selected explicitly.
             output_nodes, _ = self.audio_facade.get_plugged_node_types()
-            if 'HEADPHONE' in output_nodes:
+            if 'HEADPHONE' in output_nodes or 'LINEOUT' in output_nodes:
                 self.audio_facade.set_chrome_active_node_type('BLUETOOTH',
                                                               None)
             # Checks the node selected by Cras is correct.
diff --git a/server/site_tests/audio_AudioBasicBluetoothPlaybackRecord/audio_AudioBasicBluetoothPlaybackRecord.py b/server/site_tests/audio_AudioBasicBluetoothPlaybackRecord/audio_AudioBasicBluetoothPlaybackRecord.py
index 9c071f0..8e88948 100644
--- a/server/site_tests/audio_AudioBasicBluetoothPlaybackRecord/audio_AudioBasicBluetoothPlaybackRecord.py
+++ b/server/site_tests/audio_AudioBasicBluetoothPlaybackRecord/audio_AudioBasicBluetoothPlaybackRecord.py
@@ -154,7 +154,7 @@
                 # Bluetooth output node should be selected explicitly.
                 output_nodes, _ = self.audio_facade.get_plugged_node_types()
                 audio_jack_plugged = False
-                if 'HEADPHONE' in output_nodes:
+                if 'HEADPHONE' in output_nodes or 'LINEOUT' in output_nodes:
                     audio_jack_plugged = True
                     audio_test_utils.check_audio_nodes(self.audio_facade,
                                                        (None, ['MIC']))
diff --git a/server/site_tests/audio_AudioBasicBluetoothRecord/audio_AudioBasicBluetoothRecord.py b/server/site_tests/audio_AudioBasicBluetoothRecord/audio_AudioBasicBluetoothRecord.py
index b623eea..7fc31e6 100644
--- a/server/site_tests/audio_AudioBasicBluetoothRecord/audio_AudioBasicBluetoothRecord.py
+++ b/server/site_tests/audio_AudioBasicBluetoothRecord/audio_AudioBasicBluetoothRecord.py
@@ -138,7 +138,7 @@
             # Bluetooth output node should be selected explicitly.
             output_nodes, _ = self.audio_facade.get_plugged_node_types()
             audio_jack_plugged = False
-            if 'HEADPHONE' in output_nodes:
+            if 'HEADPHONE' in output_nodes or 'LINEOUT' in output_nodes:
                 audio_jack_plugged = True
                 audio_test_utils.check_audio_nodes(self.audio_facade,
                                                     (None, ['MIC']))
diff --git a/server/site_tests/audio_AudioBasicHDMI/audio_AudioBasicHDMI.py b/server/site_tests/audio_AudioBasicHDMI/audio_AudioBasicHDMI.py
index ef6b1a9..7120e69 100644
--- a/server/site_tests/audio_AudioBasicHDMI/audio_AudioBasicHDMI.py
+++ b/server/site_tests/audio_AudioBasicHDMI/audio_AudioBasicHDMI.py
@@ -95,7 +95,7 @@
         audio_facade = self.factory.create_audio_facade()
         output_nodes, _ = audio_facade.get_selected_node_types()
         audio_jack_plugged = False
-        if output_nodes == ['HEADPHONE']:
+        if output_nodes == ['HEADPHONE'] or output_nodes == ['LINEOUT']:
             audio_jack_plugged = True
             logging.debug('Found audio jack plugged!')
 
diff --git a/server/site_tests/audio_AudioBasicHeadphone/audio_AudioBasicHeadphone.py b/server/site_tests/audio_AudioBasicHeadphone/audio_AudioBasicHeadphone.py
index 64ee2a4..c2ca4b0 100644
--- a/server/site_tests/audio_AudioBasicHeadphone/audio_AudioBasicHeadphone.py
+++ b/server/site_tests/audio_AudioBasicHeadphone/audio_AudioBasicHeadphone.py
@@ -65,11 +65,7 @@
             audio_test_utils.dump_cros_audio_logs(
                     host, audio_facade, self.resultsdir, 'after_binding')
 
-            output_nodes, _ = audio_facade.get_selected_node_types()
-            if output_nodes != ['HEADPHONE']:
-                raise error.TestFail(
-                        '%s rather than headphone is selected on Cros '
-                        'device' % output_nodes)
+            audio_test_utils.check_audio_nodes(audio_facade, (['HEADPHONE'], None))
 
             logging.info('Setting playback data on Cros device')
             source.set_playback_data(golden_file)
diff --git a/server/site_tests/audio_MediaBasicVerification/audio_MediaBasicVerification.py b/server/site_tests/audio_MediaBasicVerification/audio_MediaBasicVerification.py
index 785a53d..0c0c276 100644
--- a/server/site_tests/audio_MediaBasicVerification/audio_MediaBasicVerification.py
+++ b/server/site_tests/audio_MediaBasicVerification/audio_MediaBasicVerification.py
@@ -58,11 +58,7 @@
             audio_test_utils.dump_cros_audio_logs(
                     host, audio_facade, self.resultsdir, 'after_binding')
 
-            output_nodes, _ = audio_facade.get_selected_node_types()
-            if output_nodes != ['HEADPHONE']:
-                raise error.TestFail(
-                        '%s rather than headphone is selected on Cros '
-                        'device' % output_nodes)
+            audio_test_utils.check_audio_nodes(audio_facade, (['HEADPHONE'], None))
 
             # Starts playing, waits for some time, and then starts recording.
             # This is to avoid artifact caused by codec initialization.