1# Copyright (c) 2010 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 LICENSE file.
4import logging
5
6from autotest_lib.client.bin import test
7from autotest_lib.client.common_lib import error
8from autotest_lib.client.cros import power_utils, service_stopper
9
10
11class hardware_Backlight(test.test):
12    version = 1
13
14    def initialize(self):
15        """Perform necessary initialization prior to test run.
16
17        Private Attributes:
18          _backlight: power_utils.Backlight object
19          _services: service_stopper.ServiceStopper object
20        """
21        super(hardware_Backlight, self).initialize()
22        self._backlight = None
23        # Stop powerd to avoid it adjusting backlight levels
24        self._services = service_stopper.ServiceStopper(['powerd'])
25        self._services.stop_services()
26
27
28    def run_once(self):
29        # optionally test keyboard backlight
30        kblight = None
31        kblight_errs = 0
32        try:
33            kblight = power_utils.KbdBacklight()
34        except power_utils.KbdBacklightException as e:
35            logging.info("Assuming no keyboard backlight due to %s", str(e))
36
37        if kblight:
38            init_percent = kblight.get_percent()
39            try:
40                for i in xrange(100, -1, -1):
41                    kblight.set_percent(i)
42                    result = int(kblight.get_percent())
43                    if i != result:
44                        logging.error('keyboard backlight set %d != %d get',
45                                      i, result)
46                        kblight_errs += 1
47            finally:
48                kblight.set_percent(init_percent)
49
50        if kblight_errs:
51            raise error.TestFail("%d errors testing keyboard backlight." % \
52                                 kblight_errs)
53
54        self._backlight = power_utils.Backlight()
55        backlight_errs = 0
56        backlight_max = self._backlight.get_max_level()
57        for i in xrange(backlight_max + 1):
58            self._backlight.set_level(i)
59            result = self._backlight.get_level()
60            if i != result:
61                # The kernel Documentation/ABI/stable/sysfs-class-backlight
62                # states that the requested brightness may not be the
63                # actual_brightness.
64                # Although not specified in the docs, let's allow the difference
65                # between requested brightness and actual_brightness percent be
66                # within a tolerance of 1 of each other.
67                actual_percent = self._backlight.get_percent()
68                expected_percent = float(i) / float(backlight_max) * 100.0
69                diff_percent = abs(actual_percent - expected_percent)
70                log_level_func = logging.warn
71                if diff_percent > 1:
72                    backlight_errs += 1
73                    log_level_func = logging.error
74                    log_level_func('backlight expected vs. actual exceeds error'
75                                   'tolerance')
76                log_level_func('backlight set %d != %d get', i, result)
77                log_level_func('backlight percent difference is %f%%',
78                               diff_percent)
79
80        if backlight_errs:
81            raise error.TestFail("%d errors testing backlight." % \
82                                 backlight_errs)
83
84
85    def cleanup(self):
86        if self._backlight:
87            self._backlight.restore()
88        self._services.restore_services()
89        super(hardware_Backlight, self).cleanup()
90