Merge "This is the fix for THD+N value show 0.00% after 1st iteration."
diff --git a/acts/framework/acts/controllers/android_device.py b/acts/framework/acts/controllers/android_device.py
index 22c80e1..6ccab67 100755
--- a/acts/framework/acts/controllers/android_device.py
+++ b/acts/framework/acts/controllers/android_device.py
@@ -1046,6 +1046,21 @@
         """
         return self.adb.shell('echo $EXTERNAL_STORAGE')
 
+    def file_exists(self, file_path):
+        """Returns whether a file exists on a device.
+
+        Args:
+            file_path: The path of the file to check for.
+        """
+        cmd = '(test -f %s && echo yes) || echo no' % file_path
+        result = self.adb.shell(cmd)
+        if result == 'yes':
+            return True
+        elif result == 'no':
+            return False
+        raise ValueError('Couldn\'t determine if %s exists. '
+                         'Expected yes/no, got %s' % (file_path, result[cmd]))
+
     def pull_files(self, device_paths, host_path=None):
         """Pull files from devices.
 
diff --git a/acts_tests/acts_contrib/test_utils/bt/BleEnum.py b/acts_tests/acts_contrib/test_utils/bt/BleEnum.py
index 00763aa..3371d67 100644
--- a/acts_tests/acts_contrib/test_utils/bt/BleEnum.py
+++ b/acts_tests/acts_contrib/test_utils/bt/BleEnum.py
@@ -46,15 +46,18 @@
     SCAN_MODE_BALANCED = 1
     SCAN_MODE_LOW_LATENCY = 2
 
+
 class ScanSettingsReportDelaySeconds(Enum):
     MIN = 0
     MAX = 9223372036854775807
 
+
 class ScanSettingsPhy(Enum):
     PHY_LE_1M = 1
     PHY_LE_CODED = 3
     PHY_LE_ALL_SUPPORTED = 255
 
+
 class AdvertiseSettingsAdvertiseType(Enum):
     ADVERTISE_TYPE_NON_CONNECTABLE = 0
     ADVERTISE_TYPE_CONNECTABLE = 1
@@ -73,6 +76,13 @@
     ADVERTISE_TX_POWER_HIGH = 3
 
 
+class BLEConnectionPriority(Enum):
+    # Connection Interval: BALANCED = 36ms, HIGH = 12ms, LOW = 96ms
+    CONNECTION_PRIORITY_BALANCED = 0
+    CONNECTION_PRIORITY_HIGH = 1
+    CONNECTION_PRIORITY_LOW = 2
+
+
 class JavaInteger(Enum):
     MIN = -2147483648
     MAX = 2147483647
diff --git a/acts_tests/acts_contrib/test_utils/bt/bt_power_test_utils.py b/acts_tests/acts_contrib/test_utils/bt/bt_power_test_utils.py
index 899621f..19a6b44 100644
--- a/acts_tests/acts_contrib/test_utils/bt/bt_power_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/bt/bt_power_test_utils.py
@@ -21,6 +21,9 @@
 
 BLE_LOCATION_SCAN_ENABLE = 'settings put global ble_scan_always_enabled 1'
 BLE_LOCATION_SCAN_DISABLE = 'settings put global ble_scan_always_enabled 0'
+START_BLE_ADV = 'am start -n com.google.bletesting/.ActsCommandExecutor --es command ADVERTISE#2#2#30000'
+START_BLE_SCAN = 'am start -n com.google.bletesting/.ActsCommandExecutor --es command SCAN#2#10000'
+SCAN_DURATION = 10
 SCREEN_WAIT_TIME = 1
 
 
@@ -29,7 +32,6 @@
 
     Object to control media play status using adb.
     """
-
     def __init__(self, android_device, music_file):
         """Initialize the media_control class.
 
@@ -157,3 +159,27 @@
     logging.info('Start BLE {} scans for {} seconds'.format(
         bleenum.ScanSettingsScanMode(scan_mode).name, scan_duration))
     dut.adb.shell_nb(scan_command)
+
+
+def establish_ble_connection(client_ad, server_ad, con_priority):
+    """Establish BLE connection using BLE_Test.apk.
+
+    Args:
+        client_ad: the Android device performing the BLE connection.
+        server_ad: the Android device accepting the BLE connection.
+        con_priority: The BLE Connection Priority.
+            {0: 'BALANCED'= Use the connection parameters recommended by the Bluetooth SIG,
+            1: 'HIGH'= Request a high priority, low latency connection,
+            2: 'LOW_POWER= Request low power, reduced data rate connection parameters }
+    """
+    server_ad.adb.shell(START_BLE_ADV)
+    time.sleep(5)
+    client_ad.adb.shell(START_BLE_SCAN)
+    time.sleep(SCAN_DURATION)
+    logging.info("Connection Priority is:{}".format(con_priority))
+    client_ad.adb.shell(
+        'am start -n com.google.bletesting/.ActsCommandExecutor '
+        '--es command GATTCONNECT#{}'.format(con_priority))
+    logging.info(
+        "BLE Connection Successful with Connection Priority:{}".format(
+            con_priority))
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_defines.py b/acts_tests/acts_contrib/test_utils/tel/tel_defines.py
index e5d86f4..ecc8510 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_defines.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_defines.py
@@ -475,6 +475,7 @@
 # Constant for Network RAT
 RAT_IWLAN = "IWLAN"
 RAT_NR = "NR"
+RAT_NR_SA = "NR_SA"
 RAT_LTE = "LTE"
 RAT_5G = "5G"
 RAT_4G = "4G"
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_lookup_tables.py b/acts_tests/acts_contrib/test_utils/tel/tel_lookup_tables.py
index c794fa6..247f65e 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_lookup_tables.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_lookup_tables.py
@@ -404,6 +404,13 @@
             'simultaneous_voice_data': True,
             'rat_family': tel_defines.RAT_FAMILY_NR
         },
+        tel_defines.RAT_NR_SA: {
+            'is_voice_rat': True,
+            'is_data_rat': True,
+            'generation': tel_defines.GEN_5G,
+            'simultaneous_voice_data': True,
+            'rat_family': tel_defines.RAT_FAMILY_NR
+        },
         tel_defines.RAT_EHRPD: {
             'is_voice_rat': False,
             'is_data_rat': True,
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py
index 1808b7f..cbc7636 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py
@@ -77,6 +77,7 @@
 from acts_contrib.test_utils.tel.tel_test_utils import \
     reset_preferred_network_type_to_allowable_range
 from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode
+from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode_for_subscription
 from acts_contrib.test_utils.tel.tel_test_utils import set_wifi_to_default
 from acts_contrib.test_utils.tel.tel_test_utils import TelResultWrapper
 from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
@@ -850,7 +851,7 @@
         ad.log.info("WiFi network SSID not specified, available user "
                     "parameters are: wifi_network_ssid, wifi_network_ssid_2g, "
                     "wifi_network_ssid_5g")
-    if not set_wfc_mode(log, ad, wfc_mode):
+    if not set_wfc_mode_for_subscription(ad, wfc_mode, sub_id):
         ad.log.error("Unable to set WFC mode to %s.", wfc_mode)
         return False
     if not wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceTest.py
index 27696ed..123488b 100755
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceTest.py
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gVoiceTest.py
@@ -277,7 +277,7 @@
             result = False
         return result
 
-    def _call_epdg_to_epdg_wfc_5g_nsa(self,
+    def _test_call_epdg_to_epdg_wfc_5g_nsa(self,
                                       ads,
                                       apm_mode,
                                       wfc_mode,
@@ -361,6 +361,59 @@
             self.log.error("ICMP transfer failed with parallel phone call.")
         return all(results)
 
+    def _test_call_setup_hold_unhold(self,
+                                     ads,
+                                     call_direction=DIRECTION_MOBILE_ORIGINATED,
+                                     caller_func=None,
+                                     callee_func=None):
+        """Test hold and unhold in voice call.
+
+        1. Clear call list.
+        2. Set up MO/MT call.
+        3. Test hold and unhold in call.
+        4. hangup call.
+
+        Args:
+            ads: list of android objects, this list should have two ad.
+            call_direction: MO or MT call.
+            caller_func: function to verify caller is in correct state while in-call.
+            callee_func: function to verify callee is in correct state while in-call.
+
+        Returns:
+            True if pass; False if fail.
+        """
+
+        ads[0].droid.telecomCallClearCallList()
+        if num_active_calls(self.log, ads[0]) != 0:
+            ads[0].log.error("call list is not empty")
+            return False
+        self.log.info("begin hold/unhold test")
+
+        ad_caller = ads[0]
+        ad_callee = ads[1]
+
+        if call_direction != DIRECTION_MOBILE_ORIGINATED:
+            ad_caller = ads[1]
+            ad_callee = ads[0]
+
+        if not call_setup_teardown(
+                    self.log,
+                    ad_caller,
+                    ad_callee,
+                    ad_hangup=None,
+                    verify_caller_func=caller_func,
+                    verify_callee_func=callee_func):
+            return False
+
+        if not self._hold_unhold_test(ads):
+            self.log.error("hold/unhold test fail.")
+            return False
+
+        if not hangup_call(self.log, ads[0]):
+            self.log.error("call hangup failed")
+            return False
+        return True
+
     """ Tests Begin """
 
     @test_tracker_info(uuid="1bef3da1-4608-4b0e-8b78-f3f7be0115d5")
@@ -470,27 +523,9 @@
         if not provision_both_devices_for_5g(self.log, ads):
             return False
 
-        ads[0].droid.telecomCallClearCallList()
-        if num_active_calls(self.log, ads[0]) != 0:
-            ads[0].log.error("call list is not empty")
-            return False
-
-        self.log.info("begin hold/unhold test")
-        if not call_setup_teardown(
-                self.log,
-                ads[0],
-                ads[1],
-                ad_hangup=None,
-                verify_caller_func=is_phone_in_call_volte,
-                verify_callee_func=None):
-            return False
-
-        if not self._hold_unhold_test(ads):
-            self.log.error("hold/unhold test fail.")
-            return False
-
-        if not hangup_call(self.log, ads[0]):
-            self.log.error("call hangup failed")
+        if not self._test_call_setup_hold_unhold(ads,
+                                                 DIRECTION_MOBILE_ORIGINATED,
+                                                 caller_func=is_phone_in_call_volte):
             return False
 
         if not verify_5g_attach_for_both_devices(self.log, ads):
@@ -519,27 +554,9 @@
         if not provision_both_devices_for_5g(self.log, ads):
             return False
 
-        ads[0].droid.telecomCallClearCallList()
-        if num_active_calls(self.log, ads[0]) != 0:
-            ads[0].log.error("call list is not empty.")
-            return False
-
-        self.log.info("begin mt call hold/unhold Test.")
-        if not call_setup_teardown(
-                self.log,
-                ads[1],
-                ads[0],
-                ad_hangup=None,
-                verify_caller_func=None,
-                verify_callee_func=is_phone_in_call_volte):
-            return False
-
-        if not self._hold_unhold_test(ads):
-            self.log.error("hold/unhold test fail.")
-            return False
-
-        if not hangup_call(self.log, ads[0]):
-            self.log.error("call hangup failed")
+        if not self._test_call_setup_hold_unhold(ads,
+                                                 DIRECTION_MOBILE_TERMINATED,
+                                                 callee_func=is_phone_in_call_volte):
             return False
 
         if not verify_5g_attach_for_both_devices(self.log, ads):
@@ -678,7 +695,7 @@
         Returns:
             True if pass; False if fail.
         """
-        return self._call_epdg_to_epdg_wfc_5g_nsa(
+        return self._test_call_epdg_to_epdg_wfc_5g_nsa(
             self.android_devices, False, WFC_MODE_WIFI_PREFERRED,
             self.wifi_network_ssid, self.wifi_network_pass)
 
@@ -787,4 +804,88 @@
         return self._test_call_setup_in_active_data_transfer_5g_nsa(
             call_direction=DIRECTION_MOBILE_TERMINATED)
 
+
+    @test_tracker_info(uuid="e360bc3a-96b3-4fdf-9bf3-fe3aa08b1af5")
+    @TelephonyBaseTest.tel_test_wrap
+    def test_5g_nsa_call_epdg_mo_hold_unhold_wfc_wifi_preferred(self):
+        """ WiFi Preferred, WiFi calling MO call hold/unhold test on 5G NSA
+
+        1. Setup PhoneA WFC mode: WIFI_PREFERRED.
+        2. Set preferred network of phoneA on 5G NSA
+        3. Verify phoneA is on 5G NSA.
+        4. Call from PhoneA to PhoneB, accept on PhoneB.
+        5. Hold and unhold on PhoneA.
+        6. Verify phoneA is on 5G NSA.
+
+        Returns:
+            True if pass; False if fail.
+        """
+        ads = self.android_devices
+        if not phone_setup_iwlan(self.log, self.android_devices[0], False,
+                                 WFC_MODE_WIFI_PREFERRED,
+                                 self.wifi_network_ssid,
+                                 self.wifi_network_pass):
+            self.android_devices[0].log.error(
+                "Failed to setup iwlan with APM off and WIFI and WFC on")
+            return False
+        # Mode Pref
+        set_preferred_mode_for_5g(ads[0])
+
+        # Attach nsa5g
+        if not is_current_network_5g_nsa(ads[0]):
+            ads[0].log.error("Phone not attached on 5G NSA before call.")
+            return False
+
+        if not self._test_call_setup_hold_unhold(ads,
+                                                 DIRECTION_MOBILE_ORIGINATED,
+                                                 caller_func=is_phone_in_call_iwlan):
+            return False
+
+        if not is_current_network_5g_nsa(ads[0]):
+            ads[0].log.error("Phone not attached on 5G NSA after call.")
+            return False
+        return True
+
+
+    @test_tracker_info(uuid="d2335c83-87ec-4a0e-97a8-b53f769b0d21")
+    @TelephonyBaseTest.tel_test_wrap
+    def test_5g_nsa_call_epdg_mt_hold_unhold_wfc_wifi_preferred(self):
+        """ WiFi Preferred, WiFi calling MT call hold/unhold test on 5G NSA
+
+        1. Setup PhoneA WFC mode: WIFI_PREFERRED.
+        2. Set preferred network of phoneA on 5G NSA
+        3. Verify if phoneA is on 5G NSA.
+        4. Call from PhoneB to PhoneA, accept on PhoneA.
+        5. Hold and unhold on PhoneA.
+        6. Verify if phoneA is on 5G NSA.
+
+        Returns:
+            True if pass; False if fail.
+        """
+        ads = self.android_devices
+        if not phone_setup_iwlan(self.log, self.android_devices[0], False,
+                                 WFC_MODE_WIFI_PREFERRED,
+                                 self.wifi_network_ssid,
+                                 self.wifi_network_pass):
+            self.android_devices[0].log.error(
+                "Failed to setup iwlan with APM off and WIFI and WFC on")
+            return False
+        # Mode Pref
+        set_preferred_mode_for_5g(ads[0])
+
+        # Attach nsa5g
+        if not is_current_network_5g_nsa(ads[0]):
+            ads[0].log.error("Phone not attached on 5G NSA before call.")
+            return False
+
+        if not self._test_call_setup_hold_unhold(ads,
+                                                 DIRECTION_MOBILE_TERMINATED,
+                                                 callee_func=is_phone_in_call_iwlan):
+            return False
+
+        if not is_current_network_5g_nsa(ads[0]):
+            ads[0].log.error("Phone not attached on 5G NSA after call.")
+            return False
+        return True
+
     """ Tests End """
diff --git a/acts_tests/tests/google/power/bt/PowerBLEconnectionidleTest.py b/acts_tests/tests/google/power/bt/PowerBLEconnectionidleTest.py
new file mode 100644
index 0000000..8b6cec6
--- /dev/null
+++ b/acts_tests/tests/google/power/bt/PowerBLEconnectionidleTest.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3.4
+#
+#   Copyright 2018 - The Android Open Source Project
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+import time
+from acts import utils
+import acts_contrib.test_utils.bt.BleEnum as bleenum
+import acts_contrib.test_utils.bt.bt_power_test_utils as btputils
+import acts_contrib.test_utils.bt.bt_test_utils as btutils
+import acts_contrib.test_utils.power.PowerBTBaseTest as PBtBT
+from acts_contrib.test_utils.bt.bt_test_utils import setup_multiple_devices_for_bt_test
+
+BLE_LOCATION_SCAN_ENABLE = 'settings put secure location_mode 3'
+EXTRA_CON_TIME = 3
+SCAN_TAIL = 5
+
+
+class PowerBLEconnectionidleTest(PBtBT.PowerBTBaseTest):
+    def __init__(self, configs):
+        super().__init__(configs)
+        req_params = ['BLE_Connection_Priority']
+        self.unpack_userparams(req_params)
+        for con_priority in self.BLE_Connection_Priority:
+            self.generate_test_case_ble_idle_connection(con_priority)
+
+    def setup_class(self):
+        super().setup_class()
+        self.client_ad = self.android_devices[0]
+        utils.set_location_service(self.client_ad, True)
+        self.server_ad = self.android_devices[1]
+        self.Connection_duration = self.mon_info.duration + self.mon_offset + SCAN_TAIL + EXTRA_CON_TIME
+        setup_multiple_devices_for_bt_test(self.android_devices)
+
+    def setup_test(self):
+        super().setup_test()
+        time.sleep(5)
+        self.client_ad.adb.shell(BLE_LOCATION_SCAN_ENABLE)
+        btutils.enable_bluetooth(self.client_ad.droid, self.client_ad.ed)
+        if not self.server_ad.droid.bluetoothSetLocalName('advertiser'):
+            self.log.error("Failed rename the device")
+            return False
+        self.log.info("Renamed the BT device")
+        self.client_ad.droid.goToSleepNow()
+
+    def teardown_test(self):
+        self.client_ad.droid.bluetoothFactoryReset()
+        btutils.disable_bluetooth(self.client_ad.droid)
+        self.server_ad.droid.bluetoothFactoryReset()
+        btutils.disable_bluetooth(self.server_ad.droid)
+
+    def generate_test_case_ble_idle_connection(self, con_priority):
+        def test_case_fn():
+            self.measure_ble_connection_idle_power(con_priority)
+
+        test_case_name = ('test_BLE_{}_IDLE_CONNECTION'.format(
+            bleenum.BLEConnectionPriority(con_priority).name))
+        setattr(self, test_case_name, test_case_fn)
+
+    def measure_ble_connection_idle_power(self, con_priority):
+        btputils.establish_ble_connection(self.client_ad, self.server_ad,
+                                          con_priority)
+        time.sleep(EXTRA_CON_TIME)
+        self.measure_power_and_validate()
diff --git a/acts_tests/tests/google/tel/live/TelLiveNoQXDMLogTest.py b/acts_tests/tests/google/tel/live/TelLiveNoQXDMLogTest.py
index 2ada2a8..3bafb61 100644
--- a/acts_tests/tests/google/tel/live/TelLiveNoQXDMLogTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveNoQXDMLogTest.py
@@ -95,7 +95,7 @@
         self.skip_reset_between_cases = False
         self.path = self.user_params['account_util'][0]
         self.user_account = "commsteltest1"
-        self.user_password = "tellivetest1"
+        self.user_password = "tellivetest2"
 
     def _get_list_average(self, input_list):
         total_sum = float(sum(input_list))
@@ -639,7 +639,8 @@
             result_flag = False
             time_var = 1
             ad = self.android_devices[0]
-            if ad.adb.getprop("ro.build.version.release")[0] in ("9", "P"):
+            if ad.adb.getprop("ro.build.version.release") in ("9", "P", "10", "Q",
+                                "11", "R", "12", "S"):
                 CARRIER_ID_VERSION = CARRIER_ID_VERSION_P
                 CARRIER_ID_METADATA_URL = CARRIER_ID_METADATA_URL_P
                 CARRIER_ID_CONTENT_URL = CARRIER_ID_CONTENT_URL_P
diff --git a/acts_tests/tests/google/tel/live/TelLiveVoiceConfTest.py b/acts_tests/tests/google/tel/live/TelLiveVoiceConfTest.py
index 3f56bd5..c011cdb 100644
--- a/acts_tests/tests/google/tel/live/TelLiveVoiceConfTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveVoiceConfTest.py
@@ -804,8 +804,7 @@
         # make sure PhoneB and PhoneC are GSM phone before proceed.
         for ad in [ads[1], ads[2]]:
             if (ad.droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-                ad.log.error("not GSM phone, abort wcdma swap test.")
-                return None, None
+                raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         call_ab_id = self._three_phone_call_mo_add_mo(
             [ads[0], ads[1], ads[2]],
@@ -856,8 +855,7 @@
         # make sure PhoneB and PhoneC are GSM phone before proceed.
         for ad in [ads[1], ads[2]]:
             if (ad.droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-                ad.log.error("not GSM phone, abort wcdma swap test.")
-                return None, None
+                raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         call_ab_id = self._three_phone_call_mo_add_mt(
             [ads[0], ads[1], ads[2]],
@@ -908,8 +906,7 @@
         # make sure PhoneB and PhoneC are GSM phone before proceed.
         for ad in [ads[1], ads[2]]:
             if (ad.droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-                ad.log.error("not GSM phone, abort wcdma swap test.")
-                return None, None
+                raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         call_ab_id = self._three_phone_call_mt_add_mt(
             [ads[0], ads[1], ads[2]],
@@ -1106,8 +1103,7 @@
 
         # make sure PhoneA is GSM phone before proceed.
         if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-            ad.log.error("not GSM phone, abort wcdma swap test.")
-            return None, None
+            raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         call_ab_id = self._three_phone_call_mo_add_mo(
             [ads[0], ads[1], ads[2]], [
@@ -1156,8 +1152,7 @@
 
         # make sure PhoneA is GSM phone before proceed.
         if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-            ads[0].log.error("not GSM phone, abort wcdma swap test.")
-            return None, None
+            raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         call_ab_id = self._three_phone_call_mt_add_mt(
             [ads[0], ads[1], ads[2]], [
@@ -1206,8 +1201,7 @@
 
         # make sure PhoneA is GSM phone before proceed.
         if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-            ads[0].log.error("not GSM phone, abort wcdma swap test.")
-            return None, None
+            raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         call_ab_id = self._three_phone_call_mo_add_mt(
             [ads[0], ads[1], ads[2]], [
@@ -1256,8 +1250,7 @@
 
         # make sure PhoneA is GSM phone before proceed.
         if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-            ads[0].log.error("not GSM phone, abort wcdma swap test.")
-            return None, None
+            raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         call_ab_id = self._three_phone_call_mo_add_mo(
             [ads[0], ads[1], ads[2]], [
@@ -1306,8 +1299,7 @@
 
         # make sure PhoneA is GSM phone before proceed.
         if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-            ads[0].log.error("not GSM phone, abort wcdma swap test.")
-            return None, None
+            raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         call_ab_id = self._three_phone_call_mo_add_mt(
             [ads[0], ads[1], ads[2]], [
@@ -2050,8 +2042,7 @@
         # make sure PhoneB and PhoneC are GSM phone before proceed.
         for ad in [ads[1], ads[2]]:
             if (ad.droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-                ad.log.error("not GSM phone, abort wcdma swap test.")
-                return None, None
+                raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         # To make thing simple, for epdg, setup should be called before calling
         # _test_epdg_mo_mo_add_wcdma_swap_x in test cases.
@@ -2103,8 +2094,7 @@
         # make sure PhoneB and PhoneC are GSM phone before proceed.
         for ad in [ads[1], ads[2]]:
             if (ad.droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-                ad.log.error("not GSM phone, abort wcdma swap test.")
-                return None, None
+                raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         # To make thing simple, for epdg, setup should be called before calling
         # _test_epdg_mo_mt_add_wcdma_swap_x in test cases.
@@ -2156,8 +2146,7 @@
         # make sure PhoneB and PhoneC are GSM phone before proceed.
         for ad in [ads[1], ads[2]]:
             if (ad.droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-                ad.log.error("not GSM phone, abort wcdma swap test.")
-                return None, None
+                raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         # To make thing simple, for epdg, setup should be called before calling
         # _test_epdg_mo_mt_add_wcdma_swap_x in test cases.
@@ -9501,8 +9490,7 @@
 
         # make sure PhoneA is GSM phone before proceed.
         if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-            ads[0].log.error("not GSM phone, abort wcdma swap test.")
-            return None, None
+            raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         call_ab_id = self._three_phone_call_mo_add_mo(
             [ads[0], ads[1], ads[2]], [
@@ -9551,8 +9539,7 @@
 
         # make sure PhoneA is GSM phone before proceed.
         if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
-            ads[0].log.error("not GSM phone, abort wcdma swap test.")
-            return None, None
+            raise signals.TestSkip("not GSM phone, abort wcdma swap test.")
 
         call_ab_id = self._three_phone_call_mt_add_mt(
             [ads[0], ads[1], ads[2]], [