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