1#!/usr/bin/env python3.4
2#
3#   Copyright 2016 - Google
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"""
17    Test Script for Telephony Pre Flight check.
18"""
19
20from acts import signals
21from acts import utils
22
23from acts.controllers.android_device import get_info
24from acts.libs.ota import ota_updater
25from acts.test_decorators import test_tracker_info
26from acts.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
27from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
28from acts.test_utils.tel.tel_defines import RAT_FAMILY_WLAN
29from acts.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
30from acts.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
31from acts.test_utils.tel.tel_test_utils import abort_all_tests
32from acts.test_utils.tel.tel_test_utils import call_setup_teardown
33from acts.test_utils.tel.tel_test_utils import ensure_phones_default_state
34from acts.test_utils.tel.tel_test_utils import ensure_phone_subscription
35from acts.test_utils.tel.tel_test_utils import ensure_wifi_connected
36from acts.test_utils.tel.tel_test_utils import get_user_config_profile
37from acts.test_utils.tel.tel_test_utils import is_sim_locked
38from acts.test_utils.tel.tel_test_utils import multithread_func
39from acts.test_utils.tel.tel_test_utils import unlock_sim
40from acts.test_utils.tel.tel_test_utils import verify_internet_connection
41from acts.test_utils.tel.tel_test_utils import wait_for_network_rat
42from acts.test_utils.tel.tel_test_utils import wait_for_wfc_enabled
43from acts.test_utils.tel.tel_test_utils import wait_for_wifi_data_connection
44from acts.test_utils.tel.tel_test_utils import wifi_toggle_state
45from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
46from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
47from acts.test_utils.tel.tel_voice_utils import phone_setup_iwlan
48from acts.test_utils.tel.tel_voice_utils import phone_setup_iwlan_cellular_preferred
49
50
51class TelLivePreflightTest(TelephonyBaseTest):
52    def setup_class(self):
53        super().setup_class()
54        self.user_params["telephony_auto_rerun"] = 0
55
56    def _check_wfc_enabled(self, ad):
57        if not wait_for_wifi_data_connection(self.log, ad, True):
58            ad.log.error("Failed to connect to WIFI")
59            return False
60        if not wait_for_wfc_enabled(self.log, ad):
61            ad.log.error("WFC is not enabled")
62            return False
63        if not wait_for_network_rat(
64                self.log, ad, RAT_FAMILY_WLAN,
65                voice_or_data=NETWORK_SERVICE_DATA):
66            ad.log.info("Data rat can not go to iwlan mode successfully")
67            return False
68        return True
69
70    def _get_call_verification_function(self, ad):
71        user_profile = get_user_config_profile(ad)
72        if user_profile.get("WFC Enabled", False):
73            return is_phone_in_call_iwlan
74        if user_profile.get("VoLTE Enabled", False):
75            return is_phone_in_call_volte
76        return None
77
78    def _set_user_profile_before_ota(self):
79        ad = self.android_devices[0]
80        if not phone_setup_iwlan_cellular_preferred(
81                self.log, ad, self.wifi_network_ssid, self.wifi_network_pass):
82            ad.log.error("Failed to setup WFC to %s.",
83                         WFC_MODE_CELLULAR_PREFERRED)
84        if len(self.android_devices) > 1:
85            ad = self.android_devices[1]
86            if not phone_setup_iwlan(
87                    self.log, ad, True, WFC_MODE_WIFI_PREFERRED,
88                    self.wifi_network_ssid, self.wifi_network_pass):
89                ad.log.error("Failed to setup WFC to %s.",
90                             WFC_MODE_WIFI_PREFERRED)
91
92        if ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform():
93            ad.droid.imsSetEnhanced4gMode(False)
94            state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser()
95            ad.log.info("Enhanced 4G LTE Setting is %s", "on"
96                        if state else "off")
97            if state:
98                ad.log.error("Expecting Enhanced 4G LTE Setting off")
99
100    def _ota_upgrade(self, ad):
101        result = True
102        self._set_user_profile_before_ota()
103        config_profile_before = get_user_config_profile(ad)
104        ad.log.info("Before OTA user config is: %s", config_profile_before)
105        try:
106            ota_updater.update(ad)
107        except Exception as e:
108            ad.log.error("OTA upgrade failed with %s", e)
109            raise
110        if is_sim_locked(ad):
111            ad.log.info("After OTA, SIM keeps the locked state")
112        elif getattr(ad, "is_sim_locked", False):
113            ad.log.error("After OTA, SIM loses the locked state")
114            result = False
115        if not unlock_sim(ad):
116            ad.log.error(ad.log, "unable to unlock SIM")
117        if not ad.droid.connectivityCheckAirplaneMode():
118            if not ensure_phone_subscription(self.log, ad):
119                ad.log.error("Subscription check failed")
120                result = False
121        if config_profile_before.get("WFC Enabled", False):
122            self._check_wfc_enabled(ad)
123            result = False
124        config_profile_after = get_user_config_profile(ad)
125        ad.log.info("After OTA user config is: %s", config_profile_after)
126        if config_profile_before != config_profile_after:
127            ad.log.error("Before: %s, After: %s", config_profile_before,
128                         config_profile_after)
129            ad.log.error("User config profile changed after OTA")
130            result = False
131        return result
132
133    """ Tests Begin """
134
135    @test_tracker_info(uuid="cb897221-99e1-4697-927e-02d92d969440")
136    @TelephonyBaseTest.tel_test_wrap
137    def test_ota_upgrade(self):
138        ota_package = self.user_params.get("ota_package")
139        if isinstance(ota_package, list):
140            ota_package = ota_package[0]
141        if ota_package and "dev/null" not in ota_package:
142            self.log.info("Upgrade with ota_package %s", ota_package)
143            self.log.info("Before OTA upgrade: %s",
144                          get_info(self.android_devices))
145        else:
146            raise signals.TestSkip("No ota_package is defined")
147        ota_util = self.user_params.get("ota_util")
148        if isinstance(ota_util, list):
149            ota_util = ota_util[0]
150        if ota_util:
151            if "update_engine_client.zip" in ota_util:
152                self.user_params["UpdateDeviceOtaTool"] = ota_util
153                self.user_params["ota_tool"] = "UpdateDeviceOtaTool"
154            else:
155                self.user_params["AdbSideloadOtaTool"] = ota_util
156                self.user_params["ota_tool"] = "AdbSideloadOtaTool"
157        self.log.info("OTA upgrade with %s by %s", ota_package,
158                      self.user_params["ota_tool"])
159        ota_updater.initialize(self.user_params, self.android_devices)
160        tasks = [(self._ota_upgrade, [ad]) for ad in self.android_devices]
161        try:
162            result = multithread_func(self.log, tasks)
163        except Exception as err:
164            abort_all_tests(self.log, "Unable to do ota upgrade: %s" % err)
165        device_info = get_info(self.android_devices)
166        self.log.info("After OTA upgrade: %s", device_info)
167        self.results.add_controller_info("AndroidDevice", device_info)
168        if len(self.android_devices) > 1:
169            caller = self.android_devices[0]
170            callee = self.android_devices[1]
171            return call_setup_teardown(
172                self.log, caller, callee, caller,
173                self._get_call_verification_function(caller),
174                self._get_call_verification_function(callee)) and result
175        return result
176
177    @test_tracker_info(uuid="8390a2eb-a744-4cda-bade-f94a2cc83f02")
178    @TelephonyBaseTest.tel_test_wrap
179    def test_check_environment(self):
180        ad = self.android_devices[0]
181        # Check WiFi environment.
182        # 1. Connect to WiFi.
183        # 2. Check WiFi have Internet access.
184        try:
185            if not ensure_wifi_connected(self.log, ad, self.wifi_network_ssid,
186                                         self.wifi_network_pass):
187                abort_all_tests(ad.log, "WiFi connect fail")
188            if (not wait_for_wifi_data_connection(self.log, ad, True)
189                    or not verify_internet_connection(self.log, ad)):
190                abort_all_tests(ad.log, "Data not available on WiFi")
191        finally:
192            wifi_toggle_state(self.log, ad, False)
193        # TODO: add more environment check here.
194        return True
195
196    @test_tracker_info(uuid="7bb23ac7-6b7b-4d5e-b8d6-9dd10032b9ad")
197    @TelephonyBaseTest.tel_test_wrap
198    def test_pre_flight_check(self):
199        return ensure_phones_default_state(self.log, self.android_devices)
200
201    @test_tracker_info(uuid="1070b160-902b-43bf-92a0-92cc2d05bb13")
202    @TelephonyBaseTest.tel_test_wrap
203    def test_check_crash(self):
204        result = True
205        begin_time = None
206        for ad in self.android_devices:
207            output = ad.adb.shell("cat /proc/uptime")
208            epoch_up_time = utils.get_current_epoch_time() - 1000 * float(
209                output.split(" ")[0])
210            ad.crash_report_preflight = ad.check_crash_report(
211                self.test_name,
212                begin_time=epoch_up_time,
213                log_crash_report=True)
214            if ad.crash_report_preflight:
215                msg = "Find crash reports %s before test starts" % (
216                    ad.crash_report_preflight)
217                ad.log.warn(msg)
218                result = False
219        return result
220