1 package android.settings.functional; 2 3 import android.app.NotificationManager; 4 import android.content.ContentResolver; 5 import android.content.Context; 6 import android.os.Handler; 7 import android.os.SystemClock; 8 import android.provider.Settings; 9 import android.service.notification.ZenModeConfig; 10 import android.platform.test.helpers.SettingsHelperImpl; 11 import android.platform.test.helpers.SettingsHelperImpl.SettingsType; 12 import android.support.test.uiautomator.By; 13 import android.support.test.uiautomator.UiDevice; 14 import android.support.test.uiautomator.Until; 15 import android.test.InstrumentationTestCase; 16 import android.test.suitebuilder.annotation.MediumTest; 17 import android.test.suitebuilder.annotation.Suppress; 18 19 import com.android.server.notification.ConditionProviders; 20 import com.android.server.notification.ManagedServices.UserProfiles; 21 import com.android.server.notification.ZenModeHelper; 22 23 public class SoundSettingsTest extends InstrumentationTestCase { 24 private static final String PAGE = Settings.ACTION_SOUND_SETTINGS; 25 private static final int TIMEOUT = 2000; 26 27 private UiDevice mDevice; 28 private ContentResolver mResolver; 29 private SettingsHelperImpl mHelper; 30 private ZenModeHelper mZenHelper; 31 32 @Override setUp()33 public void setUp() throws Exception { 34 super.setUp(); 35 mDevice = UiDevice.getInstance(getInstrumentation()); 36 mDevice.setOrientationNatural(); 37 mResolver = getInstrumentation().getContext().getContentResolver(); 38 mHelper = new SettingsHelperImpl(getInstrumentation()); 39 ConditionProviders cps = new ConditionProviders( 40 getInstrumentation().getContext(), new Handler(), new UserProfiles()); 41 mZenHelper = new ZenModeHelper(getInstrumentation().getContext(), 42 getInstrumentation().getContext().getMainLooper(), 43 cps); 44 } 45 46 @Override tearDown()47 public void tearDown() throws Exception { 48 mDevice.pressBack(); 49 mDevice.pressHome(); 50 mDevice.waitForIdle(); 51 mDevice.unfreezeRotation(); 52 super.tearDown(); 53 } 54 55 @MediumTest testCallVibrate()56 public void testCallVibrate() throws Exception { 57 assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, 58 "Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING)); 59 assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, 60 "Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING)); 61 } 62 63 @MediumTest testOtherSounds()64 public void testOtherSounds() throws Exception { 65 SettingsHelperImpl.launchSettingsPage(getInstrumentation().getContext(), PAGE); 66 mHelper.scrollVert(false); 67 Thread.sleep(1000); 68 mHelper.clickSetting("Other sounds"); 69 Thread.sleep(1000); 70 try { 71 assertTrue("Dial pad tones not toggled", mHelper.verifyToggleSetting( 72 SettingsType.SYSTEM, PAGE, "Dial pad tones", 73 Settings.System.DTMF_TONE_WHEN_DIALING)); 74 assertTrue("Screen locking sounds not toggled", 75 mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, 76 "Screen locking sounds", Settings.System.LOCKSCREEN_SOUNDS_ENABLED)); 77 assertTrue("Charging sounds not toggled", 78 mHelper.verifyToggleSetting(SettingsType.GLOBAL, PAGE, 79 "Charging sounds", Settings.Global.CHARGING_SOUNDS_ENABLED)); 80 assertTrue("Touch sounds not toggled", 81 mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, 82 "Touch sounds", Settings.System.SOUND_EFFECTS_ENABLED)); 83 assertTrue("Vibrate on tap not toggled", 84 mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, 85 "Vibrate on tap", Settings.System.HAPTIC_FEEDBACK_ENABLED)); 86 } finally { 87 mDevice.pressBack(); 88 } 89 } 90 91 @MediumTest 92 @Suppress testDndPriorityAllows()93 public void testDndPriorityAllows() throws Exception { 94 SettingsHelperImpl.launchSettingsPage(getInstrumentation().getContext(), PAGE); 95 Context ctx = getInstrumentation().getContext(); 96 try { 97 mHelper.clickSetting("Do not disturb"); 98 try { 99 mHelper.clickSetting("Priority only allows"); 100 ZenModeConfig baseZenCfg = mZenHelper.getConfig(); 101 102 mHelper.clickSetting("Reminders"); 103 mHelper.clickSetting("Events"); 104 mHelper.clickSetting("Repeat callers"); 105 106 ZenModeConfig changedCfg = mZenHelper.getConfig(); 107 assertFalse(baseZenCfg.allowReminders == changedCfg.allowReminders); 108 assertFalse(baseZenCfg.allowEvents == changedCfg.allowEvents); 109 assertFalse(baseZenCfg.allowRepeatCallers == changedCfg.allowRepeatCallers); 110 111 mHelper.clickSetting("Reminders"); 112 mHelper.clickSetting("Events"); 113 mHelper.clickSetting("Repeat callers"); 114 115 changedCfg = mZenHelper.getConfig(); 116 assertTrue(baseZenCfg.allowReminders == changedCfg.allowReminders); 117 assertTrue(baseZenCfg.allowEvents == changedCfg.allowEvents); 118 assertTrue(baseZenCfg.allowRepeatCallers == changedCfg.allowRepeatCallers); 119 120 mHelper.clickSetting("Messages"); 121 mHelper.clickSetting("From anyone"); 122 mHelper.clickSetting("Calls"); 123 mHelper.clickSetting("From anyone"); 124 125 changedCfg = mZenHelper.getConfig(); 126 assertFalse(baseZenCfg.allowCallsFrom == changedCfg.allowCallsFrom); 127 assertFalse(baseZenCfg.allowMessagesFrom == changedCfg.allowMessagesFrom); 128 } finally { 129 mDevice.pressBack(); 130 } 131 } finally { 132 mDevice.pressHome(); 133 } 134 } 135 136 @MediumTest 137 @Suppress testDndVisualInterruptions()138 public void testDndVisualInterruptions() throws Exception { 139 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 140 try { 141 mHelper.clickSetting("Do not disturb"); 142 try { 143 mHelper.clickSetting("Visual interruptions"); 144 ZenModeConfig baseZenCfg = mZenHelper.getConfig(); 145 146 mHelper.clickSetting("Block when screen is on"); 147 mHelper.clickSetting("Block when screen is off"); 148 149 ZenModeConfig changedCfg = mZenHelper.getConfig(); 150 assertFalse(baseZenCfg.allowWhenScreenOff == changedCfg.allowWhenScreenOff); 151 assertFalse(baseZenCfg.allowWhenScreenOn == changedCfg.allowWhenScreenOn); 152 153 mHelper.clickSetting("Block when screen is on"); 154 mHelper.clickSetting("Block when screen is off"); 155 156 changedCfg = mZenHelper.getConfig(); 157 assertTrue(baseZenCfg.allowWhenScreenOff == changedCfg.allowWhenScreenOff); 158 assertTrue(baseZenCfg.allowWhenScreenOn == changedCfg.allowWhenScreenOn); 159 } finally { 160 mDevice.pressBack(); 161 } 162 } finally { 163 mDevice.pressBack(); 164 } 165 } 166 167 /* 168 * Rather than verifying every ringtone, verify the ones least likely to change 169 * (None and Hangouts) and an arbitrary one from the ringtone pool. 170 */ 171 @MediumTest testPhoneRingtoneNone()172 public void testPhoneRingtoneNone() throws Exception { 173 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 174 mHelper.clickSetting("Phone ringtone"); 175 verifyRingtone(new RingtoneSetting("None", "null"), 176 Settings.System.RINGTONE, ScrollDir.UP); 177 } 178 179 @MediumTest 180 @Suppress testPhoneRingtoneHangouts()181 public void testPhoneRingtoneHangouts() throws Exception { 182 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 183 mHelper.clickSetting("Phone ringtone"); 184 verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE); 185 } 186 187 @MediumTest testPhoneRingtoneUmbriel()188 public void testPhoneRingtoneUmbriel() throws Exception { 189 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 190 mHelper.clickSetting("Phone ringtone"); 191 String ringtone = "Umbriel"; 192 String ringtoneSettingValue = "49"; 193 if (mDevice.getProductName().equals("marlin") 194 || mDevice.getProductName().equals("sailfish")) { 195 ringtone = "Spaceship"; 196 ringtoneSettingValue = "32"; 197 } 198 verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue), 199 Settings.System.RINGTONE, ScrollDir.DOWN); 200 } 201 202 @MediumTest testNotificationRingtoneNone()203 public void testNotificationRingtoneNone() throws Exception { 204 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 205 mHelper.clickSetting("Default notification ringtone"); 206 verifyRingtone(new RingtoneSetting("None", "null"), 207 Settings.System.NOTIFICATION_SOUND, ScrollDir.UP); 208 } 209 210 @MediumTest 211 @Suppress testNotificationRingtoneHangouts()212 public void testNotificationRingtoneHangouts() throws Exception { 213 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 214 mHelper.clickSetting("Default notification ringtone"); 215 verifyRingtone(new RingtoneSetting("Hangouts Message", "30"), 216 Settings.System.NOTIFICATION_SOUND); 217 } 218 219 @MediumTest testNotificationRingtoneTitan()220 public void testNotificationRingtoneTitan() throws Exception { 221 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 222 mHelper.clickSetting("Default notification ringtone"); 223 String notificationRingtone = "Titan"; 224 String notificationSettingValue = "35"; 225 if (mDevice.getProductName().equals("marlin") 226 || mDevice.getProductName().equals("sailfish")) { 227 notificationRingtone = "Trill"; 228 notificationSettingValue = "24"; 229 } 230 verifyRingtone(new RingtoneSetting(notificationRingtone, notificationSettingValue), 231 Settings.System.NOTIFICATION_SOUND, ScrollDir.DOWN); 232 } 233 234 @MediumTest testAlarmRingtoneNone()235 public void testAlarmRingtoneNone() throws Exception { 236 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 237 mHelper.clickSetting("Default alarm ringtone"); 238 verifyRingtone(new RingtoneSetting("None", "null"), 239 Settings.System.ALARM_ALERT, ScrollDir.UP); 240 } 241 242 @MediumTest testAlarmRingtoneXenon()243 public void testAlarmRingtoneXenon() throws Exception { 244 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); 245 mHelper.clickSetting("Default alarm ringtone"); 246 String alarmRingtone = "Xenon"; 247 String alarmSettingValue = "22"; 248 if (mDevice.getProductName().equals("marlin") 249 || mDevice.getProductName().equals("sailfish")) { 250 alarmRingtone = "Wag"; 251 alarmSettingValue = "15"; 252 } 253 verifyRingtone(new RingtoneSetting(alarmRingtone, alarmSettingValue), 254 Settings.System.ALARM_ALERT, ScrollDir.DOWN); 255 } 256 verifyRingtone(RingtoneSetting r, String settingName)257 private void verifyRingtone(RingtoneSetting r, String settingName) { 258 verifyRingtone(r, settingName, ScrollDir.NOSCROLL); 259 } 260 261 /* 262 * This method verifies that setting a custom ringtone changes the 263 * ringtone code setting on the system. Each ringtone sound corresponds 264 * to an arbitrary code. To see which ringtone code this is on your device, run 265 * adb shell settings get system ringtone 266 * The number you see at the end of the file path is the one you need. 267 * To see alarms and notifications ringtone codes, run the following: 268 * adb shell settings get system alarm_alert 269 * adb shell settings get system notification_sound 270 * @param r Ringtone setting - the name of the ringtone as displayed on device 271 * @param settingName - the code of the ringtone as explained above 272 * @param dir - the direction in which to scroll 273 */ verifyRingtone(RingtoneSetting r, String settingName, ScrollDir dir)274 private void verifyRingtone(RingtoneSetting r, String settingName, ScrollDir dir) { 275 if (dir != ScrollDir.NOSCROLL) { 276 mHelper.scrollVert(dir == ScrollDir.UP); 277 SystemClock.sleep(1000); 278 } 279 mDevice.wait(Until.findObject(By.text(r.getName())), TIMEOUT).click(); 280 mDevice.wait(Until.findObject(By.text("OK")), TIMEOUT).click(); 281 SystemClock.sleep(1000); 282 if (r.getVal().equals("null")) { 283 assertEquals(null, 284 Settings.System.getString(mResolver, settingName)); 285 } else if (r.getName().contains("Hangouts")) { 286 assertEquals("content://media/external/audio/media/" + r.getVal(), 287 Settings.System.getString(mResolver, settingName)); 288 } else { 289 assertEquals("content://media/internal/audio/media/" + r.getVal(), 290 Settings.System.getString(mResolver, settingName)); 291 } 292 } 293 294 private enum ScrollDir { 295 UP, 296 DOWN, 297 NOSCROLL 298 } 299 300 class RingtoneSetting { 301 private final String mName; 302 private final String mMediaVal; RingtoneSetting(String name, String fname)303 public RingtoneSetting(String name, String fname) { 304 mName = name; 305 mMediaVal = fname; 306 } getName()307 public String getName() { 308 return mName; 309 } getVal()310 public String getVal() { 311 return mMediaVal; 312 } 313 } 314 } 315