1# Lint as: python2, python3 2# Copyright 2021 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import abc 7import logging 8import six 9 10 11@six.add_metaclass(abc.ABCMeta) 12class _BaseMenuNavigator: 13 """Abstract base class for menu navigator.""" 14 15 def __init__(self, test): 16 self.test = test 17 self.faft_config = self.test.faft_config 18 self.servo = self.test.servo 19 20 @abc.abstractmethod 21 def up(self): 22 """Navigate up in the menu.""" 23 raise NotImplementedError 24 25 @abc.abstractmethod 26 def down(self): 27 """Navigate down in the menu.""" 28 raise NotImplementedError 29 30 @abc.abstractmethod 31 def select(self, msg=None): 32 """Select a menu item.""" 33 raise NotImplementedError 34 35 def move_to(self, from_idx, to_idx): 36 """Move from 'from_idx' to 'to_idx' by menu up/down.""" 37 if from_idx > to_idx: 38 for _ in range(from_idx, to_idx, -1): 39 self.up() 40 self.test.wait_for('keypress_delay') 41 elif from_idx < to_idx: 42 for _ in range(from_idx, to_idx, 1): 43 self.down() 44 self.test.wait_for('keypress_delay') 45 46 47class _KeyboardMenuNavigator(_BaseMenuNavigator): 48 """Navigate with arrow and function keys.""" 49 50 def up(self): 51 """Navigate up in the menu.""" 52 self.servo.arrow_up() 53 54 def down(self): 55 """Navigate down in the menu.""" 56 self.servo.arrow_down() 57 58 def select(self, msg=None): 59 """Select a menu item.""" 60 if msg: 61 logging.info(msg) 62 self.servo.enter_key() 63 64 65class _DetachableMenuNavigator(_BaseMenuNavigator): 66 """Navigate with physical buttons for tablet or detachable devices.""" 67 68 def up(self): 69 """Navigate up in the menu.""" 70 self.servo.set_nocheck('volume_up_hold', 100) 71 72 def down(self): 73 """Navigate down in the menu.""" 74 self.servo.set_nocheck('volume_down_hold', 100) 75 76 def select(self, msg=None): 77 """Select a menu item.""" 78 if msg: 79 logging.info(msg) 80 self.servo.power_short_press() 81 82 83def create_menu_navigator(faft_framework): 84 """Create a proper navigator based on whether or not it is detachable""" 85 if faft_framework.faft_config.is_detachable: 86 return _DetachableMenuNavigator(faft_framework) 87 else: 88 return _KeyboardMenuNavigator(faft_framework) 89