• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.platform.helpers;
18 
19 import android.app.Instrumentation;
20 import android.bluetooth.BluetoothAdapter;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.net.wifi.WifiManager;
24 import android.os.UserHandle;
25 import android.platform.helpers.ScrollUtility.ScrollActions;
26 import android.platform.helpers.ScrollUtility.ScrollDirection;
27 import android.util.Log;
28 
29 import androidx.test.InstrumentationRegistry;
30 import androidx.test.uiautomator.By;
31 import androidx.test.uiautomator.BySelector;
32 import androidx.test.uiautomator.UiObject2;
33 
34 import java.util.List;
35 import java.util.Locale;
36 import java.util.regex.Pattern;
37 
38 /** Setting Helper class for Android Auto platform functional tests */
39 public class SettingHelperImpl extends AbstractStandardAppHelper implements IAutoSettingHelper {
40     private static final String LOG_TAG = SettingHelperImpl.class.getSimpleName();
41 
42     private static final String SCREEN_BRIGHTNESS = "screen_brightness";
43 
44     private final ScrollUtility mScrollUtility;
45     private final SeekUtility mSeekUtility;
46     private Context mContext;
47     private boolean mUseCommandToOpenSettings = true;
48 
SettingHelperImpl(Instrumentation instr)49     public SettingHelperImpl(Instrumentation instr) {
50         super(instr);
51         mContext = InstrumentationRegistry.getContext();
52         mUseCommandToOpenSettings =
53                 Boolean.parseBoolean(
54                         InstrumentationRegistry.getArguments()
55                                 .getString("use_command_to_open_settings", "true"));
56         mScrollUtility = ScrollUtility.getInstance(getSpectatioUiUtil());
57         mSeekUtility = SeekUtility.getInstance(getSpectatioUiUtil());
58     }
59 
60     /** {@inheritDoc} */
61     @Override
open()62     public void open() {
63         if (mUseCommandToOpenSettings) {
64             Log.i(LOG_TAG, "Using Command to open Settings.");
65             openFullSettings();
66         } else {
67             Log.i(LOG_TAG, "Using Intent to open Settings.");
68             openSettingsIntent();
69         }
70     }
71 
72     /** {@inheritDoc} */
73     @Override
getPackage()74     public String getPackage() {
75         return getPackageFromConfig(AutomotiveConfigConstants.SETTINGS_PACKAGE);
76     }
77 
78     @Override
dismissInitialDialogs()79     public void dismissInitialDialogs() {
80         // Nothing to dismiss
81     }
82 
83     /** {@inheritDoc} */
84     @Override
stopSettingsApplication()85     public void stopSettingsApplication() {
86         getSpectatioUiUtil()
87                 .executeShellCommand(
88                         getCommandFromConfig(AutomotiveConfigConstants.STOP_SETTING_APP_COMMAND));
89     }
90 
91     /** {@inheritDoc} */
92     @Override
getLauncherName()93     public String getLauncherName() {
94         return "Settings";
95     }
96 
97     /** {@inheritDoc} */
98     @Override
exit()99     public void exit() {
100         getSpectatioUiUtil().pressHome();
101         getSpectatioUiUtil().wait1Second();
102     }
103 
104     /** {@inheritDoc} */
105     @Override
openSetting(String setting)106     public void openSetting(String setting) {
107         executeWorkflow(setting);
108     }
109 
110     @Override
getPageTitleText()111     public String getPageTitleText() {
112         UiObject2 pageToolbarTitle = getPageTitle();
113         return pageToolbarTitle.getText();
114     }
115 
116     /** {@inheritDoc} */
117     @Override
openFullSettings()118     public void openFullSettings() {
119         getSpectatioUiUtil()
120                 .executeShellCommand(
121                         getCommandFromConfig(AutomotiveConfigConstants.OPEN_SETTINGS_COMMAND));
122     }
123 
openSettingsIntent()124     private void openSettingsIntent() {
125         // Launch the application as normal.
126         String pkg = getPackage();
127         Log.i(LOG_TAG, String.format("Sending command to launch app: %s", pkg));
128         mInstrumentation
129                 .getContext()
130                 .startActivityAsUser(
131                         getOpenAppIntent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
132                         UserHandle.CURRENT);
133     }
134 
135     /** {@inheritDoc} */
136     @Override
turnOnOffWifi(boolean onOff)137     public void turnOnOffWifi(boolean onOff) {
138         boolean isOn = isWifiOn();
139         if (isOn != onOff) {
140             BySelector enableOptionSelector =
141                     getUiElementFromConfig(AutomotiveConfigConstants.TOGGLE_WIFI);
142             UiObject2 enableOption = getSpectatioUiUtil().findUiObject(enableOptionSelector);
143             getSpectatioUiUtil()
144                     .validateUiObject(enableOption, AutomotiveConfigConstants.TOGGLE_WIFI);
145             getSpectatioUiUtil().clickAndWait(enableOption);
146         } else {
147             throw new RuntimeException("Wi-Fi enabled state is already " + (onOff ? "on" : "off"));
148         }
149     }
150 
151     /** {@inheritDoc} */
152     @Override
isWifiOn()153     public boolean isWifiOn() {
154         WifiManager wifi = (WifiManager) this.mContext.getSystemService(Context.WIFI_SERVICE);
155         return wifi.isWifiEnabled();
156     }
157 
158     /** {@inheritDoc} */
159     @Override
turnOnOffHotspot(boolean onOff)160     public void turnOnOffHotspot(boolean onOff) {
161         boolean isOn = isHotspotOn();
162         if (isOn != onOff) {
163             BySelector enableOptionSelector =
164                     getUiElementFromConfig(AutomotiveConfigConstants.TOGGLE_HOTSPOT);
165             UiObject2 enableOption = getSpectatioUiUtil().findUiObject(enableOptionSelector);
166             getSpectatioUiUtil()
167                     .validateUiObject(enableOption, AutomotiveConfigConstants.TOGGLE_HOTSPOT);
168             getSpectatioUiUtil().clickAndWait(enableOption);
169         } else {
170             throw new RuntimeException(
171                     "Hotspot enabled state is already " + (onOff ? "on" : "off"));
172         }
173     }
174 
175     /** {@inheritDoc} */
176     @Override
toggleHotspot()177     public void toggleHotspot() {
178         BySelector enableOptionSelector =
179                 getUiElementFromConfig(AutomotiveConfigConstants.TOGGLE_HOTSPOT);
180         UiObject2 enableOption = getSpectatioUiUtil().findUiObject(enableOptionSelector);
181         getSpectatioUiUtil()
182                 .validateUiObject(enableOption, AutomotiveConfigConstants.TOGGLE_HOTSPOT);
183         getSpectatioUiUtil().clickAndWait(enableOption);
184     }
185 
186     /** {@inheritDoc} */
187     @Override
isHotspotOn()188     public boolean isHotspotOn() {
189         BySelector enableOptionSelector =
190                 getUiElementFromConfig(AutomotiveConfigConstants.TOGGLE_HOTSPOT);
191         UiObject2 enableOption = getSpectatioUiUtil().findUiObject(enableOptionSelector);
192         getSpectatioUiUtil()
193                 .validateUiObject(enableOption, AutomotiveConfigConstants.TOGGLE_HOTSPOT);
194         return enableOption.isChecked();
195     }
196 
197     /** {@inheritDoc} */
198     @Override
turnOnOffBluetooth(boolean onOff)199     public void turnOnOffBluetooth(boolean onOff) {
200         boolean isOn = isBluetoothOn();
201         if (isOn != onOff) {
202             BySelector enableOptionSelector =
203                     getUiElementFromConfig(AutomotiveConfigConstants.TOGGLE_BLUETOOTH);
204             UiObject2 enableOption = getSpectatioUiUtil().findUiObject(enableOptionSelector);
205             getSpectatioUiUtil()
206                     .validateUiObject(enableOption, AutomotiveConfigConstants.TOGGLE_BLUETOOTH);
207             getSpectatioUiUtil().clickAndWait(enableOption);
208         } else {
209             throw new RuntimeException(
210                     "Bluetooth enabled state is already " + (onOff ? "on" : "off"));
211         }
212     }
213 
214     /** {@inheritDoc} */
215     @Override
isBluetoothOn()216     public boolean isBluetoothOn() {
217         BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
218         return ba.isEnabled();
219     }
220 
221     /** {@inheritDoc} */
222     @Override
searchAndSelect(String item)223     public void searchAndSelect(String item) {
224         searchAndSelect(item, 0);
225     }
226 
227     /** {@inheritDoc} */
228     @Override
searchAndSelect(String item, int selectedIndex)229     public void searchAndSelect(String item, int selectedIndex) {
230         BySelector searchButtonSelector = getUiElementFromConfig(AutomotiveConfigConstants.SEARCH);
231         UiObject2 searchButton = getSpectatioUiUtil().findUiObject(searchButtonSelector);
232         getSpectatioUiUtil().validateUiObject(searchButton, AutomotiveConfigConstants.SEARCH);
233         getSpectatioUiUtil().clickAndWait(searchButton);
234         getSpectatioUiUtil().waitForIdle();
235 
236         BySelector searchBoxSelector = getUiElementFromConfig(AutomotiveConfigConstants.SEARCH_BOX);
237         UiObject2 searchBox = getSpectatioUiUtil().findUiObject(searchBoxSelector);
238         getSpectatioUiUtil().validateUiObject(searchBox, AutomotiveConfigConstants.SEARCH_BOX);
239         searchBox.setText(item);
240         getSpectatioUiUtil().wait5Seconds();
241 
242         BySelector searchResultsSelector =
243                 getUiElementFromConfig(AutomotiveConfigConstants.SEARCH_RESULTS);
244         UiObject2 searchResults = getSpectatioUiUtil().findUiObject(searchResultsSelector);
245 
246         getSpectatioUiUtil()
247                 .validateUiObject(searchResults, AutomotiveConfigConstants.SEARCH_RESULTS);
248         int numberOfResults = searchResults.getChildren().get(0).getChildren().size();
249         if (numberOfResults == 0) {
250             throw new RuntimeException("No results found");
251         }
252         getSpectatioUiUtil()
253                 .clickAndWait(searchResults.getChildren().get(0).getChildren().get(selectedIndex));
254         getSpectatioUiUtil().waitForIdle();
255         getSpectatioUiUtil().wait5Seconds();
256 
257         BySelector objectSelector = By.textContains(item);
258         UiObject2 object = getSpectatioUiUtil().findUiObject(objectSelector);
259         getSpectatioUiUtil().validateUiObject(object, AutomotiveConfigConstants.SEARCH_RESULTS);
260         getSpectatioUiUtil()
261                 .validateUiObject(
262                         object, String.format("Opened page does not contain searched item"));
263     }
264 
265     /** {@inheritDoc} */
266     @Override
isValidPageTitle(String item)267     public boolean isValidPageTitle(String item) {
268         UiObject2 pageTitle = getPageTitle();
269         return pageTitle.getText().contains(item);
270     }
271 
getPageTitle()272     private UiObject2 getPageTitle() {
273         getSpectatioUiUtil().wait5Seconds();
274         BySelector[] selectors =
275                 new BySelector[] {
276                     getUiElementFromConfig(AutomotiveConfigConstants.PAGE_TITLE),
277                     getUiElementFromConfig(AutomotiveConfigConstants.PERMISSIONS_PAGE_TITLE)
278                 };
279 
280         for (BySelector selector : selectors) {
281             List<UiObject2> pageTitles = getSpectatioUiUtil().findUiObjects(selector);
282             if (pageTitles != null && pageTitles.size() > 0) {
283                 return pageTitles.get(pageTitles.size() - 1);
284             }
285         }
286         throw new RuntimeException("Unable to find page title");
287     }
288 
289     /** {@inheritDoc} */
290     @Override
goBackToSettingsScreen()291     public void goBackToSettingsScreen() {
292         // count is used to avoid infinite loop in case someone invokes
293         // after exiting settings application
294         int count = 5;
295         BySelector titleText =
296                 getUiElementFromConfig(AutomotiveConfigConstants.SETTINGS_TITLE_TEXT);
297         while (count > 0
298                 && isAppInForeground()
299                 && getSpectatioUiUtil().findUiObjects(titleText) == null) {
300             getSpectatioUiUtil().pressBack();
301             getSpectatioUiUtil().wait5Seconds(); // to avoid stale object error
302             count--;
303         }
304     }
305 
306     /** {@inheritDoc} */
307     @Override
openMenuWith(String... menuOptions)308     public void openMenuWith(String... menuOptions) {
309         // Scroll and Find Subsettings
310         for (String menu : menuOptions) {
311             Pattern menuPattern = Pattern.compile(menu, Pattern.CASE_INSENSITIVE);
312             BySelector selector = By.text(menuPattern);
313 
314             ScrollActions scrollAction =
315                     ScrollActions.valueOf(
316                             getActionFromConfig(
317                                     AutomotiveConfigConstants.SETTINGS_SUB_SETTING_SCROLL_ACTION));
318 
319             BySelector forwardButtonSelector =
320                     getUiElementFromConfig(
321                             AutomotiveConfigConstants.SETTINGS_SUB_SETTING_SCROLL_FORWARD_BUTTON);
322             BySelector backwardButtonSelector =
323                     getUiElementFromConfig(
324                             AutomotiveConfigConstants.SETTINGS_SUB_SETTING_SCROLL_BACKWARD_BUTTON);
325 
326             BySelector scrollableElementSelector =
327                     getUiElementFromConfig(
328                             AutomotiveConfigConstants.SETTINGS_SUB_SETTING_SCROLL_ELEMENT);
329             ScrollDirection scrollDirection =
330                     ScrollDirection.valueOf(
331                             getActionFromConfig(
332                                     AutomotiveConfigConstants
333                                             .SETTINGS_SUB_SETTING_SCROLL_DIRECTION));
334 
335             UiObject2 object =
336                     mScrollUtility.scrollAndFindUiObject(
337                             scrollAction,
338                             scrollDirection,
339                             forwardButtonSelector,
340                             backwardButtonSelector,
341                             scrollableElementSelector,
342                             selector,
343                             String.format("Scroll on setting to find subssetting %s", selector));
344 
345             getSpectatioUiUtil()
346                     .validateUiObject(
347                             object,
348                             String.format("Unable to find UI Element %s.", selector.toString()));
349             getSpectatioUiUtil().clickAndWait(object);
350             getSpectatioUiUtil().waitForIdle();
351         }
352     }
353 
354     /** {@inheritDoc} */
355     @Override
getValue(String setting)356     public int getValue(String setting) {
357         String cmd = String.format("settings get system %s", setting);
358         String value = getSpectatioUiUtil().executeShellCommand(cmd);
359         return Integer.parseInt(value.replaceAll("\\s", ""));
360     }
361 
362     /** {@inheritDoc} */
363     @Override
setValue(String setting, int value)364     public void setValue(String setting, int value) {
365         String cmd = String.format(Locale.US, "settings put system %s %d", setting, value);
366         getSpectatioUiUtil().executeShellCommand(cmd);
367     }
368 
369     /** {@inheritDoc} */
370     @Override
checkMenuExists(String setting)371     public boolean checkMenuExists(String setting) {
372         return getSpectatioUiUtil().hasUiElement(setting);
373     }
374 
375     /**
376      * TODO - Keeping the below empty functions for now, to avoid the compilation error in Vendor it
377      * will be removed after vendor clean up (b/266450258)
378      */
379 
380     /** {@inheritDoc} */
381     @Override
findSettingMenu(String setting)382     public UiObject2 findSettingMenu(String setting) {
383         UiObject2 menuObject = null;
384         return menuObject;
385     }
386 
387     @Override
findSettingMenuAndClick(String setting)388     public void findSettingMenuAndClick(String setting) {}
389 
390     @Override
setBrightness(float targetPercentage)391     public int setBrightness(float targetPercentage) {
392         mSeekUtility.registerSeekBar(
393                 SCREEN_BRIGHTNESS,
394                 AutomotiveConfigConstants.BRIGHTNESS_SEEKBAR,
395                 SeekUtility.SeekLayout.HORIZONTAL,
396                 () -> getValue(SCREEN_BRIGHTNESS));
397         return mSeekUtility.seek(SCREEN_BRIGHTNESS, targetPercentage);
398     }
399 
400     /**
401      * Checks whether a setting menu is enabled or not. When not enabled, the menu item cannot be
402      * clicked.
403      */
404     @Override
isSettingMenuEnabled(String menu)405     public boolean isSettingMenuEnabled(String menu) {
406         boolean isSettingMenuEnabled = false;
407         return isSettingMenuEnabled;
408     }
409 
getMenu(String menu, int index)410     private UiObject2 getMenu(String menu, int index) {
411         UiObject2 menuButton = null;
412         return menuButton;
413     }
414 
415     /** {@inheritDoc} */
416     @Override
isRecentAppDisplayedInLocationSettings(String app)417     public boolean isRecentAppDisplayedInLocationSettings(String app) {
418         UiObject2 recentApp = getSpectatioUiUtil().findUiObject("Maps");
419         getSpectatioUiUtil()
420                 .validateUiObject(recentApp, String.format("Recently accessed app - %s", app));
421         UiObject2 recentAppsTime = recentApp.getParent();
422         if (recentAppsTime.getChildren().size() < 2) {
423             throw new RuntimeException("TimeStamp not displayed for Recently accessed app");
424         }
425         BySelector recentAppTimeStampSelector =
426                 getUiElementFromConfig(AutomotiveConfigConstants.RECENT_APPS_TIMESTAMP);
427         UiObject2 timestampObject =
428                 getSpectatioUiUtil()
429                         .findUiObjectInGivenElement(recentAppsTime, recentAppTimeStampSelector);
430         getSpectatioUiUtil().validateUiObject(timestampObject, String.format("timestamp object"));
431         String timestamp = timestampObject.getText();
432         String recentAppTimeStampTxt =
433                 getActionFromConfig(AutomotiveConfigConstants.RECENT_APPS_TIMESTAMP_TEXT);
434         return timestamp.contains(recentAppTimeStampTxt);
435     }
436 }
437