• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.system.helpers;
18 
19 import android.bluetooth.BluetoothAdapter;
20 import android.bluetooth.BluetoothManager;
21 import android.content.ComponentName;
22 import android.content.ContentResolver;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.net.wifi.WifiManager;
26 import android.provider.Settings;
27 import android.provider.Settings.SettingNotFoundException;
28 import android.support.test.InstrumentationRegistry;
29 import android.support.test.uiautomator.By;
30 import android.support.test.uiautomator.BySelector;
31 import android.support.test.uiautomator.Direction;
32 import android.support.test.uiautomator.UiDevice;
33 import android.support.test.uiautomator.UiObject;
34 import android.support.test.uiautomator.UiObject2;
35 import android.support.test.uiautomator.UiObjectNotFoundException;
36 import android.support.test.uiautomator.UiScrollable;
37 import android.support.test.uiautomator.UiSelector;
38 import android.support.test.uiautomator.Until;
39 import android.util.Log;
40 import android.widget.Switch;
41 import android.widget.TextView;
42 
43 import junit.framework.Assert;
44 
45 import java.util.Random;
46 import java.util.regex.Pattern;
47 
48 /**
49  * Implement common helper methods for settings.
50  */
51 public class SettingsHelper {
52     private static final String TAG = SettingsHelper.class.getSimpleName();
53     private static final String ANDROID_PACKAGE = "android";
54     private static final String SETTINGS_PACKAGE = "com.android.settings";
55     private static final String SETTINGS_PKG_SEARCH = "com.google.android.settings.intelligence";
56     private static final String SETTINGS_APP = "Settings";
57     private static final String SWITCH_WIDGET = "switch_widget";
58     private static final String WIFI = "Wi-Fi";
59     private static final String BLUETOOTH = "Bluetooth";
60     private static final String AIRPLANE = "Airplane mode";
61     private static final String LOCATION = "Location";
62     private static final String DND = "Do not disturb";
63     private static final String ZEN_MODE = "zen_mode";
64     private static final String FLASHLIGHT = "Flashlight";
65     private static final String AUTO_ROTATE_SCREEN = "Auto-rotate screen";
66     private static final BySelector SETTINGS_DASHBOARD = By.res(SETTINGS_PACKAGE,
67             "dashboard_container");
68     private static final String ACTION_SEARCH = "com.android.settings.action.SETTINGS_SEARCH";
69     private static final String NO_RESULT_QUERY = "no_result_query";
70     private static final String RES_ID_SEARCH_UI_TEXT_BOX = "search_src_text";
71     private static final String RES_ID_SEARCH_UI_EDIT_TEXT_BOX = "open_search_view_edit_text";
72     private static final String RES_ID_SEARCH_UI_NO_RESULT_IMAGE = "no_results_layout_v2";
73 
74     private static final UiSelector LIST_ITEM_VALUE =
75             new UiSelector().className(TextView.class);
76     public static final int TIMEOUT = 2000;
77 
78     private static SettingsHelper sInstance = null;
79     private ActivityHelper mActivityHelper = null;
80     private ContentResolver mResolver = null;
81     private Context mContext = null;
82     private UiDevice mDevice = null;
83 
SettingsHelper()84     public SettingsHelper() {
85         mContext = InstrumentationRegistry.getTargetContext();
86         mResolver = mContext.getContentResolver();
87         mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
88         mActivityHelper = ActivityHelper.getInstance();
89     }
90 
getInstance()91     public static SettingsHelper getInstance() {
92         if (sInstance == null) {
93             sInstance = new SettingsHelper();
94         }
95         return sInstance;
96     }
97 
98     /**
99      * Opens Settings search page
100      */
openSearch(Context context)101     public void openSearch(Context context) throws Exception {
102         launchSettingsPage(context, ACTION_SEARCH);
103         // Wait for the search UI to appear
104         mDevice.wait(Until.hasObject(By.res(RES_ID_SEARCH_UI_TEXT_BOX)),
105                 TIMEOUT);
106     }
107 
108     /**
109      * Performs a query that has no result and clears query afterwards.
110      */
performNoResultQuery()111     public void performNoResultQuery() {
112         final String randomQuery = NO_RESULT_QUERY + new Random().nextInt();
113 
114         mDevice.wait(
115                         Until.findObject(
116                                 By.res(SETTINGS_PKG_SEARCH, RES_ID_SEARCH_UI_EDIT_TEXT_BOX)),
117                         TIMEOUT)
118                 .setText(randomQuery);
119 
120         mDevice.wait(
121                 Until.hasObject(By.res(SETTINGS_PKG_SEARCH, RES_ID_SEARCH_UI_NO_RESULT_IMAGE)),
122                 TIMEOUT);
123         mDevice.wait(
124                         Until.findObject(
125                                 By.res(SETTINGS_PKG_SEARCH, RES_ID_SEARCH_UI_EDIT_TEXT_BOX)),
126                         TIMEOUT)
127                 .clear();
128     }
129 
130     public enum SettingsType {
131         SYSTEM, SECURE, GLOBAL
132     }
133 
134     /**
135      * @return Settings package name
136      */
getPackage()137     public String getPackage() {
138         return SETTINGS_PACKAGE;
139     }
140 
141     /**
142      * @return Settings app name
143      */
getLauncherName()144     public String getLauncherName() {
145         return SETTINGS_APP;
146     }
147 
148     /**
149      * Scroll through settings page
150      * @param numberOfFlings
151      * @throws Exception
152      */
scrollThroughSettings(int numberOfFlings)153     public void scrollThroughSettings(int numberOfFlings) throws Exception {
154         UiObject2 settingsList = loadAllSettings();
155         int count = 0;
156         while (count <= numberOfFlings && settingsList.fling(Direction.DOWN)) {
157             count++;
158         }
159     }
160 
161     /**
162      * Move to top of settings page
163      * @throws Exception
164      */
flingSettingsToStart()165     public void flingSettingsToStart() throws Exception {
166         UiObject2 settingsList = loadAllSettings();
167         while (settingsList.fling(Direction.UP));
168     }
169 
170     /**
171      * Launch specific settings page
172      * @param ctx
173      * @param pageName
174      * @throws Exception
175      */
launchSettingsPage(Context ctx, String pageName)176     public static void launchSettingsPage(Context ctx, String pageName) throws Exception {
177         Intent intent = new Intent(pageName);
178         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
179         ctx.startActivity(intent);
180         Thread.sleep(TIMEOUT * 2);
181     }
182 
183     /**
184      * Scroll vertically up or down
185      * @param isUp
186      */
scrollVert(boolean isUp)187     public void scrollVert(boolean isUp) {
188         int w = mDevice.getDisplayWidth();
189         int h = mDevice.getDisplayHeight();
190         mDevice.swipe(w / 2, h / 2, w / 2, isUp ? h : 0, 2);
191     }
192 
193     /**
194      * On N, the settingsDashboard is initially collapsed, and the user can see the "See all"
195      * element. On hitting "See all", the same settings dashboard element is now scrollable. For
196      * pre-N, the settings Dashboard is always scrollable, hence the check in the while loop. All
197      * this method does is expand the Settings list if needed, before returning the element.
198      */
loadAllSettings()199     public UiObject2 loadAllSettings() throws Exception {
200         UiObject2 settingsDashboard = mDevice.wait(Until.findObject(SETTINGS_DASHBOARD),
201                 TIMEOUT * 2);
202         Assert.assertNotNull("Could not find the settings dashboard object.", settingsDashboard);
203         int count = 0;
204         while (!settingsDashboard.isScrollable() && count <= 2) {
205             mDevice.wait(Until.findObject(By.text("SEE ALL")), TIMEOUT * 2).click();
206             settingsDashboard = mDevice.wait(Until.findObject(SETTINGS_DASHBOARD),
207                     TIMEOUT * 2);
208             count++;
209         }
210         return settingsDashboard;
211     }
212 
213     /**
214      * Performs click action on a setting when setting name is provided as exact string
215      * @param settingName
216      * @throws InterruptedException
217      */
clickSetting(String settingName)218     public void clickSetting(String settingName) throws InterruptedException {
219         int count = 5;
220         while (count > 0 && mDevice.wait(Until.findObject(By.text(settingName)), TIMEOUT) == null) {
221             scrollVert(false);
222             count--;
223         }
224         mDevice.wait(Until.findObject(By.text(settingName)), TIMEOUT).click();
225         Thread.sleep(TIMEOUT);
226     }
227 
228     /**
229      * Performs click action on a setting when setting has been found
230      *
231      * @throws InterruptedException,UiObjectNotFoundException
232      */
selectSettingFor(String settingName)233     public boolean selectSettingFor(String settingName)
234             throws InterruptedException, UiObjectNotFoundException {
235         UiScrollable settingsList = new UiScrollable(
236                 new UiSelector().resourceId("android:id/content"));
237         UiObject appSettings = settingsList.getChildByText(LIST_ITEM_VALUE, settingName);
238         if (appSettings != null) {
239             return appSettings.click();
240         }
241         return false;
242     }
243 
244     /**
245      * Performs click action on a setting when setting name is provided as pattern
246      *
247      * @param settingName
248      * @throws InterruptedException
249      */
clickSetting(Pattern settingName)250     public void clickSetting(Pattern settingName) throws InterruptedException {
251         mDevice.wait(Until.findObject(By.text(settingName)), TIMEOUT).click();
252         Thread.sleep(400);
253     }
254 
255     /**
256      * Gets string value of a setting
257      * @param type
258      * @param sName
259      * @return
260      */
getStringSetting(SettingsType type, String sName)261     public String getStringSetting(SettingsType type, String sName) {
262         switch (type) {
263             case SYSTEM:
264                 return Settings.System.getString(mResolver, sName);
265             case GLOBAL:
266                 return Settings.Global.getString(mResolver, sName);
267             case SECURE:
268                 return Settings.Secure.getString(mResolver, sName);
269         }
270         return "";
271     }
272 
273     /**
274      * Get int value of a setting
275      * @param type
276      * @param sName
277      * @return
278      * @throws SettingNotFoundException
279      */
getIntSetting(SettingsType type, String sName)280     public int getIntSetting(SettingsType type, String sName) throws SettingNotFoundException {
281         switch (type) {
282             case SYSTEM:
283                 return Settings.System.getInt(mResolver, sName);
284             case GLOBAL:
285                 return Settings.Global.getInt(mResolver, sName);
286             case SECURE:
287                 return Settings.Secure.getInt(mResolver, sName);
288         }
289         return Integer.MIN_VALUE;
290     }
291 
292     /**
293      * Set string value of a setting
294      * @param type
295      * @param sName
296      * @param value
297      */
setStringSetting(SettingsType type, String sName, String value)298     public void setStringSetting(SettingsType type, String sName, String value)
299             throws InterruptedException {
300         switch (type) {
301             case SYSTEM:
302                 Settings.System.putString(mResolver, sName, value);
303                 break;
304             case GLOBAL:
305                 Settings.Global.putString(mResolver, sName, value);
306                 break;
307             case SECURE:
308                 Settings.Secure.putString(mResolver, sName, value);
309                 break;
310         }
311         Thread.sleep(TIMEOUT);
312     }
313 
314     /**
315      * Sets int value of a setting
316      * @param type
317      * @param sName
318      * @param value
319      */
setIntSetting(SettingsType type, String sName, int value)320     public void setIntSetting(SettingsType type, String sName, int value)
321             throws InterruptedException {
322         switch (type) {
323             case SYSTEM:
324                 Settings.System.putInt(mResolver, sName, value);
325                 break;
326             case GLOBAL:
327                 Settings.Global.putInt(mResolver, sName, value);
328                 break;
329             case SECURE:
330                 Settings.Secure.putInt(mResolver, sName, value);
331                 break;
332         }
333         Thread.sleep(TIMEOUT);
334     }
335 
336     /**
337      * Toggles setting and verifies the action, when setting name is passed as string
338      * @param type
339      * @param settingAction
340      * @param settingName
341      * @param internalName
342      * @return
343      * @throws Exception
344      */
verifyToggleSetting(SettingsType type, String settingAction, String settingName, String internalName)345     public boolean verifyToggleSetting(SettingsType type, String settingAction,
346             String settingName, String internalName) throws Exception {
347         return verifyToggleSetting(
348                 type, settingAction, Pattern.compile(settingName), internalName, true);
349     }
350 
351     /**
352      * Toggles setting and verifies the action, when setting name is passed as pattern
353      * @param type
354      * @param settingAction
355      * @param settingName
356      * @param internalName
357      * @return
358      * @throws Exception
359      */
verifyToggleSetting(SettingsType type, String settingAction, Pattern settingName, String internalName)360     public boolean verifyToggleSetting(SettingsType type, String settingAction,
361             Pattern settingName, String internalName) throws Exception {
362         return verifyToggleSetting(type, settingAction, settingName, internalName, true);
363     }
364 
365     /**
366      * Toggles setting and verifies the action, when setting name is passed as string
367      * and settings page needs to be launched or not
368      * @param type
369      * @param settingAction
370      * @param settingName
371      * @param internalName
372      * @param doLaunch
373      * @return
374      * @throws Exception
375      */
verifyToggleSetting(SettingsType type, String settingAction, String settingName, String internalName, boolean doLaunch)376     public boolean verifyToggleSetting(SettingsType type, String settingAction,
377             String settingName, String internalName, boolean doLaunch) throws Exception {
378         return verifyToggleSetting(
379                 type, settingAction, Pattern.compile(settingName), internalName, doLaunch);
380     }
381 
382     /**
383      * Toggles setting and verifies the action
384      * @param type
385      * @param settingAction
386      * @param settingName
387      * @param internalName
388      * @param doLaunch
389      * @return
390      * @throws Exception
391      */
verifyToggleSetting(SettingsType type, String settingAction, Pattern settingName, String internalName, boolean doLaunch)392     public boolean verifyToggleSetting(SettingsType type, String settingAction,
393             Pattern settingName, String internalName, boolean doLaunch) throws Exception {
394         String onSettingBaseVal = getStringSetting(type, internalName);
395         if (onSettingBaseVal == null) {
396             // Per bug b/35717943 default for charging sounds is ON
397             // So if null, the value should be set to 1.
398             if (settingName.matcher("Charging sounds").matches()) {
399                 onSettingBaseVal = "1";
400             }
401             else {
402                 onSettingBaseVal = "0";
403             }
404         }
405         int onSetting = Integer.parseInt(onSettingBaseVal);
406         Log.d(TAG, "On Setting value is : " + onSetting);
407         if (doLaunch) {
408             launchSettingsPage(mContext, settingAction);
409         }
410         clickSetting(settingName);
411         Log.d(TAG, "Clicked setting : " + settingName);
412         Thread.sleep(5000);
413         String changedSetting = getStringSetting(type, internalName);
414         Log.d(TAG, "Changed Setting value is : " + changedSetting);
415         if (changedSetting == null) {
416             Log.d(TAG, "Changed Setting value is : NULL");
417             changedSetting = "0";
418         }
419         return (1 - onSetting) == Integer.parseInt(changedSetting);
420     }
421 
422     /**
423      * @param type
424      * @param settingAction
425      * @param baseName
426      * @param settingName
427      * @param internalName
428      * @param testVal
429      * @return
430      * @throws Exception
431      */
verifyRadioSetting(SettingsType type, String settingAction, String baseName, String settingName, String internalName, String testVal)432     public boolean verifyRadioSetting(SettingsType type, String settingAction,
433             String baseName, String settingName,
434             String internalName, String testVal) throws Exception {
435         if (baseName != null)
436             clickSetting(baseName);
437         clickSetting(settingName);
438         Thread.sleep(500);
439         return getStringSetting(type, internalName).equals(testVal);
440     }
441 
toggleWiFiOnOffAndVerify(boolean verifyOn, boolean isQuickSettings)442     public void toggleWiFiOnOffAndVerify(boolean verifyOn, boolean isQuickSettings)
443             throws Exception {
444         String switchText = (verifyOn ? "OFF" : "ON");
445         WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
446         wifiManager.setWifiEnabled(!verifyOn);
447         Thread.sleep(TIMEOUT * 3);
448         if (isQuickSettings) {
449             launchAndClickSettings(isQuickSettings, null, By.descContains(WIFI)
450                     .clazz(Switch.class));
451         } else {
452             launchAndClickSettings(isQuickSettings, Settings.ACTION_WIFI_SETTINGS,
453                     By.res(SETTINGS_PACKAGE, SWITCH_WIDGET).text(switchText));
454         }
455         Thread.sleep(TIMEOUT * 3);
456         String wifiValue = Settings.Global.getString(mResolver, Settings.Global.WIFI_ON);
457         if (verifyOn) {
458             Assert.assertFalse(wifiValue == "0");
459         } else {
460             Assert.assertEquals("0", wifiValue);
461         }
462         mDevice.pressHome();
463         Thread.sleep(TIMEOUT * 3);
464     }
465 
toggleBTOnOffAndVerify(boolean verifyOn, boolean isQuickSettings)466     public void toggleBTOnOffAndVerify(boolean verifyOn, boolean isQuickSettings)
467             throws Exception {
468         String switchText = (verifyOn ? "OFF" : "ON");
469         BluetoothAdapter bluetoothAdapter = ((BluetoothManager) mContext
470                 .getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
471         boolean isEnabled = bluetoothAdapter.isEnabled();
472         boolean success = (verifyOn ? bluetoothAdapter.disable() : bluetoothAdapter.enable());
473         Thread.sleep(TIMEOUT * 3);
474         if (isQuickSettings) {
475             launchAndClickSettings(isQuickSettings, null,
476                     By.descContains(BLUETOOTH).clazz(Switch.class));
477         } else {
478             launchAndClickSettings(isQuickSettings, Settings.ACTION_BLUETOOTH_SETTINGS,
479                     By.res(SETTINGS_PACKAGE, SWITCH_WIDGET).text(switchText));
480         }
481         Thread.sleep(TIMEOUT * 3);
482         String bluetoothValue = Settings.Global.getString(
483                 mResolver,
484                 Settings.Global.BLUETOOTH_ON);
485         Assert.assertEquals((verifyOn ? "1" : "0"), bluetoothValue);
486         if (isEnabled) {
487             bluetoothAdapter.enable();
488         } else {
489             bluetoothAdapter.disable();
490         }
491         mDevice.pressHome();
492         Thread.sleep(TIMEOUT * 3);
493     }
494 
toggleAirplaneModeOnOrOffAndVerify(boolean verifyOn, boolean isQuickSettings)495     public void toggleAirplaneModeOnOrOffAndVerify(boolean verifyOn, boolean isQuickSettings)
496             throws Exception {
497         String settingValToPut = (verifyOn ? "0" : "1");
498         Settings.Global.putString(mResolver, Settings.Global.AIRPLANE_MODE_ON, settingValToPut);
499         if (isQuickSettings) {
500             launchAndClickSettings(isQuickSettings, null, By.descContains(AIRPLANE));
501         } else {
502             launchAndClickSettings(isQuickSettings, Settings.ACTION_WIRELESS_SETTINGS,
503                     By.text(AIRPLANE));
504         }
505         Thread.sleep(TIMEOUT * 3);
506         String airplaneModeValue = Settings.Global
507                 .getString(mResolver,
508                         Settings.Global.AIRPLANE_MODE_ON);
509         Assert.assertEquals((verifyOn ? "1" : "0"), airplaneModeValue);
510         mDevice.pressHome();
511         Thread.sleep(TIMEOUT * 3);
512     }
513 
toggleLocationSettingsOnOrOffAndVerify(boolean verifyOn, boolean isQuickSettings)514     public void toggleLocationSettingsOnOrOffAndVerify(boolean verifyOn, boolean isQuickSettings)
515             throws Exception {
516         // Set location flag
517         int settingValToPut = (verifyOn ? Settings.Secure.LOCATION_MODE_OFF
518                 : Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
519         Settings.Secure.putInt(mResolver, Settings.Secure.LOCATION_MODE, settingValToPut);
520         // Load location settings
521         if (isQuickSettings) {
522             launchAndClickSettings(isQuickSettings, null, By.descContains(LOCATION));
523         } else {
524             launchAndClickSettings(isQuickSettings, Settings.ACTION_LOCATION_SOURCE_SETTINGS,
525                     By.res(SETTINGS_PACKAGE, SWITCH_WIDGET));
526         }
527         Thread.sleep(TIMEOUT * 3);
528         // Verify change in setting
529         int locationEnabled = Settings.Secure.getInt(mResolver,
530                 Settings.Secure.LOCATION_MODE);
531         if (verifyOn) {
532             Assert.assertFalse("Location not enabled correctly", locationEnabled == 0);
533         } else {
534             Assert.assertEquals("Location not disabled correctly", 0, locationEnabled);
535         }
536         mDevice.pressHome();
537         Thread.sleep(TIMEOUT * 3);
538     }
539 
launchAndClickSettings(boolean isQuickSettings, String settingsPage, BySelector bySelector)540     public void launchAndClickSettings(boolean isQuickSettings, String settingsPage,
541             BySelector bySelector) throws Exception {
542         if (isQuickSettings) {
543             launchQuickSettingsAndWait();
544             UiObject2 qsTile = mDevice.wait(Until.findObject(bySelector), TIMEOUT * 3);
545             qsTile.findObject(By.clazz("android.widget.FrameLayout")).click();
546         } else {
547             mActivityHelper.launchIntent(settingsPage);
548             mDevice.wait(Until.findObject(bySelector), TIMEOUT * 3).click();
549         }
550     }
551 
552     /**
553      * Verify Quick Setting DND can be toggled DND default value is OFF
554      * @throws Exception
555      */
toggleQuickSettingDNDAndVerify()556     public void toggleQuickSettingDNDAndVerify() throws Exception {
557         try {
558             int onSetting = Settings.Global.getInt(mResolver, ZEN_MODE);
559             launchQuickSettingsAndWait();
560             mDevice.wait(Until.findObject(By.descContains(DND).clazz(Switch.class)),
561                     TIMEOUT * 3).getChildren().get(0).click();
562             Thread.sleep(TIMEOUT * 3);
563             int changedSetting = Settings.Global.getInt(mResolver, ZEN_MODE);
564             Assert.assertFalse(onSetting == changedSetting);
565             mDevice.pressHome();
566             Thread.sleep(TIMEOUT * 3);
567         } finally {
568             // change to DND default value
569             int setting = Settings.Global.getInt(mResolver, ZEN_MODE);
570             if (setting > 0) {
571                 launchQuickSettingsAndWait();
572                 mDevice.wait(Until.findObject(By.descContains(DND).clazz(Switch.class)),
573                         TIMEOUT * 3).getChildren().get(0).click();
574                 Thread.sleep(TIMEOUT * 3);
575             }
576         }
577     }
578 
toggleQuickSettingFlashLightAndVerify()579     public void toggleQuickSettingFlashLightAndVerify() throws Exception {
580         String lightOn = "On";
581         String lightOff = "Off";
582         boolean verifyOn = false;
583         launchQuickSettingsAndWait();
584         UiObject2 flashLight = mDevice.wait(
585                 Until.findObject(By.desc(FLASHLIGHT)),
586                 TIMEOUT * 3);
587         if (flashLight != null && flashLight.getText().equals(lightOn)) {
588             verifyOn = true;
589         }
590         mDevice.wait(Until.findObject(By.desc(FLASHLIGHT)),
591                 TIMEOUT * 3).click();
592         Thread.sleep(TIMEOUT * 3);
593         flashLight = mDevice.wait(
594                 Until.findObject(By.desc(FLASHLIGHT)),
595                 TIMEOUT * 3);
596         if (flashLight != null) {
597             String txt = flashLight.getText();
598             if (verifyOn) {
599                 Assert.assertTrue(txt.equals(lightOff));
600             } else {
601                 Assert.assertTrue(txt.equals(lightOn));
602                 mDevice.wait(Until.findObject(By.textContains(FLASHLIGHT)),
603                         TIMEOUT * 3).click();
604             }
605         }
606         mDevice.pressHome();
607         Thread.sleep(TIMEOUT * 3);
608     }
609 
toggleQuickSettingOrientationAndVerify()610     public void toggleQuickSettingOrientationAndVerify() throws Exception {
611         launchQuickSettingsAndWait();
612         mDevice.wait(Until.findObject(By.descContains(AUTO_ROTATE_SCREEN)),
613                 TIMEOUT * 3).click();
614         Thread.sleep(TIMEOUT * 3);
615         String rotation = Settings.System.getString(mResolver,
616                 Settings.System.ACCELEROMETER_ROTATION);
617         Assert.assertEquals("1", rotation);
618         mDevice.setOrientationNatural();
619         mDevice.pressHome();
620         Thread.sleep(TIMEOUT * 3);
621     }
622 
launchQuickSettingsAndWait()623     public void launchQuickSettingsAndWait() throws Exception {
624         mDevice.openQuickSettings();
625         Thread.sleep(TIMEOUT * 2);
626     }
627 
launchSettingsPageByComponentName(Context ctx, String name)628     public void launchSettingsPageByComponentName(Context ctx, String name) {
629         Intent intent = new Intent(Intent.ACTION_MAIN);
630         ComponentName settingComponent = new ComponentName(SETTINGS_PACKAGE,
631                 String.format("%s.%s$%s", SETTINGS_PACKAGE, SETTINGS_APP, name));
632         intent.setComponent(settingComponent);
633         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
634         ctx.startActivity(intent);
635     }
636 }
637