1b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam# Use of this source code is governed by a BSD-style license that can be
3b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam# found in the LICENSE file.
4b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
563303a0c7963646f8c463180d4d25e4de751287fTom Wai-Hong Tam"""An adapter to remotely access the display facade on DUT."""
663303a0c7963646f8c463180d4d25e4de751287fTom Wai-Hong Tam
7619f336b5e4a78f70d84999116fa458cd03fc05dTom Wai-Hong Tamimport logging
8b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tamimport os
9897fcf70779924c378b7410d44363474323e85f9Tom Wai-Hong Tamimport tempfile
10619f336b5e4a78f70d84999116fa458cd03fc05dTom Wai-Hong Tamimport xmlrpclib
11b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
12428b34464f1060129cbcda08d60ec44ed88a518dJ. Richard Barnettefrom PIL import Image
13428b34464f1060129cbcda08d60ec44ed88a518dJ. Richard Barnette
14aeee12fc6bc5af104076fd3c93a995c5474a9169Hung-ying Tyanfrom autotest_lib.client.common_lib import error
15e535050c22ff1651a505e92286886b125f0071e0Tom Wai-Hong Tamfrom autotest_lib.client.cros.multimedia.display_info import DisplayInfo
16897fcf70779924c378b7410d44363474323e85f9Tom Wai-Hong Tam
17b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
1863303a0c7963646f8c463180d4d25e4de751287fTom Wai-Hong Tamclass DisplayFacadeRemoteAdapter(object):
1963303a0c7963646f8c463180d4d25e4de751287fTom Wai-Hong Tam    """DisplayFacadeRemoteAdapter is an adapter to remotely control DUT display.
20b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
21b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam    The Autotest host object representing the remote DUT, passed to this
22b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam    class on initialization, can be accessed from its _client property.
23b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
24b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam    """
25e88a818f0bc745083457df96c65e73746f653863Tom Wai-Hong Tam    def __init__(self, host, remote_facade_proxy):
2663303a0c7963646f8c463180d4d25e4de751287fTom Wai-Hong Tam        """Construct a DisplayFacadeRemoteAdapter.
27b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
28b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        @param host: Host object representing a remote host.
29e88a818f0bc745083457df96c65e73746f653863Tom Wai-Hong Tam        @param remote_facade_proxy: RemoteFacadeProxy object.
30b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        """
31b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        self._client = host
32e88a818f0bc745083457df96c65e73746f653863Tom Wai-Hong Tam        self._proxy = remote_facade_proxy
33b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
34b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
350ea72294a82d51c36fc3b488163dcafb826ac0b0Tom Wai-Hong Tam    @property
360ea72294a82d51c36fc3b488163dcafb826ac0b0Tom Wai-Hong Tam    def _display_proxy(self):
3763303a0c7963646f8c463180d4d25e4de751287fTom Wai-Hong Tam        """Gets the proxy to DUT display facade.
380ea72294a82d51c36fc3b488163dcafb826ac0b0Tom Wai-Hong Tam
3963303a0c7963646f8c463180d4d25e4de751287fTom Wai-Hong Tam        @return XML RPC proxy to DUT display facade.
40b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        """
41e88a818f0bc745083457df96c65e73746f653863Tom Wai-Hong Tam        return self._proxy.display
42b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
43b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
440c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng    def get_external_connector_name(self):
45b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        """Gets the name of the external output connector.
46b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
47253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam        @return The external output connector name as a string; False if nothing
485e58b205693045b8e8acaf25355b8ac91ed84f0dHung-ying Tyan                is connected.
49b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        """
50253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam        return self._display_proxy.get_external_connector_name()
510c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng
520c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng
530c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng    def get_internal_connector_name(self):
540c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng        """Gets the name of the internal output connector.
550c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng
56253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam        @return The internal output connector name as a string; False if nothing
57253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam                is connected.
580c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng        """
590ea72294a82d51c36fc3b488163dcafb826ac0b0Tom Wai-Hong Tam        return self._display_proxy.get_internal_connector_name()
60b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
61b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
62c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin    def move_to_display(self, display_index):
63c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin        """Moves the current window to the indicated display.
64c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin
65c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin        @param display_index: The index of the indicated display.
66c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin        """
67c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin        self._display_proxy.move_to_display(display_index)
68c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin
69c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin
70c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin    def set_fullscreen(self, is_fullscreen):
71c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin        """Sets the current window to full screen.
72c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin
73c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin        @param is_fullscreen: True or False to indicate fullscreen state.
74c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin        @return True if success, False otherwise.
75c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin        """
76c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin        return self._display_proxy.set_fullscreen(is_fullscreen)
77c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin
78c02fefede41df9f1375b4b67d5f631b715e91ac1Chin-Huang Lin
7909f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin    def load_url(self, url):
8009f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin        """Loads the given url in a new tab. The new tab will be active.
8109f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin
8209f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin        @param url: The url to load as a string.
8374ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        @return a str, the tab descriptor of the opened tab.
8409f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin        """
8574ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        return self._display_proxy.load_url(url)
8609f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin
8709f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin
88b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam    def load_calibration_image(self, resolution):
89b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        """Load a full screen calibration image from the HTTP server.
90b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
91b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        @param resolution: A tuple (width, height) of resolution.
9274ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        @return a str, the tab descriptor of the opened tab.
93b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        """
9474ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        return self._display_proxy.load_calibration_image(resolution)
95b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
96b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
9774ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu    def load_color_sequence(self, tab_descriptor, color_sequence):
9874ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        """Displays a series of colors on full screen on the tab.
9974ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        tab_descriptor is returned by any open tab API of display facade.
10074ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        e.g.,
10174ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        tab_descriptor = load_url('about:blank')
10274ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        load_color_sequence(tab_descriptor, color)
10309f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin
10474ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        @param tab_descriptor: Indicate which tab to test.
10509f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin        @param color_sequence: An integer list for switching colors.
10609f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin        @return A list of the timestamp for each switch.
10709f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin        """
10874ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        return self._display_proxy.load_color_sequence(tab_descriptor,
10974ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu                                                       color_sequence)
11009f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin
11109f9d5aa21078c54b9e0003154361608acfcddfcChin-Huang Lin
11274ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu    def close_tab(self, tab_descriptor):
11374ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        """Disables fullscreen and closes the tab of the given tab descriptor.
11474ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        tab_descriptor is returned by any open tab API of display facade.
11574ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        e.g.,
11674ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        1.
11774ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        tab_descriptor = load_url(url)
11874ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        close_tab(tab_descriptor)
119b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
12074ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        2.
12174ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        tab_descriptor = load_calibration_image(resolution)
12274ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        close_tab(tab_descriptor)
12374ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu
12474ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        @param tab_descriptor: Indicate which tab to close.
125b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        """
12674ef809f5647db614c5b8215303cc8f2f96c7d8aMoja Hsu        self._display_proxy.close_tab(tab_descriptor)
127b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
128b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
12904e759bc3b8c81030f25c99f3e1b7c6cabf0d8f0Hung-ying Tyan    def is_mirrored_enabled(self):
13004e759bc3b8c81030f25c99f3e1b7c6cabf0d8f0Hung-ying Tyan        """Checks the mirrored state.
13104e759bc3b8c81030f25c99f3e1b7c6cabf0d8f0Hung-ying Tyan
13204e759bc3b8c81030f25c99f3e1b7c6cabf0d8f0Hung-ying Tyan        @return True if mirrored mode is enabled.
13304e759bc3b8c81030f25c99f3e1b7c6cabf0d8f0Hung-ying Tyan        """
13404e759bc3b8c81030f25c99f3e1b7c6cabf0d8f0Hung-ying Tyan        return self._display_proxy.is_mirrored_enabled()
13504e759bc3b8c81030f25c99f3e1b7c6cabf0d8f0Hung-ying Tyan
13604e759bc3b8c81030f25c99f3e1b7c6cabf0d8f0Hung-ying Tyan
137b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam    def set_mirrored(self, is_mirrored):
138b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        """Sets mirrored mode.
139b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
140b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        @param is_mirrored: True or False to indicate mirrored state.
141aeee12fc6bc5af104076fd3c93a995c5474a9169Hung-ying Tyan        @throws error.TestError when the call fails.
142b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        """
143aeee12fc6bc5af104076fd3c93a995c5474a9169Hung-ying Tyan        if not self._display_proxy.set_mirrored(is_mirrored):
144aeee12fc6bc5af104076fd3c93a995c5474a9169Hung-ying Tyan            raise error.TestError('Failed to set_mirrored(%s)' % is_mirrored)
145b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
146b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
14718b08921a87efd1da6eec8cd1e1cd6edeab15b8eTom Wai-Hong Tam    def is_display_primary(self, internal=True):
14818b08921a87efd1da6eec8cd1e1cd6edeab15b8eTom Wai-Hong Tam        """Checks if internal screen is primary display.
14918b08921a87efd1da6eec8cd1e1cd6edeab15b8eTom Wai-Hong Tam
15018b08921a87efd1da6eec8cd1e1cd6edeab15b8eTom Wai-Hong Tam        @param internal: is internal/external screen primary status requested
15118b08921a87efd1da6eec8cd1e1cd6edeab15b8eTom Wai-Hong Tam        @return boolean True if internal display is primary.
15218b08921a87efd1da6eec8cd1e1cd6edeab15b8eTom Wai-Hong Tam        """
15318b08921a87efd1da6eec8cd1e1cd6edeab15b8eTom Wai-Hong Tam        return self._display_proxy.is_display_primary(internal)
15418b08921a87efd1da6eec8cd1e1cd6edeab15b8eTom Wai-Hong Tam
15518b08921a87efd1da6eec8cd1e1cd6edeab15b8eTom Wai-Hong Tam
156328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam    def suspend_resume(self, suspend_time=10):
157328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam        """Suspends the DUT for a given time in second.
158328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam
159328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam        @param suspend_time: Suspend time in second, default: 10s.
160328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam        """
161619f336b5e4a78f70d84999116fa458cd03fc05dTom Wai-Hong Tam        try:
162619f336b5e4a78f70d84999116fa458cd03fc05dTom Wai-Hong Tam            self._display_proxy.suspend_resume(suspend_time)
163619f336b5e4a78f70d84999116fa458cd03fc05dTom Wai-Hong Tam        except xmlrpclib.Fault as e:
164619f336b5e4a78f70d84999116fa458cd03fc05dTom Wai-Hong Tam            # Log suspend/resume errors but continue the test.
165619f336b5e4a78f70d84999116fa458cd03fc05dTom Wai-Hong Tam            logging.error('suspend_resume error: %s', str(e))
166328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam
167328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam
168328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam    def suspend_resume_bg(self, suspend_time=10):
169328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam        """Suspends the DUT for a given time in second in the background.
170328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam
171328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam        @param suspend_time: Suspend time in second, default: 10s.
172328dbeb9082fa1215d981572967f4913ac7af6bcTom Wai-Hong Tam        """
173b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        # TODO(waihong): Use other general API instead of this RPC.
174fe6f16dad3a97488e0f4ba85131d7e721d7fb0d1Tom Wai-Hong Tam        self._display_proxy.suspend_resume_bg(suspend_time)
175b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
176b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
1777a49d75545994c991356899af9f9ae9a355a62ebTom Wai-Hong Tam    def wait_external_display_connected(self, display):
1787a49d75545994c991356899af9f9ae9a355a62ebTom Wai-Hong Tam        """Waits for the specified display to be connected.
179568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
1807a49d75545994c991356899af9f9ae9a355a62ebTom Wai-Hong Tam        @param display: The display name as a string, like 'HDMI1', or
1817a49d75545994c991356899af9f9ae9a355a62ebTom Wai-Hong Tam                        False if no external display is expected.
1827a49d75545994c991356899af9f9ae9a355a62ebTom Wai-Hong Tam        @return: True if display is connected; False otherwise.
183568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng        """
1847a49d75545994c991356899af9f9ae9a355a62ebTom Wai-Hong Tam        return self._display_proxy.wait_external_display_connected(display)
185b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
186b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
18767541655a1a0c9356dabb02078c62cba11ba739aHung-ying Tyan    def hide_cursor(self):
18867541655a1a0c9356dabb02078c62cba11ba739aHung-ying Tyan        """Hides mouse cursor by sending a keystroke."""
189fe6f16dad3a97488e0f4ba85131d7e721d7fb0d1Tom Wai-Hong Tam        self._display_proxy.hide_cursor()
190b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
191b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
192da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam    def set_content_protection(self, state):
193da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam        """Sets the content protection of the external screen.
194da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam
195da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam        @param state: One of the states 'Undesired', 'Desired', or 'Enabled'
196da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam        """
197da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam        self._display_proxy.set_content_protection(state)
198da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam
199da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam
200da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam    def get_content_protection(self):
201da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam        """Gets the state of the content protection.
202da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam
203da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam        @param output: The output name as a string.
204da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam        @return: A string of the state, like 'Undesired', 'Desired', or 'Enabled'.
205da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam                 False if not supported.
206da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam        """
207da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam        return self._display_proxy.get_content_protection()
208da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam
209da4a85a8fefbfe3ee7bbf09629eef2522fa3d178Tom Wai-Hong Tam
21054cdcdfb4c1d82b8648dee554d74370a1b73f7e1Hung-ying Tyan    def _take_screenshot(self, screenshot_func):
21154cdcdfb4c1d82b8648dee554d74370a1b73f7e1Hung-ying Tyan        """Gets screenshot from DUT.
2120c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng
21354cdcdfb4c1d82b8648dee554d74370a1b73f7e1Hung-ying Tyan        @param screenshot_func: function to take a screenshot and save the image
21454cdcdfb4c1d82b8648dee554d74370a1b73f7e1Hung-ying Tyan                to specified path on DUT. Usage: screenshot_func(remote_path).
215b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam
2162c4a5d849e715f8046c4da7d4d4a0e1c50393f14Chin-Huang Lin        @return: An Image object.
2172c4a5d849e715f8046c4da7d4d4a0e1c50393f14Chin-Huang Lin                 Notice that the returned image may not be in RGB format,
2182c4a5d849e715f8046c4da7d4d4a0e1c50393f14Chin-Huang Lin                 depending on PIL implementation.
219b2d39dc644b2ae2c840e06c6037d0c7e4a034254Tom Wai-Hong Tam        """
220d94feb65407b07bd2c17ffd94cfcace57f9d0650Ilja H. Friedel        with tempfile.NamedTemporaryFile(suffix='.png') as f:
2214c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam            basename = os.path.basename(f.name)
2224c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam            remote_path = os.path.join('/tmp', basename)
22354cdcdfb4c1d82b8648dee554d74370a1b73f7e1Hung-ying Tyan            screenshot_func(remote_path)
2244c8022f036732d1e12931a8f6743cfce92ab2fbaTom Wai-Hong Tam            self._client.get_file(remote_path, f.name)
225d94feb65407b07bd2c17ffd94cfcace57f9d0650Ilja H. Friedel            return Image.open(f.name)
226d94feb65407b07bd2c17ffd94cfcace57f9d0650Ilja H. Friedel
227d94feb65407b07bd2c17ffd94cfcace57f9d0650Ilja H. Friedel
2280c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng    def capture_internal_screen(self):
2290c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng        """Captures the internal screen framebuffer.
2300c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng
2312c4a5d849e715f8046c4da7d4d4a0e1c50393f14Chin-Huang Lin        @return: An Image object.
2320c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng        """
23354cdcdfb4c1d82b8648dee554d74370a1b73f7e1Hung-ying Tyan        screenshot_func = self._display_proxy.take_internal_screenshot
23454cdcdfb4c1d82b8648dee554d74370a1b73f7e1Hung-ying Tyan        return self._take_screenshot(screenshot_func)
2350c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng
2360c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng
237d94feb65407b07bd2c17ffd94cfcace57f9d0650Ilja H. Friedel    # TODO(ihf): This needs to be fixed for multiple external screens.
2380c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng    def capture_external_screen(self):
2390c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng        """Captures the external screen framebuffer.
2400c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng
2410c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng        @return: An Image object.
2420c48150a2073bf2b3d610c5eb75cad1ba4d7bef5Ting-Yuan Cheng        """
24354cdcdfb4c1d82b8648dee554d74370a1b73f7e1Hung-ying Tyan        screenshot_func = self._display_proxy.take_external_screenshot
24454cdcdfb4c1d82b8648dee554d74370a1b73f7e1Hung-ying Tyan        return self._take_screenshot(screenshot_func)
245253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam
246253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam
247253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam    def get_external_resolution(self):
248253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam        """Gets the resolution of the external screen.
249253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam
250d2167a5a1ae205207e203676a4e4e2ac16dabf5fTom Wai-Hong Tam        @return The resolution tuple (width, height) or None if no external
251d2167a5a1ae205207e203676a4e4e2ac16dabf5fTom Wai-Hong Tam                display is connected.
252253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam        """
253d2167a5a1ae205207e203676a4e4e2ac16dabf5fTom Wai-Hong Tam        resolution = self._display_proxy.get_external_resolution()
254d2167a5a1ae205207e203676a4e4e2ac16dabf5fTom Wai-Hong Tam        return tuple(resolution) if resolution else None
255f6bb17f0dcad6ff3ec876e65a035a7823f9d0c7fTom Wai-Hong Tam
256f6bb17f0dcad6ff3ec876e65a035a7823f9d0c7fTom Wai-Hong Tam
257253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam    def get_internal_resolution(self):
258253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam        """Gets the resolution of the internal screen.
259f6bb17f0dcad6ff3ec876e65a035a7823f9d0c7fTom Wai-Hong Tam
260f6bb17f0dcad6ff3ec876e65a035a7823f9d0c7fTom Wai-Hong Tam        @return The resolution tuple (width, height)
261f6bb17f0dcad6ff3ec876e65a035a7823f9d0c7fTom Wai-Hong Tam        """
262253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam        return tuple(self._display_proxy.get_internal_resolution())
263568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
264568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
265568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng    def set_resolution(self, display_index, width, height):
266568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng        """Sets the resolution on the specified display.
267568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
268eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan        @param display_index: index of the display to set resolutions for.
269568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng        @param width: width of the resolution
270568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng        @param height: height of the resolution
271568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng        """
272253c0ceadf9acc1f979a4f3fe2ad3b8a7b9540c3Tom Wai-Hong Tam        self._display_proxy.set_resolution(display_index, width, height)
273568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
274568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
275d94feb65407b07bd2c17ffd94cfcace57f9d0650Ilja H. Friedel    # pylint: disable = W0141
276568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng    def get_display_info(self):
277568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng        """Gets the information of all the displays that are connected to the
278568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng                DUT.
279568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
280eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan        @return: list of object DisplayInfo for display informtion
281568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng        """
2820ea72294a82d51c36fc3b488163dcafb826ac0b0Tom Wai-Hong Tam        return map(DisplayInfo, self._display_proxy.get_display_info())
283568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
284568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
285eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan    def get_display_modes(self, display_index):
286eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan        """Gets the display modes of the specified display.
287eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan
288eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan        @param display_index: index of the display to get modes from; the index
289eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan            is from the DisplayInfo list obtained by get_display_info().
290eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan
291eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan        @return: list of DisplayMode dicts.
292eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan        """
2930ea72294a82d51c36fc3b488163dcafb826ac0b0Tom Wai-Hong Tam        return self._display_proxy.get_display_modes(display_index)
294eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan
295568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
296eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan    def get_available_resolutions(self, display_index):
297eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan        """Gets the resolutions from the specified display.
298568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng
299eea5a79bf681491974ee4c3eedbda8e1b24ed158Hung-ying Tyan        @return a list of (width, height) tuples.
300568083c3bc4676e86dd718dae9f7fc0161d84fa3Ting-Yuan Cheng        """
301fe6f16dad3a97488e0f4ba85131d7e721d7fb0d1Tom Wai-Hong Tam        return [tuple(r) for r in
302fe6f16dad3a97488e0f4ba85131d7e721d7fb0d1Tom Wai-Hong Tam                self._display_proxy.get_available_resolutions(display_index)]
30306df6022edd60e7aff06c29ff86998aa2a31afb7Tom Wai-Hong Tam
30406df6022edd60e7aff06c29ff86998aa2a31afb7Tom Wai-Hong Tam
30506df6022edd60e7aff06c29ff86998aa2a31afb7Tom Wai-Hong Tam    def get_first_external_display_index(self):
30606df6022edd60e7aff06c29ff86998aa2a31afb7Tom Wai-Hong Tam        """Gets the first external display index.
30706df6022edd60e7aff06c29ff86998aa2a31afb7Tom Wai-Hong Tam
30806df6022edd60e7aff06c29ff86998aa2a31afb7Tom Wai-Hong Tam        @return the index of the first external display; False if not found.
30906df6022edd60e7aff06c29ff86998aa2a31afb7Tom Wai-Hong Tam        """
31006df6022edd60e7aff06c29ff86998aa2a31afb7Tom Wai-Hong Tam        return self._display_proxy.get_first_external_display_index()
311