1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.ui; 18 19 import android.os.RemoteException; 20 import android.platform.test.annotations.Presubmit; 21 import android.provider.Settings; 22 import android.system.helpers.SettingsHelper; 23 import android.test.InstrumentationTestCase; 24 25 import androidx.test.filters.MediumTest; 26 import androidx.test.uiautomator.By; 27 import androidx.test.uiautomator.Direction; 28 import androidx.test.uiautomator.UiDevice; 29 import androidx.test.uiautomator.UiObject2; 30 import androidx.test.uiautomator.Until; 31 32 import org.junit.Ignore; 33 34 @Ignore 35 public class LocationSettingsTests extends InstrumentationTestCase { 36 37 private static final String SETTINGS_PACKAGE = "com.android.settings"; 38 private static final int TIMEOUT = 2000; 39 private UiDevice mDevice; 40 41 @Override setUp()42 public void setUp() throws Exception { 43 super.setUp(); 44 mDevice = UiDevice.getInstance(getInstrumentation()); 45 try { 46 mDevice.setOrientationNatural(); 47 } catch (RemoteException e) { 48 throw new RuntimeException("failed to freeze device orientaion", e); 49 } 50 } 51 52 @Override tearDown()53 protected void tearDown() throws Exception { 54 mDevice.pressBack(); 55 mDevice.pressHome(); 56 super.tearDown(); 57 } 58 59 @MediumTest testLoadingLocationSettings()60 public void testLoadingLocationSettings () throws Exception { 61 // Load Security 62 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), 63 Settings.ACTION_SECURITY_SETTINGS); 64 65 SettingsHelper helper = new SettingsHelper(); 66 helper.scrollVert(true); 67 // Tap on location 68 UiObject2 settingsPanel = mDevice.wait(Until.findObject 69 (By.res(SETTINGS_PACKAGE, "main_content")), TIMEOUT); 70 int count = 0; 71 UiObject2 locationTitle = null; 72 while(count < 6 && locationTitle == null) { 73 locationTitle = mDevice.wait(Until.findObject(By.text("Location")), TIMEOUT); 74 if (locationTitle == null) { 75 settingsPanel.scroll(Direction.DOWN, 1.0f); 76 } 77 count++; 78 } 79 // Verify location settings loads. 80 locationTitle.click(); 81 Thread.sleep(TIMEOUT); 82 assertNotNull("Location screen has not loaded correctly", 83 mDevice.wait(Until.findObject(By.text("Location services")), TIMEOUT)); 84 } 85 86 @Presubmit 87 @MediumTest testLocationSettingOn()88 public void testLocationSettingOn() throws Exception { 89 verifyLocationSettingsOnOrOff(true); 90 } 91 92 @MediumTest testLocationSettingOff()93 public void testLocationSettingOff() throws Exception { 94 verifyLocationSettingsOnOrOff(false); 95 } 96 97 @MediumTest testLocationDeviceOnlyMode()98 public void testLocationDeviceOnlyMode() throws Exception { 99 // Changing the value from default before testing the toggle to Device only mode 100 Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), 101 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_ON); 102 dismissAlertDialogs(); 103 Thread.sleep(TIMEOUT); 104 verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_SENSORS_ONLY); 105 } 106 107 @MediumTest testLocationBatterySavingMode()108 public void testLocationBatterySavingMode() throws Exception { 109 Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), 110 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_SENSORS_ONLY); 111 Thread.sleep(TIMEOUT); 112 verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_BATTERY_SAVING); 113 } 114 115 @MediumTest testLocationHighAccuracyMode()116 public void testLocationHighAccuracyMode() throws Exception { 117 Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), 118 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_SENSORS_ONLY); 119 Thread.sleep(TIMEOUT); 120 verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_ON); 121 } 122 123 @MediumTest testLocationSettingsElements()124 public void testLocationSettingsElements() throws Exception { 125 String[] textElements = {"Location", "Mode", "Recent location requests", 126 "Location services"}; 127 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), 128 Settings.ACTION_LOCATION_SOURCE_SETTINGS); 129 Thread.sleep(TIMEOUT); 130 for (String element : textElements) { 131 assertNotNull(element + " item not found under Location Settings", 132 mDevice.wait(Until.findObject(By.text(element)), TIMEOUT)); 133 } 134 } 135 136 @MediumTest testLocationSettingsOverflowMenuElements()137 public void testLocationSettingsOverflowMenuElements() throws Exception { 138 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), 139 Settings.ACTION_LOCATION_SOURCE_SETTINGS); 140 // Verify help & feedback 141 assertNotNull("Help & feedback item not found under Location Settings", 142 mDevice.wait(Until.findObject(By.desc("Help & feedback")), TIMEOUT)); 143 // Verify scanning 144 assertNotNull("Scanning item not found under Location Settings", 145 mDevice.wait(Until.findObject(By.text("Scanning")), TIMEOUT)); 146 } 147 verifyLocationSettingsMode(int mode)148 private void verifyLocationSettingsMode(int mode) throws Exception { 149 int modeIntValue = 1; 150 String textMode = "Device only"; 151 if (mode == Settings.Secure.LOCATION_MODE_ON) { 152 modeIntValue = 3; 153 textMode = "High accuracy"; 154 } 155 else if (mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) { 156 modeIntValue = 2; 157 textMode = "Battery saving"; 158 } 159 // Load location settings 160 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), 161 Settings.ACTION_LOCATION_SOURCE_SETTINGS); 162 // Tap on mode 163 dismissAlertDialogs(); 164 // Load location settings 165 mDevice.wait(Until.findObject(By.text("Mode")), TIMEOUT).click(); 166 Thread.sleep(TIMEOUT); 167 assertNotNull("Location mode screen not loaded", mDevice.wait(Until.findObject 168 (By.text("Location mode")), TIMEOUT)); 169 // Choose said mode 170 mDevice.wait(Until.findObject(By.text(textMode)), TIMEOUT).click(); 171 Thread.sleep(TIMEOUT); 172 dismissAlertDialogs(); 173 mDevice.wait(Until.findObject(By.desc("Navigate up")), TIMEOUT).click(); 174 Thread.sleep(TIMEOUT); 175 if (mode == Settings.Secure.LOCATION_MODE_ON || 176 mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) { 177 dismissAlertDialogs(); 178 } 179 // get setting and verify value 180 // Verify change of mode 181 int locationSettingMode = 182 Settings.Secure.getInt(getInstrumentation().getContext().getContentResolver(), 183 Settings.Secure.LOCATION_MODE); 184 assertEquals(mode + " value not set correctly for location.", modeIntValue, 185 locationSettingMode); 186 } 187 verifyLocationSettingsOnOrOff(boolean verifyOn)188 private void verifyLocationSettingsOnOrOff(boolean verifyOn) throws Exception { 189 // Set location flag 190 if (verifyOn) { 191 Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), 192 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); 193 } 194 else { 195 Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), 196 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_ON); 197 } 198 dismissAlertDialogs(); 199 // Load location settings 200 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), 201 Settings.ACTION_LOCATION_SOURCE_SETTINGS); 202 dismissAlertDialogs(); 203 // Toggle UI 204 mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE, "switch_widget")), TIMEOUT).click(); 205 dismissAlertDialogs(); 206 Thread.sleep(TIMEOUT); 207 // Verify change in setting 208 int locationEnabled = Settings.Secure.getInt(getInstrumentation() 209 .getContext().getContentResolver(), 210 Settings.Secure.LOCATION_MODE); 211 if (verifyOn) { 212 assertFalse("Location not enabled correctly", locationEnabled == 0); 213 } 214 else { 215 assertEquals("Location not disabled correctly", 0, locationEnabled); 216 } 217 } 218 219 // This method dismisses both alert dialogs that might popup and 220 // interfere with the test. Since the order in which the dialog 221 // shows up changes in no specific known way, we're checking for 222 // both dialogs in any order for a robust test. Bug b/36233151 223 // filed against Location team for specifications. This is a 224 // workaround in the meantime to ensure coverage. dismissAlertDialogs()225 private void dismissAlertDialogs() throws Exception { 226 for (int count = 0; count < 2; count++) { 227 UiObject2 agreeDialog = mDevice.wait(Until.findObject 228 (By.text("Improve location accuracy?")), TIMEOUT); 229 UiObject2 previousChoiceYesButton = mDevice.wait(Until.findObject 230 (By.text("YES")), TIMEOUT); 231 if (agreeDialog != null) { 232 mDevice.wait(Until.findObject 233 (By.text("AGREE")), TIMEOUT).click(); 234 Thread.sleep(TIMEOUT); 235 assertNull("Improve location dialog not dismissed", 236 mDevice.wait(Until.findObject 237 (By.text("Improve location accuracy?")), TIMEOUT)); 238 } 239 if (previousChoiceYesButton != null) { 240 previousChoiceYesButton.click(); 241 // Short sleep to wait for the new screen 242 Thread.sleep(TIMEOUT); 243 } 244 } 245 } 246 } 247