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 loadOtherSoundsPage()156 private void loadOtherSoundsPage() throws Exception { 157 launchSoundSettings(); 158 mHelper.scrollVert(false); 159 Thread.sleep(1000); 160 } 161 launchSoundSettings()162 private void launchSoundSettings() throws Exception { 163 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 164 mHelper.scrollVert(false); 165 clickMore(); 166 Thread.sleep(1000); 167 mHelper.scrollVert(true); 168 Thread.sleep(1000); 169 } 170 171 /* 172 * Rather than verifying every ringtone, verify the ones least likely to change 173 * (None and Hangouts) and an arbitrary one from the ringtone pool. 174 */ 175 @MediumTest testPhoneRingtoneNone()176 public void testPhoneRingtoneNone() throws Exception { 177 launchSoundSettings(); 178 mHelper.clickSetting("Phone ringtone"); 179 verifyRingtone(new RingtoneSetting("None", "null"), 180 Settings.System.RINGTONE); 181 } 182 183 @MediumTest 184 @Suppress testPhoneRingtoneHangouts()185 public void testPhoneRingtoneHangouts() throws Exception { 186 launchSoundSettings(); 187 mHelper.clickSetting("Phone ringtone"); 188 verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE); 189 } 190 191 @MediumTest testPhoneRingtone()192 public void testPhoneRingtone() throws Exception { 193 launchSoundSettings(); 194 mHelper.clickSetting("Phone ringtone"); 195 String ringtone = ringtoneSounds.get(mDevice.getProductName()).toString(); 196 String ringtoneSettingValue = ringtoneCodes.get(mDevice.getProductName()).toString(); 197 verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue), 198 Settings.System.RINGTONE); 199 } 200 201 @MediumTest testNotificationRingtoneNone()202 public void testNotificationRingtoneNone() throws Exception { 203 launchSoundSettings(); 204 mHelper.clickSetting("Default notification sound"); 205 verifyRingtone(new RingtoneSetting("None", "null"), 206 Settings.System.NOTIFICATION_SOUND); 207 } 208 209 @MediumTest 210 @Suppress testNotificationRingtoneHangouts()211 public void testNotificationRingtoneHangouts() throws Exception { 212 launchSoundSettings(); 213 mHelper.clickSetting("Default notification sound"); 214 verifyRingtone(new RingtoneSetting("Hangouts Message", "30"), 215 Settings.System.NOTIFICATION_SOUND); 216 } 217 218 @MediumTest testNotificationRingtone()219 public void testNotificationRingtone() throws Exception { 220 launchSoundSettings(); 221 mHelper.clickSetting("Default notification sound"); 222 String notificationRingtone = notificationSounds.get(mDevice.getProductName()).toString(); 223 String notificationSettingValue = notificationCodes.get(mDevice.getProductName()).toString(); 224 verifyRingtone(new RingtoneSetting(notificationRingtone, notificationSettingValue), 225 Settings.System.NOTIFICATION_SOUND); 226 } 227 228 @MediumTest testAlarmRingtoneNone()229 public void testAlarmRingtoneNone() throws Exception { 230 launchSoundSettings(); 231 mHelper.clickSetting("Default alarm sound"); 232 verifyRingtone(new RingtoneSetting("None", "null"), 233 Settings.System.ALARM_ALERT); 234 } 235 236 @MediumTest testAlarmRingtone()237 public void testAlarmRingtone() throws Exception { 238 launchSoundSettings(); 239 String alarmRingtone = alarmSounds.get(mDevice.getProductName()).toString(); 240 String alarmSettingValue = alarmCodes.get(mDevice.getProductName()).toString(); 241 mHelper.clickSetting("Default alarm sound"); 242 verifyRingtone(new RingtoneSetting(alarmRingtone, alarmSettingValue), 243 Settings.System.ALARM_ALERT); 244 } 245 246 /* 247 * This method verifies that setting a custom ringtone changes the 248 * ringtone code setting on the system. Each ringtone sound corresponds 249 * to an arbitrary code. To see which ringtone code this is on your device, run 250 * adb shell settings get system ringtone 251 * The number you see at the end of the file path is the one you need. 252 * To see alarms and notifications ringtone codes, run the following: 253 * adb shell settings get system alarm_alert 254 * adb shell settings get system notification_sound 255 * @param r Ringtone setting - the name of the ringtone as displayed on device 256 * @param settingName - the code of the ringtone as explained above 257 * @param dir - the direction in which to scroll 258 */ verifyRingtone(RingtoneSetting r, String settingName)259 private void verifyRingtone(RingtoneSetting r, String settingName) throws Exception { 260 findRingtoneInList(r.getName()).click(); 261 if (mDevice.getProductName().equals("walleye") || mDevice.getProductName().equals("taimen")) { 262 mDevice.wait(Until.findObject(By.text("SAVE")), TIMEOUT).click(); 263 } 264 else { 265 mDevice.wait(Until.findObject(By.text("OK")), TIMEOUT).click(); 266 } 267 SystemClock.sleep(1000); 268 if (r.getVal().equals("null")) { 269 assertEquals(null, 270 Settings.System.getString(mResolver, settingName)); 271 } else if (r.getName().contains("Hangouts")) { 272 assertEquals("content://media/external/audio/media/" + r.getVal(), 273 Settings.System.getString(mResolver, settingName)); 274 } else { 275 assertEquals("content://media/internal/audio/media/" + r.getVal(), 276 Settings.System.getString(mResolver, settingName)); 277 } 278 } 279 280 private enum ScrollDir { 281 UP, 282 DOWN, 283 NOSCROLL 284 } 285 286 class RingtoneSetting { 287 private final String mName; 288 private final String mMediaVal; RingtoneSetting(String name, String fname)289 public RingtoneSetting(String name, String fname) { 290 mName = name; 291 mMediaVal = fname; 292 } getName()293 public String getName() { 294 return mName; 295 } getVal()296 public String getVal() { 297 return mMediaVal; 298 } 299 } 300 clickMore()301 private void clickMore() throws InterruptedException { 302 UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT); 303 if (more != null) { 304 more.click(); 305 Thread.sleep(TIMEOUT); 306 } 307 } 308 findRingtoneInList(String ringtone)309 private UiObject2 findRingtoneInList(String ringtone) throws Exception { 310 mHelper.scrollVert(false); 311 SystemClock.sleep(1000); 312 UiObject2 ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT); 313 int count = 0; 314 while (ringToneObject == null && count < 5) { 315 mHelper.scrollVert(true); 316 SystemClock.sleep(1000); 317 ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT); 318 count++; 319 } 320 return ringToneObject; 321 } 322 } 323