chameleon.py revision 428b34464f1060129cbcda08d60ec44ed88a518d
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
5d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tamimport time
6eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tamimport xmlrpclib
7eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
8428b34464f1060129cbcda08d60ec44ed88a518dJ. Richard Barnettefrom PIL import Image
9428b34464f1060129cbcda08d60ec44ed88a518dJ. Richard Barnette
107a4ba1cad16c47849d8dfabcfaf5aa9d64960977Tom Wai-Hong Tamfrom autotest_lib.server.cros.chameleon import edid
117a4ba1cad16c47849d8dfabcfaf5aa9d64960977Tom Wai-Hong Tam
12eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
13eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tamclass ChameleonBoard(object):
14eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    """ChameleonBoard is an abstraction of a Chameleon board.
15eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
16eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    A Chameleond RPC proxy is passed to the construction such that it can
17eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    use this proxy to control the Chameleon board.
18eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    """
19eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
20eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def __init__(self, chameleond_proxy):
21eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Construct a ChameleonBoard.
22eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
23eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        @param chameleond_proxy: Chameleond RPC proxy object.
24eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """
25eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        self._chameleond_proxy = chameleond_proxy
26eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
27eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
28eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def reset(self):
29eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Resets Chameleon board."""
30eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        self._chameleond_proxy.Reset()
31eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
32eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
33d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam    def is_healthy(self):
34d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam        """Returns if the Chameleon is healthy or any repair is needed.
35d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam
36d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam        @return: True if the Chameleon is healthy;
37d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam                 otherwise, False, need to repair.
38d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam        """
39d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam        return self._chameleond_proxy.IsHealthy()
40d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam
41d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam
42d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam    def repair(self):
43d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam        """Repairs the Chameleon.
44d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam
45d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam        It is a synchronous call. It returns after repairs.
46d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam        """
47d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam        repair_time = self._chameleond_proxy.Repair()
48d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam        time.sleep(repair_time)
49d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam
50d548e8c2637f75cad896c72099fc1ed4ec0ff80eTom Wai-Hong Tam
51eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def get_all_ports(self):
52eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Gets all the ports on Chameleon board which are connected.
53eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
54eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        @return: A list of ChameleonPort objects.
55eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """
56eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        ports = self._chameleond_proxy.ProbeInputs()
57eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        return [ChameleonPort(self._chameleond_proxy, port) for port in ports]
58eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
59eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
60ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam    def get_pixel_format(self):
61ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam        """Gets the pixel format for the output of DumpPixels.
62ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam
63ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam        @return: A string of the format, like 'rgba', 'bgra', 'rgb', etc.
64ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam        """
65ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam        return self._chameleond_proxy.GetPixelFormat()
66ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam
67ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam
68ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam    def get_pixel_length(self):
69ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam        """Gets the length of a pixel, which is returned from DumpPixels().
70ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam
71ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam        @return: A number of length, in byte.
72ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam        """
73ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam        return len(self.get_pixel_format())
74ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam
75ad92a7510865bf32c65d1c882b34d3f11d699afcTom Wai-Hong Tam
76eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tamclass ChameleonPort(object):
77eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    """ChameleonPort is an abstraction of a port of a Chameleon board.
78eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
79eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    A Chameleond RPC proxy and an input_id are passed to the construction.
80eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    The input_id is the unique identity to the port.
81eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    """
82eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
83eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def __init__(self, chameleond_proxy, input_id):
84eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Construct a ChameleonPort.
85eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
86eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        @param chameleond_proxy: Chameleond RPC proxy object.
87eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        @param input_id: The ID of the input port.
88eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """
89eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        self._chameleond_proxy = chameleond_proxy
90eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        self._input_id = input_id
91eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
92eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
93eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def get_connector_id(self):
94eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Returns the connector ID.
95eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
96eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        @return: A number of connector ID.
97eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """
98eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        return self._input_id
99eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
100eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
101eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def get_connector_type(self):
102eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Returns the human readable string for the connector type.
103eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
104eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        @return: A string, like "VGA", "DVI", "HDMI", or "DP".
105eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """
106eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        return self._chameleond_proxy.GetConnectorType(self._input_id)
107eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
108eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
109e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam    def wait_video_input_stable(self, timeout=None):
110e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam        """Waits the video input stable or timeout.
111e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam
112e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam        @param timeout: The time period to wait for.
113e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam
114e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam        @return: True if the video input becomes stable within the timeout
115e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam                 period; otherwise, False.
116e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam        """
117e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam        return self._chameleond_proxy.WaitVideoInputStable(self._input_id,
118e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam                                                           timeout)
119e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam
120e090aa536604063fcaa59955f74eefb07c80ca3aTom Wai-Hong Tam
121eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def read_edid(self):
122eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Reads the EDID.
123eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
1247a4ba1cad16c47849d8dfabcfaf5aa9d64960977Tom Wai-Hong Tam        @return: An Edid object.
125eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """
1263737b1d3e9ce9e12341585d5431d947373dfc424Tom Wai-Hong Tam        # Read EDID without verify. It may be made corrupted as intended
1273737b1d3e9ce9e12341585d5431d947373dfc424Tom Wai-Hong Tam        # for the test purpose.
1283737b1d3e9ce9e12341585d5431d947373dfc424Tom Wai-Hong Tam        return edid.Edid(self._chameleond_proxy.ReadEdid(self._input_id).data,
1293737b1d3e9ce9e12341585d5431d947373dfc424Tom Wai-Hong Tam                         skip_verify=True)
130eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
131eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
1327a4ba1cad16c47849d8dfabcfaf5aa9d64960977Tom Wai-Hong Tam    def apply_edid(self, edid):
133eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Applies the given EDID.
134eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
1357a4ba1cad16c47849d8dfabcfaf5aa9d64960977Tom Wai-Hong Tam        @param edid: An Edid object.
136eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """
1377a4ba1cad16c47849d8dfabcfaf5aa9d64960977Tom Wai-Hong Tam        edid_id = self._chameleond_proxy.CreateEdid(xmlrpclib.Binary(edid.data))
138eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        self._chameleond_proxy.ApplyEdid(self._input_id, edid_id)
13954b88eeb381522cff5e94889739d38a8b06168d5Tom Wai-Hong Tam        self._chameleond_proxy.DestroyEdid(edid_id)
140eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
141eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
142eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def plug(self):
143eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Asserts HPD line to high, emulating plug."""
144eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        self._chameleond_proxy.Plug(self._input_id)
145eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
146eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
147eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def unplug(self):
148eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Deasserts HPD line to low, emulating unplug."""
149eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        self._chameleond_proxy.Unplug(self._input_id)
150eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
151eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
152eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def fire_hpd_pulse(self, deassert_interval_usec, assert_interval_usec=None,
153eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam                       repeat_count=1):
154eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Fires a HPD pulse (high -> low -> high) or multiple HPD pulses.
155eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
156eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        @param deassert_interval_usec: The time of the deassert pulse.
157eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        @param assert_interval_usec: The time of the assert pulse.
158eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        @param repeat_count: The count of repeating the HPD pulses.
159eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """
160eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        self._chameleond_proxy.FireHpdPulse(
161eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam                self._input_id, deassert_interval_usec, assert_interval_usec,
162eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam                repeat_count)
163eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
164eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
1654c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam    def capture_screen(self):
166eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Captures Chameleon framebuffer.
167eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
1684c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam        @return An Image object.
169eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """
1704c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam        image = Image.fromstring(
1714c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam                self._chameleond_proxy.GetPixelFormat().upper(),
1724c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam                self.get_resolution(),
1734c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam                self._chameleond_proxy.DumpPixels(self._input_id).data)
1744c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam        return image.convert('RGB')
175eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
176eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
177eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam    def get_resolution(self):
178eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """Gets the source resolution.
179eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam
180eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        @return: A (width, height) tuple.
181eaee34082a63a957e6881ad779b825a774e3d7edTom Wai-Hong Tam        """
18284d759bd4be143e04f69a1def09ad5f36dadb12bTom Wai-Hong Tam        # The return value of RPC is converted to a list. Convert it back to
18384d759bd4be143e04f69a1def09ad5f36dadb12bTom Wai-Hong Tam        # a tuple.
18484d759bd4be143e04f69a1def09ad5f36dadb12bTom Wai-Hong Tam        return tuple(self._chameleond_proxy.DetectResolution(self._input_id))
185