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 com.android.settings.ui; 18 19 import android.content.ContentResolver; 20 import android.os.SystemClock; 21 import android.provider.Settings; 22 import android.support.test.uiautomator.By; 23 import android.support.test.uiautomator.UiDevice; 24 import android.support.test.uiautomator.UiObject2; 25 import android.support.test.uiautomator.Until; 26 import android.system.helpers.SettingsHelper; 27 import android.system.helpers.SettingsHelper.SettingsType; 28 import android.test.InstrumentationTestCase; 29 import android.test.suitebuilder.annotation.MediumTest; 30 import android.test.suitebuilder.annotation.Suppress; 31 32 import java.util.HashMap; 33 34 public class SoundSettingsTest extends InstrumentationTestCase { 35 private static final String PAGE = Settings.ACTION_SOUND_SETTINGS; 36 private static final int TIMEOUT = 2000; 37 38 private UiDevice mDevice; 39 private ContentResolver mResolver; 40 private SettingsHelper mHelper; 41 42 43 private HashMap ringtoneSounds = new HashMap<String, String>() {{ 44 put("angler","Dione"); 45 put("bullhead","Dione"); 46 put("marlin","Spaceship"); 47 put("sailfish","Spaceship"); 48 put("walleye","Copycat"); 49 put("taimen","Copycat"); 50 }}; 51 52 private HashMap ringtoneCodes = new HashMap<String, String>() {{ 53 put("angler","38"); 54 put("bullhead","38"); 55 put("marlin","37"); 56 put("sailfish","37"); 57 put("walleye","26"); 58 put("taimen","26"); 59 }}; 60 61 private HashMap alarmSounds = new HashMap<String, String>() {{ 62 put("angler","Awaken"); 63 put("bullhead","Awaken"); 64 put("marlin","Bounce"); 65 put("sailfish","Bounce"); 66 put("walleye","Cuckoo clock"); 67 put("taimen","Cuckoo clock"); 68 }}; 69 70 private HashMap alarmCodes = new HashMap<String, String>() {{ 71 put("angler","6"); 72 put("bullhead","6"); 73 put("marlin","49"); 74 put("sailfish","49"); 75 put("walleye","15"); 76 put("taimen","15"); 77 }}; 78 79 private HashMap notificationSounds = new HashMap<String, String>() {{ 80 put("angler","Ceres"); 81 put("bullhead","Ceres"); 82 put("marlin","Trill"); 83 put("sailfish","Trill"); 84 put("walleye","Pipes"); 85 put("taimen","Pipes"); 86 }}; 87 88 89 private HashMap notificationCodes = new HashMap<String, String>() {{ 90 put("angler","26"); 91 put("bullhead","26"); 92 put("marlin","57"); 93 put("sailfish","57"); 94 put("walleye","69"); 95 put("taimen","69"); 96 }}; 97 98 @Override setUp()99 public void setUp() throws Exception { 100 super.setUp(); 101 mDevice = UiDevice.getInstance(getInstrumentation()); 102 mDevice.setOrientationNatural(); 103 mResolver = getInstrumentation().getContext().getContentResolver(); 104 mHelper = new SettingsHelper(); 105 } 106 107 @Override tearDown()108 public void tearDown() throws Exception { 109 mDevice.pressBack(); 110 mDevice.pressHome(); 111 mDevice.waitForIdle(); 112 mDevice.unfreezeRotation(); 113 super.tearDown(); 114 } 115 116 @MediumTest testCallVibrate()117 public void testCallVibrate() throws Exception { 118 assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, 119 "Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING)); 120 assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, 121 "Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING)); 122 } 123 124 @MediumTest testOtherSoundsDialPadTones()125 public void testOtherSoundsDialPadTones() throws Exception { 126 loadOtherSoundsPage(); 127 assertTrue("Dial pad tones not toggled", mHelper.verifyToggleSetting( 128 SettingsType.SYSTEM, PAGE, "Dial pad tones", 129 Settings.System.DTMF_TONE_WHEN_DIALING)); 130 } 131 132 @MediumTest testOtherSoundsScreenLocking()133 public void testOtherSoundsScreenLocking() throws Exception { 134 loadOtherSoundsPage(); 135 assertTrue("Screen locking sounds not toggled", 136 mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, 137 "Screen locking sounds", Settings.System.LOCKSCREEN_SOUNDS_ENABLED)); 138 } 139 140 @MediumTest testOtherSoundsCharging()141 public void testOtherSoundsCharging() throws Exception { 142 loadOtherSoundsPage(); 143 assertTrue("Charging sounds not toggled", 144 mHelper.verifyToggleSetting(SettingsType.GLOBAL, PAGE, 145 "Charging sounds", Settings.Global.CHARGING_SOUNDS_ENABLED)); 146 } 147 148 @MediumTest testOtherSoundsTouch()149 public void testOtherSoundsTouch() throws Exception { 150 loadOtherSoundsPage(); 151 assertTrue("Touch sounds not toggled", 152 mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, 153 "Touch sounds", Settings.System.SOUND_EFFECTS_ENABLED)); 154 } 155 156 @MediumTest testOtherSoundsVibrateOnTap()157 public void testOtherSoundsVibrateOnTap() throws Exception { 158 loadOtherSoundsPage(); 159 assertTrue("Vibrate on tap not toggled", 160 mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, 161 "Vibrate on tap", Settings.System.HAPTIC_FEEDBACK_ENABLED)); 162 } 163 loadOtherSoundsPage()164 private void loadOtherSoundsPage() throws Exception { 165 launchSoundSettings(); 166 mHelper.scrollVert(false); 167 Thread.sleep(1000); 168 } 169 launchSoundSettings()170 private void launchSoundSettings() throws Exception { 171 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 172 mHelper.scrollVert(false); 173 clickMore(); 174 Thread.sleep(1000); 175 mHelper.scrollVert(true); 176 Thread.sleep(1000); 177 } 178 179 /* 180 * Rather than verifying every ringtone, verify the ones least likely to change 181 * (None and Hangouts) and an arbitrary one from the ringtone pool. 182 */ 183 @MediumTest testPhoneRingtoneNone()184 public void testPhoneRingtoneNone() throws Exception { 185 launchSoundSettings(); 186 mHelper.clickSetting("Phone ringtone"); 187 verifyRingtone(new RingtoneSetting("None", "null"), 188 Settings.System.RINGTONE); 189 } 190 191 @MediumTest 192 @Suppress testPhoneRingtoneHangouts()193 public void testPhoneRingtoneHangouts() throws Exception { 194 launchSoundSettings(); 195 mHelper.clickSetting("Phone ringtone"); 196 verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE); 197 } 198 199 @MediumTest testPhoneRingtone()200 public void testPhoneRingtone() throws Exception { 201 launchSoundSettings(); 202 mHelper.clickSetting("Phone ringtone"); 203 String ringtone = ringtoneSounds.get(mDevice.getProductName()).toString(); 204 String ringtoneSettingValue = ringtoneCodes.get(mDevice.getProductName()).toString(); 205 verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue), 206 Settings.System.RINGTONE); 207 } 208 209 @MediumTest testNotificationRingtoneNone()210 public void testNotificationRingtoneNone() throws Exception { 211 launchSoundSettings(); 212 mHelper.clickSetting("Default notification sound"); 213 verifyRingtone(new RingtoneSetting("None", "null"), 214 Settings.System.NOTIFICATION_SOUND); 215 } 216 217 @MediumTest 218 @Suppress testNotificationRingtoneHangouts()219 public void testNotificationRingtoneHangouts() throws Exception { 220 launchSoundSettings(); 221 mHelper.clickSetting("Default notification sound"); 222 verifyRingtone(new RingtoneSetting("Hangouts Message", "30"), 223 Settings.System.NOTIFICATION_SOUND); 224 } 225 226 @MediumTest testNotificationRingtone()227 public void testNotificationRingtone() throws Exception { 228 launchSoundSettings(); 229 mHelper.clickSetting("Default notification sound"); 230 String notificationRingtone = notificationSounds.get(mDevice.getProductName()).toString(); 231 String notificationSettingValue = notificationCodes.get(mDevice.getProductName()).toString(); 232 verifyRingtone(new RingtoneSetting(notificationRingtone, notificationSettingValue), 233 Settings.System.NOTIFICATION_SOUND); 234 } 235 236 @MediumTest testAlarmRingtoneNone()237 public void testAlarmRingtoneNone() throws Exception { 238 launchSoundSettings(); 239 mHelper.clickSetting("Default alarm sound"); 240 verifyRingtone(new RingtoneSetting("None", "null"), 241 Settings.System.ALARM_ALERT); 242 } 243 244 @MediumTest testAlarmRingtone()245 public void testAlarmRingtone() throws Exception { 246 launchSoundSettings(); 247 String alarmRingtone = alarmSounds.get(mDevice.getProductName()).toString(); 248 String alarmSettingValue = alarmCodes.get(mDevice.getProductName()).toString(); 249 mHelper.clickSetting("Default alarm sound"); 250 verifyRingtone(new RingtoneSetting(alarmRingtone, alarmSettingValue), 251 Settings.System.ALARM_ALERT); 252 } 253 254 /* 255 * This method verifies that setting a custom ringtone changes the 256 * ringtone code setting on the system. Each ringtone sound corresponds 257 * to an arbitrary code. To see which ringtone code this is on your device, run 258 * adb shell settings get system ringtone 259 * The number you see at the end of the file path is the one you need. 260 * To see alarms and notifications ringtone codes, run the following: 261 * adb shell settings get system alarm_alert 262 * adb shell settings get system notification_sound 263 * @param r Ringtone setting - the name of the ringtone as displayed on device 264 * @param settingName - the code of the ringtone as explained above 265 * @param dir - the direction in which to scroll 266 */ verifyRingtone(RingtoneSetting r, String settingName)267 private void verifyRingtone(RingtoneSetting r, String settingName) throws Exception { 268 findRingtoneInList(r.getName()).click(); 269 if (mDevice.getProductName().equals("walleye") || mDevice.getProductName().equals("taimen")) { 270 mDevice.wait(Until.findObject(By.text("SAVE")), TIMEOUT).click(); 271 } 272 else { 273 mDevice.wait(Until.findObject(By.text("OK")), TIMEOUT).click(); 274 } 275 SystemClock.sleep(1000); 276 if (r.getVal().equals("null")) { 277 assertEquals(null, 278 Settings.System.getString(mResolver, settingName)); 279 } else if (r.getName().contains("Hangouts")) { 280 assertEquals("content://media/external/audio/media/" + r.getVal(), 281 Settings.System.getString(mResolver, settingName)); 282 } else { 283 assertEquals("content://media/internal/audio/media/" + r.getVal(), 284 Settings.System.getString(mResolver, settingName)); 285 } 286 } 287 288 private enum ScrollDir { 289 UP, 290 DOWN, 291 NOSCROLL 292 } 293 294 class RingtoneSetting { 295 private final String mName; 296 private final String mMediaVal; RingtoneSetting(String name, String fname)297 public RingtoneSetting(String name, String fname) { 298 mName = name; 299 mMediaVal = fname; 300 } getName()301 public String getName() { 302 return mName; 303 } getVal()304 public String getVal() { 305 return mMediaVal; 306 } 307 } 308 clickMore()309 private void clickMore() throws InterruptedException { 310 UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT); 311 if (more != null) { 312 more.click(); 313 Thread.sleep(TIMEOUT); 314 } 315 } 316 findRingtoneInList(String ringtone)317 private UiObject2 findRingtoneInList(String ringtone) throws Exception { 318 mHelper.scrollVert(false); 319 SystemClock.sleep(1000); 320 UiObject2 ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT); 321 int count = 0; 322 while (ringToneObject == null && count < 5) { 323 mHelper.scrollVert(true); 324 SystemClock.sleep(1000); 325 ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT); 326 count++; 327 } 328 return ringToneObject; 329 } 330 } 331