chameleon.py revision d3fad2c8a0ba1508f5fc3efb90592687ec219d5c
1eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 2eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam# Use of this source code is governed by a BSD-style license that can be 3eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam# found in the LICENSE file. 4eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 5c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tamimport httplib 672e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tamimport logging 7c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tamimport socket 8e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tamimport time 9eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tamimport xmlrpclib 10e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tamfrom contextlib import contextmanager 11eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 12428b34464f1060129cbcda08d60ec44ed88a518dJ. Richard Barnettefrom PIL import Image 13428b34464f1060129cbcda08d60ec44ed88a518dJ. Richard Barnette 14c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tamfrom autotest_lib.client.bin import utils 15c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tamfrom autotest_lib.client.common_lib import error 165b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tamfrom autotest_lib.client.cros.chameleon import edid as edid_lib 177a4ba1cad16c47849d8dfabcfaf5aa9d64960977Tom Wai-Hong Tam 18eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 19c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong TamCHAMELEON_PORT = 9992 20c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 21c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 22c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tamclass ChameleonConnectionError(error.TestError): 23c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """Indicates that connecting to Chameleon failed. 24c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 25c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam It is fatal to the test unless caught. 26c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """ 27c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam pass 28c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 29c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 30c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tamclass ChameleonConnection(object): 31c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """ChameleonConnection abstracts the network connection to the board. 32c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 33c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam ChameleonBoard and ChameleonPort use it for accessing Chameleon RPC. 34c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 35c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """ 36c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 37c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam def __init__(self, hostname, port=CHAMELEON_PORT): 38c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """Constructs a ChameleonConnection. 39c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 40c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @param hostname: Hostname the chameleond process is running. 41c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @param port: Port number the chameleond process is listening on. 42c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 43c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @raise ChameleonConnectionError if connection failed. 44c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """ 45c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam self.chameleond_proxy = ChameleonConnection._create_server_proxy( 46c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam hostname, port) 47c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 48c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 49c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @staticmethod 50c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam def _create_server_proxy(hostname, port): 51c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """Creates the chameleond server proxy. 52c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 53c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @param hostname: Hostname the chameleond process is running. 54c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @param port: Port number the chameleond process is listening on. 55c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 56c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @return ServerProxy object to chameleond. 57c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 58c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @raise ChameleonConnectionError if connection failed. 59c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """ 60c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam remote = 'http://%s:%s' % (hostname, port) 61c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam chameleond_proxy = xmlrpclib.ServerProxy(remote, allow_none=True) 62c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam # Call a RPC to test. 63c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam try: 64b4fd848987c6ac62a9e65ff4bb91ef281ab6894eTom Wai-Hong Tam chameleond_proxy.GetSupportedPorts() 65c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam except (socket.error, 66c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam xmlrpclib.ProtocolError, 67c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam httplib.BadStatusLine) as e: 68c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam raise ChameleonConnectionError(e) 69c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam return chameleond_proxy 70c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 71c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 72eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tamclass ChameleonBoard(object): 73eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ChameleonBoard is an abstraction of a Chameleon board. 74eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 75eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam A Chameleond RPC proxy is passed to the construction such that it can 76eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam use this proxy to control the Chameleon board. 77c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 78eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 79eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 80c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam def __init__(self, chameleon_connection): 81eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """Construct a ChameleonBoard. 82eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 83c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @param chameleon_connection: ChameleonConnection object. 84eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 85c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam self._chameleond_proxy = chameleon_connection.chameleond_proxy 86eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 87eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 88eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam def reset(self): 89eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """Resets Chameleon board.""" 90eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam self._chameleond_proxy.Reset() 91eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 92eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 93eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam def get_all_ports(self): 94eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """Gets all the ports on Chameleon board which are connected. 95eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 96eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam @return: A list of ChameleonPort objects. 97eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 9819c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam ports = self._chameleond_proxy.ProbePorts() 9919c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam return [ChameleonPort(self._chameleond_proxy, port) for port in ports] 10019c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam 10119c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam 10219c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam def get_all_inputs(self): 10319c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam """Gets all the input ports on Chameleon board which are connected. 10419c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam 10519c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam @return: A list of ChameleonPort objects. 10619c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam """ 107eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam ports = self._chameleond_proxy.ProbeInputs() 108eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam return [ChameleonPort(self._chameleond_proxy, port) for port in ports] 109eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 110eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 11119c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam def get_all_outputs(self): 11219c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam """Gets all the output ports on Chameleon board which are connected. 11319c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam 11419c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam @return: A list of ChameleonPort objects. 11519c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam """ 11619c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam ports = self._chameleond_proxy.ProbeOutputs() 11719c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam return [ChameleonPort(self._chameleond_proxy, port) for port in ports] 11819c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam 11919c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam 1203d75ebce0a965218db301852e3feb309b3d5b333Tom Wai-Hong Tam def get_label(self): 1213d75ebce0a965218db301852e3feb309b3d5b333Tom Wai-Hong Tam """Gets the label which indicates the display connection. 1223d75ebce0a965218db301852e3feb309b3d5b333Tom Wai-Hong Tam 1233d75ebce0a965218db301852e3feb309b3d5b333Tom Wai-Hong Tam @return: A string of the label, like 'hdmi', 'dp_hdmi', etc. 1243d75ebce0a965218db301852e3feb309b3d5b333Tom Wai-Hong Tam """ 125d7a45223ad35e98496bf3d0f8eeefa7a1eb2d731Tom Wai-Hong Tam connectors = [] 126d7a45223ad35e98496bf3d0f8eeefa7a1eb2d731Tom Wai-Hong Tam for port in self._chameleond_proxy.ProbeInputs(): 127d7a45223ad35e98496bf3d0f8eeefa7a1eb2d731Tom Wai-Hong Tam if self._chameleond_proxy.HasVideoSupport(port): 128d7a45223ad35e98496bf3d0f8eeefa7a1eb2d731Tom Wai-Hong Tam connector = self._chameleond_proxy.GetConnectorType(port).lower() 129d7a45223ad35e98496bf3d0f8eeefa7a1eb2d731Tom Wai-Hong Tam connectors.append(connector) 1303d75ebce0a965218db301852e3feb309b3d5b333Tom Wai-Hong Tam # Eliminate duplicated ports. It simplifies the labels of dual-port 1313d75ebce0a965218db301852e3feb309b3d5b333Tom Wai-Hong Tam # devices, i.e. dp_dp categorized into dp. 1323d75ebce0a965218db301852e3feb309b3d5b333Tom Wai-Hong Tam return '_'.join(sorted(set(connectors))) 1333d75ebce0a965218db301852e3feb309b3d5b333Tom Wai-Hong Tam 1343d75ebce0a965218db301852e3feb309b3d5b333Tom Wai-Hong Tam 135eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tamclass ChameleonPort(object): 1368578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """ChameleonPort is an abstraction of a general port of a Chameleon board. 1378578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 1388578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam It only contains some common methods shared with audio and video ports. 139eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 14019c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam A Chameleond RPC proxy and an port_id are passed to the construction. 14119c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam The port_id is the unique identity to the port. 142eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 143eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 14419c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam def __init__(self, chameleond_proxy, port_id): 145eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """Construct a ChameleonPort. 146eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 147eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam @param chameleond_proxy: Chameleond RPC proxy object. 14819c95d740e9b6194d94e30c4bfce9ce449b34da5Tom Wai-Hong Tam @param port_id: The ID of the input port. 149eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 1508578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.chameleond_proxy = chameleond_proxy 1518578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.port_id = port_id 152eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 153eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 154eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam def get_connector_id(self): 155eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """Returns the connector ID. 156eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 157eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam @return: A number of connector ID. 158eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 1598578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam return self.port_id 160eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 161eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 162eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam def get_connector_type(self): 163eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """Returns the human readable string for the connector type. 164eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 165eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam @return: A string, like "VGA", "DVI", "HDMI", or "DP". 166eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 1678578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam return self.chameleond_proxy.GetConnectorType(self.port_id) 168eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 169eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 1706bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam def has_audio_support(self): 1716bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam """Returns if the input has audio support. 1726bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam 1736bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam @return: True if the input has audio support; otherwise, False. 1746bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam """ 1758578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam return self.chameleond_proxy.HasAudioSupport(self.port_id) 1766bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam 1776bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam 1786bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam def has_video_support(self): 1796bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam """Returns if the input has video support. 1806bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam 1816bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam @return: True if the input has video support; otherwise, False. 1826bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam """ 1838578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam return self.chameleond_proxy.HasVideoSupport(self.port_id) 1848578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 1858578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 1868578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam def plug(self): 1878578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """Asserts HPD line to high, emulating plug.""" 18872e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam logging.info('Plug Chameleon port %d', self.port_id) 1898578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.chameleond_proxy.Plug(self.port_id) 1908578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 1918578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 1928578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam def unplug(self): 1938578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """Deasserts HPD line to low, emulating unplug.""" 19472e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam logging.info('Unplug Chameleon port %d', self.port_id) 1958578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.chameleond_proxy.Unplug(self.port_id) 1968578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 1978578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 19872e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam def set_plug(self, plug_status): 19972e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam """Sets plug/unplug by plug_status. 20072e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam 20172e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam @param plug_status: True to plug; False to unplug. 20272e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam """ 20372e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam if plug_status: 20472e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam self.plug() 20572e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam else: 20672e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam self.unplug() 20772e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam 20872e354c97eb4890f4ce770ea27caa62cf620b4c1Tom Wai-Hong Tam 2098578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam @property 2108578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam def plugged(self): 2118578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """ 2128578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam @returns True if this port is plugged to Chameleon, False otherwise. 2138578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 2148578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """ 2158578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam return self.chameleond_proxy.IsPlugged(self.port_id) 2168578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 2178578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 2188578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tamclass ChameleonVideoInput(ChameleonPort): 2198578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """ChameleonVideoInput is an abstraction of a video input port. 2208578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 2218578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam It contains some special methods to control a video input. 2228578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """ 2238578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 224e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam _DURATION_UNPLUG_FOR_EDID = 5 225e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam _TIMEOUT_VIDEO_STABLE_PROBE = 10 2265b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam _EDID_ID_DISABLE = -1 227e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 2288578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam def __init__(self, chameleon_port): 2298578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """Construct a ChameleonVideoInput. 2308578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 2318578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam @param chameleon_port: A general ChameleonPort object. 2328578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """ 2338578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.chameleond_proxy = chameleon_port.chameleond_proxy 2348578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.port_id = chameleon_port.port_id 2356bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam 2366bd2f1998baf5e9d53680f52511e2694ccc5d6d6Tom Wai-Hong Tam 237e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam def wait_video_input_stable(self, timeout=None): 238e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam """Waits the video input stable or timeout. 239e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam 240e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam @param timeout: The time period to wait for. 241e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam 242e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam @return: True if the video input becomes stable within the timeout 243e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam period; otherwise, False. 244e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam """ 2458578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam return self.chameleond_proxy.WaitVideoInputStable(self.port_id, 2468578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam timeout) 247e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam 248e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam 249eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam def read_edid(self): 250eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """Reads the EDID. 251eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 2525b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam @return: An Edid object or NO_EDID. 253eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 2545b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam edid_binary = self.chameleond_proxy.ReadEdid(self.port_id) 2555b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam if edid_binary is None: 2565b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam return edid_lib.NO_EDID 2573737b1d3e9ce9e12341585d5431d947373dfc424Tom Wai-Hong Tam # Read EDID without verify. It may be made corrupted as intended 2583737b1d3e9ce9e12341585d5431d947373dfc424Tom Wai-Hong Tam # for the test purpose. 2595b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam return edid_lib.Edid(edid_binary.data, skip_verify=True) 260eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 261eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 2627a4ba1cad16c47849d8dfabcfaf5aa9d64960977Tom Wai-Hong Tam def apply_edid(self, edid): 263eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """Applies the given EDID. 264eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 2655b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam @param edid: An Edid object or NO_EDID. 266eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 2675b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam if edid is edid_lib.NO_EDID: 2685b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam self.chameleond_proxy.ApplyEdid(self.port_id, self._EDID_ID_DISABLE) 2695b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam else: 2705b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam edid_binary = xmlrpclib.Binary(edid.data) 2715b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam edid_id = self.chameleond_proxy.CreateEdid(edid_binary) 2725b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam self.chameleond_proxy.ApplyEdid(self.port_id, edid_id) 2735b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam self.chameleond_proxy.DestroyEdid(edid_id) 274c95277635c90ee616898d1f547440eff2dafc9cbMussa 275c95277635c90ee616898d1f547440eff2dafc9cbMussa 276e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam @contextmanager 277e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam def use_edid(self, edid): 278e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam """Uses the given EDID in a with statement. 279e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 280e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam It sets the EDID up in the beginning and restores to the original 281e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam EDID in the end. This function is expected to be used in a with 282e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam statement, like the following: 283e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 284e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam with chameleon_port.use_edid(edid): 285e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam do_some_test_on(chameleon_port) 286e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 287e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam @param edid: An EDID object. 288e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam """ 289e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam # Set the EDID up in the beginning. 290e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam plugged = self.plugged 291e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam if plugged: 292e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam self.unplug() 293e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 294e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam original_edid = self.read_edid() 295e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam logging.info('Apply EDID on port %d', self.port_id) 296e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam self.apply_edid(edid) 297e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 298e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam if plugged: 299e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam time.sleep(self._DURATION_UNPLUG_FOR_EDID) 300e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam self.plug() 301e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam self.wait_video_input_stable(self._TIMEOUT_VIDEO_STABLE_PROBE) 302e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 3032876774869edc2ca66476e471c409773ee0ab06dTom Wai-Hong Tam try: 3042876774869edc2ca66476e471c409773ee0ab06dTom Wai-Hong Tam # Yeild to execute the with statement. 3052876774869edc2ca66476e471c409773ee0ab06dTom Wai-Hong Tam yield 3062876774869edc2ca66476e471c409773ee0ab06dTom Wai-Hong Tam finally: 3072876774869edc2ca66476e471c409773ee0ab06dTom Wai-Hong Tam # Restore the original EDID in the end. 3082876774869edc2ca66476e471c409773ee0ab06dTom Wai-Hong Tam current_edid = self.read_edid() 3092876774869edc2ca66476e471c409773ee0ab06dTom Wai-Hong Tam if original_edid.data != current_edid.data: 3102876774869edc2ca66476e471c409773ee0ab06dTom Wai-Hong Tam logging.info('Restore the original EDID.') 3112876774869edc2ca66476e471c409773ee0ab06dTom Wai-Hong Tam self.apply_edid(original_edid) 312e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 313e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 314e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam def use_edid_file(self, filename): 315e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam """Uses the given EDID file in a with statement. 316e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 317e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam It sets the EDID up in the beginning and restores to the original 318e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam EDID in the end. This function is expected to be used in a with 319e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam statement, like the following: 320e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 321e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam with chameleon_port.use_edid_file(filename): 322e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam do_some_test_on(chameleon_port) 323e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 324e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam @param filename: A path to the EDID file. 325e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam """ 3265b43d6ab4e30473d0935e7ffc3a59767cdfbd34eTom Wai-Hong Tam return self.use_edid(edid_lib.Edid.from_file(filename)) 327e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 328e6e901f00651bdd4796942b66d492b2de3d803f0Tom Wai-Hong Tam 329eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam def fire_hpd_pulse(self, deassert_interval_usec, assert_interval_usec=None, 330e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng repeat_count=1, end_level=1): 331eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 332e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng """Fires one or more HPD pulse (low -> high -> low -> ...). 333e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng 334e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng @param deassert_interval_usec: The time in microsecond of the 335e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng deassert pulse. 336e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng @param assert_interval_usec: The time in microsecond of the 337e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng assert pulse. If None, then use the same value as 338e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng deassert_interval_usec. 339e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng @param repeat_count: The count of HPD pulses to fire. 340e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng @param end_level: HPD ends with 0 for LOW (unplugged) or 1 for 341e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng HIGH (plugged). 342eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 3438578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.chameleond_proxy.FireHpdPulse( 3448578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.port_id, deassert_interval_usec, 345e06f80fae6b4a54721bd0953f3383759791259f9Ting-Yuan Cheng assert_interval_usec, repeat_count, int(bool(end_level))) 346eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 347eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 348dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan def fire_mixed_hpd_pulses(self, widths): 349dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan """Fires one or more HPD pulses, starting at low, of mixed widths. 350dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan 351dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan One must specify a list of segment widths in the widths argument where 352dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan widths[0] is the width of the first low segment, widths[1] is that of 353dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan the first high segment, widths[2] is that of the second low segment... 354dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan etc. The HPD line stops at low if even number of segment widths are 355dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan specified; otherwise, it stops at high. 356dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan 357dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan @param widths: list of pulse segment widths in usec. 358dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan """ 3598578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.chameleond_proxy.FireMixedHpdPulses(self.port_id, widths) 360dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan 361dab3815cdcea63b68bb18318442fb759fc8cb6ebHung-ying Tyan 3624c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam def capture_screen(self): 363eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """Captures Chameleon framebuffer. 364eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 3654c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam @return An Image object. 366eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 367200a00c77422f92a28811c8174a364e1a716e9afTom Wai-Hong Tam return Image.fromstring( 368200a00c77422f92a28811c8174a364e1a716e9afTom Wai-Hong Tam 'RGB', 3694c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam self.get_resolution(), 3708578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.chameleond_proxy.DumpPixels(self.port_id).data) 371c95277635c90ee616898d1f547440eff2dafc9cbMussa 372eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 373eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam def get_resolution(self): 374eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """Gets the source resolution. 375eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam 376eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam @return: A (width, height) tuple. 377eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam """ 37884d759bd4be143e04f69a1def09ad5f36dadb12bTom Wai-Hong Tam # The return value of RPC is converted to a list. Convert it back to 37984d759bd4be143e04f69a1def09ad5f36dadb12bTom Wai-Hong Tam # a tuple. 3808578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam return tuple(self.chameleond_proxy.DetectResolution(self.port_id)) 3818578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 3828578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 3834e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam def set_content_protection(self, enable): 3844e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam """Sets the content protection state on the port. 3854e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam 3864e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam @param enable: True to enable; False to disable. 3874e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam """ 3884e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam self.chameleond_proxy.SetContentProtection(self.port_id, enable) 3894e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam 3904e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam 3914e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam def is_content_protection_enabled(self): 3924e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam """Returns True if the content protection is enabled on the port. 3934e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam 3944e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam @return: True if the content protection is enabled; otherwise, False. 3954e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam """ 3964e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam return self.chameleond_proxy.IsContentProtectionEnabled(self.port_id) 3974e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam 3984e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam 3994e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam def is_video_input_encrypted(self): 4004e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam """Returns True if the video input on the port is encrypted. 4014e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam 4024e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam @return: True if the video input is encrypted; otherwise, False. 4034e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam """ 4044e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam return self.chameleond_proxy.IsVideoInputEncrypted(self.port_id) 4054e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam 4064e241012e91ba74f1e85d5e6a630290e18a15aa9Tom Wai-Hong Tam 4078578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tamclass ChameleonAudioInput(ChameleonPort): 4088578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """ChameleonAudioInput is an abstraction of an audio input port. 4098578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 4108578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam It contains some special methods to control an audio input. 4118578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """ 4128578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 4138578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam def __init__(self, chameleon_port): 4148578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """Construct a ChameleonAudioInput. 4158578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam 4168578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam @param chameleon_port: A general ChameleonPort object. 4178578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam """ 4188578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.chameleond_proxy = chameleon_port.chameleond_proxy 4198578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.port_id = chameleon_port.port_id 420c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 421c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 422e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang def start_capturing_audio(self): 423e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang """Starts capturing audio.""" 4248578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam return self.chameleond_proxy.StartCapturingAudio(self.port_id) 425e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang 426e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang 427e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang def stop_capturing_audio(self): 428e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang """Stops capturing audio. 429e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang 430e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang Returns: 431e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang A tuple (data, format). 432e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang data: The captured binary data. 433e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang format: A dict containing: 434e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang file_type: 'raw' or 'wav'. 435e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang sample_format: 'S32_LE' for 32-bit signed integer in little-endian. 436e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang Refer to aplay manpage for other formats. 437e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang channel: channel number. 438e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang rate: sampling rate. 439e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang """ 4408578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam rpc_data, data_format = self.chameleond_proxy.StopCapturingAudio( 4418578eeb003a7db21e0a4d85f0192fa45faf8ec80Tom Wai-Hong Tam self.port_id) 442e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang return rpc_data.data, data_format 443e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang 444e3bbd6188e6354b55bea1cad39004d587dbe7631Cheng-Yi Chiang 445d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiangclass ChameleonAudioOutput(ChameleonPort): 446d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang """ChameleonAudioOutput is an abstraction of an audio output port. 447d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 448d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang It contains some special methods to control an audio output. 449d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang """ 450d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 451d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang def __init__(self, chameleon_port): 452d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang """Construct a ChameleonAudioOutput. 453d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 454d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang @param chameleon_port: A general ChameleonPort object. 455d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang """ 456d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang self.chameleond_proxy = chameleon_port.chameleond_proxy 457d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang self.port_id = chameleon_port.port_id 458d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 459d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 460d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang def start_playing_audio(self, data, data_format): 461d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang """Starts playing audio. 462d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 463d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang @param data: The audio data to play. 464d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang @param data_format: A dict containing data format. Currently Chameleon 465d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang only accepts data format: 466d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang dict(file_type='raw', sample_format='S32_LE', 467d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang channel=8, rate=48000). 468d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 469d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang """ 470d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang return self.chameleond_proxy.StartPlayingAudio( 471d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang self.port_id, xmlrpclib.Binary(data), data_format) 472d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 473d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 474d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang def stop_playing_audio(self): 475d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang """Stops capturing audio.""" 476d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang self.chameleond_proxy.StopPlayingAudio(self.port_id) 477d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 478d3fad2c8a0ba1508f5fc3efb90592687ec219d5cCheng-Yi Chiang 479c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tamdef make_chameleon_hostname(dut_hostname): 480c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """Given a DUT's hostname, returns the hostname of its Chameleon. 481c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 482c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @param dut_hostname: Hostname of a DUT. 483c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 484c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @return Hostname of the DUT's Chameleon. 485c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """ 486c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam host_parts = dut_hostname.split('.') 487c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam host_parts[0] = host_parts[0] + '-chameleon' 488c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam return '.'.join(host_parts) 489c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 490c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 491c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tamdef create_chameleon_board(dut_hostname, args): 492c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """Given either DUT's hostname or argments, creates a ChameleonBoard object. 493c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 494c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam If the DUT's hostname is in the lab zone, it connects to the Chameleon by 495c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam append the hostname with '-chameleon' suffix. If not, checks if the args 496c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam contains the key-value pair 'chameleon_host=IP'. 497c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 498c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @param dut_hostname: Hostname of a DUT. 499c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @param args: A string of arguments passed from the command line. 500c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 501c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @return A ChameleonBoard object. 502c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 503c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam @raise ChameleonConnectionError if unknown hostname. 504c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam """ 505c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam connection = None 506c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam hostname = make_chameleon_hostname(dut_hostname) 507c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam if utils.host_is_in_lab_zone(hostname): 508c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam connection = ChameleonConnection(hostname) 509c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam else: 510c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam args_dict = utils.args_to_dict(args) 511c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam hostname = args_dict.get('chameleon_host', None) 512c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam port = args_dict.get('chameleon_port', CHAMELEON_PORT) 513c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam if hostname: 514c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam connection = ChameleonConnection(hostname, port) 515c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam else: 516c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam raise ChameleonConnectionError('No chameleon_host is given in args') 517c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam 518c3fb2f6ce00d4dad5c5f6478a6fb650dfd89f42cTom Wai-Hong Tam return ChameleonBoard(connection) 519