• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3#   Copyright 2022 - 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
18import logging
19import os
20import time
21import random
22from queue import Empty
23
24from acts.controllers.android_device import SL4A_APK_NAME
25from acts.utils import adb_shell_ping
26from acts.utils import rand_ascii_str
27from acts.utils import disable_doze
28from acts.utils import enable_doze
29from acts.libs.utils.multithread import multithread_func
30from acts.libs.utils.multithread import run_multithread_func
31from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
32from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
33from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
34from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
35from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
36from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_CONNECTED
37from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED
38from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
39from acts_contrib.test_utils.tel.tel_defines import EventConnectivityChanged
40from acts_contrib.test_utils.tel.tel_defines import EventNetworkCallback
41from acts_contrib.test_utils.tel.tel_defines import GEN_5G
42from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE
43from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
44from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
45from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TETHERING_ENTITLEMENT_CHECK
46from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_USER_PLANE_DATA
47from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WIFI_CONNECTION
48from acts_contrib.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_CELL
49from acts_contrib.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_WIFI
50from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
51from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
52from acts_contrib.test_utils.tel.tel_defines import RAT_5G
53from acts_contrib.test_utils.tel.tel_defines import TETHERING_MODE_WIFI
54from acts_contrib.test_utils.tel.tel_defines import TYPE_MOBILE
55from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_AFTER_REBOOT
56from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
57from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_REG_AND_CALL
58from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
59from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING
60from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL
61from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_NW_VALID_FAIL
62from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL_RECOVERY
63from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL_FOR_IMS
64from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_TETHERING_AFTER_REBOOT
65from acts_contrib.test_utils.tel.tel_defines import DataConnectionStateContainer
66from acts_contrib.test_utils.tel.tel_defines import EventDataConnectionStateChanged
67from acts_contrib.test_utils.tel.tel_5g_test_utils import check_current_network_5g
68from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
69from acts_contrib.test_utils.tel.tel_5g_test_utils import verify_5g_attach_for_both_devices
70from acts_contrib.test_utils.tel.tel_ims_utils import is_ims_registered
71from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_ims_registered
72from acts_contrib.test_utils.tel.tel_lookup_tables import connection_type_from_type_string
73from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
74from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation_for_subscription
75from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_idle
76from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
77from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_default_state
78from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
79from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
80from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_on_rat
81from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
82from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_voice_attach_for_subscription
83from acts_contrib.test_utils.tel.tel_test_utils import _check_file_existence
84from acts_contrib.test_utils.tel.tel_test_utils import _generate_file_directory_and_file_name
85from acts_contrib.test_utils.tel.tel_test_utils import _wait_for_droid_in_state
86from acts_contrib.test_utils.tel.tel_test_utils import get_internet_connection_type
87from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat_for_subscription
88from acts_contrib.test_utils.tel.tel_test_utils import get_service_state_by_adb
89from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_network_generation_for_subscription
90from acts_contrib.test_utils.tel.tel_test_utils import is_event_match
91from acts_contrib.test_utils.tel.tel_test_utils import rat_generation_from_rat
92from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
93from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
94from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
95from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
96from acts_contrib.test_utils.tel.tel_test_utils import wait_for_data_attach_for_subscription
97from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state
98from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
99from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
100from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_active
101from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
102from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_short_seq
103from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
104from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G
105from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_SSID_KEY
106from acts_contrib.test_utils.tel.tel_wifi_utils import check_is_wifi_connected
107from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
108from acts_contrib.test_utils.tel.tel_wifi_utils import get_wifi_usage
109from acts_contrib.test_utils.tel.tel_wifi_utils import set_wifi_to_default
110from acts_contrib.test_utils.tel.tel_wifi_utils import start_wifi_tethering
111from acts_contrib.test_utils.tel.tel_wifi_utils import stop_wifi_tethering
112from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_reset
113from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state
114
115
116def wifi_tethering_cleanup(log, provider, client_list):
117    """Clean up steps for WiFi Tethering.
118
119    Make sure provider turn off tethering.
120    Make sure clients reset WiFi and turn on cellular data.
121
122    Args:
123        log: log object.
124        provider: android object provide WiFi tethering.
125        client_list: a list of clients using tethered WiFi.
126
127    Returns:
128        True if no error happened. False otherwise.
129    """
130    for client in client_list:
131        client.droid.telephonyToggleDataConnection(True)
132        set_wifi_to_default(log, client)
133    # If wifi tethering is enabled, disable it.
134    if provider.droid.wifiIsApEnabled() and not stop_wifi_tethering(log, provider):
135        provider.log.error("Provider stop WiFi tethering failed.")
136        return False
137    if provider.droid.wifiIsApEnabled():
138        provider.log.error("Provider WiFi tethering is still enabled.")
139        return False
140    return True
141
142
143def wifi_tethering_setup_teardown(log,
144                                  provider,
145                                  client_list,
146                                  ap_band=WIFI_CONFIG_APBAND_2G,
147                                  check_interval=30,
148                                  check_iteration=4,
149                                  do_cleanup=True,
150                                  ssid=None,
151                                  password=None):
152    """Test WiFi Tethering.
153
154    Turn off WiFi on clients.
155    Turn off data and reset WiFi on clients.
156    Verify no Internet access on clients.
157    Turn on WiFi tethering on provider.
158    Clients connect to provider's WiFI.
159    Verify Internet on provider and clients.
160    Tear down WiFi tethering setup and clean up.
161
162    Args:
163        log: log object.
164        provider: android object provide WiFi tethering.
165        client_list: a list of clients using tethered WiFi.
166        ap_band: setup WiFi tethering on 2G or 5G.
167            This is optional, default value is WIFI_CONFIG_APBAND_2G
168        check_interval: delay time between each around of Internet connection check.
169            This is optional, default value is 30 (seconds).
170        check_iteration: check Internet connection for how many times in total.
171            This is optional, default value is 4 (4 times).
172        do_cleanup: after WiFi tethering test, do clean up to tear down tethering
173            setup or not. This is optional, default value is True.
174        ssid: use this string as WiFi SSID to setup tethered WiFi network.
175            This is optional. Default value is None.
176            If it's None, a random string will be generated.
177        password: use this string as WiFi password to setup tethered WiFi network.
178            This is optional. Default value is None.
179            If it's None, a random string will be generated.
180
181    Returns:
182        True if no error happened. False otherwise.
183    """
184    log.info("--->Start wifi_tethering_setup_teardown<---")
185    log.info("Provider: {}".format(provider.serial))
186    if not provider.droid.connectivityIsTetheringSupported():
187        provider.log.error(
188            "Provider does not support tethering. Stop tethering test.")
189        return False
190
191    if ssid is None:
192        ssid = rand_ascii_str(10)
193    if password is None:
194        password = rand_ascii_str(8)
195
196    # No password
197    if password == "":
198        password = None
199
200    try:
201        for client in client_list:
202            log.info("Client: {}".format(client.serial))
203            wifi_toggle_state(log, client, False)
204            client.droid.telephonyToggleDataConnection(False)
205        log.info("WiFI Tethering: Verify client have no Internet access.")
206        for client in client_list:
207            if not verify_internet_connection(
208                    log, client, expected_state=False):
209                client.log.error("Turn off Data on client fail")
210                return False
211
212        provider.log.info(
213            "Provider turn on WiFi tethering. SSID: %s, password: %s", ssid,
214            password)
215
216        if not start_wifi_tethering(log, provider, ssid, password, ap_band):
217            provider.log.error("Provider start WiFi tethering failed.")
218            return False
219        time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
220
221        provider.log.info("Provider check Internet connection.")
222        if not verify_internet_connection(log, provider):
223            return False
224        for client in client_list:
225            client.log.info(
226                "Client connect to WiFi and verify AP band correct.")
227            if not ensure_wifi_connected(log, client, ssid, password):
228                client.log.error("Client connect to WiFi failed.")
229                return False
230
231            wifi_info = client.droid.wifiGetConnectionInfo()
232            if ap_band == WIFI_CONFIG_APBAND_5G:
233                if wifi_info["is_24ghz"]:
234                    client.log.error("Expected 5g network. WiFi Info: %s",
235                                     wifi_info)
236                    return False
237            else:
238                if wifi_info["is_5ghz"]:
239                    client.log.error("Expected 2g network. WiFi Info: %s",
240                                     wifi_info)
241                    return False
242
243            client.log.info("Client check Internet connection.")
244            if (not wait_for_wifi_data_connection(log, client, True)
245                    or not verify_internet_connection(log, client)):
246                client.log.error("No WiFi Data on client")
247                return False
248
249        if not tethering_check_internet_connection(
250                log, provider, client_list, check_interval, check_iteration):
251            return False
252
253    finally:
254        if (do_cleanup
255                and (not wifi_tethering_cleanup(log, provider, client_list))):
256            return False
257    return True
258
259
260def tethering_check_internet_connection(log, provider, client_list,
261                                        check_interval, check_iteration):
262    """During tethering test, check client(s) and provider Internet connection.
263
264    Do the following for <check_iteration> times:
265        Delay <check_interval> seconds.
266        Check Tethering provider's Internet connection.
267        Check each client's Internet connection.
268
269    Args:
270        log: log object.
271        provider: android object provide WiFi tethering.
272        client_list: a list of clients using tethered WiFi.
273        check_interval: delay time between each around of Internet connection check.
274        check_iteration: check Internet connection for how many times in total.
275
276    Returns:
277        True if no error happened. False otherwise.
278    """
279    for i in range(1, check_iteration + 1):
280        result = True
281        time.sleep(check_interval)
282        provider.log.info(
283            "Provider check Internet connection after %s seconds.",
284            check_interval * i)
285        if not verify_internet_connection(log, provider):
286            result = False
287            continue
288        for client in client_list:
289            client.log.info(
290                "Client check Internet connection after %s seconds.",
291                check_interval * i)
292            if not verify_internet_connection(log, client):
293                result = False
294                break
295        if result: return result
296    return False
297
298
299def wifi_cell_switching(log,
300                        ad,
301                        nw_gen,
302                        wifi_network_ssid=None,
303                        wifi_network_pass=None,
304                        nr_type=None):
305    """Test data connection network switching when phone on <nw_gen>.
306
307    Ensure phone is on <nw_gen>
308    Ensure WiFi can connect to live network,
309    Airplane mode is off, data connection is on, WiFi is on.
310    Turn off WiFi, verify data is on cell and browse to google.com is OK.
311    Turn on WiFi, verify data is on WiFi and browse to google.com is OK.
312    Turn off WiFi, verify data is on cell and browse to google.com is OK.
313
314    Args:
315        log: log object.
316        ad: android object.
317        wifi_network_ssid: ssid for live wifi network.
318        wifi_network_pass: password for live wifi network.
319        nw_gen: network generation the phone should be camped on.
320        nr_type: check NR network.
321
322    Returns:
323        True if pass.
324    """
325    try:
326        if nw_gen == GEN_5G:
327            if not provision_device_for_5g(log, ad, nr_type):
328                return False
329        elif nw_gen:
330            if not ensure_network_generation_for_subscription(
331                    log, ad, get_default_data_sub_id(ad), nw_gen,
332                    MAX_WAIT_TIME_NW_SELECTION, NETWORK_SERVICE_DATA):
333                ad.log.error("Device failed to register in %s", nw_gen)
334                return False
335        else:
336            ad.log.debug("Skipping network generation since it is None")
337
338        start_youtube_video(ad)
339        # Ensure WiFi can connect to live network
340        ad.log.info("Make sure phone can connect to live network by WIFI")
341        if not ensure_wifi_connected(log, ad, wifi_network_ssid,
342                                     wifi_network_pass):
343            ad.log.error("WiFi connect fail.")
344            return False
345        log.info("Phone connected to WIFI.")
346
347        log.info("Step1 Airplane Off, WiFi On, Data On.")
348        toggle_airplane_mode(log, ad, False)
349        wifi_toggle_state(log, ad, True)
350        ad.droid.telephonyToggleDataConnection(True)
351        if (not wait_for_wifi_data_connection(log, ad, True)
352                or not verify_internet_connection(log, ad)):
353            ad.log.error("Data is not on WiFi")
354            return False
355
356        log.info("Step2 WiFi is Off, Data is on Cell.")
357        wifi_toggle_state(log, ad, False)
358        if (not wait_for_cell_data_connection(log, ad, True)
359                or not verify_internet_connection(log, ad)):
360            ad.log.error("Data did not return to cell")
361            return False
362
363        log.info("Step3 WiFi is On, Data is on WiFi.")
364        wifi_toggle_state(log, ad, True)
365        if (not wait_for_wifi_data_connection(log, ad, True)
366                or not verify_internet_connection(log, ad)):
367            ad.log.error("Data did not return to WiFi")
368            return False
369
370        log.info("Step4 WiFi is Off, Data is on Cell.")
371        wifi_toggle_state(log, ad, False)
372        if (not wait_for_cell_data_connection(log, ad, True)
373                or not verify_internet_connection(log, ad)):
374            ad.log.error("Data did not return to cell")
375            return False
376        return True
377
378    finally:
379        ad.force_stop_apk("com.google.android.youtube")
380        wifi_toggle_state(log, ad, False)
381
382
383def airplane_mode_test(log, ad, wifi_ssid=None, retries=3):
384    """ Test airplane mode basic on Phone and Live SIM.
385
386    Test steps:
387        1. Ensure airplane mode is disabled and multiple network services are
388           available. Check WiFi and IMS registration status.
389        2. Turn on airplane mode and ensure cellular data and internet
390           connection are not available.
391        3. Turn off airplane mode and then ensure multiple network services are
392           available. Check if WiFi and IMS registration status keep the same.
393
394    Args:
395        log: log object.
396        ad: android object.
397        wifi_ssid: SSID of WiFi AP which ad should connect to.
398        retries: times of retry
399
400    Returns:
401        True if pass; False if fail.
402    """
403    if not ensure_phones_idle(log, [ad]):
404        log.error("Failed to return phones to idle.")
405        return False
406
407    try:
408        log.info("Step1: disable airplane mode and ensure attach")
409
410        if not toggle_airplane_mode(log, ad, False):
411            ad.log.error("Failed to disable airplane mode,")
412            return False
413
414        wifi_connected = False
415        if wifi_ssid:
416            wifi_connected = check_is_wifi_connected(log, ad, wifi_ssid)
417
418        ims_reg = is_ims_registered(log, ad)
419
420        if not wait_for_network_service(
421            log,
422            ad,
423            wifi_connected=wifi_connected,
424            wifi_ssid=wifi_ssid,
425            ims_reg=ims_reg):
426
427            return False
428
429        log.info("Step2: enable airplane mode and ensure detach")
430        if not toggle_airplane_mode(log, ad, True):
431            ad.log.error("Failed to enable Airplane Mode")
432            return False
433
434        if not wait_for_cell_data_connection(log, ad, False):
435            ad.log.error("Failed to disable cell data connection")
436            return False
437
438        if not verify_internet_connection(log, ad, expected_state=False):
439            ad.log.error("Data available in airplane mode.")
440            return False
441
442        log.info("Step3: disable airplane mode and ensure attach")
443        if not toggle_airplane_mode(log, ad, False):
444            ad.log.error("Failed to disable Airplane Mode")
445            return False
446
447        if not wait_for_network_service(
448            log,
449            ad,
450            wifi_connected=wifi_connected,
451            wifi_ssid=wifi_ssid,
452            ims_reg=ims_reg):
453
454            return False
455
456        return True
457    finally:
458        toggle_airplane_mode(log, ad, False)
459
460
461def data_connectivity_single_bearer(log, ad, nw_gen=None, nr_type=None):
462    """Test data connection: single-bearer (no voice).
463
464    Turn off airplane mode, enable Cellular Data.
465    Ensure phone data generation is expected.
466    Verify Internet.
467    Disable Cellular Data, verify Internet is inaccessible.
468    Enable Cellular Data, verify Internet.
469
470    Args:
471        log: log object.
472        ad: android object.
473        nw_gen: network generation the phone should on.
474        nr_type: NR network type e.g. NSA, SA, MMWAVE
475
476    Returns:
477        True if success.
478        False if failed.
479    """
480    ensure_phones_idle(log, [ad])
481    wait_time = MAX_WAIT_TIME_NW_SELECTION
482    if getattr(ad, 'roaming', False):
483        wait_time = 2 * wait_time
484
485    if nw_gen == GEN_5G:
486        if not provision_device_for_5g(log, ad, nr_type):
487            return False
488    elif nw_gen:
489        if not ensure_network_generation_for_subscription(
490                log, ad, get_default_data_sub_id(ad), nw_gen,
491                MAX_WAIT_TIME_NW_SELECTION, NETWORK_SERVICE_DATA):
492            ad.log.error("Device failed to connect to %s in %s seconds.", nw_gen,
493                         wait_time)
494            return False
495    else:
496        ad.log.debug("Skipping network generation since it is None")
497
498    try:
499        log.info("Step1 Airplane Off, Data On.")
500        toggle_airplane_mode(log, ad, False)
501        ad.droid.telephonyToggleDataConnection(True)
502        if not wait_for_cell_data_connection(log, ad, True, timeout_value=wait_time):
503            ad.log.error("Failed to enable data connection.")
504            return False
505
506        log.info("Step2 Verify internet")
507        if not verify_internet_connection(log, ad, retries=3):
508            ad.log.error("Data not available on cell.")
509            return False
510
511        log.info("Step3 Turn off data and verify not connected.")
512        ad.droid.telephonyToggleDataConnection(False)
513        if not wait_for_cell_data_connection(log, ad, False):
514            ad.log.error("Step3 Failed to disable data connection.")
515            return False
516
517        if not verify_internet_connection(log, ad, expected_state=False):
518            ad.log.error("Step3 Data still available when disabled.")
519            return False
520
521        log.info("Step4 Re-enable data.")
522        ad.droid.telephonyToggleDataConnection(True)
523        if not wait_for_cell_data_connection(log, ad, True, timeout_value=wait_time):
524            ad.log.error("Step4 failed to re-enable data.")
525            return False
526        if not verify_internet_connection(log, ad, retries=3):
527            ad.log.error("Data not available on cell.")
528            return False
529
530        if nw_gen == GEN_5G:
531            if not check_current_network_5g(ad, nr_type=nr_type, timeout=60):
532                return False
533        else:
534            if not is_droid_in_network_generation_for_subscription(
535                    log, ad, get_default_data_sub_id(ad), nw_gen,
536                    NETWORK_SERVICE_DATA):
537                ad.log.error("Failed: droid is no longer on correct network")
538                ad.log.info("Expected:%s, Current:%s", nw_gen,
539                            rat_generation_from_rat(
540                                get_network_rat_for_subscription(
541                                    log, ad, get_default_data_sub_id(ad),
542                                    NETWORK_SERVICE_DATA)))
543                return False
544        return True
545    finally:
546        ad.droid.telephonyToggleDataConnection(True)
547
548
549def change_data_sim_and_verify_data(log, ad, sim_slot):
550    """Change Data SIM and verify Data attach and Internet access
551
552    Args:
553        log: log object.
554        ad: android device object.
555        sim_slot: SIM slot index.
556
557    Returns:
558        Data SIM changed successfully, data attached and Internet access is OK.
559    """
560    sub_id = get_subid_from_slot_index(log, ad, sim_slot)
561    ad.log.info("Change Data to subId: %s, SIM slot: %s", sub_id, sim_slot)
562    set_subid_for_data(ad, sub_id)
563    if not wait_for_data_attach_for_subscription(log, ad, sub_id,
564                                                 MAX_WAIT_TIME_NW_SELECTION):
565        ad.log.error("Failed to attach data on subId:%s", sub_id)
566        return False
567    if not verify_internet_connection(log, ad):
568        ad.log.error("No Internet access after changing Data SIM.")
569        return False
570    return True
571
572
573def browsing_test(log, ad, wifi_ssid=None, pass_threshold_in_mb = 1.0):
574    """ Ramdomly browse 6 among 23 selected web sites. The idle time is used to
575    simulate visit duration and normally distributed with the mean 35 seconds
576    and std dev 15 seconds, which means 95% of visit duration will be between
577    5 and 65 seconds. DUT will enter suspend mode when idle time is greater than
578    35 seconds.
579
580    Args:
581        log: log object.
582        ad: android object.
583        pass_threshold_in_mb: minimum traffic of browsing 6 web sites in MB for
584            test pass
585
586    Returns:
587        True if the total traffic of Chrome for browsing 6 web sites is greater
588        than pass_threshold_in_mb. Otherwise False.
589    """
590    web_sites = [
591        "http://tw.yahoo.com",
592        "http://24h.pchome.com.tw",
593        "http://www.mobile01.com",
594        "https://www.android.com/phones/",
595        "http://www.books.com.tw",
596        "http://www.udn.com.tw",
597        "http://news.baidu.com",
598        "http://www.google.com",
599        "http://www.cnn.com",
600        "http://www.nytimes.com",
601        "http://www.amazon.com",
602        "http://www.wikipedia.com",
603        "http://www.ebay.com",
604        "http://www.youtube.com",
605        "http://espn.go.com",
606        "http://www.sueddeutsche.de",
607        "http://www.bild.de",
608        "http://www.welt.de",
609        "http://www.lefigaro.fr",
610        "http://www.accuweather.com",
611        "https://www.flickr.com",
612        "http://world.taobao.com",
613        "http://www.theguardian.com",
614        "http://www.abc.net.au",
615        "http://www.gumtree.com.au",
616        "http://www.commbank.com.au",
617        "http://www.news.com.au",
618        "http://rakuten.co.jp",
619        "http://livedoor.jp",
620        "http://yahoo.co.jp"]
621
622    wifi_connected = False
623    if wifi_ssid and check_is_wifi_connected(ad.log, ad, wifi_ssid):
624        wifi_connected = True
625        usage_level_at_start = get_wifi_usage(ad, apk="com.android.chrome")
626    else:
627        usage_level_at_start = get_mobile_data_usage(ad, apk="com.android.chrome")
628
629    for web_site in random.sample(web_sites, 6):
630        ad.log.info("Browsing %s..." % web_site)
631        ad.adb.shell(
632            "am start -a android.intent.action.VIEW -d %s --es "
633            "com.android.browser.application_id com.android.browser" % web_site)
634
635        idle_time = round(random.normalvariate(35, 15))
636        if idle_time < 2:
637            idle_time = 2
638        elif idle_time > 90:
639            idle_time = 90
640
641        ad.log.info(
642            "Idle time before browsing next web site: %s sec." % idle_time)
643
644        if idle_time > 35:
645            time.sleep(35)
646            rest_idle_time = idle_time-35
647            if rest_idle_time < 3:
648                rest_idle_time = 3
649            ad.log.info("Let device go to sleep for %s sec." % rest_idle_time)
650            ad.droid.wakeLockRelease()
651            ad.droid.goToSleepNow()
652            time.sleep(rest_idle_time)
653            ad.log.info("Wake up device.")
654            ad.wakeup_screen()
655            ad.adb.shell("input keyevent 82")
656            time.sleep(3)
657        else:
658            time.sleep(idle_time)
659
660    if wifi_connected:
661        usage_level = get_wifi_usage(ad, apk="com.android.chrome")
662    else:
663        usage_level = get_mobile_data_usage(ad, apk="com.android.chrome")
664
665    try:
666        usage = round((usage_level - usage_level_at_start)/1024/1024, 2)
667        if usage < pass_threshold_in_mb:
668            ad.log.error(
669                "Usage of browsing '%s MB' is smaller than %s " % (
670                    usage, pass_threshold_in_mb))
671            return False
672        else:
673            ad.log.info("Usage of browsing: %s MB" % usage)
674            return True
675    except Exception as e:
676        ad.log.error(e)
677        usage = "unknown"
678        ad.log.info("Usage of browsing: %s MB" % usage)
679        return False
680
681
682def reboot_test(log, ad, wifi_ssid=None):
683    """ Reboot test to verify the service availability after reboot.
684
685    Test procedure:
686    1. Check WiFi and IMS registration status.
687    2. Reboot
688    3. Wait WAIT_TIME_AFTER_REBOOT for reboot complete.
689    4. Wait for multiple network services, including:
690       - service state
691       - network connection
692       - wifi connection if connected before reboot
693       - cellular data
694       - internet connection
695       - IMS registration if available before reboot
696    5. Check if DSDS mode, data sub ID, voice sub ID and message sub ID still keep the same.
697    6. Check if voice and data RAT keep the same.
698
699    Args:
700        log: log object.
701        ad: android object.
702        wifi_ssid: SSID of Wi-Fi AP for Wi-Fi connection.
703
704    Returns:
705        True if pass; False if fail.
706    """
707    try:
708        data_subid = get_default_data_sub_id(ad)
709        voice_subid = get_outgoing_voice_sub_id(ad)
710        sms_subid = get_outgoing_message_sub_id(ad)
711
712        sim_mode_before_reboot = ad.droid.telephonyGetPhoneCount()
713        data_rat_before_reboot = get_network_rat_for_subscription(
714            log, ad, data_subid, NETWORK_SERVICE_DATA)
715        voice_rat_before_reboot = get_network_rat_for_subscription(
716            log, ad, voice_subid, NETWORK_SERVICE_VOICE)
717
718        wifi_connected = False
719        if wifi_ssid:
720            wifi_connected = check_is_wifi_connected(log, ad, wifi_ssid)
721
722        ims_reg = is_ims_registered(log, ad)
723
724        ad.reboot()
725        time.sleep(WAIT_TIME_AFTER_REBOOT)
726
727        if not wait_for_network_service(
728            log,
729            ad,
730            wifi_connected=wifi_connected,
731            wifi_ssid=wifi_ssid,
732            ims_reg=ims_reg):
733
734            return False
735
736        sim_mode_after_reboot = ad.droid.telephonyGetPhoneCount()
737
738        if sim_mode_after_reboot != sim_mode_before_reboot:
739            ad.log.error(
740                "SIM mode changed! (Before reboot: %s; after reboot: %s)",
741                sim_mode_before_reboot, sim_mode_after_reboot)
742            return False
743
744        if getattr(ad, 'dsds', False):
745            if sim_mode_after_reboot == 1:
746                ad.log.error("Phone is in single SIM mode after reboot.")
747                return False
748            elif sim_mode_after_reboot == 2:
749                ad.log.info("Phone keeps being in dual SIM mode after reboot.")
750        else:
751            if sim_mode_after_reboot == 1:
752                ad.log.info("Phone keeps being in single SIM mode after reboot.")
753
754        data_subid_after_reboot = get_default_data_sub_id(ad)
755        if data_subid_after_reboot != data_subid:
756            ad.log.error(
757                "Data sub ID changed! (Before reboot: %s; after reboot: %s)",
758                data_subid, data_subid_after_reboot)
759            return False
760        else:
761            ad.log.info("Data sub ID does not change after reboot.")
762
763        voice_subid_after_reboot = get_outgoing_voice_sub_id(ad)
764        if voice_subid_after_reboot != voice_subid:
765            ad.log.error(
766                "Voice sub ID changed! (Before reboot: %s; after reboot: %s)",
767                voice_subid, voice_subid_after_reboot)
768            return False
769        else:
770            ad.log.info("Voice sub ID does not change after reboot.")
771
772        sms_subid_after_reboot = get_outgoing_message_sub_id(ad)
773        if sms_subid_after_reboot != sms_subid:
774            ad.log.error(
775                "Message sub ID changed! (Before reboot: %s; after reboot: %s)",
776                sms_subid, sms_subid_after_reboot)
777            return False
778        else:
779            ad.log.info("Message sub ID does not change after reboot.")
780
781        data_rat_after_reboot = get_network_rat_for_subscription(
782            log, ad, data_subid_after_reboot, NETWORK_SERVICE_DATA)
783        voice_rat_after_reboot = get_network_rat_for_subscription(
784            log, ad, voice_subid_after_reboot, NETWORK_SERVICE_VOICE)
785
786        if data_rat_after_reboot == data_rat_before_reboot:
787            ad.log.info(
788                "Data RAT (%s) does not change after reboot.",
789                data_rat_after_reboot)
790        else:
791            ad.log.error(
792                "Data RAT changed! (Before reboot: %s; after reboot: %s)",
793                data_rat_before_reboot,
794                data_rat_after_reboot)
795            return False
796
797        if voice_rat_after_reboot == voice_rat_before_reboot:
798            ad.log.info(
799                "Voice RAT (%s) does not change after reboot.",
800                voice_rat_after_reboot)
801        else:
802            ad.log.error(
803                "Voice RAT changed! (Before reboot: %s; after reboot: %s)",
804                voice_rat_before_reboot,
805                voice_rat_after_reboot)
806            return False
807
808    except Exception as e:
809        ad.log.error(e)
810        return False
811
812    return True
813
814
815def verify_for_network_callback(log, ad, event, apm_mode=False):
816    """Verify network callback for Meteredness
817
818    Args:
819        ad: DUT to get the network callback for
820        event: Network callback event
821
822    Returns:
823        True: if the expected network callback found, False if not
824    """
825    key = ad.droid.connectivityRegisterDefaultNetworkCallback()
826    ad.droid.connectivityNetworkCallbackStartListeningForEvent(key, event)
827    if apm_mode:
828        ad.log.info("Turn on Airplane Mode")
829        toggle_airplane_mode(ad.log, ad, True)
830    curr_time = time.time()
831    status = False
832    while time.time() < curr_time + MAX_WAIT_TIME_USER_PLANE_DATA:
833        try:
834            nc_event = ad.ed.pop_event(EventNetworkCallback)
835            ad.log.info("Received: %s" %
836                        nc_event["data"]["networkCallbackEvent"])
837            if nc_event["data"]["networkCallbackEvent"] == event:
838                status = nc_event["data"]["metered"]
839                ad.log.info("Current state of Meteredness is %s", status)
840                break
841        except Empty:
842            pass
843
844    ad.droid.connectivityNetworkCallbackStopListeningForEvent(key, event)
845    ad.droid.connectivityUnregisterNetworkCallback(key)
846    if apm_mode:
847        ad.log.info("Turn off Airplane Mode")
848        toggle_airplane_mode(ad.log, ad, False)
849        time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
850    return status
851
852
853def test_data_connectivity_multi_bearer(
854        log,
855        android_devices,
856        rat=None,
857        simultaneous_voice_data=True,
858        call_direction=DIRECTION_MOBILE_ORIGINATED,
859        nr_type=None):
860    """Test data connection before call and in call.
861
862    Turn off airplane mode, disable WiFi, enable Cellular Data.
863    Make sure phone in <nw_gen>, verify Internet.
864    Initiate a voice call.
865    if simultaneous_voice_data is True, then:
866        Verify Internet.
867        Disable Cellular Data, verify Internet is inaccessible.
868        Enable Cellular Data, verify Internet.
869    if simultaneous_voice_data is False, then:
870        Verify Internet is not available during voice call.
871    Hangup Voice Call, verify Internet.
872
873    Returns:
874        True if success.
875        False if failed.
876    """
877
878    class _LocalException(Exception):
879        pass
880
881    ad_list = [android_devices[0], android_devices[1]]
882    ensure_phones_idle(log, ad_list)
883
884    if rat:
885        if not phone_setup_on_rat(log,
886                                  android_devices[0],
887                                  rat,
888                                  sub_id=android_devices[0]
889                                  .droid.subscriptionGetDefaultDataSubId(),
890                                  nr_type=nr_type):
891            return False
892    else:
893        android_devices[0].log.debug(
894            "Skipping setup network rat since it is None")
895
896    if not wait_for_voice_attach_for_subscription(
897            log, android_devices[0], android_devices[0]
898            .droid.subscriptionGetDefaultVoiceSubId(),
899            MAX_WAIT_TIME_NW_SELECTION):
900        return False
901
902    log.info("Step1 WiFi is Off, Data is on Cell.")
903    toggle_airplane_mode(log, android_devices[0], False)
904    wifi_toggle_state(log, android_devices[0], False)
905    android_devices[0].droid.telephonyToggleDataConnection(True)
906    if (not wait_for_cell_data_connection(log,
907                                          android_devices[0], True)
908            or not verify_internet_connection(log,
909                                              android_devices[0])):
910        log.error("Data not available on cell")
911        return False
912
913    log.info(
914        "b/69431819, sending data to increase NW threshold limit")
915    adb_shell_ping(
916        android_devices[0], count=30, timeout=60, loss_tolerance=100)
917
918    try:
919        log.info("Step2 Initiate call and accept.")
920        if call_direction == DIRECTION_MOBILE_ORIGINATED:
921            ad_caller = android_devices[0]
922            ad_callee = android_devices[1]
923        else:
924            ad_caller = android_devices[1]
925            ad_callee = android_devices[0]
926        if not call_setup_teardown(log, ad_caller, ad_callee, None,
927                                   None, None):
928            log.error(
929                "Failed to Establish {} Voice Call".format(call_direction))
930            return False
931        if simultaneous_voice_data:
932            log.info("Step3 Verify internet.")
933            time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
934            if not verify_internet_connection(
935                    log, android_devices[0], retries=3):
936                raise _LocalException("Internet Inaccessible when Enabled")
937
938            log.info("Step4 Turn off data and verify not connected.")
939            android_devices[0].droid.telephonyToggleDataConnection(
940                False)
941            if not wait_for_cell_data_connection(
942                    log, android_devices[0], False):
943                raise _LocalException("Failed to Disable Cellular Data")
944
945            if not verify_internet_connection(log,
946                                          android_devices[0], expected_state=False):
947                raise _LocalException("Internet Accessible when Disabled")
948
949            log.info("Step5 Re-enable data.")
950            android_devices[0].droid.telephonyToggleDataConnection(
951                True)
952            if not wait_for_cell_data_connection(
953                    log, android_devices[0], True):
954                raise _LocalException("Failed to Re-Enable Cellular Data")
955            if not verify_internet_connection(
956                    log, android_devices[0], retries=3):
957                raise _LocalException("Internet Inaccessible when Enabled")
958        else:
959            log.info("Step3 Verify no Internet and skip step 4-5.")
960            if verify_internet_connection(
961                    log, android_devices[0], retries=0):
962                raise _LocalException("Internet Accessible.")
963
964        log.info("Step6 Verify phones still in call and Hang up.")
965        if not verify_incall_state(
966                log,
967            [android_devices[0], android_devices[1]], True):
968            return False
969        if not hangup_call(log, android_devices[0]):
970            log.error("Failed to hang up call")
971            return False
972        if not verify_internet_connection(
973                log, android_devices[0], retries=3):
974            raise _LocalException("Internet Inaccessible when Enabled")
975
976    except _LocalException as e:
977        log.error(str(e))
978        try:
979            hangup_call(log, android_devices[0])
980            android_devices[0].droid.telephonyToggleDataConnection(
981                True)
982        except Exception:
983            pass
984        return False
985
986    return True
987
988
989def test_internet_connection(log, provider, clients,
990                              client_status=True,
991                              provider_status=True):
992    client_retry = 10 if client_status else 1
993    for client in clients:
994        if not verify_internet_connection(
995                log,
996                client,
997                retries=client_retry,
998                expected_state=client_status):
999            client.log.error("client internet connection state is not %s",
1000                             client_status)
1001            return False
1002        else:
1003            client.log.info("client internet connection state is %s",
1004                            client_status)
1005    if not verify_internet_connection(
1006            log, provider, retries=3,
1007            expected_state=provider_status):
1008        provider.log.error(
1009            "provider internet connection is not %s" % provider_status)
1010        return False
1011    else:
1012        provider.log.info(
1013            "provider internet connection is %s" % provider_status)
1014    return True
1015
1016
1017def test_setup_tethering(log,
1018                        provider,
1019                        clients,
1020                        network_generation=None,
1021                        nr_type=None):
1022    """Pre setup steps for WiFi tethering test.
1023
1024    Ensure all ads are idle.
1025    Ensure tethering provider:
1026        turn off APM, turn off WiFI, turn on Data.
1027        have Internet connection, no active ongoing WiFi tethering.
1028    nr_type: NR network type.
1029
1030    Returns:
1031        True if success.
1032        False if failed.
1033    """
1034
1035    ensure_phone_idle(log, provider)
1036    ensure_phones_idle(log, clients)
1037    wifi_toggle_state(log, provider, False)
1038    if network_generation == RAT_5G:
1039        if not provision_device_for_5g(log, provider, nr_type=nr_type):
1040            return False
1041    elif network_generation:
1042        if not ensure_network_generation(
1043                log, provider, network_generation,
1044                MAX_WAIT_TIME_NW_SELECTION, NETWORK_SERVICE_DATA):
1045            provider.log.error("Provider failed to connect to %s.",
1046                                    network_generation)
1047            return False
1048    else:
1049        log.debug("Skipping network generation since it is None")
1050
1051    provider.log.info(
1052        "Set provider Airplane Off, Wifi Off, Bluetooth Off, Data On.")
1053    toggle_airplane_mode(log, provider, False)
1054    provider.droid.telephonyToggleDataConnection(True)
1055    provider.log.info("Provider disable wifi")
1056    wifi_toggle_state(log, provider, False)
1057
1058    # Turn off active SoftAP if any.
1059    if provider.droid.wifiIsApEnabled():
1060        provider.log.info("Disable provider wifi tethering")
1061        stop_wifi_tethering(log, provider)
1062    provider.log.info("Provider disable bluetooth")
1063    provider.droid.bluetoothToggleState(False)
1064    time.sleep(10)
1065
1066    for ad in clients:
1067        ad.log.info(
1068            "Set client Airplane Off, Wifi Off, Bluetooth Off, Data Off.")
1069        toggle_airplane_mode(log, ad, False)
1070        ad.log.info("Client disable data")
1071        ad.droid.telephonyToggleDataConnection(False)
1072        ad.log.info("Client disable bluetooth")
1073        ad.droid.bluetoothToggleState(False)
1074        ad.log.info("Client disable wifi")
1075        wifi_toggle_state(log, ad, False)
1076
1077    if not wait_for_cell_data_connection(log, provider, True):
1078        provider.log.error(
1079            "Provider failed to enable data connection.")
1080        return False
1081
1082    time.sleep(10)
1083    log.info("Verify internet")
1084    if not test_internet_connection(log, provider, clients,
1085            client_status=False, provider_status=True):
1086        log.error("Internet connection check failed before tethering")
1087        return False
1088
1089    return True
1090
1091
1092def test_tethering_wifi_and_voice_call(log, provider, clients,
1093                                        provider_data_rat,
1094                                        provider_setup_func,
1095                                        provider_in_call_check_func,
1096                                        nr_type=None):
1097
1098    if not test_setup_tethering(log, provider, clients, provider_data_rat):
1099        log.error("Verify 4G Internet access failed.")
1100        return False
1101
1102    tasks = [(provider_setup_func, (log, provider)),
1103             (phone_setup_voice_general, (log, clients[0]))]
1104    if not multithread_func(log, tasks):
1105        log.error("Phone Failed to Set Up VoLTE.")
1106        return False
1107
1108    if provider_setup_func == RAT_5G:
1109        if not provision_device_for_5g(log, provider, nr_type=nr_type):
1110            return False
1111    try:
1112        log.info("1. Setup WiFi Tethering.")
1113        if not wifi_tethering_setup_teardown(
1114                log,
1115                provider, [clients[0]],
1116                ap_band=WIFI_CONFIG_APBAND_2G,
1117                check_interval=10,
1118                check_iteration=2,
1119                do_cleanup=False):
1120            log.error("WiFi Tethering failed.")
1121            return False
1122        log.info("2. Make outgoing call.")
1123        if not call_setup_teardown(
1124                log,
1125                provider,
1126                clients[0],
1127                ad_hangup=None,
1128                verify_caller_func=provider_in_call_check_func):
1129            log.error("Setup Call Failed.")
1130            return False
1131        log.info("3. Verify data.")
1132        if not verify_internet_connection(log, provider):
1133            provider.log.error("Provider have no Internet access.")
1134        if not verify_internet_connection(log, clients[0]):
1135            clients[0].log.error("Client have no Internet access.")
1136        hangup_call(log, provider)
1137        time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL)
1138
1139        log.info("4. Make incoming call.")
1140        if not call_setup_teardown(
1141                log,
1142                clients[0],
1143                provider,
1144                ad_hangup=None,
1145                verify_callee_func=provider_in_call_check_func):
1146            log.error("Setup Call Failed.")
1147            return False
1148        log.info("5. Verify data.")
1149        if not verify_internet_connection(log, provider):
1150            provider.log.error("Provider have no Internet access.")
1151        if not verify_internet_connection(log, clients[0]):
1152            clients[0].log.error("Client have no Internet access.")
1153        hangup_call(log, provider)
1154
1155    finally:
1156        if not wifi_tethering_cleanup(log, provider, clients):
1157            return False
1158    return True
1159
1160
1161def test_wifi_connect_disconnect(log, ad, wifi_network_ssid=None, wifi_network_pass=None):
1162    """Perform multiple connects and disconnects from WiFi and verify that
1163        data switches between WiFi and Cell.
1164
1165    Steps:
1166    1. Reset Wifi on DUT
1167    2. Connect DUT to a WiFi AP
1168    3. Repeat steps 1-2, alternately disconnecting and disabling wifi
1169
1170    Expected Results:
1171    1. Verify Data on Cell
1172    2. Verify Data on Wifi
1173
1174    Returns:
1175        True if success.
1176        False if failed.
1177    """
1178
1179    wifi_toggles = [
1180        True, False, True, False, False, True, False, False, False, False,
1181        True, False, False, False, False, False, False, False, False
1182    ]
1183    try:
1184        for toggle in wifi_toggles:
1185
1186            wifi_reset(log, ad, toggle)
1187
1188            if not wait_for_cell_data_connection(
1189                    log, ad, True, MAX_WAIT_TIME_WIFI_CONNECTION):
1190                log.error("Failed data connection, aborting!")
1191                return False
1192
1193            if not verify_internet_connection(log, ad):
1194                log.error("Failed to get user-plane traffic, aborting!")
1195                return False
1196
1197            if toggle:
1198                wifi_toggle_state(log, ad, True)
1199
1200            ensure_wifi_connected(log, ad, wifi_network_ssid,
1201                        wifi_network_pass)
1202
1203            if not wait_for_wifi_data_connection(
1204                    log, ad, True, MAX_WAIT_TIME_WIFI_CONNECTION):
1205                log.error("Failed wifi connection, aborting!")
1206                return False
1207
1208            if not verify_http_connection(
1209                    log, ad, 'http://www.google.com', 100, .1):
1210                log.error("Failed to get user-plane traffic, aborting!")
1211                return False
1212        return True
1213    finally:
1214        wifi_toggle_state(log, ad, False)
1215
1216
1217def test_call_setup_in_active_data_transfer(
1218        log,
1219        ads,
1220        rat=None,
1221        is_airplane_mode=False,
1222        wfc_mode=None,
1223        wifi_ssid=None,
1224        wifi_pwd=None,
1225        nr_type=None,
1226        call_direction=DIRECTION_MOBILE_ORIGINATED,
1227        allow_data_transfer_interruption=False):
1228    """Test call can be established during active data connection.
1229
1230    Turn off airplane mode, disable WiFi, enable Cellular Data.
1231    Make sure phone in <rat>.
1232    Starting downloading file from Internet.
1233    Initiate a voice call. Verify call can be established.
1234    Hangup Voice Call, verify file is downloaded successfully.
1235    Note: file download will be suspended when call is initiated if voice
1236          is using voice channel and voice channel and data channel are
1237          on different RATs.
1238
1239    Args:
1240        log: log object.
1241        ads: list of android objects, this list should have two ad.
1242        rat: network rat.
1243        is_airplane_mode: True to turn APM on during WFC, False otherwise.
1244        wfc_mode: Calling preference of WFC, e.g., Wi-Fi/mobile network.
1245        wifi_ssid: Wi-Fi ssid to connect with.
1246        wifi_pwd: Password of target Wi-Fi AP.
1247        nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone.
1248        call_direction: MO(DIRECTION_MOBILE_ORIGINATED) or MT(DIRECTION_MOBILE_TERMINATED) call.
1249        allow_data_transfer_interruption: if allow to interrupt data transfer.
1250
1251    Returns:
1252        True if success.
1253        False if failed.
1254    """
1255
1256    def _call_setup_teardown(log, ad_caller, ad_callee, ad_hangup,
1257                             caller_verifier, callee_verifier,
1258                             wait_time_in_call):
1259        # wait time for active data transfer
1260        time.sleep(5)
1261        return call_setup_teardown(log, ad_caller, ad_callee, ad_hangup,
1262                                   caller_verifier, callee_verifier,
1263                                   wait_time_in_call)
1264    try:
1265        if rat:
1266            if not phone_setup_on_rat(log,
1267                                      ads[0],
1268                                      rat,
1269                                      is_airplane_mode=is_airplane_mode,
1270                                      wfc_mode=wfc_mode,
1271                                      wifi_ssid=wifi_ssid,
1272                                      wifi_pwd=wifi_pwd,
1273                                      nr_type=nr_type):
1274                return False
1275        else:
1276            ads[0].log.debug("Skipping setup network rat since it is None")
1277
1278        if not verify_internet_connection(log, ads[0]):
1279            ads[0].log.error("Internet connection is not available")
1280            return False
1281
1282        if call_direction == DIRECTION_MOBILE_ORIGINATED:
1283            ad_caller = ads[0]
1284            ad_callee = ads[1]
1285        else:
1286            ad_caller = ads[1]
1287            ad_callee = ads[0]
1288        ad_download = ads[0]
1289
1290        start_youtube_video(ad_download)
1291        call_task = (_call_setup_teardown, (log, ad_caller, ad_callee,
1292                                            ad_caller, None, None, 30))
1293        download_task = active_file_download_task(log, ad_download)
1294        results = run_multithread_func(log, [download_task, call_task])
1295        if wait_for_state(ad_download.droid.audioIsMusicActive, True, 15, 1):
1296            ad_download.log.info("After call hangup, audio is back to music")
1297        else:
1298            ad_download.log.warning(
1299                "After call hang up, audio is not back to music")
1300        ad_download.force_stop_apk("com.google.android.youtube")
1301        if not results[1]:
1302            log.error("Call setup failed in active data transfer.")
1303        if results[0]:
1304            ad_download.log.info("Data transfer succeeded.")
1305        elif not allow_data_transfer_interruption:
1306            ad_download.log.error(
1307                "Data transfer failed with parallel phone call.")
1308            return False
1309        else:
1310            ad_download.log.info("Retry data connection after call hung up")
1311            if not verify_internet_connection(log, ad_download):
1312                ad_download.log.error("Internet connection is not available")
1313                return False
1314
1315        if is_airplane_mode:
1316            toggle_airplane_mode(log, ads[0], False)
1317
1318        if rat and '5g' in rat and not check_current_network_5g(ads[0],
1319                                                                nr_type=nr_type):
1320            ads[0].log.error("Phone not attached on 5G after call.")
1321            return False
1322        return True
1323    finally:
1324        # Disable airplane mode if test under apm on.
1325        if is_airplane_mode:
1326            toggle_airplane_mode(log, ads[0], False)
1327
1328
1329def test_call_setup_in_active_youtube_video(
1330        log,
1331        ads,
1332        rat=None,
1333        is_airplane_mode=False,
1334        wfc_mode=None,
1335        wifi_ssid=None,
1336        wifi_pwd=None,
1337        nr_type=None,
1338        call_direction=DIRECTION_MOBILE_ORIGINATED):
1339    """Test call can be established during active data connection.
1340
1341    Turn off airplane mode, disable WiFi, enable Cellular Data.
1342    Make sure phone in <rat>.
1343    Starting playing youtube video.
1344    Initiate a voice call. Verify call can be established.
1345
1346    Args:
1347        log: log object.
1348        ads: list of android objects, this list should have two ad.
1349        rat: network rat.
1350        is_airplane_mode: True to turn APM on during WFC, False otherwise.
1351        wfc_mode: Calling preference of WFC, e.g., Wi-Fi/mobile network.
1352        wifi_ssid: Wi-Fi ssid to connect with.
1353        wifi_pwd: Password of target Wi-Fi AP.
1354        nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone.
1355        call_direction: MO(DIRECTION_MOBILE_ORIGINATED) or MT(DIRECTION_MOBILE_TERMINATED) call.
1356
1357    Returns:
1358        True if success.
1359        False if failed.
1360    """
1361    try:
1362        if rat:
1363            if not phone_setup_on_rat(log,
1364                                      ads[0],
1365                                      rat,
1366                                      is_airplane_mode=is_airplane_mode,
1367                                      wfc_mode=wfc_mode,
1368                                      wifi_ssid=wifi_ssid,
1369                                      wifi_pwd=wifi_pwd,
1370                                      nr_type=nr_type):
1371                return False
1372        else:
1373            ensure_phones_default_state(log, ads)
1374
1375        if not verify_internet_connection(log, ads[0]):
1376            ads[0].log.error("Internet connection is not available")
1377            return False
1378
1379        if call_direction == DIRECTION_MOBILE_ORIGINATED:
1380            ad_caller = ads[0]
1381            ad_callee = ads[1]
1382        else:
1383            ad_caller = ads[1]
1384            ad_callee = ads[0]
1385        ad_download = ads[0]
1386
1387        if not start_youtube_video(ad_download):
1388            ad_download.log.warning("Fail to bring up youtube video")
1389
1390        if not call_setup_teardown(log, ad_caller, ad_callee, ad_caller,
1391                                None, None, 30):
1392            ad_download.log.error("Call setup failed in active youtube video")
1393            result = False
1394        else:
1395            ad_download.log.info("Call setup succeed in active youtube video")
1396            result = True
1397
1398        if wait_for_state(ad_download.droid.audioIsMusicActive, True, 15, 1):
1399            ad_download.log.info("After call hangup, audio is back to music")
1400        else:
1401            ad_download.log.warning(
1402                    "After call hang up, audio is not back to music")
1403        ad_download.force_stop_apk("com.google.android.youtube")
1404
1405        if is_airplane_mode:
1406            toggle_airplane_mode(log, ads[0], False)
1407
1408        if rat and '5g' in rat and not check_current_network_5g(ads[0],
1409                                                                nr_type=nr_type):
1410            ads[0].log.error("Phone not attached on 5G after call.")
1411            result = False
1412        return result
1413    finally:
1414        # Disable airplane mode if test under apm on.
1415        if is_airplane_mode:
1416            toggle_airplane_mode(log, ads[0], False)
1417
1418
1419def call_epdg_to_epdg_wfc(log,
1420                          ads,
1421                          apm_mode,
1422                          wfc_mode,
1423                          wifi_ssid,
1424                          wifi_pwd,
1425                          nw_gen=None,
1426                          nr_type=None):
1427    """ Test epdg<->epdg call functionality.
1428
1429    Make Sure PhoneA is set to make epdg call.
1430    Make Sure PhoneB is set to make epdg call.
1431    Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
1432    Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.
1433
1434    Args:
1435        log: log object.
1436        ads: list of android objects, this list should have two ad.
1437        apm_mode: phones' airplane mode.
1438            if True, phones are in airplane mode during test.
1439            if False, phones are not in airplane mode during test.
1440        wfc_mode: phones' wfc mode.
1441            Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
1442            WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED.
1443        wifi_ssid: WiFi ssid to connect during test.
1444        wifi_pwd: WiFi password.
1445        nw_gen: network generation.
1446
1447    Returns:
1448        True if pass; False if fail.
1449    """
1450    DEFAULT_PING_DURATION = 120
1451
1452    if nw_gen == GEN_5G:
1453        # Turn off apm first before setting network preferred mode to 5G NSA.
1454        log.info("Turn off APM mode before starting testing.")
1455        tasks = [(toggle_airplane_mode, (log, ads[0], False)),
1456                 (toggle_airplane_mode, (log, ads[1], False))]
1457        if not multithread_func(log, tasks):
1458            log.error("Failed to turn off airplane mode")
1459            return False
1460        if not provision_device_for_5g(log, ads, nr_type):
1461            return False
1462
1463    tasks = [(phone_setup_iwlan, (log, ads[0], apm_mode, wfc_mode,
1464                                  wifi_ssid, wifi_pwd)),
1465             (phone_setup_iwlan, (log, ads[1], apm_mode, wfc_mode,
1466                                  wifi_ssid, wifi_pwd))]
1467    if not multithread_func(log, tasks):
1468        log.error("Phone Failed to Set Up Properly.")
1469        return False
1470
1471    ad_ping = ads[0]
1472
1473    call_task = (two_phone_call_short_seq,
1474                 (log, ads[0], phone_idle_iwlan,
1475                  is_phone_in_call_iwlan, ads[1], phone_idle_iwlan,
1476                  is_phone_in_call_iwlan, None, WAIT_TIME_IN_CALL_FOR_IMS))
1477    ping_task = (adb_shell_ping, (ad_ping, DEFAULT_PING_DURATION))
1478
1479    results = run_multithread_func(log, [ping_task, call_task])
1480
1481    time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
1482
1483    if apm_mode:
1484        toggle_airplane_mode(log, ads[0], False)
1485
1486    if nw_gen == GEN_5G and not verify_5g_attach_for_both_devices(
1487        log, ads, nr_type=nr_type):
1488        log.error("Phone not attached on 5G after epdg call.")
1489        return False
1490
1491    if not results[1]:
1492        log.error("Call setup failed in active ICMP transfer.")
1493    if results[0]:
1494        log.info("ICMP transfer succeeded with parallel phone call.")
1495    else:
1496        log.error("ICMP transfer failed with parallel phone call.")
1497    return all(results)
1498
1499
1500def verify_toggle_apm_tethering_internet_connection(log, provider, clients, ssid):
1501    """ Verify internet connection by toggling apm during wifi tethering.
1502    Args:
1503        log: log object.
1504        provider: android object provide WiFi tethering.
1505        clients: a list of clients using tethered WiFi.
1506        ssid: use this string as WiFi SSID to setup tethered WiFi network.
1507
1508    """
1509    if not provider.droid.wifiIsApEnabled():
1510        log.error("Provider WiFi tethering stopped.")
1511        return False
1512
1513    log.info(
1514        "Provider turn on APM, verify no wifi/data on Client.")
1515    try:
1516        if not toggle_airplane_mode(log, provider, True):
1517            log.error("Provider turn on APM failed.")
1518            return False
1519        time.sleep(WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING)
1520
1521        if provider.droid.wifiIsApEnabled():
1522            provider.log.error("Provider WiFi tethering not stopped.")
1523            return False
1524
1525        if not verify_internet_connection(log, clients[0], expected_state=False):
1526            clients[0].log.error(
1527                "Client should not have Internet connection.")
1528            return False
1529
1530        wifi_info = clients[0].droid.wifiGetConnectionInfo()
1531        clients[0].log.info("WiFi Info: {}".format(wifi_info))
1532        if wifi_info[WIFI_SSID_KEY] == ssid:
1533            clients[0].log.error(
1534                "WiFi error. WiFi should not be connected.".format(
1535                    wifi_info))
1536            return False
1537
1538        log.info("Provider turn off APM.")
1539        if not toggle_airplane_mode(log, provider, False):
1540            provider.log.error("Provider turn off APM failed.")
1541            return False
1542        time.sleep(WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING)
1543        if provider.droid.wifiIsApEnabled():
1544            provider.log.error(
1545                "Provider WiFi tethering should not on.")
1546            return False
1547        if not verify_internet_connection(log, provider):
1548            provider.log.error(
1549                "Provider should have Internet connection.")
1550            return False
1551        return True
1552    finally:
1553        # Disable airplane mode before test end.
1554        toggle_airplane_mode(log, provider, False)
1555
1556
1557def verify_tethering_entitlement_check(log, provider):
1558    """Tethering Entitlement Check Test
1559
1560    Get tethering entitlement check result.
1561    Args:
1562        log: log object.
1563        provider: android object provide WiFi tethering.
1564
1565    Returns:
1566        True if entitlement check returns True.
1567    """
1568    if (not wait_for_cell_data_connection(log, provider, True)
1569            or not verify_internet_connection(log, provider)):
1570        log.error("Failed cell data call for entitlement check.")
1571        return False
1572
1573    result = provider.droid.carrierConfigIsTetheringModeAllowed(
1574        TETHERING_MODE_WIFI, MAX_WAIT_TIME_TETHERING_ENTITLEMENT_CHECK)
1575    provider.log.info("Tethering entitlement check result: %s",
1576                      result)
1577    return result
1578
1579
1580def test_wifi_tethering(log, provider,
1581                        clients,
1582                        clients_tethering,
1583                        nw_gen,
1584                        ap_band=WIFI_CONFIG_APBAND_2G,
1585                        check_interval=30,
1586                        check_iteration=4,
1587                        do_cleanup=True,
1588                        ssid=None,
1589                        password=None,
1590                        pre_teardown_func=None,
1591                        nr_type=None):
1592    """WiFi Tethering test
1593    Args:
1594        log: log object.
1595        provider: android object provide WiFi tethering.
1596        clients: a list of clients are valid for tethered WiFi.
1597        clients_tethering: a list of clients using tethered WiFi.
1598        nw_gen: network generation.
1599        ap_band: setup WiFi tethering on 2G or 5G.
1600            This is optional, default value is WIFI_CONFIG_APBAND_2G
1601        check_interval: delay time between each around of Internet connection check.
1602            This is optional, default value is 30 (seconds).
1603        check_iteration: check Internet connection for how many times in total.
1604            This is optional, default value is 4 (4 times).
1605        do_cleanup: after WiFi tethering test, do clean up to tear down tethering
1606            setup or not. This is optional, default value is True.
1607        ssid: use this string as WiFi SSID to setup tethered WiFi network.
1608            This is optional. Default value is None.
1609            If it's None, a random string will be generated.
1610        password: use this string as WiFi password to setup tethered WiFi network.
1611            This is optional. Default value is None.
1612            If it's None, a random string will be generated.
1613        pre_teardown_func: execute custom actions between tethering setup adn teardown.
1614        nr_type: NR network type e.g. NSA, SA, MMWAVE.
1615
1616    """
1617    if not test_setup_tethering(log, provider, clients, nw_gen, nr_type=nr_type):
1618        log.error("Verify %s Internet access failed.", nw_gen)
1619        return False
1620
1621    if pre_teardown_func:
1622        if not pre_teardown_func():
1623            return False
1624
1625    return wifi_tethering_setup_teardown(
1626        log,
1627        provider,
1628        clients_tethering,
1629        ap_band=ap_band,
1630        check_interval=check_interval,
1631        check_iteration=check_iteration,
1632        do_cleanup=do_cleanup,
1633        ssid=ssid,
1634        password=password)
1635
1636
1637def run_stress_test(log,
1638                    stress_test_number,
1639                    precondition_func=None,
1640                    test_case_func=None):
1641    """Run stress test of a test case.
1642
1643    Args:
1644        log: log object.
1645        stress_test_number: The number of times the test case is run.
1646        precondition_func: A function performing set up before running test case
1647        test_case_func: A test case function.
1648
1649    Returns:
1650        True stress pass rate is higher than MINIMUM_SUCCESS_RATE.
1651        False otherwise.
1652
1653    """
1654    MINIMUM_SUCCESS_RATE = .95
1655    success_count = 0
1656    fail_count = 0
1657    for i in range(1, stress_test_number + 1):
1658        if precondition_func:
1659            precondition_func()
1660        if test_case_func:
1661            result = test_case_func()
1662        if result:
1663            success_count += 1
1664            result_str = "Succeeded"
1665        else:
1666            fail_count += 1
1667            result_str = "Failed"
1668        log.info("Iteration {} {}. Current: {} / {} passed.".format(
1669            i, result_str, success_count, stress_test_number))
1670
1671    log.info("Final Count - Success: {}, Failure: {} - {}%".format(
1672        success_count, fail_count,
1673        str(100 * success_count / (success_count + fail_count))))
1674    if success_count / (
1675            success_count + fail_count) >= MINIMUM_SUCCESS_RATE:
1676        return True
1677    else:
1678        return False
1679
1680
1681def test_start_wifi_tethering_connect_teardown(log,
1682                                               ad_host,
1683                                               ad_client,
1684                                               ssid,
1685                                               password):
1686    """Private test util for WiFi Tethering.
1687
1688    1. Host start WiFi tethering.
1689    2. Client connect to tethered WiFi.
1690    3. Host tear down WiFi tethering.
1691
1692    Args:
1693        log: log object.
1694        ad_host: android device object for host
1695        ad_client: android device object for client
1696        ssid: WiFi tethering ssid
1697        password: WiFi tethering password
1698
1699    Returns:
1700        True if pass, otherwise False.
1701    """
1702    result = True
1703    # Turn off active SoftAP if any.
1704    if ad_host.droid.wifiIsApEnabled():
1705        stop_wifi_tethering(log, ad_host)
1706
1707    time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
1708    if not start_wifi_tethering(log, ad_host, ssid, password,
1709                                WIFI_CONFIG_APBAND_2G):
1710        log.error("Start WiFi tethering failed.")
1711        result = False
1712    time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
1713    if not ensure_wifi_connected(log, ad_client, ssid, password):
1714        log.error("Client connect to WiFi failed.")
1715        result = False
1716    if not wifi_reset(log, ad_client):
1717        log.error("Reset client WiFi failed. {}".format(
1718            ad_client.serial))
1719        result = False
1720    if not stop_wifi_tethering(log, ad_host):
1721        log.error("Stop WiFi tethering failed.")
1722        result = False
1723    return result
1724
1725
1726def verify_wifi_tethering_when_reboot(log,
1727                                      provider,
1728                                      post_reboot_func=None):
1729    """ Verify wifi tethering when reboot.
1730
1731    Verify wifi tethering is enabled before reboot and disabled
1732    after reboot, and execute additional custom actions verification
1733    of wifi tethering.
1734
1735    Args:
1736        log: log object.
1737        provider: android object provide WiFi tethering.
1738        post_reboot_func: execute custom actions after reboot.
1739    Returns:
1740        True if pass, otherwise False.
1741
1742    """
1743    if not provider.droid.wifiIsApEnabled():
1744        log.error("Provider WiFi tethering stopped.")
1745        return False
1746
1747    provider.log.info("Reboot provider")
1748    provider.reboot()
1749    time.sleep(
1750        WAIT_TIME_AFTER_REBOOT + WAIT_TIME_TETHERING_AFTER_REBOOT)
1751
1752    log.info("After reboot check if tethering stopped.")
1753    if provider.droid.wifiIsApEnabled():
1754        log.error("Provider WiFi tethering did NOT stopped.")
1755        return False
1756    if post_reboot_func:
1757        post_reboot_func()
1758    return True
1759
1760
1761def setup_device_internet_connection(log,
1762                                     device,
1763                                     network_ssid,
1764                                     network_password):
1765    """Setup wifi network for device and verify internet connection.
1766    Args:
1767        log: log object.
1768        device: android device object.
1769        network_ssid: wifi network ssid.
1770        network_password: wifi network password.
1771    Returns:
1772        True if pass, otherwise False.
1773
1774    """
1775    log.info("Make sure DUT can connect to live network by WIFI")
1776    if ((not ensure_wifi_connected(log,
1777                                   device,
1778                                   network_ssid,
1779                                   network_password))
1780            or (not verify_internet_connection(log, device))):
1781        log.error("WiFi connect fail.")
1782        return False
1783    return True
1784
1785
1786def wait_and_verify_device_internet_connection(log,
1787                                               device):
1788    """Wait for device connecting to wifi network and verify internet connection.
1789    Args:
1790        log: log object.
1791        device: Android device object.
1792    Returns:
1793        True if pass, otherwise False.
1794
1795    """
1796    log.info("Make sure WiFi can connect automatically.")
1797    if (not wait_for_wifi_data_connection(log, device, True) or
1798            not verify_internet_connection(log, device)):
1799        log.error("Data did not return to WiFi")
1800        return False
1801    return True
1802
1803
1804def setup_device_internet_connection_then_reboot(log,
1805                                                 device,
1806                                                 network_ssid,
1807                                                 network_password):
1808    """Setup wifi network for device and verify internet connection, then reboot.
1809    Args:
1810        log: log object.
1811        device: android device object.
1812        network_ssid: wifi network ssid.
1813        network_password: wifi network password.
1814    Returns:
1815        True if pass, otherwise False.
1816
1817    """
1818    if not setup_device_internet_connection(log,
1819                                            device,
1820                                            network_ssid,
1821                                            network_password):
1822        return False
1823
1824    device.log.info("Reboot!")
1825    device.reboot()
1826    time.sleep(WAIT_TIME_AFTER_REBOOT)
1827    time.sleep(WAIT_TIME_TETHERING_AFTER_REBOOT)
1828    return True
1829
1830
1831def verify_internet_connection_in_doze_mode(log,
1832                                            provider,
1833                                            client):
1834    """Set provider in doze mode and verify client's internet connection.
1835    Args:
1836        log: log object.
1837        provider: android device object for provider.
1838        client: android device object for client.
1839    Returns:
1840        True if pass, otherwise False.
1841
1842    """
1843    try:
1844        if not provider.droid.wifiIsApEnabled():
1845            provider.log.error("Provider WiFi tethering stopped.")
1846            return False
1847        provider.log.info("Turn off screen on provider")
1848        provider.droid.goToSleepNow()
1849        time.sleep(60)
1850        if not verify_internet_connection(log, client):
1851            client.log.error("Client have no Internet access.")
1852            return False
1853
1854        provider.log.info("Enable doze mode on provider")
1855        if not enable_doze(provider):
1856            provider.log.error("Failed to enable doze mode.")
1857            return False
1858        time.sleep(60)
1859        if not verify_internet_connection(log, client):
1860            client.log.error("Client have no Internet access.")
1861            return False
1862    finally:
1863        log.info("Disable doze mode.")
1864        if not disable_doze(provider):
1865            log.error("Failed to disable doze mode.")
1866            return False
1867    return True
1868
1869
1870def test_wifi_cell_switching_in_call(log,
1871                                     ads,
1872                                     network_ssid,
1873                                     network_password,
1874                                     new_gen=None,
1875                                     verify_caller_func=None,
1876                                     verify_callee_func=None):
1877    """Test data connection network switching during voice call when phone on <nw_gen>
1878    Args:
1879        log: log object.
1880        ads: android device objects.
1881        network_ssid: wifi network ssid.
1882        network_password: wifi network password.
1883        new_gen: network generation.
1884    Returns:
1885        True if pass, otherwise False.
1886
1887    """
1888    result = True
1889    if not call_setup_teardown(log,
1890                               ads[0],
1891                               ads[1],
1892                               None,
1893                               verify_caller_func,
1894                               verify_callee_func,
1895                               5):
1896        log.error("Call setup failed")
1897        return False
1898    else:
1899        log.info("Call setup succeed")
1900
1901    if not wifi_cell_switching(log,
1902                               ads[0],
1903                               new_gen,
1904                               network_ssid,
1905                               network_password):
1906        ads[0].log.error("Failed to do WIFI and Cell switch in call")
1907        result = False
1908
1909    if not is_phone_in_call_active(ads[0]):
1910        return False
1911    else:
1912        if not ads[0].droid.telecomCallGetAudioState():
1913            ads[0].log.error("Audio is not on call")
1914            result = False
1915        else:
1916            ads[0].log.info("Audio is on call")
1917        hangup_call(log, ads[0])
1918        return result
1919
1920
1921def verify_toggle_data_during_wifi_tethering(log,
1922                                             provider,
1923                                             clients,
1924                                             new_gen=None,
1925                                             nr_type=None):
1926    """Verify toggle Data network during WiFi Tethering.
1927    Args:
1928        log: log object.
1929        provider: android device object for provider.
1930        clients: android device objects for clients.
1931        new_gen: network generation.
1932        nr_type: NR network type e.g. NSA, SA, MMWAVE.
1933
1934    Returns:
1935        True if pass, otherwise False.
1936
1937    """
1938    try:
1939        ssid = rand_ascii_str(10)
1940        if not test_wifi_tethering(log,
1941                                   provider,
1942                                   clients,
1943                                   [clients[0]],
1944                                   new_gen,
1945                                   WIFI_CONFIG_APBAND_2G,
1946                                   check_interval=10,
1947                                   check_iteration=2,
1948                                   do_cleanup=False,
1949                                   ssid=ssid,
1950                                   nr_type=nr_type):
1951            log.error("WiFi Tethering failed.")
1952            return False
1953        if not provider.droid.wifiIsApEnabled():
1954            provider.log.error("Provider WiFi tethering stopped.")
1955            return False
1956
1957        provider.log.info(
1958            "Disable Data on Provider, verify no data on Client.")
1959        provider.droid.telephonyToggleDataConnection(False)
1960        time.sleep(WAIT_TIME_DATA_STATUS_CHANGE_DURING_WIFI_TETHERING)
1961        if not verify_internet_connection(log, provider, expected_state=False):
1962            provider.log.error("Disable data on provider failed.")
1963            return False
1964        if not provider.droid.wifiIsApEnabled():
1965            provider.log.error("Provider WiFi tethering stopped.")
1966            return False
1967        if not check_is_wifi_connected(log, clients[0], ssid):
1968            clients[0].log.error("Client WiFi is not connected")
1969            return False
1970
1971        log.info(
1972            "Enable Data on Provider, verify data available on Client.")
1973        provider.droid.telephonyToggleDataConnection(True)
1974        if not wait_for_cell_data_connection(log, provider,
1975                                             True):
1976            provider.log.error(
1977                "Provider failed to enable data connection.")
1978            return False
1979        if not verify_internet_connection(log, provider):
1980            provider.log.error(
1981                "Provider internet connection check failed.")
1982            return False
1983        if not provider.droid.wifiIsApEnabled():
1984            provider.log.error("Provider WiFi tethering stopped.")
1985            return False
1986
1987        if not check_is_wifi_connected(log, clients[0], ssid) or (not verify_internet_connection(log, clients[0])):
1988            clients[0].log.error("Client wifi connection check failed!")
1989            return False
1990
1991    finally:
1992        if not wifi_tethering_cleanup(log,
1993                                      provider,
1994                                      clients):
1995            return False
1996    return True
1997
1998def deactivate_and_verify_cellular_data(log, ad):
1999    """Toggle off cellular data and ensure there is no internet connection.
2000
2001    Args:
2002        ad: Android object
2003
2004    Returns:
2005        True if cellular data is deactivated successfully. Otherwise False.
2006    """
2007    ad.log.info('Deactivating cellular data......')
2008    ad.droid.telephonyToggleDataConnection(False)
2009
2010    if not wait_for_cell_data_connection(log, ad, False):
2011        ad.log.error("Failed to deactivate cell data connection.")
2012        return False
2013
2014    if not verify_internet_connection(log, ad, expected_state=False):
2015        ad.log.error("Internet connection is still available.")
2016        return False
2017
2018    return True
2019
2020def activate_and_verify_cellular_data(log, ad):
2021    """Toggle on cellular data and ensure there is internet connection.
2022
2023    Args:
2024        ad: Android object
2025
2026    Returns:
2027        True if cellular data is activated successfully. Otherwise False.
2028    """
2029    ad.log.info('Activating cellular data......')
2030    ad.droid.telephonyToggleDataConnection(True)
2031
2032    if not wait_for_cell_data_connection(log, ad, True):
2033        ad.log.error("Failed to activate data connection.")
2034        return False
2035
2036    if not verify_internet_connection(log, ad, retries=3):
2037        ad.log.error("Internet connection is NOT available.")
2038        return False
2039
2040    return True
2041
2042
2043def wait_for_network_service(
2044    log,
2045    ad,
2046    wifi_connected=False,
2047    wifi_ssid=None,
2048    ims_reg=True,
2049    recover=False,
2050    retry=3):
2051    """ Wait for multiple network services in sequence, including:
2052        - service state
2053        - network connection
2054        - wifi connection
2055        - cellular data
2056        - internet connection
2057        - IMS registration
2058
2059        The mechanism (cycling airplane mode) to recover network services is
2060        also provided if any service is not available.
2061
2062        Args:
2063            log: log object
2064            ad: android device
2065            wifi_connected: True if wifi should be connected. Otherwise False.
2066            ims_reg: True if IMS should be registered. Otherwise False.
2067            recover: True if the mechanism (cycling airplane mode) to recover
2068            network services should be enabled (by default False).
2069            retry: times of retry.
2070    """
2071    times = 1
2072    while times <= retry:
2073        while True:
2074            if not wait_for_state(
2075                    get_service_state_by_adb,
2076                    "IN_SERVICE",
2077                    MAX_WAIT_TIME_FOR_STATE_CHANGE,
2078                    WAIT_TIME_BETWEEN_STATE_CHECK,
2079                    log,
2080                    ad):
2081                ad.log.error("Current service state is not 'IN_SERVICE'.")
2082                break
2083
2084            if not wait_for_state(
2085                    ad.droid.connectivityNetworkIsConnected,
2086                    True,
2087                    MAX_WAIT_TIME_FOR_STATE_CHANGE,
2088                    WAIT_TIME_BETWEEN_STATE_CHECK):
2089                ad.log.error("Network is NOT connected!")
2090                break
2091
2092            if wifi_connected and wifi_ssid:
2093                if not wait_for_state(
2094                        check_is_wifi_connected,
2095                        True,
2096                        MAX_WAIT_TIME_FOR_STATE_CHANGE,
2097                        WAIT_TIME_BETWEEN_STATE_CHECK,
2098                        log,
2099                        ad,
2100                        wifi_ssid):
2101                    ad.log.error("Failed to connect Wi-Fi SSID '%s'.", wifi_ssid)
2102                    break
2103            else:
2104                if not wait_for_cell_data_connection(log, ad, True):
2105                    ad.log.error("Failed to enable data connection.")
2106                    break
2107
2108            if not wait_for_state(
2109                    verify_internet_connection,
2110                    True,
2111                    MAX_WAIT_TIME_FOR_STATE_CHANGE,
2112                    WAIT_TIME_BETWEEN_STATE_CHECK,
2113                    log,
2114                    ad):
2115                ad.log.error("Data not available on cell.")
2116                break
2117
2118            if ims_reg:
2119                if not wait_for_ims_registered(log, ad):
2120                    ad.log.error("IMS is not registered.")
2121                    break
2122                ad.log.info("IMS is registered.")
2123            return True
2124
2125        if recover:
2126            ad.log.warning("Trying to recover by cycling airplane mode...")
2127            if not toggle_airplane_mode(log, ad, True):
2128                ad.log.error("Failed to enable airplane mode")
2129                break
2130
2131            time.sleep(5)
2132
2133            if not toggle_airplane_mode(log, ad, False):
2134                ad.log.error("Failed to disable airplane mode")
2135                break
2136
2137            times = times + 1
2138
2139        else:
2140            return False
2141    return False
2142
2143
2144def wait_for_cell_data_connection(
2145        log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
2146    """Wait for data connection status to be expected value for default
2147       data subscription.
2148
2149    Wait for the data connection status to be DATA_STATE_CONNECTED
2150        or DATA_STATE_DISCONNECTED.
2151
2152    Args:
2153        log: Log object.
2154        ad: Android Device Object.
2155        state: Expected status: True or False.
2156            If True, it will wait for status to be DATA_STATE_CONNECTED.
2157            If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
2158        timeout_value: wait for cell data timeout value.
2159            This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
2160
2161    Returns:
2162        True if success.
2163        False if failed.
2164    """
2165    sub_id = get_default_data_sub_id(ad)
2166    return wait_for_cell_data_connection_for_subscription(
2167        log, ad, sub_id, state, timeout_value)
2168
2169
2170def _is_data_connection_state_match(log, ad, expected_data_connection_state):
2171    return (expected_data_connection_state ==
2172            ad.droid.telephonyGetDataConnectionState())
2173
2174
2175def _is_network_connected_state_match(log, ad,
2176                                      expected_network_connected_state):
2177    return (expected_network_connected_state ==
2178            ad.droid.connectivityNetworkIsConnected())
2179
2180
2181def wait_for_cell_data_connection_for_subscription(
2182        log,
2183        ad,
2184        sub_id,
2185        state,
2186        timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
2187    """Wait for data connection status to be expected value for specified
2188       subscrption id.
2189
2190    Wait for the data connection status to be DATA_STATE_CONNECTED
2191        or DATA_STATE_DISCONNECTED.
2192
2193    Args:
2194        log: Log object.
2195        ad: Android Device Object.
2196        sub_id: subscription Id
2197        state: Expected status: True or False.
2198            If True, it will wait for status to be DATA_STATE_CONNECTED.
2199            If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
2200        timeout_value: wait for cell data timeout value.
2201            This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
2202
2203    Returns:
2204        True if success.
2205        False if failed.
2206    """
2207    state_str = {
2208        True: DATA_STATE_CONNECTED,
2209        False: DATA_STATE_DISCONNECTED
2210    }[state]
2211
2212    data_state = ad.droid.telephonyGetDataConnectionState()
2213    if not state and ad.droid.telephonyGetDataConnectionState() == state_str:
2214        return True
2215
2216    ad.ed.clear_events(EventDataConnectionStateChanged)
2217    ad.droid.telephonyStartTrackingDataConnectionStateChangeForSubscription(
2218        sub_id)
2219    ad.droid.connectivityStartTrackingConnectivityStateChange()
2220    try:
2221        ad.log.info("User data enabled for sub_id %s: %s", sub_id,
2222                    ad.droid.telephonyIsDataEnabledForSubscription(sub_id))
2223        data_state = ad.droid.telephonyGetDataConnectionState()
2224        ad.log.info("Data connection state is %s", data_state)
2225        ad.log.info("Network is connected: %s",
2226                    ad.droid.connectivityNetworkIsConnected())
2227        if data_state == state_str:
2228            return _wait_for_nw_data_connection(
2229                log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
2230
2231        try:
2232            ad.ed.wait_for_event(
2233                EventDataConnectionStateChanged,
2234                is_event_match,
2235                timeout=timeout_value,
2236                field=DataConnectionStateContainer.DATA_CONNECTION_STATE,
2237                value=state_str)
2238        except Empty:
2239            ad.log.info("No expected event EventDataConnectionStateChanged %s",
2240                        state_str)
2241
2242        # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
2243        # data connection state.
2244        # Otherwise, the network state will not be correct.
2245        # The bug is tracked here: b/20921915
2246
2247        # Previously we use _is_data_connection_state_match,
2248        # but telephonyGetDataConnectionState sometimes return wrong value.
2249        # The bug is tracked here: b/22612607
2250        # So we use _is_network_connected_state_match.
2251
2252        if _wait_for_droid_in_state(log, ad, timeout_value,
2253                                    _is_network_connected_state_match, state):
2254            return _wait_for_nw_data_connection(
2255                log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
2256        else:
2257            return False
2258
2259    finally:
2260        ad.droid.telephonyStopTrackingDataConnectionStateChangeForSubscription(
2261            sub_id)
2262
2263
2264def wait_for_data_connection(
2265        log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
2266    """Wait for data connection status to be expected value.
2267
2268    Wait for the data connection status to be DATA_STATE_CONNECTED
2269        or DATA_STATE_DISCONNECTED.
2270
2271    Args:
2272        log: Log object.
2273        ad: Android Device Object.
2274        state: Expected status: True or False.
2275            If True, it will wait for status to be DATA_STATE_CONNECTED.
2276            If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
2277        timeout_value: wait for network data timeout value.
2278            This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
2279
2280    Returns:
2281        True if success.
2282        False if failed.
2283    """
2284    return _wait_for_nw_data_connection(log, ad, state, None, timeout_value)
2285
2286
2287def wait_for_wifi_data_connection(
2288        log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
2289    """Wait for data connection status to be expected value and connection is by WiFi.
2290
2291    Args:
2292        log: Log object.
2293        ad: Android Device Object.
2294        state: Expected status: True or False.
2295            If True, it will wait for status to be DATA_STATE_CONNECTED.
2296            If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
2297        timeout_value: wait for network data timeout value.
2298            This is optional, default value is MAX_WAIT_TIME_NW_SELECTION
2299
2300    Returns:
2301        True if success.
2302        False if failed.
2303    """
2304    ad.log.info("wait_for_wifi_data_connection")
2305    return _wait_for_nw_data_connection(
2306        log, ad, state, NETWORK_CONNECTION_TYPE_WIFI, timeout_value)
2307
2308
2309def _connection_state_change(_event, target_state, connection_type):
2310    if connection_type:
2311        if 'TypeName' not in _event['data']:
2312            return False
2313        connection_type_string_in_event = _event['data']['TypeName']
2314        cur_type = connection_type_from_type_string(
2315            connection_type_string_in_event)
2316        if cur_type != connection_type:
2317            logging.info(
2318                "_connection_state_change expect: %s, received: %s <type %s>",
2319                connection_type, connection_type_string_in_event, cur_type)
2320            return False
2321
2322    if 'isConnected' in _event['data'] and _event['data']['isConnected'] == target_state:
2323        return True
2324    return False
2325
2326
2327def _wait_for_nw_data_connection(
2328        log,
2329        ad,
2330        is_connected,
2331        connection_type=None,
2332        timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
2333    """Wait for data connection status to be expected value.
2334
2335    Wait for the data connection status to be DATA_STATE_CONNECTED
2336        or DATA_STATE_DISCONNECTED.
2337
2338    Args:
2339        log: Log object.
2340        ad: Android Device Object.
2341        is_connected: Expected connection status: True or False.
2342            If True, it will wait for status to be DATA_STATE_CONNECTED.
2343            If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
2344        connection_type: expected connection type.
2345            This is optional, if it is None, then any connection type will return True.
2346        timeout_value: wait for network data timeout value.
2347            This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
2348
2349    Returns:
2350        True if success.
2351        False if failed.
2352    """
2353    ad.ed.clear_events(EventConnectivityChanged)
2354    ad.droid.connectivityStartTrackingConnectivityStateChange()
2355    try:
2356        cur_data_connection_state = ad.droid.connectivityNetworkIsConnected()
2357        if is_connected == cur_data_connection_state:
2358            current_type = get_internet_connection_type(log, ad)
2359            ad.log.info("current data connection type: %s", current_type)
2360            if not connection_type:
2361                return True
2362            else:
2363                if not is_connected and current_type != connection_type:
2364                    ad.log.info("data connection not on %s!", connection_type)
2365                    return True
2366                elif is_connected and current_type == connection_type:
2367                    ad.log.info("data connection on %s as expected",
2368                                connection_type)
2369                    return True
2370        else:
2371            ad.log.info("current data connection state: %s target: %s",
2372                        cur_data_connection_state, is_connected)
2373
2374        try:
2375            event = ad.ed.wait_for_event(
2376                EventConnectivityChanged, _connection_state_change,
2377                timeout_value, is_connected, connection_type)
2378            ad.log.info("Got event: %s", event)
2379        except Empty:
2380            pass
2381
2382        log.info(
2383            "_wait_for_nw_data_connection: check connection after wait event.")
2384        # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
2385        # data connection state.
2386        # Otherwise, the network state will not be correct.
2387        # The bug is tracked here: b/20921915
2388        if _wait_for_droid_in_state(log, ad, timeout_value,
2389                                    _is_network_connected_state_match,
2390                                    is_connected):
2391            current_type = get_internet_connection_type(log, ad)
2392            ad.log.info("current data connection type: %s", current_type)
2393            if not connection_type:
2394                return True
2395            else:
2396                if not is_connected and current_type != connection_type:
2397                    ad.log.info("data connection not on %s", connection_type)
2398                    return True
2399                elif is_connected and current_type == connection_type:
2400                    ad.log.info("after event wait, data connection on %s",
2401                                connection_type)
2402                    return True
2403                else:
2404                    return False
2405        else:
2406            return False
2407    except Exception as e:
2408        ad.log.error("Exception error %s", str(e))
2409        return False
2410    finally:
2411        ad.droid.connectivityStopTrackingConnectivityStateChange()
2412
2413
2414def check_curl_availability(ad):
2415    if not hasattr(ad, "curl_capable"):
2416        try:
2417            out = ad.adb.shell("/data/curl --version")
2418            if not out or "not found" in out:
2419                setattr(ad, "curl_capable", False)
2420                ad.log.info("curl is unavailable, use chrome to download file")
2421            else:
2422                setattr(ad, "curl_capable", True)
2423        except Exception:
2424            setattr(ad, "curl_capable", False)
2425            ad.log.info("curl is unavailable, use chrome to download file")
2426    return ad.curl_capable
2427
2428
2429def start_youtube_video(ad, url="vnd.youtube:watch?v=pSJoP0LR8CQ"):
2430    ad.log.info("Open an youtube video")
2431    for _ in range(3):
2432        ad.ensure_screen_on()
2433        ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
2434        if wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1):
2435            ad.log.info("Started a video in youtube, audio is in MUSIC state")
2436            return True
2437        ad.log.info("Audio is not in MUSIC state. Quit Youtube.")
2438        for _ in range(3):
2439            ad.send_keycode("BACK")
2440            time.sleep(1)
2441        time.sleep(3)
2442    return False
2443
2444
2445def http_file_download_by_sl4a(ad,
2446                               url,
2447                               out_path=None,
2448                               expected_file_size=None,
2449                               remove_file_after_check=True,
2450                               timeout=300):
2451    """Download http file by sl4a RPC call.
2452
2453    Args:
2454        ad: Android Device Object.
2455        url: The url that file to be downloaded from".
2456        out_path: Optional. Where to download file to.
2457                  out_path is /sdcard/Download/ by default.
2458        expected_file_size: Optional. Provided if checking the download file meet
2459                            expected file size in unit of byte.
2460        remove_file_after_check: Whether to remove the downloaded file after
2461                                 check.
2462        timeout: timeout for file download to complete.
2463    """
2464    file_folder, file_name = _generate_file_directory_and_file_name(
2465        url, out_path)
2466    file_path = os.path.join(file_folder, file_name)
2467    ad.adb.shell("rm -f %s" % file_path)
2468    accounting_apk = SL4A_APK_NAME
2469    result = True
2470    try:
2471        if not getattr(ad, "data_droid", None):
2472            ad.data_droid, ad.data_ed = ad.get_droid()
2473            ad.data_ed.start()
2474        else:
2475            try:
2476                if not ad.data_droid.is_live:
2477                    ad.data_droid, ad.data_ed = ad.get_droid()
2478                    ad.data_ed.start()
2479            except Exception:
2480                ad.log.info("Start new sl4a session for file download")
2481                ad.data_droid, ad.data_ed = ad.get_droid()
2482                ad.data_ed.start()
2483        data_accounting = {
2484            "mobile_rx_bytes":
2485            ad.droid.getMobileRxBytes(),
2486            "subscriber_mobile_data_usage":
2487            get_mobile_data_usage(ad, None, None),
2488            "sl4a_mobile_data_usage":
2489            get_mobile_data_usage(ad, None, accounting_apk)
2490        }
2491        ad.log.debug("Before downloading: %s", data_accounting)
2492        ad.log.info("Download file from %s to %s by sl4a RPC call", url,
2493                    file_path)
2494        try:
2495            ad.data_droid.httpDownloadFile(url, file_path, timeout=timeout)
2496        except Exception as e:
2497            ad.log.warning("SL4A file download error: %s", e)
2498            ad.data_droid.terminate()
2499            return False
2500        if _check_file_existence(ad, file_path, expected_file_size):
2501            ad.log.info("%s is downloaded successfully", url)
2502            new_data_accounting = {
2503                "mobile_rx_bytes":
2504                ad.droid.getMobileRxBytes(),
2505                "subscriber_mobile_data_usage":
2506                get_mobile_data_usage(ad, None, None),
2507                "sl4a_mobile_data_usage":
2508                get_mobile_data_usage(ad, None, accounting_apk)
2509            }
2510            ad.log.debug("After downloading: %s", new_data_accounting)
2511            accounting_diff = {
2512                key: value - data_accounting[key]
2513                for key, value in new_data_accounting.items()
2514            }
2515            ad.log.debug("Data accounting difference: %s", accounting_diff)
2516            if getattr(ad, "on_mobile_data", False):
2517                for key, value in accounting_diff.items():
2518                    if value < expected_file_size:
2519                        ad.log.debug("%s diff is %s less than %s", key,
2520                                       value, expected_file_size)
2521                        ad.data_accounting["%s_failure"] += 1
2522            else:
2523                for key, value in accounting_diff.items():
2524                    if value >= expected_file_size:
2525                        ad.log.error("%s diff is %s. File download is "
2526                                     "consuming mobile data", key, value)
2527                        result = False
2528            return result
2529        else:
2530            ad.log.warning("Fail to download %s", url)
2531            return False
2532    except Exception as e:
2533        ad.log.error("Download %s failed with exception %s", url, e)
2534        raise
2535    finally:
2536        if remove_file_after_check:
2537            ad.log.info("Remove the downloaded file %s", file_path)
2538            ad.adb.shell("rm %s" % file_path, ignore_status=True)
2539
2540
2541def http_file_download_by_curl(ad,
2542                               url,
2543                               out_path=None,
2544                               expected_file_size=None,
2545                               remove_file_after_check=True,
2546                               timeout=3600,
2547                               limit_rate=None,
2548                               retry=3):
2549    """Download http file by adb curl.
2550
2551    Args:
2552        ad: Android Device Object.
2553        url: The url that file to be downloaded from".
2554        out_path: Optional. Where to download file to.
2555                  out_path is /sdcard/Download/ by default.
2556        expected_file_size: Optional. Provided if checking the download file meet
2557                            expected file size in unit of byte.
2558        remove_file_after_check: Whether to remove the downloaded file after
2559                                 check.
2560        timeout: timeout for file download to complete.
2561        limit_rate: download rate in bps. None, if do not apply rate limit.
2562        retry: the retry request times provided in curl command.
2563    """
2564    file_directory, file_name = _generate_file_directory_and_file_name(
2565        url, out_path)
2566    file_path = os.path.join(file_directory, file_name)
2567    curl_cmd = "/data/curl"
2568    if limit_rate:
2569        curl_cmd += " --limit-rate %s" % limit_rate
2570    if retry:
2571        curl_cmd += " --retry %s" % retry
2572    curl_cmd += " --url %s > %s" % (url, file_path)
2573    try:
2574        ad.log.info("Download %s to %s by adb shell command %s", url,
2575                    file_path, curl_cmd)
2576
2577        ad.adb.shell(curl_cmd, timeout=timeout)
2578        if _check_file_existence(ad, file_path, expected_file_size):
2579            ad.log.info("%s is downloaded to %s successfully", url, file_path)
2580            return True
2581        else:
2582            ad.log.warning("Fail to download %s", url)
2583            return False
2584    except Exception as e:
2585        ad.log.warning("Download %s failed with exception %s", url, e)
2586        return False
2587    finally:
2588        if remove_file_after_check:
2589            ad.log.info("Remove the downloaded file %s", file_path)
2590            ad.adb.shell("rm %s" % file_path, ignore_status=True)
2591
2592
2593def open_url_by_adb(ad, url):
2594    ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
2595
2596
2597def http_file_download_by_chrome(ad,
2598                                 url,
2599                                 expected_file_size=None,
2600                                 remove_file_after_check=True,
2601                                 timeout=3600):
2602    """Download http file by chrome.
2603
2604    Args:
2605        ad: Android Device Object.
2606        url: The url that file to be downloaded from".
2607        expected_file_size: Optional. Provided if checking the download file meet
2608                            expected file size in unit of byte.
2609        remove_file_after_check: Whether to remove the downloaded file after
2610                                 check.
2611        timeout: timeout for file download to complete.
2612    """
2613    chrome_apk = "com.android.chrome"
2614    file_directory, file_name = _generate_file_directory_and_file_name(
2615        url, "/sdcard/Download/")
2616    file_path = os.path.join(file_directory, file_name)
2617    # Remove pre-existing file
2618    ad.force_stop_apk(chrome_apk)
2619    file_to_be_delete = os.path.join(file_directory, "*%s*" % file_name)
2620    ad.adb.shell("rm -f %s" % file_to_be_delete)
2621    ad.adb.shell("rm -rf /sdcard/Download/.*")
2622    ad.adb.shell("rm -f /sdcard/Download/.*")
2623    data_accounting = {
2624        "total_rx_bytes": ad.droid.getTotalRxBytes(),
2625        "mobile_rx_bytes": ad.droid.getMobileRxBytes(),
2626        "subscriber_mobile_data_usage": get_mobile_data_usage(ad, None, None),
2627        "chrome_mobile_data_usage": get_mobile_data_usage(
2628            ad, None, chrome_apk)
2629    }
2630    ad.log.debug("Before downloading: %s", data_accounting)
2631    ad.log.info("Download %s with timeout %s", url, timeout)
2632    ad.ensure_screen_on()
2633    open_url_by_adb(ad, url)
2634    elapse_time = 0
2635    result = True
2636    while elapse_time < timeout:
2637        time.sleep(30)
2638        if _check_file_existence(ad, file_path, expected_file_size):
2639            ad.log.info("%s is downloaded successfully", url)
2640            if remove_file_after_check:
2641                ad.log.info("Remove the downloaded file %s", file_path)
2642                ad.adb.shell("rm -f %s" % file_to_be_delete)
2643                ad.adb.shell("rm -rf /sdcard/Download/.*")
2644                ad.adb.shell("rm -f /sdcard/Download/.*")
2645            #time.sleep(30)
2646            new_data_accounting = {
2647                "mobile_rx_bytes":
2648                ad.droid.getMobileRxBytes(),
2649                "subscriber_mobile_data_usage":
2650                get_mobile_data_usage(ad, None, None),
2651                "chrome_mobile_data_usage":
2652                get_mobile_data_usage(ad, None, chrome_apk)
2653            }
2654            ad.log.info("After downloading: %s", new_data_accounting)
2655            accounting_diff = {
2656                key: value - data_accounting[key]
2657                for key, value in new_data_accounting.items()
2658            }
2659            ad.log.debug("Data accounting difference: %s", accounting_diff)
2660            if getattr(ad, "on_mobile_data", False):
2661                for key, value in accounting_diff.items():
2662                    if value < expected_file_size:
2663                        ad.log.warning("%s diff is %s less than %s", key,
2664                                       value, expected_file_size)
2665                        ad.data_accounting["%s_failure" % key] += 1
2666            else:
2667                for key, value in accounting_diff.items():
2668                    if value >= expected_file_size:
2669                        ad.log.error("%s diff is %s. File download is "
2670                                     "consuming mobile data", key, value)
2671                        result = False
2672            return result
2673        elif _check_file_existence(ad, "%s.crdownload" % file_path):
2674            ad.log.info("Chrome is downloading %s", url)
2675        elif elapse_time < 60:
2676            # download not started, retry download wit chrome again
2677            open_url_by_adb(ad, url)
2678        else:
2679            ad.log.error("Unable to download file from %s", url)
2680            break
2681        elapse_time += 30
2682    ad.log.warning("Fail to download file from %s", url)
2683    ad.force_stop_apk("com.android.chrome")
2684    ad.adb.shell("rm -f %s" % file_to_be_delete)
2685    ad.adb.shell("rm -rf /sdcard/Download/.*")
2686    ad.adb.shell("rm -f /sdcard/Download/.*")
2687    return False
2688
2689
2690def get_mobile_data_usage(ad, sid=None, apk=None):
2691    if not sid:
2692        sid = ad.droid.subscriptionGetDefaultDataSubId()
2693    current_time = int(time.time() * 1000)
2694    begin_time = current_time - 10 * 24 * 60 * 60 * 1000
2695    end_time = current_time + 10 * 24 * 60 * 60 * 1000
2696
2697    if apk:
2698        uid = ad.get_apk_uid(apk)
2699        ad.log.debug("apk %s uid = %s", apk, uid)
2700        try:
2701            usage_info = ad.droid.getMobileDataUsageInfoForUid(uid, sid)
2702            ad.log.debug("Mobile data usage info for uid %s = %s", uid,
2703                        usage_info)
2704            return usage_info["UsageLevel"]
2705        except:
2706            try:
2707                return ad.droid.connectivityQueryDetailsForUid(
2708                    TYPE_MOBILE,
2709                    ad.droid.telephonyGetSubscriberIdForSubscription(sid),
2710                    begin_time, end_time, uid)
2711            except:
2712                return ad.droid.connectivityQueryDetailsForUid(
2713                    ad.droid.telephonyGetSubscriberIdForSubscription(sid),
2714                    begin_time, end_time, uid)
2715    else:
2716        try:
2717            usage_info = ad.droid.getMobileDataUsageInfo(sid)
2718            ad.log.debug("Mobile data usage info = %s", usage_info)
2719            return usage_info["UsageLevel"]
2720        except:
2721            try:
2722                return ad.droid.connectivityQuerySummaryForDevice(
2723                    TYPE_MOBILE,
2724                    ad.droid.telephonyGetSubscriberIdForSubscription(sid),
2725                    begin_time, end_time)
2726            except:
2727                return ad.droid.connectivityQuerySummaryForDevice(
2728                    ad.droid.telephonyGetSubscriberIdForSubscription(sid),
2729                    begin_time, end_time)
2730
2731
2732def set_mobile_data_usage_limit(ad, limit, subscriber_id=None):
2733    if not subscriber_id:
2734        subscriber_id = ad.droid.telephonyGetSubscriberId()
2735    ad.log.debug("Set subscriber mobile data usage limit to %s", limit)
2736    ad.droid.logV("Setting subscriber mobile data usage limit to %s" % limit)
2737    try:
2738        ad.droid.connectivitySetDataUsageLimit(subscriber_id, str(limit))
2739    except:
2740        ad.droid.connectivitySetDataUsageLimit(subscriber_id, limit)
2741
2742
2743def remove_mobile_data_usage_limit(ad, subscriber_id=None):
2744    if not subscriber_id:
2745        subscriber_id = ad.droid.telephonyGetSubscriberId()
2746    ad.log.debug("Remove subscriber mobile data usage limit")
2747    ad.droid.logV(
2748        "Setting subscriber mobile data usage limit to -1, unlimited")
2749    try:
2750        ad.droid.connectivitySetDataUsageLimit(subscriber_id, "-1")
2751    except:
2752        ad.droid.connectivitySetDataUsageLimit(subscriber_id, -1)
2753
2754
2755def active_file_download_task(log, ad, file_name="5MB", method="curl"):
2756    # files available for download on the same website:
2757    # 1GB.zip, 512MB.zip, 200MB.zip, 50MB.zip, 20MB.zip, 10MB.zip, 5MB.zip
2758    # download file by adb command, as phone call will use sl4a
2759    file_size_map = {
2760        '1MB': 1000000,
2761        '5MB': 5000000,
2762        '10MB': 10000000,
2763        '20MB': 20000000,
2764        '50MB': 50000000,
2765        '100MB': 100000000,
2766        '200MB': 200000000,
2767        '512MB': 512000000
2768    }
2769    url_map = {
2770        "1MB": [
2771            "http://146.148.91.8/download/1MB.zip",
2772            "http://ipv4.download.thinkbroadband.com/1MB.zip"
2773        ],
2774        "5MB": [
2775            "http://146.148.91.8/download/5MB.zip",
2776            "http://212.183.159.230/5MB.zip",
2777            "http://ipv4.download.thinkbroadband.com/5MB.zip"
2778        ],
2779        "10MB": [
2780            "http://146.148.91.8/download/10MB.zip",
2781            "http://212.183.159.230/10MB.zip",
2782            "http://ipv4.download.thinkbroadband.com/10MB.zip",
2783            "http://lax.futurehosting.com/test.zip",
2784            "http://ovh.net/files/10Mio.dat"
2785        ],
2786        "20MB": [
2787            "http://146.148.91.8/download/20MB.zip",
2788            "http://212.183.159.230/20MB.zip",
2789            "http://ipv4.download.thinkbroadband.com/20MB.zip"
2790        ],
2791        "50MB": [
2792            "http://146.148.91.8/download/50MB.zip",
2793            "http://212.183.159.230/50MB.zip",
2794            "http://ipv4.download.thinkbroadband.com/50MB.zip"
2795        ],
2796        "100MB": [
2797            "http://146.148.91.8/download/100MB.zip",
2798            "http://212.183.159.230/100MB.zip",
2799            "http://ipv4.download.thinkbroadband.com/100MB.zip",
2800            "http://speedtest-ca.turnkeyinternet.net/100mb.bin",
2801            "http://ovh.net/files/100Mio.dat",
2802            "http://lax.futurehosting.com/test100.zip"
2803        ],
2804        "200MB": [
2805            "http://146.148.91.8/download/200MB.zip",
2806            "http://212.183.159.230/200MB.zip",
2807            "http://ipv4.download.thinkbroadband.com/200MB.zip"
2808        ],
2809        "512MB": [
2810            "http://146.148.91.8/download/512MB.zip",
2811            "http://212.183.159.230/512MB.zip",
2812            "http://ipv4.download.thinkbroadband.com/512MB.zip"
2813        ]
2814    }
2815
2816    file_size = file_size_map.get(file_name)
2817    file_urls = url_map.get(file_name)
2818    file_url = None
2819    for url in file_urls:
2820        url_splits = url.split("/")
2821        if verify_http_connection(log, ad, url=url, retry=1):
2822            output_path = "/sdcard/Download/%s" % url_splits[-1]
2823            file_url = url
2824            break
2825    if not file_url:
2826        ad.log.error("No url is available to download %s", file_name)
2827        return False
2828    timeout = min(max(file_size / 100000, 600), 3600)
2829    if method == "sl4a":
2830        return (http_file_download_by_sl4a, (ad, file_url, output_path,
2831                                             file_size, True, timeout))
2832    if method == "curl" and check_curl_availability(ad):
2833        return (http_file_download_by_curl, (ad, file_url, output_path,
2834                                             file_size, True, timeout))
2835    elif method == "sl4a" or method == "curl":
2836        return (http_file_download_by_sl4a, (ad, file_url, output_path,
2837                                             file_size, True, timeout))
2838    else:
2839        return (http_file_download_by_chrome, (ad, file_url, file_size, True,
2840                                               timeout))
2841
2842
2843def active_file_download_test(log, ad, file_name="5MB", method="sl4a"):
2844    task = active_file_download_task(log, ad, file_name, method=method)
2845    if not task:
2846        return False
2847    return task[0](*task[1])
2848
2849
2850def check_data_stall_detection(ad, wait_time=WAIT_TIME_FOR_DATA_STALL):
2851    data_stall_detected = False
2852    time_var = 1
2853    try:
2854        while (time_var < wait_time):
2855            out = ad.adb.shell("dumpsys network_stack " \
2856                              "| grep \"Suspecting data stall\"",
2857                            ignore_status=True)
2858            ad.log.debug("Output is %s", out)
2859            if out:
2860                ad.log.info("NetworkMonitor detected - %s", out)
2861                data_stall_detected = True
2862                break
2863            time.sleep(30)
2864            time_var += 30
2865    except Exception as e:
2866        ad.log.error(e)
2867    return data_stall_detected
2868
2869
2870def check_network_validation_fail(ad, begin_time=None,
2871                                  wait_time=WAIT_TIME_FOR_NW_VALID_FAIL):
2872    network_validation_fail = False
2873    time_var = 1
2874    try:
2875        while (time_var < wait_time):
2876            time_var += 30
2877            nw_valid = ad.search_logcat("validation failed",
2878                                         begin_time)
2879            if nw_valid:
2880                ad.log.info("Validation Failed received here - %s",
2881                            nw_valid[0]["log_message"])
2882                network_validation_fail = True
2883                break
2884            time.sleep(30)
2885    except Exception as e:
2886        ad.log.error(e)
2887    return network_validation_fail
2888
2889
2890def check_data_stall_recovery(ad, begin_time=None,
2891                              wait_time=WAIT_TIME_FOR_DATA_STALL_RECOVERY):
2892    data_stall_recovery = False
2893    time_var = 1
2894    try:
2895        while (time_var < wait_time):
2896            time_var += 30
2897            recovery = ad.search_logcat("doRecovery() cleanup all connections",
2898                                         begin_time)
2899            if recovery:
2900                ad.log.info("Recovery Performed here - %s",
2901                            recovery[-1]["log_message"])
2902                data_stall_recovery = True
2903                break
2904            time.sleep(30)
2905    except Exception as e:
2906        ad.log.error(e)
2907    return data_stall_recovery