• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
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 GATT writing.
18This test script was designed with this setup in mind:
19Shield box one: Two Android Devices 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.BleEnum import ScanSettingsScanMode
28from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
29from acts.test_utils.bt.PowerBaseTest import PowerBaseTest
30from acts.test_utils.bt.bt_test_utils import bluetooth_enabled_check
31from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects
32from acts.utils import get_current_human_time
33from acts.utils import sync_device_time
34
35
36class GattPowerTest(PowerBaseTest):
37    """Class for Gatt Power Test"""
38    # Time to start GATT write
39    START_TIME = 30
40    # Repetitions
41    REPETITIONS_40 = 7
42    REPETITIONS_1 = 1
43    # Time for GATT writing
44    WRITE_TIME_60 = 60
45    WRITE_TIME_3600 = 600
46    # Time for idle
47    IDLE_TIME_30 = 30
48    IDLE_TIME_0 = 0
49    # Base commands for PMC
50    PMC_GATT_CMD = ("am broadcast -a com.android.pmc.GATT ")
51    GATT_SERVER_MSG = "%s--es GattServer 1" % (PMC_GATT_CMD)
52
53    def __init__(self, controllers):
54        PowerBaseTest.__init__(self, controllers)
55
56        self.cen_ad = self.android_devices[0]
57        self.per_ad = self.android_devices[1]
58
59    def setup_class(self):
60        super(GattPowerTest, self).setup_class()
61        if not bluetooth_enabled_check(self.per_ad):
62            self.log.error("Failed to turn on Bluetooth on peripheral")
63
64        # Start PMC app for peripheral here
65        # since base class has started PMC for central device
66        self.per_ad.adb.shell(PowerBaseTest.START_PMC_CMD)
67        self.per_ad.adb.shell(self.PMC_VERBOSE_CMD)
68
69    def _measure_power_for_gatt_n_log_data(self, write_time, idle_time,
70                                           repetitions, test_case):
71        """Utility function for power test with GATT write.
72
73        Steps:
74        1. Prepare adb shell command for GATT server
75        2. Send the adb shell command to PMC to startup GATT Server
76        3. Prepare adb shell command for GATT Client
77        4. Send the adb shell command to PMC to startup GATT Client
78        5. PMC will start first alarm on GATT Client to start
79           GATT write continuousely for "write_time" seconds
80        6. After finishing writing for write_time it will stop for
81           for "idle_time" seconds
82        7  Repeat the write/idle cycle for "repetitions" times
83        8. Save the power usage data into log file
84
85        Args:
86            write_time: time(sec) duration for writing GATT characteristic
87            idle_time: time(sec) of idle (not write)
88            repetitions: number of repetitions of writing cycles
89
90        Returns:
91            True if the average current is within the allowed tolerance;
92            False otherwise.
93        """
94
95        if not self.disable_location_scanning():
96            return False
97
98        # Verify Bluetooth is enabled on the companion phone.
99        if not bluetooth_enabled_check(self.android_devices[1]):
100            self.log.error("FAILED to enable Bluetooth on companion phone")
101            return False
102
103        # Send message to Gatt Server
104        self.per_ad.log.info("Send broadcast message to GATT Server: %s",
105                             self.GATT_SERVER_MSG)
106        self.per_ad.adb.shell(self.GATT_SERVER_MSG)
107
108        # Send message to Gatt Client
109        first_part_msg = "%s--es StartTime %d --es WriteTime %d" % (
110            self.PMC_GATT_CMD, self.START_TIME, write_time)
111        clientmsg = "%s --es IdleTime %d --es Repetitions %d" % (
112            first_part_msg, idle_time, repetitions)
113        self.cen_ad.log.info("Send broadcast message to GATT Client: %s",
114                             clientmsg)
115        self.cen_ad.adb.shell(clientmsg)
116
117        sample_time = (write_time + idle_time) * repetitions
118        # Start the power measurement
119        result = self.mon.measure_power(self.POWER_SAMPLING_RATE, sample_time,
120                               self.current_test_name, self.START_TIME)
121
122        # Calculate average and save power data into a file
123        (current_avg, stdev) = self.save_logs_for_power_test(
124            result, write_time, idle_time)
125        # Take bug report for peripheral device
126        current_time = get_current_human_time()
127        self.per_ad.take_bug_report(self.current_test_name, current_time)
128
129        # perform watermark comparison numbers
130        self.log.info("==> CURRENT AVG from PMC Monsoon app: %s" % current_avg)
131        self.log.info(
132            "==> WATERMARK from config file: %s" % self.user_params[test_case])
133        return self.check_test_pass(current_avg, self.user_params[test_case])
134
135    @BluetoothBaseTest.bt_test_wrap
136    @test_tracker_info(uuid='f14cc28b-54f2-4a87-9fa9-68f39bf96701')
137    def test_power_for_60_sec_n_30_sec_idle_gatt_write(self):
138        """Test power usage when do 60 sec GATT write & 30 sec idle
139
140        Tests power usage when the test device do 60 sec GATT write
141        and 30 sec idle with max MTU bytes after being connected.
142        After each write GATT server will send a response
143        back to GATT client so GATT client can do another write.
144
145        Steps:
146        1. Prepare adb shell command for GATT server
147        2. Send the adb shell command to PMC to startup GATT Server
148        3. Prepare adb shell command for GATT Client
149        4. Send the adb shell command to PMC to startup GATT Client
150        5. PMC will start first alarm on GATT Client
151        6. Start power measurement
152        7. Alarm will be triggered to start GATT write for 60 second
153        8. Then it will be idle for 30 seconds
154        9. Reconnect after idle time
155        10. Repeat the cycles for 60 minutes
156        11. End power measurement
157        12. Save the power usage data into log file
158
159        Expected Result:
160        power consumption results
161
162        TAGS: LE, GATT, Power
163        Priority: 3
164        """
165        current_test_case = func_name = sys._getframe().f_code.co_name
166        return self._measure_power_for_gatt_n_log_data(
167            self.WRITE_TIME_60, self.IDLE_TIME_30, self.REPETITIONS_40,
168            current_test_case)
169
170    @BluetoothBaseTest.bt_test_wrap
171    @test_tracker_info(uuid='41ca217e-161b-4899-a5b7-2d59d8dc7973')
172    def test_power_for_60_min_non_stop_gatt_write(self):
173        """Test power usage when do a single GATT write.
174
175        Tests power usage when the test device do 60 minutes of GATT write with
176        max MTU bytes after being connected. After each write GATT server will
177        send a response back to GATT client so GATT client can do another write.
178
179        Steps:
180        1. Prepare adb shell command for GATT server
181        2. Send the adb shell command to PMC to startup GATT Server
182        3. Prepare adb shell command for GATT Client
183        4. Send the adb shell command to PMC to startup GATT Client
184        5. PMC will start first alarm on GATT Client to start GATT write
185        6. Start power measurement
186        7. GATT server gets the write request after GATT Client sends a write
187        8. GATT server sends a response back to GATT Client
188        9. After GATT Client receive the response from GATT Server
189           it will check if time reaches 60 minutes.
190           if not it will write another characteristic
191           otherwise it will stop writing
192        10. Stop power measurement
193        11. Save the power usage data into log file
194
195        Expected Result:
196        power consumption results
197
198        TAGS: LE, GATT, Power
199        Priority: 3
200        """
201        current_test_case = func_name = sys._getframe().f_code.co_name
202        return self._measure_power_for_gatt_n_log_data(
203            self.WRITE_TIME_3600, self.IDLE_TIME_0, self.REPETITIONS_1,
204            current_test_case)
205