| # Copyright 2018 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LISENCE file. |
| |
| import logging |
| import re |
| import os |
| import time |
| |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.server import test |
| |
| CEC_COMMAND = "sudo -u chronos dbus-send --system --print-reply \ |
| --type=method_call --dest=org.chromium.CecService \ |
| /org/chromium/CecService org.chromium.CecService." |
| CEC_CMD_STANDBY = "SendStandByToAllDevices" |
| CEC_CMD_IMAGEON = "SendWakeUpToAllDevices" |
| CEC_CMD_DISP_STATUS = "GetTvsPowerStatus" |
| |
| CHAMELEON_ROOT = '/home/root/' |
| |
| STATUS_ERROR = 0 |
| STATUS_ON = 3 |
| STATUS_OFF = 4 |
| STATUS_TO_ON = 5 |
| STATUS_TO_OFF = 6 |
| |
| class enterprise_CFM_CEC(test.test): |
| """ |
| Test CEC feature for display power control. |
| """ |
| |
| version = 1 |
| # TODO: how to get whether it connects to chameleon board |
| chameleon_mode = True |
| |
| def initialize(self): |
| """ initialize is a stub function.""" |
| pass |
| |
| # Simply run a command in machine and return result messages. |
| def _shcmd(self, cmd): |
| """ A simple wrapper for remote shell command execution. |
| @param cmd: shell command for Fizz |
| """ |
| logging.info('CMD: [%s]', cmd) |
| try: |
| result = self._client.run(cmd) |
| if result is None: |
| return result |
| if result.stderr: |
| logging.info('CMD ERR:\n' + result.stderr) |
| logging.info('CMD OUT:\n' + result.stdout) |
| return result |
| except Exception as e: |
| logging.info('run command failed. ' + str(e)) |
| |
| def run_once(self, host=None): |
| """ |
| Test scenario: |
| |
| If system does not support cec port, we simply throw an exception. |
| |
| Generally we are using the build-in cecservice for this test. This |
| service supports multiple features including turning TV(display) |
| power on/off and monitor its power status. |
| |
| Following is test plan: |
| 0.0 Copy two python files to chameleon |
| 0.1 enable chameleon as hdmi mode |
| 0.2 run cec service on chameleon |
| |
| 0.3 Make sure chrome box is running cecservice |
| 0.4 Make sure chrome box's /dev/cecX is open |
| 0.5 Run TV power status to check configuration correct |
| (end of step 0) |
| |
| |
| 1.0 Send TV turn-off command |
| 1.1 Check TV power status to check whether it is off. |
| (end of step 1) |
| |
| 2.0 Send TV turn-on command |
| 2.1 Check TV power status to check whether it is on. |
| (end of step 2) |
| At every end of step, we have to decide whether we stop this test |
| right now or continue next ones. |
| Note that we could turn on TV first and then turn off it, |
| according to its initial power status. |
| |
| 3.0 Stop cec service on chameleon |
| 3.1 Remove python files from chameleon |
| |
| @param host: host object machine. |
| """ |
| |
| self._client = host |
| self.chameleon = host.chameleon |
| |
| ## TODO check same port |
| #Step 0.0 - 0.2 |
| self.copy_cecservice() |
| self.cec_service_init() |
| |
| |
| # Step 0.3 - 0.5 |
| if not self.is_cecservice_running(): |
| self.cec_cleanup() |
| raise error.TestFail("CEC service is not running.") |
| if not self.is_cec_available(): |
| self.cec_cleanup() |
| raise error.TestFail("/dev/cecX port is not open.") |
| status = self.check_display_status() |
| if STATUS_ERROR == status: |
| self.cec_cleanup() |
| raise error.TestFail("CEC communication is not good.") |
| |
| # Step 1 & 2 |
| if STATUS_ON == status: |
| self.test_turn_off() |
| if not self.chameleon_mode: |
| time.sleep(5) |
| self.test_turn_on() |
| else: |
| self.test_turn_on() |
| if not self.chameleon_mode: |
| time.sleep(5) |
| self.test_turn_off() |
| |
| # Step 3 |
| self.cec_cleanup() |
| |
| # Chameleon |
| def copy_cecservice(self): |
| """ copy python files under ./chameleon_cecservice to chameleon. |
| In that folder, we have two files for cecservice. |
| """ |
| current_dir = os.path.dirname(os.path.realpath(__file__)) |
| base_dir = current_dir + '/chameleon_cecservice/' |
| self.chameleon.host.send_file(base_dir + 'cec_service', CHAMELEON_ROOT) |
| self.chameleon.host.send_file(base_dir + 'it6803.py', CHAMELEON_ROOT) |
| |
| def cec_service_init(self): |
| """ Setup chameleon board as a hdmi mode. |
| Run cec service on chameleon |
| """ |
| self.chameleon.host.run('/home/root/setup hdmi') |
| self.chameleon.host.run('(/home/root/cec_service start) '\ |
| '</dev/null >/dev/null 2>&1 & echo -n $!') |
| |
| def cec_cleanup(self): |
| """ Stop cec service on chameleon. |
| Delete files new coming on chameleon. |
| """ |
| if self.chameleon_mode: |
| stop_cmd = 'kill $(ps | grep \'cec_service\' | awk \'{print $1}\')' |
| self.chameleon.host.run(stop_cmd) |
| cleanup_cmd = 'rm /home/root/cec_service /home/root/it6803*' |
| self.chameleon.host.run(cleanup_cmd) |
| |
| # Fizz |
| def is_cecservice_running(self): |
| """ try to confirm that current box is running cecservice. |
| @return: whether cecservice is running in Fizz. |
| """ |
| cmd = 'initctl list | grep cecservice' |
| result = self._shcmd(cmd) |
| if result is None: |
| return False; |
| if "running" not in result.stdout: |
| return False; |
| return True; |
| |
| def is_cec_available(self): |
| """ try to get whether the system makes /dev/cecX open. |
| @return: whether /dev/cecX is open in Fizz |
| """ |
| cmd = "ls /dev/cec*" |
| result = self._shcmd(cmd) |
| if result is None: |
| return False; |
| return True; |
| |
| def check_display_status(self): |
| """ try to confirm that current box connected to a display |
| which supports cec feature. |
| @return: current display power status |
| """ |
| cmd = CEC_COMMAND + CEC_CMD_DISP_STATUS |
| result = self._shcmd(cmd).stdout |
| status = re.findall('int32 \\d', result) |
| for s in status: |
| code = int(s[-1]); |
| if code == STATUS_ON or code == STATUS_TO_ON: |
| return STATUS_ON |
| if code == STATUS_OFF or code == STATUS_TO_OFF: |
| return STATUS_OFF |
| return STATUS_ERROR |
| |
| def display_on(self): |
| """ send a power turn on cec message """ |
| self._shcmd(CEC_COMMAND + CEC_CMD_IMAGEON) |
| |
| def display_off(self): |
| """ send a power turn off cec message""" |
| self._shcmd(CEC_COMMAND + CEC_CMD_STANDBY) |
| |
| def test_turn_on(self): |
| """ test sending turn_on cec message process. """ |
| self.display_on() |
| if not self.chameleon_mode: |
| time.sleep(10) |
| status = self.check_display_status() |
| if STATUS_ON != status: |
| self.cec_cleanup() |
| raise error.TestFail("CEC display image on does not work.") |
| |
| def test_turn_off(self): |
| """ test sending turn_off cec message process. """ |
| self.display_off() |
| if not self.chameleon_mode: |
| time.sleep(1) |
| status = self.check_display_status() |
| if STATUS_OFF != status: |
| self.cec_cleanup() |
| raise error.TestFail("CEC display standby does not work.") |