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