audio_widget: Refactor, subclass and add field to store playback file data format

Refactor with method _scale_and_send_playback_data so that subclasses
like ChameleonLineOutOutputWidgetHandler can use. Add a field to store
playback file data format to ChameleonOutputWidgetHandler.

BUG=chromium:514541
TEST=not used yet.

Change-Id: I888a4ee2277f0324f46535b6d52f533085aeb36e
Reviewed-on: https://chromium-review.googlesource.com/297694
Commit-Ready: Cheng-Yi Chiang <cychiang@chromium.org>
Tested-by: Cheng-Yi Chiang <cychiang@chromium.org>
Reviewed-by: Cheng-Yi Chiang <cychiang@chromium.org>
diff --git a/client/cros/chameleon/audio_widget.py b/client/cros/chameleon/audio_widget.py
index 105b2ce..6babdca 100644
--- a/client/cros/chameleon/audio_widget.py
+++ b/client/cros/chameleon/audio_widget.py
@@ -416,10 +416,11 @@
     This class abstracts a Chameleon audio output widget handler.
 
     """
-    _DEFAULT_DATA_FORMAT = dict(file_type='raw',
-                                sample_format='S32_LE',
-                                channel=8,
-                                rate=48000)
+    def __init__(self, *args, **kwargs):
+        """Initializes an ChameleonOutputWidgetHandler."""
+        super(ChameleonOutputWidgetHandler, self).__init__(*args, **kwargs)
+        self._test_data_for_chameleon_format = None
+
 
     def set_playback_data(self, test_data):
         """Sets data to play.
@@ -432,16 +433,30 @@
         @return: The remote data path on Chameleon.
 
         """
-        converted_audio_test_data = test_data.convert(
-                self._DEFAULT_DATA_FORMAT, self.scale)
+        self._test_data_for_chameleon_format = test_data.data_format
+        return self._scale_and_send_playback_data(test_data)
+
+
+    def _scale_and_send_playback_data(self, test_data):
+        """Sets data to play on Chameleon.
+
+        Creates a path and sends the scaled test data to Chameleon at that path.
+
+        @param test_data: An AudioTestData object.
+
+        @return: The remote data path on Chameleon.
+
+        """
+        test_data_for_chameleon = test_data.convert(
+                self._test_data_for_chameleon_format, self.scale)
 
         try:
             with tempfile.NamedTemporaryFile(prefix='audio_') as f:
                 self._chameleon_board.host.send_file(
-                        converted_audio_test_data.path, f.name)
+                        test_data_for_chameleon.path, f.name)
             return f.name
         finally:
-            converted_audio_test_data.delete()
+            test_data_for_chameleon.delete()
 
 
     def start_playback(self, path, blocking=False):
@@ -455,7 +470,8 @@
             raise NotImplementedError(
                     'Blocking playback on chameleon is not supported')
 
-        self._port.start_playing_audio(path, self._DEFAULT_DATA_FORMAT)
+        self._port.start_playing_audio(
+                path, self._test_data_for_chameleon_format)
 
 
     def stop_playback(self):
@@ -482,6 +498,33 @@
         return chameleon_port
 
 
+class ChameleonLineOutOutputWidgetHandler(ChameleonOutputWidgetHandler):
+    """
+    This class abstracts a Chameleon usb audio output widget handler.
+
+    """
+
+    _DEFAULT_DATA_FORMAT = dict(file_type='raw',
+                                sample_format='S32_LE',
+                                channel=8,
+                                rate=48000)
+
+    def set_playback_data(self, test_data):
+        """Sets data to play.
+
+        Handles scale if needed. Creates a path and sends the scaled data to
+        Chameleon at that path.
+
+        @param test_data: An AudioTestData object.
+
+        @return: The remote data path on Chameleon.
+
+        """
+        self._test_data_for_chameleon_format = self._DEFAULT_DATA_FORMAT
+        return self._scale_and_send_playback_data(test_data)
+
+
+
 class CrosWidgetHandler(WidgetHandler):
     """
     This class abstracts a Cros device audio widget handler.
diff --git a/client/cros/chameleon/chameleon_audio_helper.py b/client/cros/chameleon/chameleon_audio_helper.py
index a0692b5..56ce288 100644
--- a/client/cros/chameleon/chameleon_audio_helper.py
+++ b/client/cros/chameleon/chameleon_audio_helper.py
@@ -267,8 +267,12 @@
                 return audio_widget.ChameleonInputWidgetHandler(
                         self._chameleon_board, audio_port.interface)
             else:
-                return audio_widget.ChameleonOutputWidgetHandler(
-                        self._chameleon_board, audio_port.interface)
+                if audio_port.port_id == ids.ChameleonIds.LINEOUT:
+                    return audio_widget.ChameleonLineOutOutputWidgetHandler(
+                            self._chameleon_board, audio_port.interface)
+                else:
+                    return audio_widget.ChameleonOutputWidgetHandler(
+                            self._chameleon_board, audio_port.interface)
 
 
         def _create_cros_handler(audio_port):