1 /* 2 * Copyright (C) 2016 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 android.settings.functional; 18 19 import android.bluetooth.BluetoothManager; 20 import android.content.ContentResolver; 21 import android.content.Context; 22 import android.location.LocationManager; 23 import android.net.wifi.WifiManager; 24 import android.os.RemoteException; 25 import android.provider.Settings; 26 import android.support.test.uiautomator.UiDevice; 27 import android.support.test.uiautomator.UiObject2; 28 import android.support.test.uiautomator.By; 29 import android.support.test.uiautomator.Until; 30 import android.test.InstrumentationTestCase; 31 import android.test.suitebuilder.annotation.MediumTest; 32 import android.util.Log; 33 34 public class QuickSettingsTest extends InstrumentationTestCase { 35 private static final String LOG_TAG = QuickSettingsTest.class.getSimpleName(); 36 private static final int LONG_TIMEOUT = 2000; 37 private static final int SHORT_TIMEOUT = 500; 38 39 private enum QuickSettingTiles { 40 WIFI("Wi-Fi"), SIM("SIM"), DND("Do not disturb"), FLASHLIGHT("Flashlight"), SCREEN( 41 "Auto-rotate screen"), BLUETOOTH("Bluetooth"), AIRPLANE("Airplane mode"), 42 LOCATION("Location"), BRIGHTNESS("Display brightness"); 43 44 private final String name; 45 QuickSettingTiles(String name)46 private QuickSettingTiles(String name) { 47 this.name = name; 48 } 49 getName()50 public String getName() { 51 return this.name; 52 } 53 }; 54 55 private UiDevice mDevice = null; 56 private ContentResolver mResolver; 57 58 @Override setUp()59 public void setUp() throws Exception { 60 super.setUp(); 61 mDevice = UiDevice.getInstance(getInstrumentation()); 62 getInstrumentation().getContext(); 63 mResolver = getInstrumentation().getContext().getContentResolver(); 64 mDevice.wakeUp(); 65 mDevice.pressHome(); 66 mDevice.setOrientationNatural(); 67 } 68 69 @Override tearDown()70 protected void tearDown() throws Exception { 71 // Need to finish settings activity 72 mDevice.pressHome(); 73 mDevice.unfreezeRotation(); 74 super.tearDown(); 75 } 76 77 @MediumTest testQuickSettingDrawDown()78 public void testQuickSettingDrawDown() throws Exception { 79 mDevice.pressHome(); 80 // Draw down once to load quick settings shade only 81 swipeDown(); 82 UiObject2 quicksettingsShade = mDevice.wait( 83 Until.findObject(By.res("com.android.systemui:id/expand_indicator")), 84 LONG_TIMEOUT); 85 assertNotNull("Quick settings shade not visible on draw down", quicksettingsShade); 86 } 87 88 @MediumTest testQuickSettingExpand()89 public void testQuickSettingExpand() throws Exception { 90 launchQuickSetting(); 91 // Verify that the settings object is visible on full expansion 92 UiObject2 quicksettingsExpand = mDevice.wait(Until.findObject(By.desc("Open settings.")), 93 LONG_TIMEOUT); 94 assertNotNull("Quick settings shade did not expand correctly on two swipe downs", 95 quicksettingsExpand); 96 } 97 98 @MediumTest testQuickSettingCollapse()99 public void testQuickSettingCollapse() throws Exception { 100 launchQuickSetting(); 101 // Tap on the expand chevron once more to collapse the QS shade 102 mDevice.wait(Until.findObject(By.res("com.android.systemui:id/expand_indicator")), 103 LONG_TIMEOUT).click(); 104 105 // Verify that the brightness slider which is only visible on full expansion 106 // isn't visible in the collapsed state 107 UiObject2 quicksettingsExpandedShade = mDevice.wait( 108 Until.findObject(By.descContains(QuickSettingTiles.BRIGHTNESS.getName())), 109 LONG_TIMEOUT); 110 assertNotNull("Quick settings shade did not collapse correctly", 111 quicksettingsExpandedShade); 112 } 113 114 @MediumTest testQuickSettingDismiss()115 public void testQuickSettingDismiss() throws Exception { 116 launchQuickSetting(); 117 // Swipe up twice to fully dismiss quick settings 118 swipeUp(); 119 swipeUp(); 120 UiObject2 quicksettingsShade = mDevice.wait( 121 Until.findObject(By.res("com.android.systemui:id/expand_indicator")), 122 SHORT_TIMEOUT); 123 assertNull("Quick settings collapsed shade was not dismissed correctly", 124 quicksettingsShade); 125 } 126 127 @MediumTest testQuickSettingTilesVisible()128 public void testQuickSettingTilesVisible() throws Exception { 129 launchQuickSetting(); 130 Thread.sleep(LONG_TIMEOUT); 131 for (QuickSettingTiles tile : QuickSettingTiles.values()) { 132 UiObject2 quickSettingTile = mDevice.wait( 133 Until.findObject(By.descContains(tile.getName())), 134 SHORT_TIMEOUT); 135 assertNotNull(String.format("%s did not load correctly", tile.getName()), 136 quickSettingTile); 137 } 138 } 139 140 @MediumTest testQuickSettingWifiEnabled()141 public void testQuickSettingWifiEnabled() throws Exception { 142 verifyWiFiOnOrOff(true); 143 } 144 145 @MediumTest testQuickSettingWifiDisabled()146 public void testQuickSettingWifiDisabled() throws Exception { 147 verifyWiFiOnOrOff(false); 148 } 149 verifyWiFiOnOrOff(boolean verifyOn)150 private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception { 151 String airPlaneMode = Settings.Global.getString( 152 mResolver, 153 Settings.Global.AIRPLANE_MODE_ON); 154 try { 155 Settings.Global.putString(mResolver, 156 Settings.Global.AIRPLANE_MODE_ON, "0"); 157 Thread.sleep(LONG_TIMEOUT); 158 WifiManager wifiManager = (WifiManager) getInstrumentation().getContext() 159 .getSystemService(Context.WIFI_SERVICE); 160 wifiManager.setWifiEnabled(!verifyOn); 161 launchQuickSetting(); 162 mDevice.wait(Until.findObject(By.descContains(QuickSettingTiles.WIFI.getName())), 163 LONG_TIMEOUT).click(); 164 if (verifyOn) { 165 mDevice.pressBack(); 166 } else { 167 mDevice.wait(Until.findObject(By.res("android:id/toggle")), LONG_TIMEOUT).click(); 168 } 169 Thread.sleep(LONG_TIMEOUT); 170 String changedWifiValue = Settings.Global.getString(mResolver, Settings.Global.WIFI_ON); 171 Thread.sleep(LONG_TIMEOUT); 172 if (verifyOn) { 173 assertEquals("1", changedWifiValue); 174 } else { 175 assertEquals("0", changedWifiValue); 176 } 177 } finally { 178 Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), 179 Settings.Global.AIRPLANE_MODE_ON, airPlaneMode); 180 } 181 } 182 183 @MediumTest testQuickSettingBluetoothEnabled()184 public void testQuickSettingBluetoothEnabled() throws Exception { 185 verifyBluetoothOnOrOff(true); 186 } 187 188 @MediumTest testQuickSettingBluetoothDisabled()189 public void testQuickSettingBluetoothDisabled() throws Exception { 190 verifyBluetoothOnOrOff(false); 191 } 192 verifyBluetoothOnOrOff(boolean verifyOn)193 private void verifyBluetoothOnOrOff(boolean verifyOn) throws Exception { 194 BluetoothManager bluetoothManager = (BluetoothManager) getInstrumentation().getContext() 195 .getSystemService(Context.BLUETOOTH_SERVICE); 196 if (!verifyOn) { 197 bluetoothManager.getAdapter().enable(); 198 } else { 199 bluetoothManager.getAdapter().disable(); 200 } 201 launchQuickSetting(); 202 mDevice.wait(Until.findObject(By.textContains(QuickSettingTiles.BLUETOOTH.getName())), 203 LONG_TIMEOUT).click(); 204 if (verifyOn) { 205 mDevice.pressBack(); 206 } else { 207 mDevice.wait(Until.findObject(By.res("android:id/toggle")), LONG_TIMEOUT).click(); 208 } 209 Thread.sleep(LONG_TIMEOUT); 210 String bluetoothVal = Settings.Global.getString( 211 mResolver, 212 Settings.Global.BLUETOOTH_ON); 213 if (verifyOn) { 214 assertEquals("1", bluetoothVal); 215 } else { 216 assertEquals("0", bluetoothVal); 217 } 218 } 219 220 @MediumTest testQuickSettingFlashLight()221 public void testQuickSettingFlashLight() throws Exception { 222 String lightOn = "On"; 223 String lightOff = "Off"; 224 boolean verifyOn = false; 225 launchQuickSetting(); 226 UiObject2 flashLight = mDevice.wait( 227 Until.findObject(By.descContains(QuickSettingTiles.FLASHLIGHT.getName())), 228 LONG_TIMEOUT); 229 if (flashLight.getText().equals(lightOn)) { 230 verifyOn = true; 231 } 232 mDevice.wait(Until.findObject(By.textContains(QuickSettingTiles.FLASHLIGHT.getName())), 233 LONG_TIMEOUT).click(); 234 Thread.sleep(LONG_TIMEOUT); 235 flashLight = mDevice.wait( 236 Until.findObject(By.descContains(QuickSettingTiles.FLASHLIGHT.getName())), 237 LONG_TIMEOUT); 238 if (verifyOn) { 239 assertTrue(flashLight.getText().equals(lightOff)); 240 } else { 241 assertTrue(flashLight.getText().equals(lightOn)); 242 mDevice.wait(Until.findObject(By.textContains(QuickSettingTiles.FLASHLIGHT.getName())), 243 LONG_TIMEOUT).click(); 244 } 245 } 246 247 @MediumTest testQuickSettingDND()248 public void testQuickSettingDND() throws Exception { 249 int onSetting = Settings.Global.getInt(mResolver, "zen_mode"); 250 launchQuickSetting(); 251 mDevice.wait(Until.findObject(By.descContains(QuickSettingTiles.DND.getName())), 252 LONG_TIMEOUT).click(); 253 if (onSetting == 0) { 254 mDevice.pressBack(); 255 } 256 Thread.sleep(LONG_TIMEOUT); 257 int changedSetting = Settings.Global.getInt(mResolver, "zen_mode"); 258 assertFalse(onSetting == changedSetting); 259 } 260 261 @MediumTest testQuickSettingAirplaneMode()262 public void testQuickSettingAirplaneMode() throws Exception { 263 int onSetting = Integer.parseInt(Settings.Global.getString( 264 mResolver, 265 Settings.Global.AIRPLANE_MODE_ON)); 266 try { 267 launchQuickSetting(); 268 mDevice.wait(Until.findObject(By.descContains(QuickSettingTiles.AIRPLANE.getName())), 269 LONG_TIMEOUT).click(); 270 Thread.sleep(LONG_TIMEOUT); 271 int changedSetting = Integer.parseInt(Settings.Global.getString( 272 mResolver, 273 Settings.Global.AIRPLANE_MODE_ON)); 274 assertTrue((1 - onSetting) == changedSetting); 275 } finally { 276 Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), 277 Settings.Global.AIRPLANE_MODE_ON, Integer.toString(onSetting)); 278 } 279 } 280 281 @MediumTest testQuickSettingOrientation()282 public void testQuickSettingOrientation() throws Exception { 283 launchQuickSetting(); 284 mDevice.wait(Until.findObject(By.descContains(QuickSettingTiles.SCREEN.getName())), 285 LONG_TIMEOUT).click(); 286 Thread.sleep(LONG_TIMEOUT); 287 String rotation = Settings.System.getString(mResolver, 288 Settings.System.ACCELEROMETER_ROTATION); 289 assertEquals("1", rotation); 290 } 291 292 @MediumTest testQuickSettingLocation()293 public void testQuickSettingLocation() throws Exception { 294 LocationManager service = (LocationManager) getInstrumentation().getContext() 295 .getSystemService(Context.LOCATION_SERVICE); 296 boolean onSetting = service.isProviderEnabled(LocationManager.GPS_PROVIDER); 297 try { 298 launchQuickSetting(); 299 mDevice.wait(Until.findObject(By.descContains(QuickSettingTiles.LOCATION.getName())), 300 LONG_TIMEOUT).click(); 301 Thread.sleep(LONG_TIMEOUT); 302 boolean changedSetting = service.isProviderEnabled(LocationManager.GPS_PROVIDER); 303 assertTrue(onSetting == !changedSetting); 304 } finally { 305 mDevice.wait(Until.findObject(By.descContains(QuickSettingTiles.LOCATION.getName())), 306 LONG_TIMEOUT).click(); 307 } 308 } 309 launchQuickSetting()310 private void launchQuickSetting() throws Exception { 311 mDevice.pressHome(); 312 swipeDown(); 313 Thread.sleep(LONG_TIMEOUT); 314 swipeDown(); 315 } 316 swipeUp()317 private void swipeUp() throws Exception { 318 mDevice.swipe(mDevice.getDisplayWidth() / 2, mDevice.getDisplayHeight(), 319 mDevice.getDisplayWidth() / 2, 0, 30); 320 Thread.sleep(SHORT_TIMEOUT); 321 } 322 swipeDown()323 private void swipeDown() throws Exception { 324 mDevice.swipe(mDevice.getDisplayWidth() / 2, 0, mDevice.getDisplayWidth() / 2, 325 mDevice.getDisplayHeight() / 2 + 50, 20); 326 Thread.sleep(SHORT_TIMEOUT); 327 } 328 swipeLeft()329 private void swipeLeft() { 330 mDevice.swipe(mDevice.getDisplayWidth() / 2, mDevice.getDisplayHeight() / 2, 0, 331 mDevice.getDisplayHeight() / 2, 5); 332 } 333 } 334