1#!/usr/bin/env python3.5
2#
3#   Copyright 2019 - The Android Open Source Project
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.
16import time
17from collections import namedtuple
18
19from acts import asserts
20from acts import signals
21from acts import utils
22from acts.base_test import BaseTestClass
23from acts.test_utils.gnss import gnss_test_utils as gutils
24from acts.test_utils.wifi import wifi_test_utils as wutils
25from acts.test_utils.tel import tel_test_utils as tutils
26
27BACKGROUND_LOCATION_PERMISSION = 'android.permission.ACCESS_BACKGROUND_LOCATION'
28APP_CLEAN_UP_TIME = 60
29
30class LocationPlatinumTest(BaseTestClass):
31    """Location Platinum Tests"""
32
33    def setup_class(self):
34        super().setup_class()
35        self.ad = self.android_devices[0]
36        req_params = [
37            # A { SSID, password } dictionary. Password is optional.
38            'wifi_network',
39            # A [latitude, longitude] list to identify test location.
40            'test_location',
41            # Cold Start Criteria, a int to define the criteria.
42            'cs_criteria',
43            # Warm Start Criteria, a int to define the criteria.
44            'ws_criteria',
45            # Hot Start Criteria, a int to define the criteria.
46            'hs_criteria',
47            # NetworkLocationProvide Criteria, a int to define the criteria.
48            'nlp_criteria',
49            # A list to identify QXDM log path.
50            'qdsp6m_path'
51        ]
52        self.unpack_userparams(req_param_names=req_params)
53
54        # Init test types Cold Start, Warm Start and Hot Start.
55        test_type = namedtuple('Type', ['command', 'criteria'])
56        self.test_types = {
57            'cs': test_type('Cold Start', self.cs_criteria),
58            'ws': test_type('Warm Start', self.ws_criteria),
59            'hs': test_type('Hot Start', self.hs_criteria)
60        }
61        gutils._init_device(self.ad)
62        self.begin_time = utils.get_current_epoch_time()
63        gutils.clear_logd_gnss_qxdm_log(self.ad)
64        tutils.start_qxdm_logger(self.ad, self.begin_time)
65        tutils.start_adb_tcpdump(self.ad)
66
67    def setup_test(self):
68        """Prepare device with mobile data, wifi and gps ready for test """
69        if int(self.ad.adb.shell('settings get secure location_mode')) != 3:
70            self.ad.adb.shell('settings put secure location_mode 3')
71        if not self.ad.droid.wifiCheckState():
72            wutils.wifi_toggle_state(self.ad, True)
73            gutils.connect_to_wifi_network(self.ad, self.wifi_network)
74        if int(self.ad.adb.shell('settings get global mobile_data')) != 1:
75            gutils.set_mobile_data(self.ad, True)
76        gutils.grant_location_permission(self.ad, True)
77        self.ad.adb.shell('pm grant com.android.gpstool %s' %
78                          BACKGROUND_LOCATION_PERMISSION)
79
80    def teardown_class(self):
81        tutils.stop_qxdm_logger(self.ad)
82        gutils.get_gnss_qxdm_log(self.ad, self.qdsp6m_path)
83        tutils.stop_adb_tcpdump(self.ad)
84        tutils.get_tcpdump_log(self.ad, 'location_platinum', self.begin_time)
85        self.ad.take_bug_report('location_platinum', self.begin_time)
86
87    def get_and_verify_ttff(self, mode):
88        """Retrieve ttff with designate mode.
89
90        Args:
91            mode: A string for identify gnss test mode.
92        """
93        if mode in self.test_types:
94            test_type = self.test_types.get(mode)
95        else:
96            raise signals.TestFailure('Unrecognized mode %s' % mode)
97
98        gutils.process_gnss_by_gtw_gpstool(self.ad,
99                                           self.test_types['cs'].criteria)
100        begin_time = gutils.get_current_epoch_time()
101        gutils.start_ttff_by_gtw_gpstool(
102            self.ad, ttff_mode=mode, iteration=1, aid_data=True)
103        ttff_data = gutils.process_ttff_by_gtw_gpstool(self.ad, begin_time,
104                                                       self.test_location)
105        result = gutils.check_ttff_data(
106            self.ad,
107            ttff_data,
108            ttff_mode=test_type.command,
109            criteria=test_type.criteria)
110        asserts.assert_true(
111            result,
112            '%s TTFF fails to reach designated criteria' % test_type.command)
113
114    # Test cases
115    def test_gnss_cold_ttff(self):
116        """
117            1. Send intent to GPSTool for cold start test.
118            2. Retrieve ttff and validate with target criteria.
119        """
120        self.get_and_verify_ttff('cs')
121
122    def test_gnss_warm_ttff(self):
123        """
124            1. Send intent to GPSTool for warm start test.
125            2. Retrieve ttff and validate with target criteria.
126        """
127        self.get_and_verify_ttff('ws')
128
129    def test_gnss_hot_ttff(self):
130        """
131            1. Send intent to GPSTool for hot start test.
132            2. Retrieve ttff and validate with target criteria.
133        """
134        self.get_and_verify_ttff('hs')
135
136    def test_nlp_available_by_wifi(self):
137        """
138            1. Disable mobile data.
139            2. Send intent to GPSTool for NLP.
140            3. Retrieve response time and validate with criteria.
141        """
142        gutils.set_mobile_data(self.ad, False)
143        asserts.assert_true(
144            gutils.check_network_location(
145                self.ad, 1, 'wifi', self.nlp_criteria),
146            'Fail to get NLP from wifi')
147
148    def test_nlp_available_by_cell(self):
149        """
150            1. Disable wifi.
151            2. Send intent to GPSTool for NLP.
152            3. Retrieve response time and validate with criteria.
153        """
154        wutils.wifi_toggle_state(self.ad, False)
155        asserts.assert_true(
156            gutils.check_network_location(
157                self.ad, 1, 'cell', self.nlp_criteria),
158            'Fail to get NLP from cell')
159
160    def test_toggle_location_setting_off_on_report_location(self):
161        """
162            1. Toggle location setting off on.
163            2. Open Google Map and ask for location.
164            3. Validate there are location fix in logcat.
165        """
166        self.ad.adb.shell('settings put secure location_mode 0')
167        self.ad.adb.shell('settings put secure location_mode 3')
168        gutils.launch_google_map(self.ad)
169        asserts.assert_true(
170            gutils.check_location_api(self.ad, retries=1),
171            'DUT failed to receive location fix')
172
173    def test_toggle_location_setting_off_not_report_location(self):
174        """
175            1. Toggle location setting off.
176            2. Open Google Map and ask for location.
177            3. Validate there is no location fix in logcat.
178        """
179        self.ad.adb.shell('settings put secure location_mode 0')
180        gutils.launch_google_map(self.ad)
181        asserts.assert_false(
182            gutils.check_location_api(self.ad, retries=1),
183            'DUT Still receive location fix')
184
185    def test_toggle_location_permission_off_on(self):
186        """
187            1. Toggle Google Map location permission off on.
188            2. Open Google Map and ask for location.
189            3. Validate there are location fix in logcat.
190        """
191        gutils.grant_location_permission(self.ad, False)
192        gutils.grant_location_permission(self.ad, True)
193        gutils.launch_google_map(self.ad)
194        asserts.assert_true(
195            gutils.check_location_api(self.ad, retries=1),
196            'DUT fail to receive location fix')
197
198    def test_toggle_location_permission_off(self):
199        """
200            1. Toggle Google Map location permission off.
201            2. Open Google Map and ask for location.
202            3. Validate there is no location fix in logcat.
203        """
204        gutils.grant_location_permission(self.ad, False)
205        gutils.launch_google_map(self.ad)
206        asserts.assert_false(
207            gutils.check_location_api(self.ad, retries=1),
208            'DUT still receive location fix')
209
210    def test_location_only_in_use_state(self):
211        """
212            1. Revoke ACCESS_BACKGROUBND_LOCATION permission on GPSTool.
213            2. Open GPSTool for tracking.
214            3. Validate there are location fix in logcat.
215            4. Turn GPSTool from foreground to background by press home.
216            5. Wait 60 seconds for app clean up.
217            6. Validate GPSTool is skipping for location update in logcat.
218        """
219        self.ad.log.info('Revoke background permission')
220        self.ad.adb.shell('pm revoke com.android.gpstool %s' %
221                          BACKGROUND_LOCATION_PERMISSION)
222        gutils.start_gnss_by_gtw_gpstool(self.ad, True)
223        asserts.assert_true(
224            gutils.check_location_api(self.ad, retries=1),
225            'APP failed to receive location fix in foreground')
226        self.ad.log.info('Trun GPSTool from foreground to background')
227        self.ad.adb.shell('input keyevent 3')
228        self.ad.log.info('Wait %d seconds for app clean up' % APP_CLEAN_UP_TIME)
229        time.sleep(APP_CLEAN_UP_TIME)
230        asserts.assert_false(
231            gutils.check_location_api(self.ad, retries=1),
232            'DUT still receive location fix')
233