Chameleon: Make ChameleonPortFinder work on both client and server tests

This change is to demonstrate how a library, like ChameleonPortFinder, work
on both client and server tests. The interfaces to access DUT audio/display
are achieved by the facade, either locally or remotely.

It also makes all client and server Chameleon tests use ChameleonPortFinder
to identity the connected ports.

BUG=chromium:405143
TEST=Ran the chameleon_hdmi suite and verified it did not break the tests.

Change-Id: I9f991296eb497e2e86655635bc433618d4b45a5c
Reviewed-on: https://chromium-review.googlesource.com/226142
Reviewed-by: Wai-Hong Tam <waihong@chromium.org>
Tested-by: Wai-Hong Tam <waihong@chromium.org>
Commit-Queue: Wai-Hong Tam <waihong@chromium.org>
diff --git a/client/cros/chameleon/chameleon_port_finder.py b/client/cros/chameleon/chameleon_port_finder.py
index e11f45a..85a600e 100644
--- a/client/cros/chameleon/chameleon_port_finder.py
+++ b/client/cros/chameleon/chameleon_port_finder.py
@@ -4,8 +4,6 @@
 
 from collections import namedtuple
 
-from autotest_lib.client.cros.graphics import graphics_utils
-
 ChameleonPorts = namedtuple('ChameleonPorts', 'connected failed')
 
 
@@ -15,13 +13,16 @@
 
     """
 
-    def __init__(self, chameleon_board):
+    def __init__(self, chameleon_board, display_facade):
         """
         @param chameleon_board: a ChameleonBoard object representing the Chameleon
                                 board whose ports we are interested in finding.
+        @param display_facade: a display facade object, to access the DUT display
+                               functionality, either locally or remotely.
 
         """
         self.chameleon_board = chameleon_board
+        self.display_facade = display_facade
         self._TIMEOUT_VIDEO_STABLE_PROBE = 10
         self.connected = None
         self.failed = None
@@ -54,12 +55,9 @@
             chameleon_port.wait_video_input_stable(
                 self._TIMEOUT_VIDEO_STABLE_PROBE)
 
-            # Add the connected ports if they are detected by xrandr.
-            xrandr_output = graphics_utils.get_xrandr_output_state()
-            for output in xrandr_output.iterkeys():
-                if output.startswith(connector_type):
-                    connected_ports.append(chameleon_port)
-                    break
+            output = self.display_facade.get_external_connector_name()
+            if output and output.startswith(connector_type):
+                connected_ports.append(chameleon_port)
             else:
                 dut_failed_ports.append(chameleon_port)
 
diff --git a/client/cros/video/chameleon_screenshot_capturer.py b/client/cros/video/chameleon_screenshot_capturer.py
index 8f71706..cfbf615 100644
--- a/client/cros/video/chameleon_screenshot_capturer.py
+++ b/client/cros/video/chameleon_screenshot_capturer.py
@@ -67,7 +67,8 @@
 
         """
         self.chameleon_board.reset()
-        finder = chameleon_port_finder.ChameleonPortFinder(self.chameleon_board)
+        finder = chameleon_port_finder.ChameleonPortFinder(
+                self.chameleon_board, self.display_facade)
 
         connected_port = finder.find_video_port(self.interface)
 
diff --git a/client/site_tests/display_ClientChameleonConnection/display_ClientChameleonConnection.py b/client/site_tests/display_ClientChameleonConnection/display_ClientChameleonConnection.py
index e8a744c..f5ed57f 100755
--- a/client/site_tests/display_ClientChameleonConnection/display_ClientChameleonConnection.py
+++ b/client/site_tests/display_ClientChameleonConnection/display_ClientChameleonConnection.py
@@ -8,8 +8,11 @@
 
 from autotest_lib.client.bin import test
 from autotest_lib.client.common_lib import error
+from autotest_lib.client.common_lib.cros import chrome
+from autotest_lib.client.cros import constants
 from autotest_lib.client.cros.chameleon import chameleon
 from autotest_lib.client.cros.chameleon import chameleon_port_finder
+from autotest_lib.client.cros.multimedia import local_facade_factory
 
 
 class display_ClientChameleonConnection(test.test):
@@ -20,21 +23,25 @@
     """
     version = 1
 
-    _TIMEOUT_VIDEO_STABLE_PROBE = 10
-
-
     def run_once(self, host, args):
-        self.chameleon = chameleon.create_chameleon_board(host.hostname, args)
-        self.chameleon.reset()
+        ext_paths = [constants.MULTIMEDIA_TEST_EXTENSION]
+        with chrome.Chrome(extension_paths=ext_paths) as cr:
+            factory = local_facade_factory.LocalFacadeFactory(cr)
+            display_facade = factory.create_display_facade()
 
-        finder = chameleon_port_finder.ChameleonPortFinder(self.chameleon)
-        ports = finder.find_all_video_ports()
+            chameleon_board = chameleon.create_chameleon_board(host.hostname,
+                                                               args)
+            chameleon_board.reset()
 
-        connected_ports = ports.connected
-        dut_failed_ports = ports.failed
+            finder = chameleon_port_finder.ChameleonPortFinder(chameleon_board,
+                                                               display_facade)
+            ports = finder.find_all_video_ports()
 
-        msg = str(finder)
-        logging.debug(msg)
+            connected_ports = ports.connected
+            dut_failed_ports = ports.failed
 
-        if dut_failed_ports or not connected_ports:
-            raise error.TestFail(msg)
+            msg = str(finder)
+            logging.debug(msg)
+
+            if dut_failed_ports or not connected_ports:
+                raise error.TestFail(msg)
diff --git a/server/cros/chameleon/chameleon_test.py b/server/cros/chameleon/chameleon_test.py
index e7ff821..e5c9067 100644
--- a/server/cros/chameleon/chameleon_test.py
+++ b/server/cros/chameleon/chameleon_test.py
@@ -12,6 +12,7 @@
 
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.common_lib.cros import retry
+from autotest_lib.client.cros.chameleon import chameleon_port_finder
 from autotest_lib.client.cros.chameleon import edid
 from autotest_lib.client.cros.multimedia import image_generator
 from autotest_lib.server import test
@@ -59,9 +60,8 @@
         self.display_facade = factory.create_display_facade()
         self.chameleon = host.chameleon
         self.host = host
+        # TODO(waihong): Support multiple connectors.
         self.chameleon_port = self._get_connected_port()
-        if self.chameleon_port is None:
-            raise error.TestError('DUT and Chameleon board not connected')
         self._platform_prefix = host.get_platform().lower().split('_')[0]
 
 
@@ -346,30 +346,21 @@
     def _get_connected_port(self):
         """Gets the first connected output port between Chameleon and DUT.
 
+        This method also plugs this port at the end.
+
         @return: A ChameleonPort object.
         """
         self.chameleon.reset()
-        # TODO(waihong): Support multiple connectors.
-        for chameleon_port in self.chameleon.get_all_ports():
-            # Skip the non-video port.
-            if not chameleon_port.has_video_support():
-                continue
-
-            connector_type = chameleon_port.get_connector_type()
-            # Plug to ensure the connector is plugged.
-            chameleon_port.plug()
-            # Don't care about video input stable in the end or timeout.
-            # It will be checked on the matching of the connect names.
-            chameleon_port.wait_video_input_stable(
-                    self._TIMEOUT_VIDEO_STABLE_PROBE)
-            output = self.display_facade.get_external_connector_name()
-
-            # TODO(waihong): Make sure eDP work in this way.
-            if output and output.startswith(connector_type):
-                return chameleon_port
-            # Unplug the port if it is not the connected.
-            chameleon_port.unplug()
-        return None
+        finder = chameleon_port_finder.ChameleonPortFinder(self.chameleon,
+                                                           self.display_facade)
+        ports = finder.find_all_video_ports()
+        if len(ports.connected) == 0:
+            raise error.TestError('DUT and Chameleon board not connected')
+        # Plug the first port and return it.
+        first_port = ports.connected[0]
+        first_port.plug()
+        first_port.wait_video_input_stable(self._TIMEOUT_VIDEO_STABLE_PROBE)
+        return first_port
 
 
     @retry.retry(xmlrpclib.Fault,