1#/usr/bin/env python3.4
2#
3#   Copyright 2016 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16"""
17Sanity tests for voice tests in telephony
18"""
19import time, os
20
21from acts.controllers.anritsu_lib._anritsu_utils import AnritsuError
22from acts.controllers.anritsu_lib.md8475a import MD8475A
23from acts.controllers.anritsu_lib.md8475a import BtsBandwidth
24from acts.test_utils.tel.anritsu_utils import set_system_model_lte
25from acts.test_utils.tel.anritsu_utils import set_usim_parameters
26from acts.test_utils.tel.tel_defines import RAT_FAMILY_LTE
27from acts.test_utils.tel.tel_defines import NETWORK_MODE_LTE_CDMA_EVDO
28from acts.test_utils.tel.tel_defines import NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA
29from acts.test_utils.tel.tel_test_utils import ensure_network_rat
30from acts.test_utils.tel.tel_test_utils import set_phone_screen_on
31from acts.test_utils.tel.tel_test_utils import toggle_volte
32from acts.test_utils.tel.tel_voice_utils import phone_idle_volte
33from acts.test_utils.tel.tel_voice_utils import phone_setup_volte
34from acts.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
35from acts.utils import create_dir
36from acts.utils import disable_doze
37from acts.utils import set_adaptive_brightness
38from acts.utils import set_ambient_display
39from acts.utils import set_auto_rotate
40from acts.utils import set_location_service
41
42DEFAULT_CALL_NUMBER = "+11234567891"
43
44# Monsoon output Voltage in V
45MONSOON_OUTPUT_VOLTAGE = 4.2
46# Monsoon output max current in A
47MONSOON_MAX_CURRENT = 7.8
48
49# Sampling rate in Hz
50ACTIVE_CALL_TEST_SAMPLING_RATE = 100
51# Sample duration in seconds
52ACTIVE_CALL_TEST_SAMPLE_TIME = 10
53# Offset time in seconds
54ACTIVE_CALL_TEST_OFFSET_TIME = 10
55
56
57class TelephonyLabPowerTest(TelephonyBaseTest):
58    def __init__(self, controllers):
59        TelephonyBaseTest.__init__(self, controllers)
60        self.ad = self.android_devices[0]
61        self.ad.sim_card = getattr(self.ad, "sim_card", None)
62        self.md8475a_ip_address = self.user_params[
63            "anritsu_md8475a_ip_address"]
64        self.wlan_option = self.user_params.get("anritsu_wlan_option", False)
65
66    def _configure_dut(self):
67        try:
68            self.log.info("Rebooting DUT")
69            self.ad.reboot()
70            self.log.info("DUT rebooted")
71            set_adaptive_brightness(self.ad, False)
72            set_ambient_display(self.ad, False)
73            set_auto_rotate(self.ad, False)
74            set_location_service(self.ad, False)
75            # This is not needed for AOSP build
76            disable_doze(self.ad)
77            set_phone_screen_on(self.log, self.ad, 15)
78            self.ad.droid.telephonyFactoryReset()
79        except Exception as e:
80            self.ad.log.error(e)
81            return False
82        return True
83
84    def _configure_dut_network_mode_for_data_volte(self):
85        self._configure_dut()
86        try:
87            # TODO do what is needed to verify connected for LTE data transfer
88            self.log.info("setting back to LTE")
89            self.ad.droid.telephonySetPreferredNetworkTypesForSubscription(
90                "NETWORK_MODE_LTE_CDMA_EVDO",
91                self.ad.droid.subscriptionGetDefaultSubId())
92            self.ad.adb.shell(
93                "setprop net.lte.ims.volte.provisioned 1", ignore_status=True)
94        except Exception as e:
95            self.ad.log.error(e)
96            return False
97        return True
98
99    def _configure_simulation(self):
100        try:
101            self.anritsu = MD8475A(self.md8475a_ip_address, self.log,
102                                   self.wlan_option)
103            [lte_bts] = set_system_model_lte(self.anritsu, self.user_params,
104                                             self.ad.sim_card)
105            self.bts = lte_bts
106            lte_bts.bandwidth = BtsBandwidth.LTE_BANDWIDTH_10MHz
107            set_usim_parameters(self.anritsu, self.ad.sim_card)
108            self.anritsu.start_simulation()
109            self.anritsu.send_command("IMSSTARTVN 1")
110        except AnritsuError:
111            self.log.error("Error in connecting to Anritsu Simulator")
112            return False
113        return True
114
115    def _dut_setup_data_volte(self, ad):
116        ad.droid.telephonyToggleDataConnection(True)
117        toggle_volte(self.log, ad, True)
118        return ensure_network_rat(
119            self.log,
120            ad,
121            NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA,
122            RAT_FAMILY_LTE,
123            toggle_apm_after_setting=True)
124
125    def setup_class(self):
126        # Monsoon setup
127        self.log.info("Starting Monsoon setup")
128        self.mon = self.monsoons[0]
129        self.mon.set_voltage(MONSOON_OUTPUT_VOLTAGE)
130        self.mon.set_max_current(MONSOON_MAX_CURRENT)
131        self.mon.dut = self.ad = self.android_devices[0]
132        self.monsoon_log_path = os.path.join(self.log_path, "MonsoonLog")
133        create_dir(self.monsoon_log_path)
134        self.log.info("Conffiguring MD8475A network simulator")
135        self._configure_simulation()
136        self.log.info("Setting DUT's network mode for data and volte")
137        self._configure_dut_network_mode_for_data_volte()
138        self.log.info("Enabling DUT for data and VoLTE")
139        if not self._dut_setup_data_volte(self.ad):
140            self.log.error("phone_setup_volte failed.")
141        self.log.info("Waiting for DUT to register on MD8475A")
142        self.anritsu.wait_for_registration_state()
143        self.log.info("Waiting for DUT to register with IMS server")
144        if not phone_idle_volte(self.log, self.ad):
145            self.log.error("phone_idle_volte failed.")
146
147    def setup_test(self):
148        self.log.info("Bypassing empty setup_test() in TelephonyLabPowerTest")
149
150    def teardown_class(self):
151        self.log.info("Stopping Simulation and disconnect MD8475A")
152        self.anritsu.stop_simulation()
153        self.anritsu.disconnect()
154        return True
155
156    def _save_logs_for_power_test(self, monsoon_result, bug_report):
157        if monsoon_result and "monsoon_log_for_power_test" in self.user_params:
158            monsoon_result.save_to_text_file(
159                [monsoon_result],
160                os.path.join(self.monsoon_log_path, self.test_id))
161        if bug_report and "bug_report_for_power_test" in self.user_params:
162            self.android_devices[0].take_bug_report(self.test_name,
163                                                    self.begin_time)
164
165    def power_test(self,
166                   olvl,
167                   rflvl,
168                   sch_mode="DYNAMIC",
169                   sample_rate=ACTIVE_CALL_TEST_SAMPLING_RATE,
170                   sample_time=ACTIVE_CALL_TEST_SAMPLE_TIME,
171                   offset_time=ACTIVE_CALL_TEST_OFFSET_TIME):
172        """ Set Output(DL)/InputDL(UL) power and scheduling mode of BTS,
173            and samping parameters of Monsoon
174            Args: ovlv: Output (DL) level in dBm
175                  rflvl: Input (UL) level in dBm
176                  sch_mode: Scheduling mode, either "STATIC" or "DYNAMIC"
177                  sample_rate: Sampling rate in Hz
178                  sample_time: Sample duration in seconds
179                  offset_time: Offset time in seconds
180            Return: True if no exception
181        """
182        self.bts.output_level = olvl
183        self.bts.input_level = rflvl
184        self.bts.lte_scheduling_mode = sch_mode
185        bug_report = True
186        average_current = 0
187        result = None
188        self.log.info("Test %s" % self.test_name)
189        try:
190            result = self.mon.measure_power(sample_rate, sample_time,
191                                            self.test_id, offset_time)
192            average_current = result.average_current
193            self._save_logs_for_power_test(result, bug_report)
194            self.log.info("{} Result: {} mA".format(self.test_id,
195                                                    average_current))
196        except Exception as e:
197            self.log.error("Exception during power consumption measurement: " +
198                           str(e))
199            return False
200        return True
201