1#/usr/bin/env python3.4 2# 3# Copyright (C) 2016 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may not 6# use this file except in compliance with the License. You may obtain a copy of 7# 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, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14# License for the specific language governing permissions and limitations under 15# the License. 16""" 17This test script exercises power test scenarios for different scan modes. 18This test script was designed with this setup in mind: 19Shield box one: Android Device and Monsoon tool box 20""" 21 22import json 23import os 24import sys 25 26from acts.test_decorators import test_tracker_info 27from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest 28from acts.test_utils.bt.bt_constants import ble_scan_settings_modes 29from acts.test_utils.bt.bt_test_utils import bluetooth_enabled_check 30from acts.test_utils.bt.bt_test_utils import disable_bluetooth 31from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects 32from acts.test_utils.bt.PowerBaseTest import PowerBaseTest 33 34 35class BleScanPowerTest(PowerBaseTest): 36 # Repetitions for scan and idle 37 REPETITIONS_40 = 5 38 REPETITIONS_360 = 40 39 40 # Power measurement start time in seconds 41 SCAN_START_TIME = 60 42 # BLE scanning time in seconds 43 SCAN_TIME_60 = 60 44 SCAN_TIME_5 = 5 45 # BLE no scanning time in seconds 46 IDLE_TIME_30 = 30 47 IDLE_TIME_5 = 5 48 49 PMC_BASE_CMD = ("am broadcast -a com.android.pmc.BLESCAN --es ScanMode ") 50 # Log file name 51 LOG_FILE = "BLEPOWER.log" 52 53 def setup_class(self): 54 super(BleScanPowerTest, self).setup_class() 55 # Get power test device serial number 56 power_test_device_serial = self.user_params["PowerTestDevice"] 57 # If there are multiple devices in the shield box turn off 58 # all of them except the one for the power testing 59 if len(self.android_devices) > 1: 60 for ad in self.android_devices: 61 if ad.serial != power_test_device_serial[0]: 62 self.ad.log.info("Disable BT for %s != %s", ad.serial, 63 power_test_device_serial[0]) 64 disable_bluetooth(ad.droid) 65 66 def _measure_power_for_scan_n_log_data(self, scan_mode, scan_time, 67 idle_time, repetitions, test_case): 68 """utility function for power test with BLE scan. 69 70 Steps: 71 1. Prepare adb shell command 72 2. Send the adb shell command to PMC 73 3. PMC start first alarm to start scan 74 4. After first alarm triggered it start the second alarm to stop scan 75 5. Repeat the scan/idle cycle for the number of repetitions 76 6. Save the power usage data into log file 77 78 Args: 79 scan_mode: Scan mode 80 scan_time: Time duration for scanning 81 idle_time: Time duration for idle after scanning 82 repetitions: The number of cycles of scanning/idle 83 84 Returns: 85 True if the average current is within the allowed tolerance; 86 False otherwise. 87 """ 88 89 if not self.disable_location_scanning(): 90 return False 91 92 first_part_msg = "%s%s --es StartTime %d --es ScanTime %d" % ( 93 self.PMC_BASE_CMD, scan_mode, self.SCAN_START_TIME, scan_time) 94 msg = "%s --es NoScanTime %d --es Repetitions %d" % (first_part_msg, 95 idle_time, 96 repetitions) 97 98 self.ad.log.info("Send broadcast message: %s", msg) 99 self.ad.adb.shell(msg) 100 101 # Check if PMC is ready 102 if not self.check_pmc_status(self.LOG_FILE, "READY", 103 "PMC is not ready"): 104 return 105 106 # Start the power measurement 107 sample_time = (scan_time + idle_time) * repetitions 108 result = self.mon.measure_power(self.POWER_SAMPLING_RATE, sample_time, 109 self.current_test_name, self.SCAN_START_TIME) 110 111 self.ad.log.info("Monsoon start_time: {}".format(result.timestamps[0])) 112 113 start_times = [] 114 end_times = [] 115 json_data = self.check_pmc_timestamps(self.LOG_FILE) 116 for timestamp in json_data: 117 start_times.append(timestamp["StartTime"]) 118 end_times.append(timestamp["EndTime"]) 119 120 self.ad.log.info("Number of test cycles: {}".format(len(start_times))) 121 122 (current_avg, stdev) = self.save_logs_for_power_test( 123 result, start_times, end_times, False) 124 125 # perform watermark comparison numbers 126 self.log.info("==> CURRENT AVG from PMC Monsoon app: %s" % current_avg) 127 self.log.info( 128 "==> WATERMARK from config file: %s" % self.user_params[test_case]) 129 return self.check_test_pass(current_avg, self.user_params[test_case]) 130 131 @BluetoothBaseTest.bt_test_wrap 132 @test_tracker_info(uuid='1e8c793f-897d-4160-8ebf-fd1addcd9c71') 133 def test_power_for_scan_w_low_latency(self): 134 """Test power usage when scan with low latency. 135 136 Tests power usage when the device scans with low latency mode 137 for 60 seconds and then idle for 30 seconds, repeat for 60 minutes 138 where there are no advertisements. 139 140 Steps: 141 1. Prepare adb shell command 142 2. Send the adb shell command to PMC 143 3. PMC start first alarm to start scan 144 4. After first alarm triggered it start the second alarm to stop scan 145 5. Repeat the cycle for 60 minutes 146 6. Save the power usage data into log file 147 148 Expected Result: 149 power consumption results 150 151 TAGS: LE, Scanning, Power 152 Priority: 3 153 """ 154 current_test_case = func_name = sys._getframe().f_code.co_name 155 return self._measure_power_for_scan_n_log_data( 156 ble_scan_settings_modes['low_latency'], self.SCAN_TIME_60, 157 self.IDLE_TIME_30, self.REPETITIONS_40, current_test_case) 158 159 @BluetoothBaseTest.bt_test_wrap 160 @test_tracker_info(uuid='83e37081-9f00-4b5f-ba1c-92136047fa83') 161 def test_power_for_scan_w_balanced(self): 162 """Test power usage when scan with balanced mode. 163 164 Tests power usage when the device scans with balanced mode 165 for 60 seconds and then idle for 30 seconds, repeat for 60 minutes 166 where there are no advertisements. 167 168 Steps: 169 1. Prepare adb shell command 170 2. Send the adb shell command to PMC 171 3. PMC start first alarm to start scan 172 4. After first alarm triggered it start the second alarm to stop scan 173 5. Repeat the cycle for 60 minutes 174 6. Save the power usage data into log file 175 176 Expected Result: 177 power consumption results 178 179 TAGS: LE, Scanning, Power 180 Priority: 3 181 """ 182 current_test_case = func_name = sys._getframe().f_code.co_name 183 return self._measure_power_for_scan_n_log_data( 184 ble_scan_settings_modes['balanced'], self.SCAN_TIME_60, 185 self.IDLE_TIME_30, self.REPETITIONS_40, current_test_case) 186 187 @BluetoothBaseTest.bt_test_wrap 188 @test_tracker_info(uuid='cbf16414-3468-4f60-8a62-2a88556d7a87') 189 def test_power_for_scan_w_low_power(self): 190 """Test power usage when scan with low power. 191 192 Tests power usage when the device scans with low power mode 193 for 60 seconds and then idle for 30 seconds, repeat for 60 minutes 194 where there are no advertisements. 195 196 Steps: 197 1. Prepare adb shell command 198 2. Send the adb shell command to PMC 199 3. PMC start first alarm to start scan 200 4. After first alarm triggered it start the second alarm to stop scan 201 5. Repeat the cycle for 60 minutes 202 6. Save the power usage data into log file 203 204 Expected Result: 205 power consumption results 206 207 TAGS: LE, Scanning, Power 208 Priority: 3 209 """ 210 current_test_case = func_name = sys._getframe().f_code.co_name 211 return self._measure_power_for_scan_n_log_data( 212 ble_scan_settings_modes['low_power'], self.SCAN_TIME_60, 213 self.IDLE_TIME_30, self.REPETITIONS_40, current_test_case) 214 215 @BluetoothBaseTest.bt_test_wrap 216 @test_tracker_info(uuid='0b1eaedb-4385-48ba-a175-7db79360aed8') 217 def test_power_for_intervaled_scans_w_balanced(self): 218 """Test power usage when intervaled scans with balanced mode 219 220 Tests power usage when the device perform multiple intervaled scans with 221 balanced mode for 5 seconds each where there are no advertisements. 222 223 Steps: 224 1. Prepare adb shell command 225 2. Send the adb shell command to PMC 226 3. PMC start first alarm to start scan 227 4. After first alarm triggered it starts the second alarm to stop scan 228 5. After second alarm triggered it starts the third alarm to start scan 229 6. Repeat the alarms until 360 scans are done 230 7. Save the power usage data into log file 231 232 Expected Result: 233 power consumption results 234 235 TAGS: LE, Scanning, Power 236 Priority: 3 237 """ 238 current_test_case = func_name = sys._getframe().f_code.co_name 239 return self._measure_power_for_scan_n_log_data( 240 ble_scan_settings_modes['balanced'], self.SCAN_TIME_5, 241 self.IDLE_TIME_5, self.REPETITIONS_360, current_test_case) 242 243 @BluetoothBaseTest.bt_test_wrap 244 @test_tracker_info(uuid='90e6b341-9b11-4740-8ec1-dc605db93ec9') 245 def test_power_for_intervaled_scans_w_low_latency(self): 246 """Test power usage when intervaled scans with low latency mode 247 248 Tests power usage when the device perform multiple intervaled scans with 249 low latency mode for 5 seconds each where there are no advertisements. 250 251 Steps: 252 1. Prepare adb shell command 253 2. Send the adb shell command to PMC 254 3. PMC start first alarm to start scan 255 4. After first alarm triggered it starts the second alarm to stop scan 256 5. After second alarm triggered it starts the third alarm to start scan 257 6. Repeat the alarms until 360 scans are done 258 7. Save the power usage data into log file 259 260 Expected Result: 261 power consumption results 262 263 TAGS: LE, Scanning, Power 264 Priority: 3 265 """ 266 current_test_case = func_name = sys._getframe().f_code.co_name 267 return self._measure_power_for_scan_n_log_data( 268 ble_scan_settings_modes['low_latency'], self.SCAN_TIME_5, 269 self.IDLE_TIME_5, self.REPETITIONS_360, current_test_case) 270 271 @BluetoothBaseTest.bt_test_wrap 272 @test_tracker_info(uuid='cbf16414-3468-4f60-8a62-2a88556d7a87') 273 def test_power_for_intervaled_scans_w_low_power(self): 274 """Test power usage when intervaled scans with low power mode 275 276 Tests power usage when the device perform multiple intervaled scans with 277 low power mode for 5 seconds each where there are no advertisements. 278 279 Steps: 280 1. Prepare adb shell command 281 2. Send the adb shell command to PMC 282 3. PMC start first alarm to start scan 283 4. After first alarm triggered it starts the second alarm to stop scan 284 5. After second alarm triggered it starts the third alarm to start scan 285 6. Repeat the alarms until 360 scans are done 286 7. Save the power usage data into log file 287 288 Expected Result: 289 power consumption results 290 291 TAGS: LE, Scanning, Power 292 Priority: 3 293 """ 294 current_test_case = func_name = sys._getframe().f_code.co_name 295 return self._measure_power_for_scan_n_log_data( 296 ble_scan_settings_modes['low_power'], self.SCAN_TIME_5, 297 self.IDLE_TIME_5, self.REPETITIONS_360, current_test_case) 298