1# Copyright 2016 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.
4
5import logging
6import time
7
8from autotest_lib.client.common_lib import error
9from autotest_lib.server.cros.cfm import cfm_base_test
10
11_SHORT_TIMEOUT = 5
12
13_CAMERA = 'Camera'
14_MICROPHONE = 'Microphone'
15_SPEAKER = 'Speaker'
16
17
18class enterprise_CFM_USBPeripheralHotplugStress(cfm_base_test.CfmBaseTest):
19    """
20    Uses servo to hotplug and unplug USB peripherals multiple times and
21    verify's that the hotrod app appropriately detects the peripherals using
22    app api's.
23    """
24    version = 1
25
26
27    def _set_hub_power(self, on=True):
28        """
29        Setting USB hub power status
30
31        @param on: To power on the servo usb hub or not.
32        """
33        # To power on the hub means to turn reset off.
34        if on:
35            self._host.servo.set('dut_hub1_rst1', 'off')
36        else:
37            self._host.servo.set('dut_hub1_rst1', 'on')
38        time.sleep(_SHORT_TIMEOUT)
39
40
41    def _set_preferred_peripheral(self, peripheral_dict):
42        """
43        Set perferred peripherals.
44
45        @param peripheral_dict: Dictionary of peripherals.
46        """
47        avail_mics = self.cfm_facade.get_mic_devices()
48        avail_speakers = self.cfm_facade.get_speaker_devices()
49        avail_cameras = self.cfm_facade.get_camera_devices()
50
51        if peripheral_dict.get(_MICROPHONE) in avail_mics:
52            self.cfm_facade.set_preferred_mic(
53                    peripheral_dict.get(_MICROPHONE))
54        if peripheral_dict.get(_SPEAKER) in avail_speakers:
55            self.cfm_facade.set_preferred_speaker(
56                    peripheral_dict.get(_SPEAKER))
57        if peripheral_dict.get(_CAMERA) in avail_cameras:
58            self.cfm_facade.set_preferred_camera(
59                    peripheral_dict.get(_CAMERA))
60
61
62    def _check_peripheral(self, device_type, hub_on, peripheral_dict,
63                          get_preferred, get_all):
64        """
65        Checks a connected peripheral depending on the usb hub state.
66
67        @param device_type: The type of the peripheral.
68        @param hub_on: wheter the USB hub is on or off.
69        @param peripheral_dict: A dictionary of connected peripherals, keyed
70            by type.
71        @param get_preferred: Function that gets the prefered device for the
72            specified type. Prefered means the CfM selects that device as active
73            even if other devices of the same type are conncted to it
74            (e.g. multiple cameras).
75        @param get_all: Function that gets all conncted devices for the
76            specified type.
77        """
78        device_name = peripheral_dict.get(device_type)
79        prefered_peripheral = get_preferred()
80        avail_devices = get_all()
81
82        if hub_on:
83            if device_name != prefered_peripheral:
84                raise error.TestFail('%s not detected.' % device_type)
85        else:
86            if device_name == prefered_peripheral:
87                raise error.TestFail('%s should not be detected.' % device_type)
88
89        if avail_devices:
90            if prefered_peripheral is None:
91                raise error.TestFail('Available %s not selected.' % device_type)
92            if ((not hub_on and device_name != prefered_peripheral) and
93                (prefered_peripheral not in avail_devices)):
94                raise error.TestFail('Available %s not selected.' % device_type)
95
96        if hub_on:
97            logging.info("[SUCCESS] %s has been detected.", device_type)
98        else:
99            logging.info("[SUCCESS] %s has not been detected.", device_type)
100
101
102    def _check_peripherals(self, peripheral_dict, hub_on):
103        """
104        Sets the hub power and verifies the visibility of peripherals.
105
106        @param peripheral_dict: Dictionary of peripherals to check.
107        @param hub_on: To turn the USB hub on or off.
108        """
109        self._set_hub_power(hub_on)
110
111        if _MICROPHONE in peripheral_dict:
112            self._check_peripheral(
113                _MICROPHONE,
114                hub_on,
115                peripheral_dict,
116                self.cfm_facade.get_preferred_mic,
117                self.cfm_facade.get_mic_devices)
118
119        if _SPEAKER in peripheral_dict:
120            self._check_peripheral(
121                _SPEAKER,
122                hub_on,
123                peripheral_dict,
124                self.cfm_facade.get_preferred_speaker,
125                self.cfm_facade.get_speaker_devices)
126
127        if _CAMERA in peripheral_dict:
128            self._check_peripheral(
129                _CAMERA,
130                hub_on,
131                peripheral_dict,
132                self.cfm_facade.get_preferred_camera,
133                self.cfm_facade.get_camera_devices)
134
135
136    def run_once(self, repeat, peripheral_whitelist_dict):
137        """
138        Main function to run autotest.
139
140        @param repeat: Number of times peripheral should be hotplugged.
141        @param peripheral_whitelist_dict: Dictionary of peripherals to test.
142        """
143        self.cfm_facade.wait_for_hangouts_telemetry_commands()
144        self._set_preferred_peripheral(peripheral_whitelist_dict)
145        for _ in xrange(repeat):
146            # Plug out.
147            self._check_peripherals(peripheral_whitelist_dict, False)
148            # Plug in.
149            self._check_peripherals(peripheral_whitelist_dict, True)
150