• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2018 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LISENCE file.
4
5import logging
6import re
7import os
8import time
9
10from autotest_lib.client.common_lib import error
11from autotest_lib.server import test
12
13CEC_COMMAND = "sudo -u chronos dbus-send --system --print-reply \
14--type=method_call --dest=org.chromium.CecService   \
15/org/chromium/CecService org.chromium.CecService."
16CEC_CMD_STANDBY = "SendStandByToAllDevices"
17CEC_CMD_IMAGEON = "SendWakeUpToAllDevices"
18CEC_CMD_DISP_STATUS = "GetTvsPowerStatus"
19
20CHAMELEON_ROOT = '/home/root/'
21
22STATUS_ERROR = 0
23STATUS_ON = 3
24STATUS_OFF = 4
25STATUS_TO_ON = 5
26STATUS_TO_OFF = 6
27
28class enterprise_CFM_CEC(test.test):
29    """
30    Test CEC feature for display power control.
31    """
32
33    version = 1
34    # TODO: how to get whether it connects to chameleon board
35    chameleon_mode = True
36
37    def initialize(self):
38        """ initialize is a stub function."""
39        pass
40
41    # Simply run a command in machine and return result messages.
42    def _shcmd(self, cmd):
43        """ A simple wrapper for remote shell command execution.
44        @param cmd: shell command for Fizz
45        """
46        logging.info('CMD: [%s]', cmd)
47        try:
48            result = self._client.run(cmd)
49            if result is None:
50                return result
51            if result.stderr:
52                logging.info('CMD ERR:\n' + result.stderr)
53            logging.info('CMD OUT:\n' + result.stdout)
54            return result
55        except Exception as e:
56            logging.info('run command failed. ' + str(e))
57
58    def run_once(self, host=None):
59        """
60        Test scenario:
61
62            If system does not support cec port, we simply throw an exception.
63
64            Generally we are using the build-in cecservice for this test. This
65        service supports multiple features including turning TV(display)
66        power on/off and monitor its power status.
67
68            Following is test plan:
69            0.0 Copy two python files to chameleon
70            0.1 enable chameleon as hdmi mode
71            0.2 run cec service on chameleon
72
73            0.3 Make sure chrome box is running cecservice
74            0.4 Make sure chrome box's /dev/cecX is open
75            0.5 Run TV power status to check configuration correct
76            (end of step 0)
77
78
79            1.0 Send TV turn-off command
80            1.1 Check TV power status to check whether it is off.
81            (end of step 1)
82
83            2.0 Send TV turn-on command
84            2.1 Check TV power status to check whether it is on.
85            (end of step 2)
86            At every end of step, we have to decide whether we stop this test
87        right now or continue next ones.
88            Note that we could turn on TV first and then turn off it,
89        according to its initial power status.
90
91            3.0 Stop cec service on chameleon
92            3.1 Remove python files from chameleon
93
94        @param host: host object machine.
95        """
96
97        self._client = host
98        self.chameleon = host.chameleon
99
100        ## TODO check same port
101        #Step 0.0 - 0.2
102        self.copy_cecservice()
103        self.cec_service_init()
104
105
106        # Step 0.3 - 0.5
107        if not self.is_cecservice_running():
108            self.cec_cleanup()
109            raise error.TestFail("CEC service is not running.")
110        if not self.is_cec_available():
111            self.cec_cleanup()
112            raise error.TestFail("/dev/cecX port is not open.")
113        status = self.check_display_status()
114        if STATUS_ERROR == status:
115            self.cec_cleanup()
116            raise error.TestFail("CEC communication is not good.")
117
118        # Step 1 & 2
119        if STATUS_ON == status:
120            self.test_turn_off()
121            if not self.chameleon_mode:
122                time.sleep(5)
123            self.test_turn_on()
124        else:
125            self.test_turn_on()
126            if not self.chameleon_mode:
127                time.sleep(5)
128            self.test_turn_off()
129
130        # Step 3
131        self.cec_cleanup()
132
133    # Chameleon
134    def copy_cecservice(self):
135        """ copy python files under ./chameleon_cecservice to chameleon.
136            In that folder, we have two files for cecservice.
137        """
138        current_dir = os.path.dirname(os.path.realpath(__file__))
139        base_dir = current_dir + '/chameleon_cecservice/'
140        self.chameleon.host.send_file(base_dir + 'cec_service', CHAMELEON_ROOT)
141        self.chameleon.host.send_file(base_dir + 'it6803.py', CHAMELEON_ROOT)
142
143    def cec_service_init(self):
144        """ Setup chameleon board as a hdmi mode.
145            Run cec service on chameleon
146        """
147        self.chameleon.host.run('/home/root/setup hdmi')
148        self.chameleon.host.run('(/home/root/cec_service start) '\
149            '</dev/null >/dev/null 2>&1 & echo -n $!')
150
151    def cec_cleanup(self):
152        """ Stop cec service on chameleon.
153            Delete files new coming on chameleon.
154        """
155        if self.chameleon_mode:
156            stop_cmd = 'kill $(ps | grep \'cec_service\' | awk \'{print $1}\')'
157            self.chameleon.host.run(stop_cmd)
158            cleanup_cmd = 'rm /home/root/cec_service /home/root/it6803*'
159            self.chameleon.host.run(cleanup_cmd)
160
161    # Fizz
162    def is_cecservice_running(self):
163        """ try to confirm that current box is running cecservice.
164        @return: whether cecservice is running in Fizz.
165        """
166        cmd = 'initctl list | grep cecservice'
167        result = self._shcmd(cmd)
168        if result is None:
169            return False;
170        if "running" not in result.stdout:
171            return False;
172        return True;
173
174    def is_cec_available(self):
175        """ try to get whether the system makes /dev/cecX open.
176        @return: whether /dev/cecX is open in Fizz
177        """
178        cmd = "ls /dev/cec*"
179        result = self._shcmd(cmd)
180        if result is None:
181            return False;
182        return True;
183
184    def check_display_status(self):
185        """ try to confirm that current box connected to a display
186        which supports cec feature.
187        @return: current display power status
188        """
189        cmd = CEC_COMMAND + CEC_CMD_DISP_STATUS
190        result = self._shcmd(cmd).stdout
191        status = re.findall('int32 \\d', result)
192        for s in status:
193            code = int(s[-1]);
194            if code == STATUS_ON or code == STATUS_TO_ON:
195                return STATUS_ON
196            if code == STATUS_OFF or code == STATUS_TO_OFF:
197                return STATUS_OFF
198        return STATUS_ERROR
199
200    def display_on(self):
201        """ send a power turn on cec message """
202        self._shcmd(CEC_COMMAND + CEC_CMD_IMAGEON)
203
204    def display_off(self):
205        """ send a power turn off cec message"""
206        self._shcmd(CEC_COMMAND + CEC_CMD_STANDBY)
207
208    def test_turn_on(self):
209        """ test sending turn_on cec message process. """
210        self.display_on()
211        if not self.chameleon_mode:
212            time.sleep(10)
213        status = self.check_display_status()
214        if STATUS_ON != status:
215            self.cec_cleanup()
216            raise error.TestFail("CEC display image on does not work.")
217
218    def test_turn_off(self):
219        """ test sending turn_off cec message process. """
220        self.display_off()
221        if not self.chameleon_mode:
222            time.sleep(1)
223        status = self.check_display_status()
224        if STATUS_OFF != status:
225            self.cec_cleanup()
226            raise error.TestFail("CEC display standby does not work.")
227