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 android.provider.cts;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assume.assumeFalse;
22 import static org.junit.Assume.assumeTrue;
23 
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.pm.PackageManager;
27 import android.provider.Settings;
28 import android.support.test.uiautomator.By;
29 import android.support.test.uiautomator.UiDevice;
30 import android.support.test.uiautomator.UiObject2;
31 import android.support.test.uiautomator.Until;
32 
33 import androidx.test.InstrumentationRegistry;
34 import androidx.test.filters.MediumTest;
35 import androidx.test.runner.AndroidJUnit4;
36 import androidx.test.uiautomator.StaleObjectException;
37 
38 import org.junit.After;
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 
43 /**
44  * Tests related SettingsPanels:
45  *
46  * atest SettingsPanelTest
47  */
48 @MediumTest
49 @RunWith(AndroidJUnit4.class)
50 public class SettingsPanelTest {
51 
52     private static final int TIMEOUT = 8000;
53 
54     private static final String RESOURCE_DONE = "done";
55     private static final String RESOURCE_SEE_MORE = "see_more";
56     private static final String RESOURCE_TITLE = "panel_title";
57 
58     private String mSettingsPackage;
59     private String mLauncherPackage;
60 
61     private Context mContext;
62     private boolean mHasTouchScreen;
63     private boolean mHasBluetooth;
64 
65     private UiDevice mDevice;
66 
67     @Before
setUp()68     public void setUp() throws Exception {
69         mContext = InstrumentationRegistry.getTargetContext();
70         mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
71 
72         final PackageManager packageManager = mContext.getPackageManager();
73 
74         mHasTouchScreen = packageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
75                 || packageManager.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
76         mHasBluetooth = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
77 
78         Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
79         launcherIntent.addCategory(Intent.CATEGORY_HOME);
80         mLauncherPackage = packageManager.resolveActivity(launcherIntent,
81                 PackageManager.MATCH_DEFAULT_ONLY).activityInfo.packageName;
82 
83         Intent settingsIntent = new Intent(android.provider.Settings.ACTION_SETTINGS);
84         mSettingsPackage = packageManager.resolveActivity(settingsIntent,
85                 PackageManager.MATCH_DEFAULT_ONLY).activityInfo.packageName;
86 
87         assumeFalse("Skipping test: Auto does not support provider android.settings.panel", isCar());
88         assumeFalse(
89             "Skipping test: Watch does not support provider android.settings.panel", isWatch());
90     }
91 
92     @After
cleanUp()93     public void cleanUp() {
94         mDevice.pressHome();
95         mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
96     }
97 
98     // Check correct package is opened
99 
100     @Test
volumePanel_correctPackage()101     public void volumePanel_correctPackage() {
102         assumeTrue(mHasTouchScreen);
103         launchVolumePanel();
104 
105         String currentPackage = mDevice.getCurrentPackageName();
106 
107         assertThat(currentPackage).isEqualTo(mSettingsPackage);
108     }
109 
110     @Test
nfcPanel_correctPackage()111     public void nfcPanel_correctPackage() {
112         launchNfcPanel();
113 
114         String currentPackage = mDevice.getCurrentPackageName();
115 
116         assertThat(currentPackage).isEqualTo(mSettingsPackage);
117     }
118 
119     @Test
wifiPanel_correctPackage()120     public void wifiPanel_correctPackage() {
121         launchWifiPanel();
122 
123         String currentPackage = mDevice.getCurrentPackageName();
124 
125         assertThat(currentPackage).isEqualTo(mSettingsPackage);
126     }
127 
128     @Test
volumePanel_doneClosesPanel()129     public void volumePanel_doneClosesPanel() {
130         assumeTrue(mHasTouchScreen);
131         // Launch panel
132         launchVolumePanel();
133         String currentPackage = mDevice.getCurrentPackageName();
134         assertThat(currentPackage).isEqualTo(mSettingsPackage);
135 
136         // Click the done button
137         pressDone();
138 
139         // Assert that we have left the panel
140         currentPackage = mDevice.getCurrentPackageName();
141         assertThat(currentPackage).isNotEqualTo(mSettingsPackage);
142     }
143 
144     @Test
nfcPanel_doneClosesPanel()145     public void nfcPanel_doneClosesPanel() {
146         // Launch panel
147         launchNfcPanel();
148         String currentPackage = mDevice.getCurrentPackageName();
149         assertThat(currentPackage).isEqualTo(mSettingsPackage);
150 
151         // Click the done button
152         pressDone();
153 
154         // Assert that we have left the panel
155         currentPackage = mDevice.getCurrentPackageName();
156         assertThat(currentPackage).isNotEqualTo(mSettingsPackage);
157     }
158 
159     @Test
wifiPanel_doneClosesPanel()160     public void wifiPanel_doneClosesPanel() {
161         // Launch panel
162         launchWifiPanel();
163         String currentPackage = mDevice.getCurrentPackageName();
164         assertThat(currentPackage).isEqualTo(mSettingsPackage);
165 
166         // Click the done button
167         pressDone();
168 
169         // Assert that we have left the panel
170         currentPackage = mDevice.getCurrentPackageName();
171         assertThat(currentPackage).isNotEqualTo(mSettingsPackage);
172     }
173 
174     @Test
volumePanel_seeMoreButton_launchesIntoSettings()175     public void volumePanel_seeMoreButton_launchesIntoSettings() {
176         assumeTrue(mHasTouchScreen);
177         // Launch panel
178         launchVolumePanel();
179         String currentPackage = mDevice.getCurrentPackageName();
180         assertThat(currentPackage).isEqualTo(mSettingsPackage);
181 
182         // Click the see more button
183         pressSeeMore();
184 
185         // Assert that we're still in Settings, on a different page.
186         currentPackage = mDevice.getCurrentPackageName();
187         assertThat(currentPackage).isEqualTo(mSettingsPackage);
188         UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
189         assertThat(titleView).isNull();
190     }
191 
192     @Test
nfcPanel_seeMoreButton_launchesIntoSettings()193     public void nfcPanel_seeMoreButton_launchesIntoSettings() {
194         // Launch panel
195         launchNfcPanel();
196         String currentPackage = mDevice.getCurrentPackageName();
197         assertThat(currentPackage).isEqualTo(mSettingsPackage);
198 
199         // Click the see more button
200         assumeTrue(mHasTouchScreen);
201         pressSeeMore();
202 
203         // Assert that we're still in Settings, on a different page.
204         currentPackage = mDevice.getCurrentPackageName();
205         assertThat(currentPackage).isEqualTo(mSettingsPackage);
206         UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
207         assertThat(titleView).isNull();
208     }
209 
210     @Test
wifiPanel_seeMoreButton_launchesIntoSettings()211     public void wifiPanel_seeMoreButton_launchesIntoSettings() {
212         // Launch panel
213         launchWifiPanel();
214         String currentPackage = mDevice.getCurrentPackageName();
215         assertThat(currentPackage).isEqualTo(mSettingsPackage);
216 
217         // Click the see more button
218         assumeTrue(mHasTouchScreen);
219         pressSeeMore();
220 
221         try {
222             UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_TITLE));
223             assertThat(titleView).isNull();
224         } catch (StaleObjectException ex) {
225             // If we get a StaleObjectException, it means that the underlying View has already
226             // been destroyed. The test panel might be no longer visible, which is same as expected
227             // result. Filter out exceptions to avoid unnecessary flaky errors.
228         }
229     }
230 
launchVolumePanel()231     private void launchVolumePanel() {
232         launchPanel(Settings.Panel.ACTION_VOLUME);
233     }
234 
launchNfcPanel()235     private void launchNfcPanel() {
236         assumeTrue(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC));
237         launchPanel(Settings.Panel.ACTION_NFC);
238     }
239 
launchWifiPanel()240     private void launchWifiPanel() {
241         assumeTrue(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI));
242         launchPanel(Settings.Panel.ACTION_WIFI);
243     }
244 
launchPanel(String action)245     private void launchPanel(String action) {
246         // Start from the home screen
247         mDevice.pressHome();
248         mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
249 
250         Intent intent = new Intent(action);
251         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
252                 | Intent.FLAG_ACTIVITY_CLEAR_TASK);    // Clear out any previous instances
253         mContext.startActivity(intent);
254 
255         // Wait for the app to appear
256         mDevice.wait(Until.hasObject(By.pkg(mSettingsPackage).depth(0)), TIMEOUT);
257     }
258 
pressDone()259     private void pressDone() {
260         UiObject2 doneObject = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_DONE));
261         if (!mHasTouchScreen || doneObject == null) {
262             mDevice.pressBack();
263             return;
264         }
265 
266         doneObject.click();
267         mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
268     }
269 
pressSeeMore()270     private void pressSeeMore() {
271         mDevice.findObject(By.res(mSettingsPackage, RESOURCE_SEE_MORE)).click();
272         mDevice.wait(Until.hasObject(By.pkg(mSettingsPackage).depth(0)), TIMEOUT);
273     }
274 
isCar()275     private boolean isCar() {
276         PackageManager pm = mContext.getPackageManager();
277         return pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
278     }
279 
isWatch()280     private boolean isWatch() {
281       return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
282     }
283 }
284