blob: 6adddcde434c12de596470875178822f4d58cc02 [file] [log] [blame]
# Copyright 2013 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 LICENSE file.
"""Probes SIM card tray
Detects SIM card tray by GPIO.
Args:
tray_already_present:SIM card tray is in machine before test starts.
tray_detection_gpio: SIM card tray detection gpio number.
"""
import logging
import os
import factory_common # pylint: disable=unused-import
from cros.factory.test.i18n import _
from cros.factory.test import session
from cros.factory.test import test_case
from cros.factory.utils.arg_utils import Arg
from cros.factory.utils import file_utils
from cros.factory.utils import type_utils
_INSERT_CHECK_PERIOD_SECS = 1
_GPIO_PATH = '/sys/class/gpio'
_TrayState = type_utils.Enum(['INSERTED', 'REMOVED'])
class ProbeTrayException(Exception):
pass
class ProbeSimCardTrayTest(test_case.TestCase):
"""Test to probe sim card tray.
Usage examples:
1.Just check presence or absence:
tray_already_present=True/False
2.Ask user to insert tray:
tray_already_present=False,
insert=True,
only_check_presence=False
3.Ask user to remove tray:
tray_already_present=True,
remove=True,
only_check_presence=False
4.Ask user to insert then remove tray.
tray_already_present=False,
insert=True,
remove=True,
only_check_presence=False
5.Ask user to remove then insert tray.
tray_already_present=True,
insert=True,
remove=True,
only_check_presence=False
"""
ARGS = [
Arg('timeout_secs', int,
'timeout in seconds for insertion/removal', default=10),
Arg('tray_already_present', bool,
'SIM card tray is in machine before test starts', default=False),
Arg('tray_detection_gpio', int,
'SIM card tray detection gpio number', default=159),
Arg('insert', bool, 'Check sim card tray insertion', default=False),
Arg('remove', bool, 'Check sim card tray removal', default=False),
Arg('only_check_presence', bool,
'Only checks sim card tray presence matches tray_already_present. '
'No user interaction required', default=True),
Arg('gpio_active_high', bool, 'Whether GPIO is active high.',
default=True)]
def setUp(self):
self._detection_gpio_path = os.path.join(
_GPIO_PATH, 'gpio%d' % self.args.tray_detection_gpio)
def runTest(self):
self.ExportGPIO()
self.CheckPresence()
if self.args.only_check_presence:
return
self.ui.StartFailingCountdownTimer(self.args.timeout_secs)
if self.args.tray_already_present:
self.assertTrue(self.args.remove, 'Must set remove to Ture '
'since tray_already_present is True')
self.WaitTrayRemoved()
if self.args.insert:
self.WaitTrayInserted()
else:
self.assertTrue(self.args.insert, 'Must set insert to Ture '
'since tray_already_present is False')
self.WaitTrayInserted()
if self.args.remove:
self.WaitTrayRemoved()
def ExportGPIO(self):
"""Exports GPIO of tray detection pin.
Raises:
ProbeTrayException if gpio can not be exported.
"""
if os.path.exists(self._detection_gpio_path):
logging.info('gpio %s was exported before', self._detection_gpio_path)
return
export_path = os.path.join(_GPIO_PATH, 'export')
try:
file_utils.WriteFile(export_path, str(self.args.tray_detection_gpio),
log=True)
except IOError:
logging.exception('Can not write %s into %s',
self.args.tray_detection_gpio, export_path)
raise ProbeTrayException('Can not export detection gpio %s' %
self.args.tray_detection_gpio)
direction_path = os.path.join(self._detection_gpio_path, 'direction')
try:
file_utils.WriteFile(direction_path, 'out', log=True)
except IOError:
logging.exception('Can not write "out" into %s', direction_path)
raise ProbeTrayException('Can set detection gpio direction to out')
def GetDetection(self):
"""Returns tray status _TrayState.INSERTED or _TrayState.REMOVED."""
value_path = os.path.join(self._detection_gpio_path, 'value')
lines = file_utils.ReadLines(value_path)
if not lines:
raise ProbeTrayException('Can not get detection result from %s' %
value_path)
ret = lines[0].strip()
if ret not in ['0', '1']:
raise ProbeTrayException('Get invalid detection %s from %s' %
(ret, value_path))
if self.args.gpio_active_high:
return _TrayState.INSERTED if ret == '1' else _TrayState.REMOVED
else:
return _TrayState.INSERTED if ret == '0' else _TrayState.REMOVED
def CheckPresence(self):
self.assertEquals(
self.args.tray_already_present,
self.GetDetection() == _TrayState.INSERTED,
('Unexpected tray %s. Please %s SIM card tray and retest.' %
(('absence', 'insert')
if self.args.tray_already_present else ('presence', 'remove'))))
def WaitTrayInserted(self):
self.ui.SetState(_('Please insert the SIM card tray'))
self.WaitTrayState(_TrayState.INSERTED)
def WaitTrayRemoved(self):
self.ui.SetState(_('Detected! Please remove the SIM card tray'))
self.WaitTrayState(_TrayState.REMOVED)
def WaitTrayState(self, state):
logging.info('wait for %s event', state)
while True:
if self.GetDetection() == state:
logging.info('%s detected', state)
session.console.info('%s detected', state)
return
self.Sleep(_INSERT_CHECK_PERIOD_SECS)