1# Copyright (C) 2025 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import logging 16from mobly import base_test 17from mobly import test_runner 18from mobly.controllers import android_device 19from utilities.main_utils import common_main 20 21class GPSLocationValidationTest(base_test.BaseTestClass): 22 23 def setup_class(self): 24 self.android_devices = self.register_controller(android_device) 25 26 def toggle_location_settings(self, enable): 27 """Enables or disables the location settings on the device. 28 29 Args: 30 enable (bool): True to enable location settings, False to disable. 31 """ 32 state = 'true' if enable else 'false' 33 cmd = f'cmd location set-location-enabled {state}' 34 output = self.android_devices[0].adb.shell(cmd).decode('utf-8') 35 if 'Error' in output: 36 raise Exception(f'Unable to {state} location services: {output}') 37 logging.info(f'Location services {state} command output: {output}') 38 39 def check_location_status(self): 40 """Checks if the user has enabled location on the device. 41 42 Returns: 43 bool: True if the location is enabled for the user, False otherwise. 44 """ 45 try: 46 status_output_bytes = self.android_devices[0].adb.shell('dumpsys location -a | grep "location \[u10\]"') 47 except Exception as e: 48 logging.warning("Received an AdbError: %s", e) 49 # You can inspect e.stdout and e.stderr for more details if needed 50 return False 51 52 status_str = status_output_bytes.decode('utf-8') 53 status_line = status_str.strip().split('\n')[-1] 54 logging.info(status_line) 55 location_enabled = "enabled" in status_line 56 logging.info(f'User location status: {"enabled" if location_enabled else "disabled"}') 57 return location_enabled 58 59 def validate_last_location(self): 60 """Validates if the longitude and latitude of the device is captured successfully. 61 62 Returns: 63 bool: True if valid GNSS location data is obtained, False otherwise. 64 """ 65 location_output_bytes = self.android_devices[0].adb.shell('dumpsys location | grep "last location"') 66 location_info = location_output_bytes.decode('utf-8').strip() 67 logging.info(f'Last known location: {location_info}') 68 return 'gps:' in location_info and 'long=' in location_info and 'lat=' in location_info 69 70 def test_location_validation(self): 71 """Runs the GPS and location validation test case.""" 72 # Ensure at least one device is available 73 if not self.android_devices: 74 raise AssertionError('No Android devices are registered.') 75 76 # Toggle off location and verify it's off 77 logging.info("Toggle off location and verify") 78 self.toggle_location_settings(enable=False) 79 assert not self.check_location_status(), 'Failed to disable location services' 80 81 # Toggle on location and verify it's on 82 logging.info("Toggle on location and verify") 83 self.toggle_location_settings(enable=True) 84 assert self.check_location_status(), 'Failed to enable location services' 85 86 logging.info("verify last location") 87 # Validate that the device captures a valid last known location 88 assert self.validate_last_location(), 'Failed to capture a valid last known location' 89 90if __name__ == '__main__': 91 common_main() 92