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