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