1# Copyright 2014 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.client.cros.networking.chrome_testing import test_utils
10
11class ChromeNetworkProvider(object):
12    """
13    ChromeNetworkProvider handles all calls made to the connection
14    manager by internally calling the Networking Private Extension API.
15
16    For Example: Enable/Disable WiFi, Scan WiFi, Connect to WiFi that can
17    be used to develop other tests.
18    """
19
20    WIFI_DEVICE = 'WiFi'
21    CELLULAR = 'Cellular'
22    SHORT_TIMEOUT = 3
23
24
25    def __init__(self, cntc):
26        """Initialization function for this class.
27
28        @param cntc: Instance of type ChromeNetworkingTestContext.
29
30        """
31        self._chrome_testing = cntc
32
33
34    def get_wifi_networks(self):
35        """Get list of available wifi networks.
36
37        @raises error.TestFail if no wifi networks are found.
38        @return List of dictionaries containing wifi network information.
39
40        """
41        wifi_networks = self._chrome_testing.find_wifi_networks()
42        if not wifi_networks:
43            raise error.TestFail('No wifi networks found.')
44
45        return wifi_networks
46
47
48    def get_enabled_devices(self):
49        """Get list of enabled network devices on the device.
50
51        @return List of enabled network devices.
52
53        """
54        enabled_network_types = self._chrome_testing.call_test_function(
55                test_utils.LONG_TIMEOUT,
56                'getEnabledNetworkDevices')
57        for key, value in enabled_network_types.items():
58            if key == 'result':
59                logging.info('Enabled Network Devices: %s', value)
60                return value
61
62
63    def disable_network_device(self, network):
64        """Disable given network device.
65
66        @param network: string name of the network device to be disabled.
67                Options include 'WiFi', 'Cellular' and 'Ethernet'.
68
69        """
70        # Do ChromeOS browser session teardown/setup before disabling the
71        # network device because chrome.networkingPrivate.disableNetworkType API
72        # fails to disable the network device on subsequent calls if we do not
73        # teardown and setup the browser session.
74        self._chrome_testing.teardown()
75        self._chrome_testing.setup()
76
77        logging.info('Disabling: %s', network)
78        disable_network_result = self._chrome_testing.call_test_function_async(
79                'disableNetworkDevice',
80                '"' + network + '"')
81
82
83    def enable_network_device(self, network):
84        """Enable given network device.
85
86        @param network: string name of the network device to be enabled. Options
87                include 'WiFi', 'Cellular' and 'Ethernet'.
88
89        """
90        logging.info('Enabling: %s', network)
91        enable_network_result = self._chrome_testing.call_test_function_async(
92                'enableNetworkDevice',
93                '"' + network + '"')
94        # Allow enough time for the DUT to fully transition into enabled state.
95        time.sleep(self.SHORT_TIMEOUT)
96
97
98    def scan_for_networks(self, timeout=SHORT_TIMEOUT):
99        """Scan for all the available networks
100
101        @param timeout int seconds to sleep while scanning for networks
102
103        """
104        self._chrome_testing.call_test_function_async('requestNetworkScan')
105        # Allow enough time for Chrome to scan and get all the network SSIDs.
106        time.sleep(timeout)
107
108
109    def connect_to_network(self, service_list):
110       """Connects to the given network using networkingPrivate API.
111
112       @param service_list: service list for the network to connect to.
113
114       """
115       connect_status = self._chrome_testing.call_test_function(
116                            test_utils.LONG_TIMEOUT,
117                            'connectToNetwork',
118                            '"' + service_list['GUID'] +'"')
119
120       if connect_status['error'] == 'connected':
121           return
122       elif connect_status['error'] == 'connecting':
123           for retry in range(3):
124               logging.debug('Just hold on for 10 seconds')
125               time.sleep(10)
126               if connect_status['error'] == 'connected':
127                   return
128
129       if connect_status['status'] == 'chrome-test-call-status-failure':
130           raise error.TestFail(
131                     'Could not connect to %s network. Error returned by '
132                     'chrome.networkingPrivate.startConnect API: %s' %
133                     (service_list['Name'], connect_status['error']))
134