1 /* 2 * Copyright (C) 2009 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 android.media.audio.cts; 18 19 import static android.media.AudioManager.ADJUST_LOWER; 20 import static android.media.AudioManager.ADJUST_RAISE; 21 import static android.media.AudioManager.ADJUST_SAME; 22 import static android.media.AudioManager.MODE_IN_CALL; 23 import static android.media.AudioManager.MODE_IN_COMMUNICATION; 24 import static android.media.AudioManager.MODE_NORMAL; 25 import static android.media.AudioManager.MODE_RINGTONE; 26 import static android.media.AudioManager.RINGER_MODE_NORMAL; 27 import static android.media.AudioManager.RINGER_MODE_SILENT; 28 import static android.media.AudioManager.RINGER_MODE_VIBRATE; 29 import static android.media.AudioManager.STREAM_ACCESSIBILITY; 30 import static android.media.AudioManager.STREAM_ALARM; 31 import static android.media.AudioManager.STREAM_DTMF; 32 import static android.media.AudioManager.STREAM_MUSIC; 33 import static android.media.AudioManager.STREAM_NOTIFICATION; 34 import static android.media.AudioManager.STREAM_RING; 35 import static android.media.AudioManager.STREAM_SYSTEM; 36 import static android.media.AudioManager.STREAM_VOICE_CALL; 37 import static android.media.AudioManager.USE_DEFAULT_STREAM_TYPE; 38 import static android.media.AudioManager.VIBRATE_SETTING_OFF; 39 import static android.media.AudioManager.VIBRATE_SETTING_ON; 40 import static android.media.AudioManager.VIBRATE_SETTING_ONLY_SILENT; 41 import static android.media.AudioManager.VIBRATE_TYPE_NOTIFICATION; 42 import static android.media.AudioManager.VIBRATE_TYPE_RINGER; 43 import static android.media.audio.cts.AudioTestUtil.resetVolumeIndex; 44 import static android.provider.Settings.Global.APPLY_RAMPING_RINGER; 45 import static android.provider.Settings.System.SOUND_EFFECTS_ENABLED; 46 47 import static org.junit.Assert.assertNotEquals; 48 import static org.junit.Assert.assertThrows; 49 50 import android.Manifest; 51 import android.app.NotificationChannel; 52 import android.app.NotificationManager; 53 import android.content.BroadcastReceiver; 54 import android.content.Context; 55 import android.content.Intent; 56 import android.content.IntentFilter; 57 import android.content.pm.PackageManager; 58 import android.content.res.Resources; 59 import android.media.AudioAttributes; 60 import android.media.AudioDescriptor; 61 import android.media.AudioDeviceAttributes; 62 import android.media.AudioDeviceInfo; 63 import android.media.AudioFormat; 64 import android.media.AudioHalVersionInfo; 65 import android.media.AudioManager; 66 import android.media.AudioMixerAttributes; 67 import android.media.AudioProfile; 68 import android.media.AudioTrack; 69 import android.media.MediaPlayer; 70 import android.media.MediaRecorder; 71 import android.media.MicrophoneInfo; 72 import android.media.audiopolicy.AudioProductStrategy; 73 import android.media.audiopolicy.AudioVolumeGroup; 74 import android.media.cts.Utils; 75 import android.os.Build; 76 import android.os.SystemClock; 77 import android.os.Vibrator; 78 import android.platform.test.annotations.AppModeFull; 79 import android.provider.Settings; 80 import android.provider.Settings.System; 81 import android.test.InstrumentationTestCase; 82 import android.text.TextUtils; 83 import android.util.Log; 84 import android.view.SoundEffectConstants; 85 86 import androidx.test.InstrumentationRegistry; 87 88 import com.android.compatibility.common.util.ApiLevelUtil; 89 import com.android.compatibility.common.util.CddTest; 90 import com.android.compatibility.common.util.MediaUtils; 91 import com.android.compatibility.common.util.NonMainlineTest; 92 import com.android.compatibility.common.util.SettingsStateKeeperRule; 93 import com.android.compatibility.common.util.UserSettings.Namespace; 94 import com.android.internal.annotations.GuardedBy; 95 96 import org.junit.ClassRule; 97 98 import java.util.ArrayList; 99 import java.util.Arrays; 100 import java.util.HashMap; 101 import java.util.HashSet; 102 import java.util.List; 103 import java.util.Map; 104 import java.util.Set; 105 import java.util.concurrent.Executors; 106 import java.util.concurrent.atomic.AtomicBoolean; 107 import java.util.function.Predicate; 108 import java.util.stream.Collectors; 109 import java.util.stream.IntStream; 110 111 @NonMainlineTest 112 public class AudioManagerTest extends InstrumentationTestCase { 113 private static final String TAG = "AudioManagerTest"; 114 115 private static final long ASYNC_TIMING_TOLERANCE_MS = 50; 116 private static final long POLL_TIME_VOLUME_ADJUST = 400; 117 private static final long POLL_TIME_UPDATE_INTERRUPTION_FILTER = 5000; 118 private static final int MP3_TO_PLAY = R.raw.testmp3; // ~ 5 second mp3 119 private static final long POLL_TIME_PLAY_MUSIC = 2000; 120 private static final long TIME_TO_PLAY = 2000; 121 private static final long TIME_TO_WAIT_CALLBACK_MS = 1000; 122 private static final String APPOPS_OP_STR = "android:write_settings"; 123 private static final Set<Integer> ALL_KNOWN_ENCAPSULATION_TYPES = Set.of( 124 AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937, 125 AudioProfile.AUDIO_ENCAPSULATION_TYPE_PCM); 126 private static final Set<Integer> ALL_ENCAPSULATION_TYPES = Set.of( 127 AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE, 128 AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937, 129 AudioProfile.AUDIO_ENCAPSULATION_TYPE_PCM); 130 private static final Set<Integer> ALL_AUDIO_STANDARDS = Set.of( 131 AudioDescriptor.STANDARD_NONE, 132 AudioDescriptor.STANDARD_EDID, 133 AudioDescriptor.STANDARD_SADB, 134 AudioDescriptor.STANDARD_VSADB); 135 private static final Map<Integer, Integer> DIRECT_OFFLOAD_MAP = Map.of( 136 AudioManager.PLAYBACK_OFFLOAD_NOT_SUPPORTED, 137 AudioManager.DIRECT_PLAYBACK_NOT_SUPPORTED, 138 AudioManager.PLAYBACK_OFFLOAD_SUPPORTED, 139 AudioManager.DIRECT_PLAYBACK_OFFLOAD_SUPPORTED, 140 AudioManager.PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED, 141 AudioManager.DIRECT_PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED); 142 private static final Set<Integer> ALL_MIXER_BEHAVIORS = Set.of( 143 AudioMixerAttributes.MIXER_BEHAVIOR_DEFAULT, 144 AudioMixerAttributes.MIXER_BEHAVIOR_BIT_PERFECT); 145 private static final int[] PUBLIC_STREAM_TYPES = { STREAM_VOICE_CALL, 146 STREAM_SYSTEM, STREAM_RING, STREAM_MUSIC, 147 STREAM_ALARM, STREAM_NOTIFICATION, 148 STREAM_DTMF, STREAM_ACCESSIBILITY }; 149 private static final int VOLUME_CHANGED_INTENT_TIMEOUT_MS = 3000; // 3s 150 151 private static final int INVALID_DIRECT_PLAYBACK_MODE = -1; 152 private AudioManager mAudioManager; 153 private NotificationManager mNm; 154 private boolean mHasVibrator; 155 private boolean mUseFixedVolume; 156 private boolean mIsTelevision; 157 private boolean mIsSingleVolume; 158 private boolean mSkipRingerTests; 159 // From N onwards, ringer mode adjustments that toggle DND are not allowed unless 160 // package has DND access. Many tests in this package toggle DND access in order 161 // to get device out of the DND state for the test to proceed correctly. 162 // But DND access is disabled completely on low ram devices, 163 // so completely skip those tests here. 164 // These tests are migrated to CTS verifier tests to ensure test coverage. 165 private Context mContext; 166 private int mOriginalRingerMode; 167 private Map<Integer, Integer> mOriginalStreamVolumes = new HashMap<>(); 168 private NotificationManager.Policy mOriginalNotificationPolicy; 169 private int mOriginalZen; 170 private boolean mDoNotCheckUnmute; 171 private boolean mAppsBypassingDnd; 172 173 @ClassRule 174 public static final SettingsStateKeeperRule mSurroundSoundFormatsSettingsKeeper = 175 new SettingsStateKeeperRule(InstrumentationRegistry.getTargetContext(), 176 Namespace.GLOBAL, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 177 178 @ClassRule 179 public static final SettingsStateKeeperRule mSurroundSoundModeSettingsKeeper = 180 new SettingsStateKeeperRule(InstrumentationRegistry.getTargetContext(), 181 Namespace.GLOBAL, Settings.Global.ENCODED_SURROUND_OUTPUT); 182 183 @Override setUp()184 protected void setUp() throws Exception { 185 super.setUp(); 186 mContext = getInstrumentation().getContext(); 187 Utils.enableAppOps(mContext.getPackageName(), APPOPS_OP_STR, getInstrumentation()); 188 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 189 Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); 190 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 191 mAppsBypassingDnd = NotificationManager.getService().areChannelsBypassingDnd(); 192 mHasVibrator = (vibrator != null) && vibrator.hasVibrator(); 193 mUseFixedVolume = mContext.getResources().getBoolean( 194 Resources.getSystem().getIdentifier("config_useFixedVolume", "bool", "android")); 195 PackageManager packageManager = mContext.getPackageManager(); 196 mIsTelevision = packageManager != null 197 && (packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) 198 || packageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION)); 199 mIsSingleVolume = mContext.getResources().getBoolean( 200 Resources.getSystem().getIdentifier("config_single_volume", "bool", "android")); 201 mSkipRingerTests = mUseFixedVolume || mIsTelevision || mIsSingleVolume; 202 203 // Store the original volumes that that they can be recovered in tearDown(). 204 final int[] streamTypes = { 205 STREAM_VOICE_CALL, 206 STREAM_SYSTEM, 207 STREAM_RING, 208 STREAM_MUSIC, 209 STREAM_ALARM, 210 STREAM_NOTIFICATION, 211 STREAM_DTMF, 212 STREAM_ACCESSIBILITY, 213 }; 214 mOriginalRingerMode = mAudioManager.getRingerMode(); 215 for (int streamType : streamTypes) { 216 mOriginalStreamVolumes.put(streamType, mAudioManager.getStreamVolume(streamType)); 217 } 218 219 try { 220 Utils.toggleNotificationPolicyAccess( 221 mContext.getPackageName(), getInstrumentation(), true); 222 mOriginalNotificationPolicy = mNm.getNotificationPolicy(); 223 mOriginalZen = mNm.getCurrentInterruptionFilter(); 224 } finally { 225 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 226 Utils.toggleNotificationPolicyAccess( 227 mContext.getPackageName(), getInstrumentation(), false); 228 } 229 230 // Check original microphone mute/unmute status 231 mDoNotCheckUnmute = false; 232 if (mAudioManager.isMicrophoneMute()) { 233 mAudioManager.setMicrophoneMute(false); 234 if (mAudioManager.isMicrophoneMute()) { 235 Log.w(TAG, "Mic seems muted by hardware! Please unmute and rerrun the test."); 236 mDoNotCheckUnmute = true; 237 } 238 } 239 } 240 241 @Override tearDown()242 protected void tearDown() throws Exception { 243 try { 244 Utils.toggleNotificationPolicyAccess( 245 mContext.getPackageName(), getInstrumentation(), true); 246 mNm.setNotificationPolicy(mOriginalNotificationPolicy); 247 setInterruptionFilter(mOriginalZen); 248 249 // Recover the volume and the ringer mode that the test may have overwritten. 250 for (Map.Entry<Integer, Integer> e : mOriginalStreamVolumes.entrySet()) { 251 mAudioManager.setStreamVolume(e.getKey(), e.getValue(), 252 AudioManager.FLAG_ALLOW_RINGER_MODES); 253 } 254 mAudioManager.setRingerMode(mOriginalRingerMode); 255 } finally { 256 Utils.toggleNotificationPolicyAccess( 257 mContext.getPackageName(), getInstrumentation(), false); 258 } 259 } 260 261 @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS") testMicrophoneMute()262 public void testMicrophoneMute() throws Exception { 263 mAudioManager.setMicrophoneMute(true); 264 assertTrue(mAudioManager.isMicrophoneMute()); 265 mAudioManager.setMicrophoneMute(false); 266 assertFalse(mAudioManager.isMicrophoneMute() && !mDoNotCheckUnmute); 267 } 268 269 @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS") testMicrophoneMuteIntent()270 public void testMicrophoneMuteIntent() throws Exception { 271 if (!mDoNotCheckUnmute) { 272 final MyBlockingIntentReceiver receiver = new MyBlockingIntentReceiver( 273 AudioManager.ACTION_MICROPHONE_MUTE_CHANGED); 274 final boolean initialMicMute = mAudioManager.isMicrophoneMute(); 275 try { 276 mContext.registerReceiver(receiver, 277 new IntentFilter(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED)); 278 // change the mic mute state 279 mAudioManager.setMicrophoneMute(!initialMicMute); 280 // verify a change was reported 281 final boolean intentFired = receiver.waitForExpectedAction(500/*ms*/); 282 assertTrue("ACTION_MICROPHONE_MUTE_CHANGED wasn't fired", intentFired); 283 // verify the mic mute state is expected 284 final boolean newMicMute = mAudioManager.isMicrophoneMute(); 285 assertTrue("new mic mute state not as expected (" + !initialMicMute + ")", 286 (newMicMute == !initialMicMute)); 287 } finally { 288 mContext.unregisterReceiver(receiver); 289 mAudioManager.setMicrophoneMute(initialMicMute); 290 } 291 } 292 } 293 294 @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS") testSpeakerphoneIntent()295 public void testSpeakerphoneIntent() throws Exception { 296 // Speaker Phone Not supported in Automotive 297 if (isAutomotive()) { 298 return; 299 } 300 if (!hasBuiltinSpeaker()) { 301 return; 302 } 303 304 final MyBlockingIntentReceiver receiver = new MyBlockingIntentReceiver( 305 AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED); 306 final boolean initialSpeakerphoneState = mAudioManager.isSpeakerphoneOn(); 307 try { 308 getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( 309 Manifest.permission.MODIFY_PHONE_STATE); 310 311 mContext.registerReceiver(receiver, 312 new IntentFilter(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED)); 313 // change the speakerphone state 314 mAudioManager.setSpeakerphoneOn(!initialSpeakerphoneState); 315 // verify a change was reported 316 final boolean intentFired = receiver.waitForExpectedAction(500/*ms*/); 317 assertTrue("ACTION_SPEAKERPHONE_STATE_CHANGED wasn't fired", intentFired); 318 // verify the speakerphon state is expected 319 final boolean newSpeakerphoneState = mAudioManager.isSpeakerphoneOn(); 320 assertTrue("new mic mute state not as expected (" 321 + !initialSpeakerphoneState + ")", 322 newSpeakerphoneState == !initialSpeakerphoneState); 323 } finally { 324 mContext.unregisterReceiver(receiver); 325 mAudioManager.setSpeakerphoneOn(initialSpeakerphoneState); 326 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 327 } 328 } 329 hasBuiltinSpeaker()330 private boolean hasBuiltinSpeaker() { 331 AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS); 332 for (AudioDeviceInfo device : devices) { 333 final int type = device.getType(); 334 if (type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER 335 || type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER_SAFE) { 336 return true; 337 } 338 } 339 return false; 340 } 341 342 @AppModeFull(reason = "ACTION_VOLUME_CHANGED is not sent to Instant apps (no FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS)") testVolumeChangedIntent()343 public void testVolumeChangedIntent() throws Exception { 344 final MyBlockingIntentReceiver receiver = 345 new MyBlockingIntentReceiver(AudioManager.ACTION_VOLUME_CHANGED); 346 if (mAudioManager.isVolumeFixed()) { 347 return; 348 } 349 // safe media can block the raising the volume, disable it 350 getInstrumentation().getUiAutomation() 351 .adoptShellPermissionIdentity(Manifest.permission.STATUS_BAR_SERVICE); 352 mAudioManager.disableSafeMediaVolume(); 353 354 try { 355 mContext.registerReceiver(receiver, 356 new IntentFilter(AudioManager.ACTION_VOLUME_CHANGED)); 357 // only listen for the STREAM_MUSIC volume changes 358 receiver.setWaitForIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, STREAM_MUSIC); 359 int mediaVol = mAudioManager.getStreamVolume(STREAM_MUSIC); 360 final int origVol = mediaVol; 361 final int maxMediaVol = mAudioManager.getStreamMaxVolume(STREAM_MUSIC); 362 // change media volume from current value 363 mAudioManager.setStreamVolume(STREAM_MUSIC, 364 mediaVol == maxMediaVol ? --mediaVol : ++mediaVol, 365 0 /*flags*/); 366 // verify a change was reported 367 final boolean intentFired = receiver.waitForExpectedAction( 368 VOLUME_CHANGED_INTENT_TIMEOUT_MS); 369 assertTrue("VOLUME_CHANGED_ACTION wasn't fired for change from " 370 + origVol + " to " + mediaVol, intentFired); 371 // verify the new value is in the extras 372 final Intent intent = receiver.getIntent(); 373 assertEquals("Not an intent for STREAM_MUSIC", STREAM_MUSIC, 374 intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1)); 375 assertEquals("New STREAM_MUSIC volume not as expected", mediaVol, 376 intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1)); 377 assertEquals("Previous STREAM_MUSIC volume not as expected", origVol, 378 intent.getIntExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, -1)); 379 } finally { 380 mContext.unregisterReceiver(receiver); 381 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 382 } 383 } 384 385 private static final class MyBlockingIntentReceiver extends BroadcastReceiver { 386 private static final String TAG = "BlockingIntentRcvr"; 387 private final SafeWaitObject mLock = new SafeWaitObject(); 388 // the action for the intent to check 389 private final String mAction; 390 private String mWaitForExtra; 391 private int mWaitForExtraInt = Integer.MAX_VALUE; 392 @GuardedBy("mLock") 393 private volatile boolean mIntentReceived = false; 394 @GuardedBy("mLock") 395 private Intent mIntent; 396 MyBlockingIntentReceiver(String action)397 MyBlockingIntentReceiver(String action) { 398 mAction = action; 399 mIntent = null; 400 mWaitForExtra = null; 401 } 402 403 /** 404 * Sets an optional extra along with an expected value that need to match for the received 405 * intent to be considered as valid for {@link #waitForExpectedAction(long)}. 406 * When querying the intent for the extra int value, the default is Integer.MIN_VALUE. 407 * @param extra 408 * @param expectedInt 409 */ setWaitForIntExtra(String extra, int expectedInt)410 public void setWaitForIntExtra(String extra, int expectedInt) { 411 mWaitForExtra = extra; 412 mWaitForExtraInt = expectedInt; 413 } 414 415 @Override onReceive(Context context, Intent intent)416 public void onReceive(Context context, Intent intent) { 417 if (!TextUtils.equals(intent.getAction(), mAction)) { 418 // move along, this is not the action we're looking for 419 return; 420 } 421 synchronized (mLock) { 422 if (mWaitForExtra != null) { 423 final int extraIntVal = intent.getIntExtra(mWaitForExtra, Integer.MIN_VALUE); 424 if (extraIntVal != mWaitForExtraInt) { 425 Log.i(TAG, "extra received: " + extraIntVal); 426 return; 427 } else { 428 Log.i(TAG, "expected extra received: " + mWaitForExtraInt); 429 } 430 } 431 mIntentReceived = true; 432 mIntent = intent; 433 mLock.notify(); 434 } 435 } 436 437 /** 438 * Wait for the intent up to a given time 439 * @param timeOutMs the timeout in ms 440 * @return true if the intent fire, false if it didn't fire within the timeout 441 */ waitForExpectedAction(long timeOutMs)442 public boolean waitForExpectedAction(long timeOutMs) { 443 synchronized (mLock) { 444 Log.i(TAG, "starting wait: expected extra:" 445 + mWaitForExtra + " val:" + mWaitForExtraInt); 446 final boolean res = mLock.waitFor(timeOutMs, () -> mIntentReceived); 447 Log.i(TAG, "wait stopped, intent received:" + mIntentReceived); 448 return res; 449 } 450 } 451 getIntent()452 public Intent getIntent() { 453 synchronized (mLock) { 454 return mIntent; 455 } 456 } 457 } 458 459 private static final class MyBlockingRunnableListener { 460 private final SafeWaitObject mLock = new SafeWaitObject(); 461 @GuardedBy("mLock") 462 private boolean mEventReceived = false; 463 onSomeEventThatsExpected()464 public void onSomeEventThatsExpected() { 465 synchronized (mLock) { 466 mEventReceived = true; 467 mLock.notify(); 468 } 469 } 470 waitForExpectedEvent(long timeOutMs)471 public boolean waitForExpectedEvent(long timeOutMs) { 472 synchronized (mLock) { 473 return mLock.waitFor(timeOutMs, () -> mEventReceived); 474 } 475 } 476 } 477 testSoundEffects()478 public void testSoundEffects() throws Exception { 479 Settings.System.putInt(mContext.getContentResolver(), SOUND_EFFECTS_ENABLED, 1); 480 481 // should hear sound after loadSoundEffects() called. 482 mAudioManager.loadSoundEffects(); 483 Thread.sleep(TIME_TO_PLAY); 484 float volume = 0.5f; // volume should be between 0.f to 1.f (or -1). 485 mAudioManager.playSoundEffect(SoundEffectConstants.CLICK); 486 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP); 487 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN); 488 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT); 489 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT); 490 491 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP, volume); 492 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN, volume); 493 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT, volume); 494 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT, volume); 495 496 // won't hear sound after unloadSoundEffects() called(); 497 mAudioManager.unloadSoundEffects(); 498 mAudioManager.playSoundEffect(AudioManager.FX_KEY_CLICK); 499 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP); 500 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN); 501 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT); 502 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT); 503 504 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP, volume); 505 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN, volume); 506 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT, volume); 507 mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT, volume); 508 } 509 testCheckingZenModeBlockDoesNotRequireNotificationPolicyAccess()510 public void testCheckingZenModeBlockDoesNotRequireNotificationPolicyAccess() throws Exception { 511 try { 512 // set zen mode to priority only, so playSoundEffect will check notification policy 513 Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(), 514 true); 515 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); 516 Settings.System.putInt(mContext.getContentResolver(), SOUND_EFFECTS_ENABLED, 1); 517 518 // take away write-notification policy access from the package 519 Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(), 520 false); 521 522 // playSoundEffect should NOT throw a security exception; all apps have read-access 523 mAudioManager.playSoundEffect(SoundEffectConstants.CLICK); 524 } finally { 525 Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(), 526 true); 527 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 528 Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(), 529 false); 530 } 531 } 532 testMusicActive()533 public void testMusicActive() throws Exception { 534 if (mAudioManager.isMusicActive()) { 535 return; 536 } 537 MediaPlayer mp = MediaPlayer.create(mContext, MP3_TO_PLAY); 538 assertNotNull(mp); 539 mp.setAudioStreamType(STREAM_MUSIC); 540 mp.start(); 541 assertMusicActive(true); 542 mp.stop(); 543 mp.release(); 544 assertMusicActive(false); 545 } 546 547 @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS") testAccessMode()548 public void testAccessMode() throws Exception { 549 mAudioManager.setMode(MODE_RINGTONE); 550 assertEquals(MODE_RINGTONE, mAudioManager.getMode()); 551 mAudioManager.setMode(MODE_IN_COMMUNICATION); 552 assertEquals(MODE_IN_COMMUNICATION, mAudioManager.getMode()); 553 mAudioManager.setMode(MODE_NORMAL); 554 assertEquals(MODE_NORMAL, mAudioManager.getMode()); 555 } 556 testSetSurroundFormatEnabled()557 public void testSetSurroundFormatEnabled() throws Exception { 558 getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( 559 Manifest.permission.WRITE_SETTINGS); 560 561 int audioFormat = AudioFormat.ENCODING_DTS; 562 563 mAudioManager.setSurroundFormatEnabled(audioFormat, true /*enabled*/); 564 assertTrue(mAudioManager.isSurroundFormatEnabled(audioFormat)); 565 566 mAudioManager.setSurroundFormatEnabled(audioFormat, false /*enabled*/); 567 assertFalse(mAudioManager.isSurroundFormatEnabled(audioFormat)); 568 569 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 570 } 571 572 @AppModeFull(reason = "Instant apps cannot hold android.permission.WRITE_SETTINGS") testSetEncodedSurroundMode()573 public void testSetEncodedSurroundMode() throws Exception { 574 getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( 575 Manifest.permission.WRITE_SETTINGS); 576 577 int expectedSurroundFormatsMode = Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL; 578 mAudioManager.setEncodedSurroundMode(expectedSurroundFormatsMode); 579 assertEquals(expectedSurroundFormatsMode, mAudioManager.getEncodedSurroundMode()); 580 581 expectedSurroundFormatsMode = Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER; 582 mAudioManager.setEncodedSurroundMode(expectedSurroundFormatsMode); 583 assertEquals(expectedSurroundFormatsMode, mAudioManager.getEncodedSurroundMode()); 584 585 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 586 } 587 588 @SuppressWarnings("deprecation") 589 @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS") testRouting()590 public void testRouting() throws Exception { 591 // setBluetoothA2dpOn is a no-op, and getRouting should always return -1 592 boolean oldA2DP = mAudioManager.isBluetoothA2dpOn(); 593 mAudioManager.setBluetoothA2dpOn(true); 594 assertEquals(oldA2DP, mAudioManager.isBluetoothA2dpOn()); 595 mAudioManager.setBluetoothA2dpOn(false); 596 assertEquals(oldA2DP, mAudioManager.isBluetoothA2dpOn()); 597 598 assertEquals(-1, mAudioManager.getRouting(MODE_RINGTONE)); 599 assertEquals(-1, mAudioManager.getRouting(MODE_NORMAL)); 600 assertEquals(-1, mAudioManager.getRouting(MODE_IN_CALL)); 601 assertEquals(-1, mAudioManager.getRouting(MODE_IN_COMMUNICATION)); 602 603 mAudioManager.setBluetoothScoOn(true); 604 assertTrueCheckTimeout(mAudioManager, p -> p.isBluetoothScoOn(), 605 DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isBluetoothScoOn returned false"); 606 607 mAudioManager.setBluetoothScoOn(false); 608 assertTrueCheckTimeout(mAudioManager, p -> !p.isBluetoothScoOn(), 609 DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isBluetoothScoOn returned true"); 610 611 // Speaker Phone Not supported in Automotive 612 if (isAutomotive()) { 613 return; 614 } 615 616 try { 617 getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( 618 Manifest.permission.MODIFY_PHONE_STATE); 619 620 mAudioManager.setSpeakerphoneOn(true); 621 assertTrueCheckTimeout(mAudioManager, p -> p.isSpeakerphoneOn(), 622 DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isSpeakerPhoneOn() returned false"); 623 624 mAudioManager.setSpeakerphoneOn(false); 625 assertTrueCheckTimeout(mAudioManager, p -> !p.isSpeakerphoneOn(), 626 DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isSpeakerPhoneOn() returned true"); 627 628 } finally { 629 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 630 } 631 } 632 testVibrateNotification()633 public void testVibrateNotification() throws Exception { 634 if (mUseFixedVolume || !mHasVibrator) { 635 return; 636 } 637 Utils.toggleNotificationPolicyAccess( 638 mContext.getPackageName(), getInstrumentation(), true); 639 // VIBRATE_SETTING_ON 640 mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON); 641 assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF, 642 mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); 643 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 644 assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); 645 646 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 647 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); 648 649 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 650 assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, 651 mAudioManager.getRingerMode()); 652 assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); 653 654 // VIBRATE_SETTING_OFF 655 mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF); 656 assertEquals(VIBRATE_SETTING_OFF, 657 mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); 658 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 659 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); 660 661 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 662 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); 663 664 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 665 assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, 666 mAudioManager.getRingerMode()); 667 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); 668 669 // VIBRATE_SETTING_ONLY_SILENT 670 mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT); 671 assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF, 672 mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); 673 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 674 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); 675 676 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 677 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); 678 679 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 680 assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, 681 mAudioManager.getRingerMode()); 682 assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); 683 684 // VIBRATE_TYPE_NOTIFICATION 685 mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON); 686 assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF, 687 mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); 688 mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF); 689 assertEquals(VIBRATE_SETTING_OFF, mAudioManager 690 .getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); 691 mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT); 692 assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF, 693 mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); 694 } 695 testVibrateRinger()696 public void testVibrateRinger() throws Exception { 697 if (mUseFixedVolume || !mHasVibrator) { 698 return; 699 } 700 Utils.toggleNotificationPolicyAccess( 701 mContext.getPackageName(), getInstrumentation(), true); 702 // VIBRATE_TYPE_RINGER 703 mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON); 704 assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF, 705 mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); 706 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 707 assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); 708 709 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 710 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); 711 712 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 713 assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, 714 mAudioManager.getRingerMode()); 715 assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); 716 717 // VIBRATE_SETTING_OFF 718 mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF); 719 assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); 720 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 721 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); 722 723 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 724 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); 725 726 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 727 assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, 728 mAudioManager.getRingerMode()); 729 // Note: as of Froyo, if VIBRATE_TYPE_RINGER is set to OFF, it will 730 // not vibrate, even in RINGER_MODE_VIBRATE. This allows users to 731 // disable the vibration for incoming calls only. 732 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); 733 734 // VIBRATE_SETTING_ONLY_SILENT 735 mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT); 736 assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF, 737 mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); 738 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 739 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); 740 741 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 742 assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); 743 744 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 745 assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, 746 mAudioManager.getRingerMode()); 747 assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); 748 749 // VIBRATE_TYPE_NOTIFICATION 750 mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON); 751 assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF, 752 mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); 753 mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF); 754 assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); 755 mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT); 756 assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF, 757 mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); 758 } 759 testAccessRingMode()760 public void testAccessRingMode() throws Exception { 761 Utils.toggleNotificationPolicyAccess( 762 mContext.getPackageName(), getInstrumentation(), true); 763 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 764 assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 765 766 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 767 // AudioService#setRingerMode() has: 768 // if (isTelevision) return; 769 if (mSkipRingerTests) { 770 assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 771 } else { 772 assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode()); 773 } 774 775 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 776 if (mSkipRingerTests) { 777 assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 778 } else { 779 assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, 780 mAudioManager.getRingerMode()); 781 } 782 } 783 784 /** 785 * Test that in RINGER_MODE_VIBRATE we observe: 786 * if NOTIFICATION & RING are not aliased: 787 * ADJUST_UNMUTE NOTIFICATION -> no change (no mode change, NOTIF still muted) 788 * ADJUST_UNMUTE NOTIFICATION + FLAG_ALLOW_RINGER_MODES -> MODE_NORMAL 789 * if NOTIFICATION & RING are aliased: 790 * ADJUST_UNMUTE NOTIFICATION -> MODE_NORMAL 791 * ADJUST_UNMUTE NOTIFICATION + FLAG_ALLOW_RINGER_MODES -> MODE_NORMAL 792 * @throws Exception 793 */ testAdjustUnmuteNotificationInVibrate()794 public void testAdjustUnmuteNotificationInVibrate() throws Exception { 795 Log.i(TAG, "starting testAdjustUnmuteNotificationInVibrate"); 796 if (mSkipRingerTests) { 797 Log.i(TAG, "skipping testAdjustUnmuteNotificationInVibrate"); 798 return; 799 } 800 if (!mHasVibrator) { 801 Log.i(TAG, "skipping testAdjustUnmuteNotificationInVibrate, no vibrator"); 802 return; 803 } 804 // set mode to VIBRATE 805 Utils.toggleNotificationPolicyAccess( 806 mContext.getPackageName(), getInstrumentation(), true); 807 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 808 assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode()); 809 Utils.toggleNotificationPolicyAccess( 810 mContext.getPackageName(), getInstrumentation(), false); 811 812 getInstrumentation().getUiAutomation() 813 .adoptShellPermissionIdentity(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED); 814 final int notifiAliasedStream = mAudioManager.getStreamTypeAlias(STREAM_NOTIFICATION); 815 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 816 817 // verify expected muting from the VIBRATE mode 818 assertStreamMuted(STREAM_RING, true, 819 "RING not muted in MODE_VIBRATE"); 820 assertStreamMuted(STREAM_NOTIFICATION, true, 821 "NOTIFICATION not muted in MODE_VIBRATE"); 822 823 if (notifiAliasedStream == STREAM_NOTIFICATION) { 824 Log.i(TAG, "testAdjustUnmuteNotificationInVibrate: NOTIF independent"); 825 // unmute NOTIFICATION 826 mAudioManager.adjustStreamVolume(STREAM_NOTIFICATION, AudioManager.ADJUST_UNMUTE, 0); 827 // verify it had no effect 828 assertStreamMuted(STREAM_NOTIFICATION, true, "NOTIFICATION did unmute"); 829 // unmuting NOTIFICATION should not have exited RINGER_MODE_VIBRATE 830 assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode()); 831 832 // unmute NOTIFICATION with FLAG_ALLOW_RINGER_MODES 833 mAudioManager.adjustStreamVolume(STREAM_NOTIFICATION, 834 AudioManager.ADJUST_UNMUTE, AudioManager.FLAG_ALLOW_RINGER_MODES); 835 // verify it unmuted NOTIFICATION and RING 836 assertStreamMuted(STREAM_NOTIFICATION, false, 837 "NOTIFICATION (+FLAG_ALLOW_RINGER_MODES) didn't unmute"); 838 assertStreamMuted(STREAM_RING, false, "RING didn't unmute"); 839 // unmuting NOTIFICATION w/ FLAG_ALLOW_RINGER_MODES should have exited MODE_VIBRATE 840 assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 841 } else if (notifiAliasedStream == STREAM_RING) { 842 Log.i(TAG, "testAdjustUnmuteNotificationInVibrate: NOTIF/RING aliased"); 843 // unmute NOTIFICATION (should be just like unmuting RING) 844 mAudioManager.adjustStreamVolume(STREAM_NOTIFICATION, AudioManager.ADJUST_UNMUTE, 0); 845 // verify it unmuted both RING and NOTIFICATION 846 assertStreamMuted(STREAM_NOTIFICATION, false, "NOTIFICATION didn't unmute"); 847 assertStreamMuted(STREAM_RING, false, "RING didn't unmute"); 848 // unmuting NOTIFICATION should have exited RINGER_MODE_VIBRATE 849 assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 850 851 // test again with FLAG_ALLOW_RINGER_MODES 852 Utils.toggleNotificationPolicyAccess( 853 mContext.getPackageName(), getInstrumentation(), true); 854 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 855 assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode()); 856 Utils.toggleNotificationPolicyAccess( 857 mContext.getPackageName(), getInstrumentation(), false); 858 // unmute NOTIFICATION (should be just like unmuting RING) 859 mAudioManager.adjustStreamVolume(STREAM_NOTIFICATION, 860 AudioManager.ADJUST_UNMUTE, AudioManager.FLAG_ALLOW_RINGER_MODES); 861 // verify it unmuted both RING and NOTIFICATION 862 assertStreamMuted(STREAM_NOTIFICATION, false, "NOTIFICATION didn't unmute"); 863 assertStreamMuted(STREAM_RING, false, "RING didn't unmute"); 864 // unmuting NOTIFICATION should have exited RINGER_MODE_VIBRATE 865 assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 866 } 867 } 868 869 /** 870 * Test that in RINGER_MODE_SILENT we observe: 871 * ADJUST_UNMUTE NOTIFICATION -> no change (no mode change, NOTIF still muted) 872 * 873 * Note that in SILENT we cannot test ADJUST_UNMUTE NOTIFICATION + FLAG_ALLOW_RINGER_MODES 874 * because it depends on VolumePolicy.volumeUpToExitSilent. 875 * TODO add test API to query VolumePolicy, expected in MODE_SILENT: 876 * ADJUST_UNMUTE NOTIFICATION + FLAG_ALLOW_RINGER_MODE -> 877 * no change if VolumePolicy.volumeUpToExitSilent false (default?) 878 * ADJUST_UNMUTE NOTIFICATION + FLAG_ALLOW_RINGER_MODE -> 879 * MODE_NORMAL if VolumePolicy.volumeUpToExitSilent true 880 * @throws Exception 881 */ testAdjustUnmuteNotificationInSilent()882 public void testAdjustUnmuteNotificationInSilent() throws Exception { 883 if (mSkipRingerTests) { 884 return; 885 } 886 // set mode to SILENT 887 Utils.toggleNotificationPolicyAccess( 888 mContext.getPackageName(), getInstrumentation(), true); 889 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 890 assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode()); 891 Utils.toggleNotificationPolicyAccess( 892 mContext.getPackageName(), getInstrumentation(), false); 893 894 // verify expected muting from the SILENT mode 895 assertStreamMuted(STREAM_RING, true, 896 "RING not muted in MODE_SILENT"); 897 assertStreamMuted(STREAM_NOTIFICATION, true, 898 "NOTIFICATION not muted in MODE_SILENT"); 899 900 // unmute NOTIFICATION 901 mAudioManager.adjustStreamVolume(STREAM_NOTIFICATION, AudioManager.ADJUST_UNMUTE, 0); 902 // verify it had no effect 903 assertStreamMuted(STREAM_NOTIFICATION, true, "NOTIFICATION did unmute"); 904 // unmuting NOTIFICATION should not have exited RINGER_MODE_SILENT 905 assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode()); 906 } 907 testSetRingerModePolicyAccess()908 public void testSetRingerModePolicyAccess() throws Exception { 909 if (mSkipRingerTests) { 910 return; 911 } 912 // Apps without policy access cannot change silent -> normal or silent -> vibrate. 913 Utils.toggleNotificationPolicyAccess( 914 mContext.getPackageName(), getInstrumentation(), true); 915 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 916 assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode()); 917 Utils.toggleNotificationPolicyAccess( 918 mContext.getPackageName(), getInstrumentation(), false); 919 920 try { 921 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 922 fail("Apps without notification policy access cannot change ringer mode"); 923 } catch (SecurityException e) { 924 } 925 926 try { 927 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 928 fail("Apps without notification policy access cannot change ringer mode"); 929 } catch (SecurityException e) { 930 } 931 932 // Apps without policy access cannot change normal -> silent. 933 Utils.toggleNotificationPolicyAccess( 934 mContext.getPackageName(), getInstrumentation(), true); 935 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 936 assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 937 Utils.toggleNotificationPolicyAccess( 938 mContext.getPackageName(), getInstrumentation(), false); 939 940 try { 941 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 942 fail("Apps without notification policy access cannot change ringer mode"); 943 } catch (SecurityException e) { 944 } 945 assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 946 947 if (mHasVibrator) { 948 // Apps without policy access cannot change vibrate -> silent. 949 Utils.toggleNotificationPolicyAccess( 950 mContext.getPackageName(), getInstrumentation(), true); 951 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 952 assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode()); 953 Utils.toggleNotificationPolicyAccess( 954 mContext.getPackageName(), getInstrumentation(), false); 955 956 try { 957 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 958 fail("Apps without notification policy access cannot change ringer mode"); 959 } catch (SecurityException e) { 960 } 961 962 // Apps without policy access can change vibrate -> normal and vice versa. 963 assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode()); 964 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 965 assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 966 mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); 967 assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode()); 968 } 969 } 970 testAccessRampingRinger()971 public void testAccessRampingRinger() { 972 boolean originalEnabledState = mAudioManager.isRampingRingerEnabled(); 973 try { 974 mAudioManager.setRampingRingerEnabled(false); 975 assertFalse(mAudioManager.isRampingRingerEnabled()); 976 977 mAudioManager.setRampingRingerEnabled(true); 978 assertTrue(mAudioManager.isRampingRingerEnabled()); 979 } finally { 980 mAudioManager.setRampingRingerEnabled(originalEnabledState); 981 } 982 } 983 testRampingRingerSetting()984 public void testRampingRingerSetting() { 985 boolean originalEnabledState = mAudioManager.isRampingRingerEnabled(); 986 try { 987 // Deprecated public setting should still be supported and affect the setting getter. 988 Settings.Global.putInt(mContext.getContentResolver(), APPLY_RAMPING_RINGER, 0); 989 assertFalse(mAudioManager.isRampingRingerEnabled()); 990 991 Settings.Global.putInt(mContext.getContentResolver(), APPLY_RAMPING_RINGER, 1); 992 assertTrue(mAudioManager.isRampingRingerEnabled()); 993 } finally { 994 mAudioManager.setRampingRingerEnabled(originalEnabledState); 995 } 996 } 997 testVolume()998 public void testVolume() throws Exception { 999 if (MediaUtils.check(mIsTelevision, "No volume test due to fixed/full vol devices")) 1000 return; 1001 Utils.toggleNotificationPolicyAccess( 1002 mContext.getPackageName(), getInstrumentation(), true); 1003 int volume, volumeDelta; 1004 int[] streams = {STREAM_ALARM, 1005 STREAM_MUSIC, 1006 STREAM_VOICE_CALL, 1007 STREAM_RING}; 1008 1009 mAudioManager.adjustVolume(ADJUST_RAISE, 0); 1010 // adjusting volume is asynchronous, wait before other volume checks 1011 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1012 mAudioManager.adjustSuggestedStreamVolume( 1013 ADJUST_LOWER, USE_DEFAULT_STREAM_TYPE, 0); 1014 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1015 int maxMusicVolume = mAudioManager.getStreamMaxVolume(STREAM_MUSIC); 1016 1017 for (int stream : streams) { 1018 if (mIsSingleVolume && stream != STREAM_MUSIC) { 1019 continue; 1020 } 1021 1022 // set ringer mode to back normal to not interfere with volume tests 1023 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 1024 1025 int maxVolume = mAudioManager.getStreamMaxVolume(stream); 1026 int minVolume = mAudioManager.getStreamMinVolume(stream); 1027 1028 // validate min 1029 assertTrue(String.format("minVolume(%d) must be >= 0", minVolume), minVolume >= 0); 1030 assertTrue(String.format("minVolume(%d) must be < maxVolume(%d)", minVolume, 1031 maxVolume), 1032 minVolume < maxVolume); 1033 1034 final int minNonZeroVolume = Math.max(minVolume, 1); 1035 mAudioManager.setStreamVolume(stream, minNonZeroVolume, 0); 1036 if (mUseFixedVolume) { 1037 assertEquals(maxVolume, mAudioManager.getStreamVolume(stream)); 1038 continue; 1039 } 1040 assertEquals(String.format("stream=%d", stream), 1041 minNonZeroVolume, mAudioManager.getStreamVolume(stream)); 1042 1043 if (stream == STREAM_MUSIC && mAudioManager.isWiredHeadsetOn()) { 1044 // due to new regulations, music sent over a wired headset may be volume limited 1045 // until the user explicitly increases the limit, so we can't rely on being able 1046 // to set the volume to getStreamMaxVolume(). Instead, determine the current limit 1047 // by increasing the volume until it won't go any higher, then use that volume as 1048 // the maximum for the purposes of this test 1049 int curvol = 0; 1050 int prevvol = 0; 1051 do { 1052 prevvol = curvol; 1053 mAudioManager.adjustStreamVolume(stream, ADJUST_RAISE, 0); 1054 curvol = mAudioManager.getStreamVolume(stream); 1055 } while (curvol != prevvol); 1056 maxVolume = maxMusicVolume = curvol; 1057 } 1058 mAudioManager.setStreamVolume(stream, maxVolume, 0); 1059 mAudioManager.adjustStreamVolume(stream, ADJUST_RAISE, 0); 1060 assertEquals(maxVolume, mAudioManager.getStreamVolume(stream)); 1061 1062 volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(stream)); 1063 mAudioManager.adjustSuggestedStreamVolume(ADJUST_LOWER, stream, 0); 1064 assertStreamVolumeEquals(stream, maxVolume - volumeDelta, 1065 "Vol ADJUST_LOWER suggested stream:" + stream + " maxVol:" + maxVolume); 1066 1067 // volume lower 1068 mAudioManager.setStreamVolume(stream, maxVolume, 0); 1069 volume = mAudioManager.getStreamVolume(stream); 1070 while (volume > minVolume) { 1071 volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(stream)); 1072 mAudioManager.adjustStreamVolume(stream, ADJUST_LOWER, 0); 1073 assertStreamVolumeEquals(stream, Math.max(0, volume - volumeDelta), 1074 "Vol ADJUST_LOWER on stream:" + stream + " vol:" + volume 1075 + " minVol:" + minVolume + " volDelta:" + volumeDelta); 1076 volume = mAudioManager.getStreamVolume(stream); 1077 } 1078 1079 mAudioManager.adjustStreamVolume(stream, ADJUST_SAME, 0); 1080 1081 // volume raise 1082 mAudioManager.setStreamVolume(stream, minNonZeroVolume, 0); 1083 volume = mAudioManager.getStreamVolume(stream); 1084 while (volume < maxVolume) { 1085 volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(stream)); 1086 mAudioManager.adjustStreamVolume(stream, ADJUST_RAISE, 0); 1087 assertStreamVolumeEquals(stream, Math.min(volume + volumeDelta, maxVolume), 1088 "Vol ADJUST_RAISE on stream:" + stream + " vol:" + volume 1089 + " maxVol:" + maxVolume + " volDelta:" + volumeDelta); 1090 volume = mAudioManager.getStreamVolume(stream); 1091 } 1092 1093 // volume same 1094 mAudioManager.setStreamVolume(stream, maxVolume, 0); 1095 mAudioManager.adjustStreamVolume(stream, ADJUST_SAME, 0); 1096 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1097 assertEquals("Vol ADJUST_RAISE onADJUST_SAME stream:" + stream, 1098 maxVolume, mAudioManager.getStreamVolume(stream)); 1099 1100 mAudioManager.setStreamVolume(stream, maxVolume, 0); 1101 } 1102 1103 if (mUseFixedVolume) { 1104 return; 1105 } 1106 1107 // adjust volume 1108 mAudioManager.adjustVolume(ADJUST_RAISE, 0); 1109 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1110 1111 boolean isMusicPlayingBeforeTest = false; 1112 if (mAudioManager.isMusicActive()) { 1113 isMusicPlayingBeforeTest = true; 1114 } 1115 1116 MediaPlayer mp = MediaPlayer.create(mContext, MP3_TO_PLAY); 1117 assertNotNull(mp); 1118 mp.setAudioStreamType(STREAM_MUSIC); 1119 mp.setLooping(true); 1120 mp.start(); 1121 assertMusicActive(true); 1122 1123 // adjust volume as ADJUST_SAME 1124 mAudioManager.adjustVolume(ADJUST_SAME, 0); 1125 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1126 assertStreamVolumeEquals(STREAM_MUSIC, maxMusicVolume); 1127 1128 // adjust volume as ADJUST_RAISE 1129 mAudioManager.setStreamVolume(STREAM_MUSIC, 0, 0); 1130 volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC)); 1131 mAudioManager.adjustVolume(ADJUST_RAISE, 0); 1132 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1133 assertStreamVolumeEquals(STREAM_MUSIC, Math.min(volumeDelta, maxMusicVolume)); 1134 1135 // adjust volume as ADJUST_LOWER 1136 mAudioManager.setStreamVolume(STREAM_MUSIC, maxMusicVolume, 0); 1137 maxMusicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); 1138 volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC)); 1139 mAudioManager.adjustVolume(ADJUST_LOWER, 0); 1140 assertStreamVolumeEquals(STREAM_MUSIC, Math.max(0, maxMusicVolume - volumeDelta)); 1141 1142 mp.stop(); 1143 mp.release(); 1144 if (!isMusicPlayingBeforeTest) { 1145 assertMusicActive(false); 1146 } 1147 } 1148 testAccessibilityVolume()1149 public void testAccessibilityVolume() throws Exception { 1150 if (mUseFixedVolume) { 1151 Log.i("AudioManagerTest", "testAccessibilityVolume() skipped: fixed volume"); 1152 return; 1153 } 1154 final int maxA11yVol = mAudioManager.getStreamMaxVolume(STREAM_ACCESSIBILITY); 1155 assertTrue("Max a11yVol not strictly positive", maxA11yVol > 0); 1156 int originalVol = mAudioManager.getStreamVolume(STREAM_ACCESSIBILITY); 1157 1158 // changing STREAM_ACCESSIBILITY is subject to permission, shouldn't be able to change it 1159 // test setStreamVolume 1160 final int testSetVol; 1161 if (originalVol != maxA11yVol) { 1162 testSetVol = maxA11yVol; 1163 } else { 1164 testSetVol = maxA11yVol - 1; 1165 } 1166 mAudioManager.setStreamVolume(STREAM_ACCESSIBILITY, testSetVol, 0); 1167 assertStreamVolumeEquals(STREAM_ACCESSIBILITY, originalVol, 1168 "Should not be able to change A11y vol"); 1169 1170 // test adjustStreamVolume 1171 // LOWER 1172 if (originalVol > 0) { 1173 mAudioManager.adjustStreamVolume(STREAM_ACCESSIBILITY, ADJUST_LOWER, 0); 1174 assertStreamVolumeEquals(STREAM_ACCESSIBILITY, originalVol, 1175 "Should not be able to change A11y vol"); 1176 } 1177 // RAISE 1178 if (originalVol < maxA11yVol) { 1179 mAudioManager.adjustStreamVolume(STREAM_ACCESSIBILITY, ADJUST_RAISE, 0); 1180 assertStreamVolumeEquals(STREAM_ACCESSIBILITY, originalVol, 1181 "Should not be able to change A11y vol"); 1182 } 1183 } 1184 testSetVoiceCallVolumeToZeroPermission()1185 public void testSetVoiceCallVolumeToZeroPermission() { 1186 // Verify that only apps with MODIFY_PHONE_STATE can set VOICE_CALL_STREAM to 0 1187 mAudioManager.setStreamVolume(STREAM_VOICE_CALL, 0, 0); 1188 assertTrue("MODIFY_PHONE_STATE is required in order to set voice call volume to 0", 1189 mAudioManager.getStreamVolume(STREAM_VOICE_CALL) != 0); 1190 } 1191 testMuteFixedVolume()1192 public void testMuteFixedVolume() throws Exception { 1193 int[] streams = { 1194 STREAM_VOICE_CALL, 1195 STREAM_MUSIC, 1196 STREAM_RING, 1197 STREAM_ALARM, 1198 STREAM_NOTIFICATION, 1199 STREAM_SYSTEM}; 1200 if (mUseFixedVolume) { 1201 for (int stream : streams) { 1202 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0); 1203 assertFalse("Muting should not affect a fixed volume device.", 1204 mAudioManager.isStreamMute(stream)); 1205 1206 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_TOGGLE_MUTE, 0); 1207 assertFalse("Toggling mute should not affect a fixed volume device.", 1208 mAudioManager.isStreamMute(stream)); 1209 1210 mAudioManager.setStreamMute(stream, true); 1211 assertFalse("Muting should not affect a fixed volume device.", 1212 mAudioManager.isStreamMute(stream)); 1213 } 1214 } 1215 } 1216 testMuteDndAffectedStreams()1217 public void testMuteDndAffectedStreams() throws Exception { 1218 if (mSkipRingerTests) { 1219 return; 1220 } 1221 int[] streams = { STREAM_RING }; 1222 // Mute streams 1223 Utils.toggleNotificationPolicyAccess( 1224 mContext.getPackageName(), getInstrumentation(), true); 1225 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 1226 Utils.toggleNotificationPolicyAccess( 1227 mContext.getPackageName(), getInstrumentation(), false); 1228 // Verify streams cannot be unmuted without policy access. 1229 for (int stream : streams) { 1230 try { 1231 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_UNMUTE, 0); 1232 assertEquals("Apps without Notification policy access can't change ringer mode", 1233 RINGER_MODE_SILENT, mAudioManager.getRingerMode()); 1234 } catch (SecurityException e) { 1235 } 1236 1237 try { 1238 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_TOGGLE_MUTE, 1239 0); 1240 assertEquals("Apps without Notification policy access can't change ringer mode", 1241 RINGER_MODE_SILENT, mAudioManager.getRingerMode()); 1242 } catch (SecurityException e) { 1243 } 1244 1245 try { 1246 mAudioManager.setStreamMute(stream, false); 1247 assertEquals("Apps without Notification policy access can't change ringer mode", 1248 RINGER_MODE_SILENT, mAudioManager.getRingerMode()); 1249 } catch (SecurityException e) { 1250 } 1251 } 1252 1253 // This ensures we're out of vibrate or silent modes. 1254 Utils.toggleNotificationPolicyAccess( 1255 mContext.getPackageName(), getInstrumentation(), true); 1256 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 1257 for (int stream : streams) { 1258 // ensure each stream is on and turned up. 1259 mAudioManager.setStreamVolume(stream, 1260 mAudioManager.getStreamMaxVolume(stream), 1261 0); 1262 1263 Utils.toggleNotificationPolicyAccess( 1264 mContext.getPackageName(), getInstrumentation(), false); 1265 try { 1266 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0); 1267 assertEquals("Apps without Notification policy access can't change ringer mode", 1268 RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 1269 } catch (SecurityException e) { 1270 } 1271 try { 1272 mAudioManager.adjustStreamVolume( 1273 stream, AudioManager.ADJUST_TOGGLE_MUTE, 0); 1274 assertEquals("Apps without Notification policy access can't change ringer mode", 1275 RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 1276 } catch (SecurityException e) { 1277 } 1278 1279 try { 1280 mAudioManager.setStreamMute(stream, true); 1281 assertEquals("Apps without Notification policy access can't change ringer mode", 1282 RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); 1283 } catch (SecurityException e) { 1284 } 1285 Utils.toggleNotificationPolicyAccess( 1286 mContext.getPackageName(), getInstrumentation(), true); 1287 testStreamMuting(stream); 1288 } 1289 } 1290 testMuteDndUnaffectedStreams()1291 public void testMuteDndUnaffectedStreams() throws Exception { 1292 if (mSkipRingerTests) { 1293 return; 1294 } 1295 int[] streams = { 1296 STREAM_VOICE_CALL, 1297 STREAM_MUSIC, 1298 STREAM_ALARM 1299 }; 1300 1301 int muteAffectedStreams = System.getInt(mContext.getContentResolver(), 1302 System.MUTE_STREAMS_AFFECTED, 1303 // same defaults as in AudioService. Should be kept in sync. 1304 (1 << STREAM_MUSIC) | 1305 (1 << STREAM_RING) | 1306 (1 << STREAM_NOTIFICATION) | 1307 (1 << STREAM_SYSTEM) | 1308 (1 << STREAM_VOICE_CALL)); 1309 1310 Utils.toggleNotificationPolicyAccess( 1311 mContext.getPackageName(), getInstrumentation(), true); 1312 // This ensures we're out of vibrate or silent modes. 1313 mAudioManager.setRingerMode(RINGER_MODE_NORMAL); 1314 Utils.toggleNotificationPolicyAccess( 1315 mContext.getPackageName(), getInstrumentation(), false); 1316 for (int stream : streams) { 1317 // ensure each stream is on and turned up. 1318 mAudioManager.setStreamVolume(stream, 1319 mAudioManager.getStreamMaxVolume(stream), 1320 0); 1321 if (((1 << stream) & muteAffectedStreams) == 0) { 1322 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0); 1323 assertFalse("Stream " + stream + " should not be affected by mute.", 1324 mAudioManager.isStreamMute(stream)); 1325 mAudioManager.setStreamMute(stream, true); 1326 assertFalse("Stream " + stream + " should not be affected by mute.", 1327 mAudioManager.isStreamMute(stream)); 1328 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_TOGGLE_MUTE, 1329 0); 1330 assertFalse("Stream " + stream + " should not be affected by mute.", 1331 mAudioManager.isStreamMute(stream)); 1332 continue; 1333 } 1334 testStreamMuting(stream); 1335 } 1336 } 1337 testStreamMuting(int stream)1338 private void testStreamMuting(int stream) { 1339 getInstrumentation().getUiAutomation() 1340 .adoptShellPermissionIdentity(Manifest.permission.QUERY_AUDIO_STATE); 1341 1342 final int streamVolume = mAudioManager.getLastAudibleStreamVolume(stream); 1343 1344 // Voice call requires MODIFY_PHONE_STATE, so we should not be able to mute 1345 if (stream == STREAM_VOICE_CALL) { 1346 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0); 1347 assertFalse("Muting voice call stream (" + stream + ") should require " 1348 + "MODIFY_PHONE_STATE.", mAudioManager.isStreamMute(stream)); 1349 } else { 1350 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0); 1351 assertTrue("Muting stream " + stream + " failed.", 1352 mAudioManager.isStreamMute(stream)); 1353 1354 assertEquals(streamVolume, mAudioManager.getLastAudibleStreamVolume(stream)); 1355 1356 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_UNMUTE, 0); 1357 assertFalse("Unmuting stream " + stream + " failed.", 1358 mAudioManager.isStreamMute(stream)); 1359 1360 assertEquals(streamVolume, mAudioManager.getLastAudibleStreamVolume(stream)); 1361 1362 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_TOGGLE_MUTE, 0); 1363 assertTrue("Toggling mute on stream " + stream + " failed.", 1364 mAudioManager.isStreamMute(stream)); 1365 1366 assertEquals(streamVolume, mAudioManager.getLastAudibleStreamVolume(stream)); 1367 1368 mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_TOGGLE_MUTE, 0); 1369 assertFalse("Toggling mute on stream " + stream + " failed.", 1370 mAudioManager.isStreamMute(stream)); 1371 1372 assertEquals(streamVolume, mAudioManager.getLastAudibleStreamVolume(stream)); 1373 1374 mAudioManager.setStreamMute(stream, true); 1375 assertTrue("Muting stream " + stream + " using setStreamMute failed", 1376 mAudioManager.isStreamMute(stream)); 1377 1378 assertEquals(streamVolume, mAudioManager.getLastAudibleStreamVolume(stream)); 1379 1380 // mute it three more times to verify the ref counting is gone. 1381 mAudioManager.setStreamMute(stream, true); 1382 mAudioManager.setStreamMute(stream, true); 1383 mAudioManager.setStreamMute(stream, true); 1384 1385 mAudioManager.setStreamMute(stream, false); 1386 assertFalse("Unmuting stream " + stream + " using setStreamMute failed.", 1387 mAudioManager.isStreamMute(stream)); 1388 } 1389 assertEquals(streamVolume, mAudioManager.getLastAudibleStreamVolume(stream)); 1390 1391 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 1392 } 1393 testSetInvalidRingerMode()1394 public void testSetInvalidRingerMode() { 1395 int ringerMode = mAudioManager.getRingerMode(); 1396 mAudioManager.setRingerMode(-1337); 1397 assertEquals(ringerMode, mAudioManager.getRingerMode()); 1398 1399 mAudioManager.setRingerMode(-3007); 1400 assertEquals(ringerMode, mAudioManager.getRingerMode()); 1401 } 1402 testAdjustVolumeInTotalSilenceMode()1403 public void testAdjustVolumeInTotalSilenceMode() throws Exception { 1404 if (mSkipRingerTests) { 1405 return; 1406 } 1407 try { 1408 Utils.toggleNotificationPolicyAccess( 1409 mContext.getPackageName(), getInstrumentation(), true); 1410 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1411 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE); 1412 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1413 int musicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); 1414 mAudioManager.adjustStreamVolume( 1415 STREAM_MUSIC, ADJUST_RAISE, 0); 1416 assertStreamVolumeEquals(STREAM_MUSIC, musicVolume); 1417 1418 } finally { 1419 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1420 } 1421 } 1422 testAdjustVolumeInAlarmsOnlyMode()1423 public void testAdjustVolumeInAlarmsOnlyMode() throws Exception { 1424 if (mSkipRingerTests) { 1425 return; 1426 } 1427 try { 1428 Utils.toggleNotificationPolicyAccess( 1429 mContext.getPackageName(), getInstrumentation(), true); 1430 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1431 1432 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS); 1433 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1434 int musicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); 1435 mAudioManager.adjustStreamVolume( 1436 STREAM_MUSIC, ADJUST_RAISE, 0); 1437 int volumeDelta = 1438 getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC)); 1439 assertStreamVolumeEquals(STREAM_MUSIC, musicVolume + volumeDelta); 1440 1441 } finally { 1442 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1443 } 1444 } 1445 testSetStreamVolumeInTotalSilenceMode()1446 public void testSetStreamVolumeInTotalSilenceMode() throws Exception { 1447 if (mSkipRingerTests) { 1448 return; 1449 } 1450 try { 1451 Utils.toggleNotificationPolicyAccess( 1452 mContext.getPackageName(), getInstrumentation(), true); 1453 mAudioManager.setStreamVolume(STREAM_RING, 1, 0); 1454 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1455 1456 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE); 1457 // delay for streams interruption filter to get into correct state 1458 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1459 1460 // cannot adjust music, can adjust ringer since it could exit DND 1461 int musicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); 1462 mAudioManager.setStreamVolume(STREAM_MUSIC, 7, 0); 1463 assertStreamVolumeEquals(STREAM_MUSIC, musicVolume); 1464 mAudioManager.setStreamVolume(STREAM_RING, 7, 0); 1465 assertStreamVolumeEquals(STREAM_RING, 7); 1466 } finally { 1467 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1468 } 1469 } 1470 testSetStreamVolumeInAlarmsOnlyMode()1471 public void testSetStreamVolumeInAlarmsOnlyMode() throws Exception { 1472 if (mSkipRingerTests) { 1473 return; 1474 } 1475 try { 1476 Utils.toggleNotificationPolicyAccess( 1477 mContext.getPackageName(), getInstrumentation(), true); 1478 mAudioManager.setStreamVolume(STREAM_RING, 1, 0); 1479 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1480 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS); 1481 // delay for streams to get into correct volume states 1482 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1483 1484 // can still adjust music and ring volume 1485 mAudioManager.setStreamVolume(STREAM_MUSIC, 3, 0); 1486 assertStreamVolumeEquals(STREAM_MUSIC, 3); 1487 mAudioManager.setStreamVolume(STREAM_RING, 7, 0); 1488 assertStreamVolumeEquals(STREAM_RING, 7); 1489 } finally { 1490 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1491 } 1492 } 1493 testSetStreamVolumeInPriorityOnlyMode()1494 public void testSetStreamVolumeInPriorityOnlyMode() throws Exception { 1495 if (mSkipRingerTests) { 1496 return; 1497 } 1498 Utils.toggleNotificationPolicyAccess( 1499 mContext.getPackageName(), getInstrumentation(), true); 1500 1501 try { 1502 // turn off zen, set stream volumes to check for later 1503 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1504 1505 final int testRingerVol = getTestRingerVol(); 1506 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1507 mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); 1508 int musicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); 1509 int alarmVolume = mAudioManager.getStreamVolume(STREAM_ALARM); 1510 1511 // disallow all sounds in priority only, turn on priority only DND, try to change volume 1512 mNm.setNotificationPolicy(new NotificationManager.Policy(0, 0 , 0)); 1513 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); 1514 // delay for streams to get into correct volume states 1515 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1516 mAudioManager.setStreamVolume(STREAM_MUSIC, 3, 0); 1517 mAudioManager.setStreamVolume(STREAM_ALARM, 5, 0); 1518 mAudioManager.setStreamVolume(STREAM_RING, testRingerVol, 0); 1519 1520 // Turn off zen and make sure stream levels are still the same prior to zen 1521 // aside from ringer since ringer can exit dnd 1522 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1523 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); // delay for streams to get into correct states 1524 assertEquals(musicVolume, mAudioManager.getStreamVolume(STREAM_MUSIC)); 1525 assertEquals(alarmVolume, mAudioManager.getStreamVolume(STREAM_ALARM)); 1526 assertEquals(testRingerVol, mAudioManager.getStreamVolume(STREAM_RING)); 1527 } finally { 1528 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1529 } 1530 } 1531 testAdjustVolumeInPriorityOnly()1532 public void testAdjustVolumeInPriorityOnly() throws Exception { 1533 if (mSkipRingerTests) { 1534 return; 1535 } 1536 1537 Utils.toggleNotificationPolicyAccess( 1538 mContext.getPackageName(), getInstrumentation(), true); 1539 try { 1540 // turn off zen, set stream volumes to check for later 1541 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1542 mAudioManager.setStreamVolume(STREAM_RING, 1, 0); 1543 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1544 mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); 1545 int ringVolume = mAudioManager.getStreamVolume(STREAM_RING); 1546 int musicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); 1547 int alarmVolume = mAudioManager.getStreamVolume(STREAM_ALARM); 1548 1549 // disallow all sounds in priority only, turn on priority only DND, try to change volume 1550 mNm.setNotificationPolicy(new NotificationManager.Policy(0, 0, 0)); 1551 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); 1552 // delay for streams to get into correct mute states 1553 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); 1554 mAudioManager.adjustStreamVolume( 1555 STREAM_RING, ADJUST_RAISE, 0); 1556 mAudioManager.adjustStreamVolume( 1557 STREAM_MUSIC, ADJUST_RAISE, 0); 1558 mAudioManager.adjustStreamVolume( 1559 STREAM_ALARM, ADJUST_RAISE, 0); 1560 1561 // Turn off zen and make sure stream levels are still the same prior to zen 1562 // aside from ringer since ringer can exit dnd 1563 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1564 Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); // delay for streams to get into correct states 1565 assertEquals(musicVolume, mAudioManager.getStreamVolume(STREAM_MUSIC)); 1566 assertEquals(alarmVolume, mAudioManager.getStreamVolume(STREAM_ALARM)); 1567 1568 int volumeDelta = 1569 getVolumeDelta(mAudioManager.getStreamVolume(STREAM_RING)); 1570 assertEquals(ringVolume + volumeDelta, 1571 mAudioManager.getStreamVolume(STREAM_RING)); 1572 } finally { 1573 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1574 } 1575 } 1576 testPriorityOnlyMuteAll()1577 public void testPriorityOnlyMuteAll() throws Exception { 1578 if (mSkipRingerTests) { 1579 return; 1580 } 1581 1582 Utils.toggleNotificationPolicyAccess( 1583 mContext.getPackageName(), getInstrumentation(), true); 1584 try { 1585 // ensure volume is not muted/0 to start test 1586 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1587 mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); 1588 mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); 1589 mAudioManager.setStreamVolume(STREAM_RING, 1, 0); 1590 1591 // disallow all sounds in priority only, turn on priority only DND 1592 mNm.setNotificationPolicy(new NotificationManager.Policy(0, 0, 0)); 1593 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); 1594 1595 assertStreamMuted(STREAM_MUSIC, true, 1596 "Music (media) stream should be muted"); 1597 assertStreamMuted(STREAM_SYSTEM, true, 1598 "System stream should be muted"); 1599 assertStreamMuted(STREAM_ALARM, true, 1600 "Alarm stream should be muted"); 1601 1602 // if channels cannot bypass DND, the Ringer stream should be muted, else it 1603 // shouldn't be muted 1604 assertStreamMuted(STREAM_RING, !mAppsBypassingDnd, 1605 "Ringer stream should be muted if channels cannot bypassDnd"); 1606 } finally { 1607 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1608 } 1609 } 1610 testPriorityOnlyMediaAllowed()1611 public void testPriorityOnlyMediaAllowed() throws Exception { 1612 if (mSkipRingerTests) { 1613 return; 1614 } 1615 Utils.toggleNotificationPolicyAccess( 1616 mContext.getPackageName(), getInstrumentation(), true); 1617 try { 1618 // ensure volume is not muted/0 to start test 1619 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1620 mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); 1621 mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); 1622 mAudioManager.setStreamVolume(STREAM_RING, 1, 0); 1623 1624 // allow only media in priority only 1625 mNm.setNotificationPolicy(new NotificationManager.Policy( 1626 NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA, 0, 0)); 1627 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); 1628 1629 assertStreamMuted(STREAM_MUSIC, false, 1630 "Music (media) stream should not be muted"); 1631 assertStreamMuted(STREAM_SYSTEM, true, 1632 "System stream should be muted"); 1633 assertStreamMuted(STREAM_ALARM, true, 1634 "Alarm stream should be muted"); 1635 1636 // if channels cannot bypass DND, the Ringer stream should be muted, else it 1637 // shouldn't be muted 1638 assertStreamMuted(STREAM_RING, !mAppsBypassingDnd, 1639 "Ringer stream should be muted if channels cannot bypassDnd"); 1640 } finally { 1641 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1642 } 1643 } 1644 testPriorityOnlySystemAllowed()1645 public void testPriorityOnlySystemAllowed() throws Exception { 1646 if (mSkipRingerTests) { 1647 return; 1648 } 1649 1650 Utils.toggleNotificationPolicyAccess( 1651 mContext.getPackageName(), getInstrumentation(), true); 1652 try { 1653 // ensure volume is not muted/0 to start test 1654 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1655 mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); 1656 mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); 1657 mAudioManager.setStreamVolume(STREAM_RING, 1, 0); 1658 1659 // allow only system in priority only 1660 mNm.setNotificationPolicy(new NotificationManager.Policy( 1661 NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM, 0, 0)); 1662 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); 1663 1664 assertStreamMuted(STREAM_MUSIC, true, 1665 "Music (media) stream should be muted"); 1666 assertStreamMuted(STREAM_SYSTEM, false, 1667 "System stream should not be muted"); 1668 assertStreamMuted(STREAM_ALARM, true, 1669 "Alarm stream should be muted"); 1670 assertStreamMuted(STREAM_RING, false, 1671 "Ringer stream should not be muted"); 1672 } finally { 1673 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1674 } 1675 } 1676 testPriorityOnlySystemDisallowedWithRingerMuted()1677 public void testPriorityOnlySystemDisallowedWithRingerMuted() throws Exception { 1678 if (mSkipRingerTests) { 1679 return; 1680 } 1681 1682 Utils.toggleNotificationPolicyAccess( 1683 mContext.getPackageName(), getInstrumentation(), true); 1684 try { 1685 // ensure volume is not muted/0 to start test, but then mute ringer 1686 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1687 mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); 1688 mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); 1689 mAudioManager.setStreamVolume(STREAM_RING, 0, 0); 1690 mAudioManager.setRingerMode(RINGER_MODE_SILENT); 1691 1692 // allow only system in priority only 1693 mNm.setNotificationPolicy(new NotificationManager.Policy( 1694 NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM, 0, 0)); 1695 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); 1696 1697 assertStreamMuted(STREAM_MUSIC, true, 1698 "Music (media) stream should be muted"); 1699 assertStreamMuted(STREAM_SYSTEM, true, 1700 "System stream should be muted"); 1701 assertStreamMuted(STREAM_ALARM, true, 1702 "Alarm stream should be muted"); 1703 assertStreamMuted(STREAM_RING, true, 1704 "Ringer stream should be muted"); 1705 } finally { 1706 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1707 } 1708 } 1709 testPriorityOnlyAlarmsAllowed()1710 public void testPriorityOnlyAlarmsAllowed() throws Exception { 1711 if (mSkipRingerTests) { 1712 return; 1713 } 1714 1715 Utils.toggleNotificationPolicyAccess( 1716 mContext.getPackageName(), getInstrumentation(), true); 1717 try { 1718 // ensure volume is not muted/0 to start test 1719 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1720 mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); 1721 mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); 1722 mAudioManager.setStreamVolume(STREAM_RING, 1, 0); 1723 1724 // allow only alarms in priority only 1725 mNm.setNotificationPolicy(new NotificationManager.Policy( 1726 NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS, 0, 0)); 1727 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); 1728 1729 assertStreamMuted(STREAM_MUSIC, true, 1730 "Music (media) stream should be muted"); 1731 assertStreamMuted(STREAM_SYSTEM, true, 1732 "System stream should be muted"); 1733 assertStreamMuted(STREAM_ALARM, false, 1734 "Alarm stream should not be muted"); 1735 1736 // if channels cannot bypass DND, the Ringer stream should be muted, else it 1737 // shouldn't be muted 1738 assertStreamMuted(STREAM_RING, !mAppsBypassingDnd, 1739 "Ringer stream should be muted if channels cannot bypassDnd"); 1740 } finally { 1741 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1742 } 1743 } 1744 testPriorityOnlyRingerAllowed()1745 public void testPriorityOnlyRingerAllowed() throws Exception { 1746 if (mSkipRingerTests) { 1747 return; 1748 } 1749 1750 Utils.toggleNotificationPolicyAccess( 1751 mContext.getPackageName(), getInstrumentation(), true); 1752 try { 1753 // ensure volume is not muted/0 to start test 1754 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1755 mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); 1756 mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); 1757 mAudioManager.setStreamVolume(STREAM_RING, 1, 0); 1758 1759 // allow only reminders in priority only 1760 mNm.setNotificationPolicy(new NotificationManager.Policy( 1761 NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS, 0, 0)); 1762 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); 1763 1764 assertStreamMuted(STREAM_MUSIC, true, 1765 "Music (media) stream should be muted"); 1766 assertStreamMuted(STREAM_SYSTEM, true, 1767 "System stream should be muted"); 1768 assertStreamMuted(STREAM_ALARM, true, 1769 "Alarm stream should be muted"); 1770 assertStreamMuted(STREAM_RING, false, 1771 "Ringer stream should not be muted"); 1772 } finally { 1773 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1774 } 1775 } 1776 testPriorityOnlyChannelsCanBypassDnd()1777 public void testPriorityOnlyChannelsCanBypassDnd() throws Exception { 1778 if (mSkipRingerTests) { 1779 return; 1780 } 1781 1782 Utils.toggleNotificationPolicyAccess( 1783 mContext.getPackageName(), getInstrumentation(), true); 1784 1785 final String NOTIFICATION_CHANNEL_ID = "test_id_" + SystemClock.uptimeMillis(); 1786 NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "TEST", 1787 NotificationManager.IMPORTANCE_DEFAULT); 1788 try { 1789 // ensure volume is not muted/0 to start test 1790 mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); 1791 mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); 1792 mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); 1793 mAudioManager.setStreamVolume(STREAM_RING, 1, 0); 1794 1795 // create a channel that can bypass dnd 1796 channel.setBypassDnd(true); 1797 mNm.createNotificationChannel(channel); 1798 1799 // allow nothing 1800 mNm.setNotificationPolicy(new NotificationManager.Policy(0,0, 0)); 1801 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); 1802 1803 assertStreamMuted(STREAM_MUSIC, true, 1804 "Music (media) stream should be muted"); 1805 assertStreamMuted(STREAM_SYSTEM, true, 1806 "System stream should be muted"); 1807 assertStreamMuted(STREAM_ALARM, true, 1808 "Alarm stream should be muted"); 1809 assertStreamMuted(STREAM_RING, false, 1810 "Ringer stream should not be muted." 1811 + " areChannelsBypassing=" 1812 + NotificationManager.getService().areChannelsBypassingDnd()); 1813 1814 // delete the channel that can bypass dnd 1815 mNm.deleteNotificationChannel(NOTIFICATION_CHANNEL_ID); 1816 1817 assertStreamMuted(STREAM_MUSIC, true, 1818 "Music (media) stream should be muted"); 1819 assertStreamMuted(STREAM_SYSTEM, true, 1820 "System stream should be muted"); 1821 assertStreamMuted(STREAM_ALARM, true, 1822 "Alarm stream should be muted"); 1823 // if channels cannot bypass DND, the Ringer stream should be muted, else it 1824 // shouldn't be muted 1825 assertStreamMuted(STREAM_RING, !mAppsBypassingDnd, 1826 "Ringer stream should be muted if apps are bypassing dnd" 1827 + " areChannelsBypassing=" 1828 + NotificationManager.getService().areChannelsBypassingDnd()); 1829 } finally { 1830 setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); 1831 mNm.deleteNotificationChannel(NOTIFICATION_CHANNEL_ID); 1832 Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(), 1833 false); 1834 } 1835 } 1836 testAdjustVolumeWithIllegalDirection()1837 public void testAdjustVolumeWithIllegalDirection() throws Exception { 1838 // Call the method with illegal direction. System should not reboot. 1839 mAudioManager.adjustVolume(37, 0); 1840 } 1841 testGetStreamVolumeDbWithIllegalArguments()1842 public void testGetStreamVolumeDbWithIllegalArguments() throws Exception { 1843 Exception ex = null; 1844 // invalid stream type 1845 try { 1846 float gain = mAudioManager.getStreamVolumeDb(-100 /*streamType*/, 0, 1847 AudioDeviceInfo.TYPE_BUILTIN_SPEAKER); 1848 } catch (Exception e) { 1849 ex = e; // expected 1850 } 1851 assertNotNull("No exception was thrown for an invalid stream type", ex); 1852 assertEquals("Wrong exception thrown for invalid stream type", 1853 ex.getClass(), IllegalArgumentException.class); 1854 1855 // invalid volume index 1856 ex = null; 1857 try { 1858 float gain = mAudioManager.getStreamVolumeDb(STREAM_MUSIC, -101 /*volume*/, 1859 AudioDeviceInfo.TYPE_BUILTIN_SPEAKER); 1860 } catch (Exception e) { 1861 ex = e; // expected 1862 } 1863 assertNotNull("No exception was thrown for an invalid volume index", ex); 1864 assertEquals("Wrong exception thrown for invalid volume index", 1865 ex.getClass(), IllegalArgumentException.class); 1866 1867 // invalid out of range volume index 1868 ex = null; 1869 try { 1870 final int maxVol = mAudioManager.getStreamMaxVolume(STREAM_MUSIC); 1871 float gain = mAudioManager.getStreamVolumeDb(STREAM_MUSIC, maxVol + 1, 1872 AudioDeviceInfo.TYPE_BUILTIN_SPEAKER); 1873 } catch (Exception e) { 1874 ex = e; // expected 1875 } 1876 assertNotNull("No exception was thrown for an invalid out of range volume index", ex); 1877 assertEquals("Wrong exception thrown for invalid out of range volume index", 1878 ex.getClass(), IllegalArgumentException.class); 1879 1880 // invalid device type 1881 ex = null; 1882 try { 1883 float gain = mAudioManager.getStreamVolumeDb(STREAM_MUSIC, 0, 1884 -102 /*deviceType*/); 1885 } catch (Exception e) { 1886 ex = e; // expected 1887 } 1888 assertNotNull("No exception was thrown for an invalid device type", ex); 1889 assertEquals("Wrong exception thrown for invalid device type", 1890 ex.getClass(), IllegalArgumentException.class); 1891 1892 // invalid input device type 1893 ex = null; 1894 try { 1895 float gain = mAudioManager.getStreamVolumeDb(STREAM_MUSIC, 0, 1896 AudioDeviceInfo.TYPE_BUILTIN_MIC); 1897 } catch (Exception e) { 1898 ex = e; // expected 1899 } 1900 assertNotNull("No exception was thrown for an invalid input device type", ex); 1901 assertEquals("Wrong exception thrown for invalid input device type", 1902 ex.getClass(), IllegalArgumentException.class); 1903 } 1904 testGetStreamVolumeDb()1905 public void testGetStreamVolumeDb() throws Exception { 1906 for (int streamType : PUBLIC_STREAM_TYPES) { 1907 // verify mininum index is strictly inferior to maximum index 1908 final int minIndex = mAudioManager.getStreamMinVolume(streamType); 1909 final int maxIndex = mAudioManager.getStreamMaxVolume(streamType); 1910 assertTrue("Min vol index (" + minIndex + ") for stream " + streamType + " not inferior" 1911 + " to max vol index (" + maxIndex + ")", minIndex <= maxIndex); 1912 float prevGain = Float.NEGATIVE_INFINITY; 1913 // verify gain increases with the volume indices 1914 for (int idx = minIndex ; idx <= maxIndex ; idx++) { 1915 float gain = mAudioManager.getStreamVolumeDb(streamType, idx, 1916 AudioDeviceInfo.TYPE_BUILTIN_SPEAKER); 1917 assertTrue("Non-monotonically increasing gain at index " + idx + " for stream" 1918 + streamType, prevGain <= gain); 1919 prevGain = gain; 1920 } 1921 } 1922 } 1923 testAdjustSuggestedStreamVolumeWithIllegalArguments()1924 public void testAdjustSuggestedStreamVolumeWithIllegalArguments() throws Exception { 1925 // Call the method with illegal direction. System should not reboot. 1926 mAudioManager.adjustSuggestedStreamVolume(37, STREAM_MUSIC, 0); 1927 1928 // Call the method with illegal stream. System should not reboot. 1929 mAudioManager.adjustSuggestedStreamVolume(ADJUST_RAISE, 66747, 0); 1930 } 1931 1932 @CddTest(requirement="5.4.1/C-1-4") testGetMicrophones()1933 public void testGetMicrophones() throws Exception { 1934 if (!mContext.getPackageManager().hasSystemFeature( 1935 PackageManager.FEATURE_MICROPHONE)) { 1936 return; 1937 } 1938 List<MicrophoneInfo> microphones = mAudioManager.getMicrophones(); 1939 assertTrue(microphones.size() > 0); 1940 for (int i = 0; i < microphones.size(); i++) { 1941 MicrophoneInfo microphone = microphones.get(i); 1942 Log.i(TAG, "deviceId:" + microphone.getDescription()); 1943 Log.i(TAG, "portId:" + microphone.getId()); 1944 Log.i(TAG, "type:" + microphone.getType()); 1945 Log.i(TAG, "address:" + microphone.getAddress()); 1946 Log.i(TAG, "deviceLocation:" + microphone.getLocation()); 1947 Log.i(TAG, "deviceGroup:" + microphone.getGroup() 1948 + " index:" + microphone.getIndexInTheGroup()); 1949 MicrophoneInfo.Coordinate3F position = microphone.getPosition(); 1950 Log.i(TAG, "position:" + position.x + " " + position.y + " " + position.z); 1951 MicrophoneInfo.Coordinate3F orientation = microphone.getOrientation(); 1952 Log.i(TAG, "orientation:" + orientation.x + " " 1953 + orientation.y + " " + orientation.z); 1954 Log.i(TAG, "frequencyResponse:" + microphone.getFrequencyResponse()); 1955 Log.i(TAG, "channelMapping:" + microphone.getChannelMapping()); 1956 Log.i(TAG, "sensitivity:" + microphone.getSensitivity()); 1957 Log.i(TAG, "max spl:" + microphone.getMaxSpl()); 1958 Log.i(TAG, "min spl:" + microphone.getMinSpl()); 1959 Log.i(TAG, "directionality:" + microphone.getDirectionality()); 1960 Log.i(TAG, "--------------"); 1961 } 1962 } 1963 testIsHapticPlaybackSupported()1964 public void testIsHapticPlaybackSupported() { 1965 // Calling the API to make sure it doesn't crash. 1966 Log.i(TAG, "isHapticPlaybackSupported: " + AudioManager.isHapticPlaybackSupported()); 1967 } 1968 testIsUltrasoundSupported()1969 public void testIsUltrasoundSupported() { 1970 // Calling the API to make sure it must crash due to no permission. 1971 try { 1972 mAudioManager.isUltrasoundSupported(); 1973 fail("isUltrasoundSupported must fail due to no permission"); 1974 } catch (SecurityException e) { 1975 } 1976 } 1977 testIsHotwordStreamSupported()1978 public void testIsHotwordStreamSupported() { 1979 // Validate API requires permission 1980 assertThrows(SecurityException.class, () -> mAudioManager.isHotwordStreamSupported(false)); 1981 assertThrows(SecurityException.class, () -> mAudioManager.isHotwordStreamSupported(true)); 1982 // Validate functionality when caller holds appropriate permissions 1983 InstrumentationRegistry.getInstrumentation() 1984 .getUiAutomation() 1985 .adoptShellPermissionIdentity( 1986 Manifest.permission.CAPTURE_AUDIO_HOTWORD); 1987 boolean result1 = mAudioManager.isHotwordStreamSupported(false); 1988 boolean result2 = mAudioManager.isHotwordStreamSupported(true); 1989 1990 InstrumentationRegistry.getInstrumentation() 1991 .getUiAutomation() 1992 .dropShellPermissionIdentity(); 1993 } 1994 testGetAudioHwSyncForSession()1995 public void testGetAudioHwSyncForSession() { 1996 // AudioManager.getAudioHwSyncForSession is not supported before S 1997 if (ApiLevelUtil.isAtMost(Build.VERSION_CODES.R)) { 1998 Log.i(TAG, "testGetAudioHwSyncForSession skipped, release: " + Build.VERSION.SDK_INT); 1999 return; 2000 } 2001 try { 2002 int sessionId = mAudioManager.generateAudioSessionId(); 2003 assertNotEquals("testGetAudioHwSyncForSession cannot get audio session ID", 2004 AudioManager.ERROR, sessionId); 2005 int hwSyncId = mAudioManager.getAudioHwSyncForSession(sessionId); 2006 Log.i(TAG, "getAudioHwSyncForSession: " + hwSyncId); 2007 } catch (UnsupportedOperationException e) { 2008 Log.i(TAG, "getAudioHwSyncForSession not supported"); 2009 } catch (Exception e) { 2010 fail("Unexpected exception thrown by getAudioHwSyncForSession: " + e); 2011 } 2012 } 2013 setInterruptionFilter(int filter)2014 private void setInterruptionFilter(int filter) { 2015 mNm.setInterruptionFilter(filter); 2016 final long startPoll = SystemClock.uptimeMillis(); 2017 int currentFilter = -1; 2018 while (SystemClock.uptimeMillis() - startPoll < POLL_TIME_UPDATE_INTERRUPTION_FILTER) { 2019 currentFilter = mNm.getCurrentInterruptionFilter(); 2020 if (currentFilter == filter) { 2021 return; 2022 } 2023 } 2024 Log.e(TAG, "interruption filter unsuccessfully set. wanted=" + filter 2025 + " actual=" + currentFilter); 2026 } 2027 getVolumeDelta(int volume)2028 private int getVolumeDelta(int volume) { 2029 return 1; 2030 } 2031 getTestRingerVol()2032 private int getTestRingerVol() { 2033 final int currentRingVol = mAudioManager.getStreamVolume(STREAM_RING); 2034 final int maxRingVol = mAudioManager.getStreamMaxVolume(STREAM_RING); 2035 if (currentRingVol != maxRingVol) { 2036 return maxRingVol; 2037 } else { 2038 return maxRingVol - 1; 2039 } 2040 } 2041 testAllowedCapturePolicy()2042 public void testAllowedCapturePolicy() throws Exception { 2043 final int policy = mAudioManager.getAllowedCapturePolicy(); 2044 assertEquals("Wrong default capture policy", AudioAttributes.ALLOW_CAPTURE_BY_ALL, policy); 2045 2046 for (int setPolicy : new int[] { AudioAttributes.ALLOW_CAPTURE_BY_NONE, 2047 AudioAttributes.ALLOW_CAPTURE_BY_SYSTEM, 2048 AudioAttributes.ALLOW_CAPTURE_BY_ALL}) { 2049 mAudioManager.setAllowedCapturePolicy(setPolicy); 2050 final int getPolicy = mAudioManager.getAllowedCapturePolicy(); 2051 assertEquals("Allowed capture policy doesn't match", setPolicy, getPolicy); 2052 } 2053 } 2054 testIsHdmiSystemAudidoSupported()2055 public void testIsHdmiSystemAudidoSupported() { 2056 // just make sure the call works 2057 boolean isSupported = mAudioManager.isHdmiSystemAudioSupported(); 2058 Log.d(TAG, "isHdmiSystemAudioSupported() = " + isSupported); 2059 } 2060 testIsBluetoothScoAvailableOffCall()2061 public void testIsBluetoothScoAvailableOffCall() { 2062 // just make sure the call works 2063 boolean isSupported = mAudioManager.isBluetoothScoAvailableOffCall(); 2064 Log.d(TAG, "isBluetoothScoAvailableOffCall() = " + isSupported); 2065 } 2066 testStartStopBluetoothSco()2067 public void testStartStopBluetoothSco() { 2068 mAudioManager.startBluetoothSco(); 2069 mAudioManager.stopBluetoothSco(); 2070 } 2071 testStartStopBluetoothScoVirtualCall()2072 public void testStartStopBluetoothScoVirtualCall() { 2073 mAudioManager.startBluetoothScoVirtualCall(); 2074 mAudioManager.stopBluetoothSco(); 2075 } 2076 testGetAdditionalOutputDeviceDelay()2077 public void testGetAdditionalOutputDeviceDelay() { 2078 AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL); 2079 for (AudioDeviceInfo device : devices) { 2080 long delay = mAudioManager.getAdditionalOutputDeviceDelay(device); 2081 assertTrue("getAdditionalOutputDeviceDelay() = " + delay +" (should be >= 0)", 2082 delay >= 0); 2083 delay = mAudioManager.getMaxAdditionalOutputDeviceDelay(device); 2084 assertTrue("getMaxAdditionalOutputDeviceDelay() = " + delay +" (should be >= 0)", 2085 delay >= 0); 2086 } 2087 } 2088 2089 static class MyPrevDevForStrategyListener implements 2090 AudioManager.OnPreferredDevicesForStrategyChangedListener { 2091 @Override onPreferredDevicesForStrategyChanged(AudioProductStrategy strategy, List<AudioDeviceAttributes> devices)2092 public void onPreferredDevicesForStrategyChanged(AudioProductStrategy strategy, 2093 List<AudioDeviceAttributes> devices) { 2094 fail("onPreferredDevicesForStrategyChanged must not be called"); 2095 } 2096 } 2097 testPreferredDevicesForStrategy()2098 public void testPreferredDevicesForStrategy() { 2099 // setPreferredDeviceForStrategy 2100 AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS); 2101 if (devices.length <= 0) { 2102 Log.i(TAG, "Skip testPreferredDevicesForStrategy as there is no output device"); 2103 return; 2104 } 2105 final AudioDeviceAttributes ada = new AudioDeviceAttributes(devices[0]); 2106 2107 final AudioAttributes mediaAttr = new AudioAttributes.Builder().setUsage( 2108 AudioAttributes.USAGE_MEDIA).build(); 2109 final List<AudioProductStrategy> strategies = 2110 AudioProductStrategy.getAudioProductStrategies(); 2111 AudioProductStrategy strategyForMedia = null; 2112 for (AudioProductStrategy strategy : strategies) { 2113 if (strategy.supportsAudioAttributes(mediaAttr)) { 2114 strategyForMedia = strategy; 2115 break; 2116 } 2117 } 2118 if (strategyForMedia == null) { 2119 Log.i(TAG, "Skip testPreferredDevicesForStrategy as there is no strategy for media"); 2120 return; 2121 } 2122 Log.i(TAG, "Found strategy " + strategyForMedia.getName() + " for media"); 2123 try { 2124 mAudioManager.setPreferredDeviceForStrategy(strategyForMedia, ada); 2125 fail("setPreferredDeviceForStrategy must fail due to no permission"); 2126 } catch (SecurityException e) { 2127 } 2128 try { 2129 mAudioManager.getPreferredDeviceForStrategy(strategyForMedia); 2130 fail("getPreferredDeviceForStrategy must fail due to no permission"); 2131 } catch (SecurityException e) { 2132 } 2133 final List<AudioDeviceAttributes> adas = new ArrayList<>(); 2134 adas.add(ada); 2135 try { 2136 mAudioManager.setPreferredDevicesForStrategy(strategyForMedia, adas); 2137 fail("setPreferredDevicesForStrategy must fail due to no permission"); 2138 } catch (SecurityException e) { 2139 } 2140 try { 2141 mAudioManager.getPreferredDevicesForStrategy(strategyForMedia); 2142 fail("getPreferredDevicesForStrategy must fail due to no permission"); 2143 } catch (SecurityException e) { 2144 } 2145 MyPrevDevForStrategyListener listener = new MyPrevDevForStrategyListener(); 2146 try { 2147 mAudioManager.addOnPreferredDevicesForStrategyChangedListener( 2148 Executors.newSingleThreadExecutor(), listener); 2149 fail("addOnPreferredDevicesForStrategyChangedListener must fail due to no permission"); 2150 } catch (SecurityException e) { 2151 } 2152 try { 2153 // removeOnPreferredDevicesForStrategyChangedListener should throw on non-registered 2154 // listener. 2155 mAudioManager.removeOnPreferredDevicesForStrategyChangedListener(listener); 2156 fail("removeOnPreferredDevicesForStrategyChangedListener must fail on bad listener"); 2157 } catch (IllegalArgumentException e) { 2158 } 2159 } 2160 2161 static class MyPrevDevicesForCapturePresetChangedListener implements 2162 AudioManager.OnPreferredDevicesForCapturePresetChangedListener { 2163 @Override onPreferredDevicesForCapturePresetChanged( int capturePreset, List<AudioDeviceAttributes> devices)2164 public void onPreferredDevicesForCapturePresetChanged( 2165 int capturePreset, List<AudioDeviceAttributes> devices) { 2166 fail("onPreferredDevicesForCapturePresetChanged must not be called"); 2167 } 2168 } 2169 testPreferredDeviceForCapturePreset()2170 public void testPreferredDeviceForCapturePreset() { 2171 AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS); 2172 if (devices.length <= 0) { 2173 Log.i(TAG, "Skip testPreferredDevicesForStrategy as there is no input device"); 2174 return; 2175 } 2176 final AudioDeviceAttributes ada = new AudioDeviceAttributes(devices[0]); 2177 2178 try { 2179 mAudioManager.setPreferredDeviceForCapturePreset(MediaRecorder.AudioSource.MIC, ada); 2180 fail("setPreferredDeviceForCapturePreset must fail due to no permission"); 2181 } catch (SecurityException e) { 2182 } 2183 try { 2184 mAudioManager.getPreferredDevicesForCapturePreset(MediaRecorder.AudioSource.MIC); 2185 fail("getPreferredDevicesForCapturePreset must fail due to no permission"); 2186 } catch (SecurityException e) { 2187 } 2188 try { 2189 mAudioManager.clearPreferredDevicesForCapturePreset(MediaRecorder.AudioSource.MIC); 2190 fail("clearPreferredDevicesForCapturePreset must fail due to no permission"); 2191 } catch (SecurityException e) { 2192 } 2193 MyPrevDevicesForCapturePresetChangedListener listener = 2194 new MyPrevDevicesForCapturePresetChangedListener(); 2195 try { 2196 mAudioManager.addOnPreferredDevicesForCapturePresetChangedListener( 2197 Executors.newSingleThreadExecutor(), listener); 2198 fail("addOnPreferredDevicesForCapturePresetChangedListener must fail" 2199 + "due to no permission"); 2200 } catch (SecurityException e) { 2201 } 2202 // There is not listener added at server side. Nothing to remove. 2203 mAudioManager.removeOnPreferredDevicesForCapturePresetChangedListener(listener); 2204 } 2205 testGetDevices()2206 public void testGetDevices() { 2207 AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL); 2208 for (AudioDeviceInfo device : devices) { 2209 Set<Integer> formats = IntStream.of(device.getEncodings()).boxed() 2210 .collect(Collectors.toSet()); 2211 Set<Integer> channelMasks = IntStream.of(device.getChannelMasks()).boxed() 2212 .collect(Collectors.toSet()); 2213 Set<Integer> channelIndexMasks = IntStream.of(device.getChannelIndexMasks()).boxed() 2214 .collect(Collectors.toSet()); 2215 Set<Integer> sampleRates = IntStream.of(device.getSampleRates()).boxed() 2216 .collect(Collectors.toSet()); 2217 HashSet<Integer> formatsFromProfile = new HashSet<>(); 2218 HashSet<Integer> channelMasksFromProfile = new HashSet<>(); 2219 HashSet<Integer> channelIndexMasksFromProfile = new HashSet<>(); 2220 HashSet<Integer> sampleRatesFromProfile = new HashSet<>(); 2221 for (AudioProfile profile : device.getAudioProfiles()) { 2222 formatsFromProfile.add(profile.getFormat()); 2223 channelMasksFromProfile.addAll(Arrays.stream(profile.getChannelMasks()).boxed() 2224 .collect(Collectors.toList())); 2225 channelIndexMasksFromProfile.addAll(Arrays.stream(profile.getChannelIndexMasks()) 2226 .boxed().collect(Collectors.toList())); 2227 sampleRatesFromProfile.addAll(Arrays.stream(profile.getSampleRates()).boxed() 2228 .collect(Collectors.toList())); 2229 assertTrue(ALL_ENCAPSULATION_TYPES.contains(profile.getEncapsulationType())); 2230 } 2231 for (AudioDescriptor descriptor : device.getAudioDescriptors()) { 2232 assertNotEquals(AudioDescriptor.STANDARD_NONE, descriptor.getStandard()); 2233 assertNotNull(descriptor.getDescriptor()); 2234 assertTrue( 2235 ALL_KNOWN_ENCAPSULATION_TYPES.contains(descriptor.getEncapsulationType())); 2236 } 2237 assertEquals(formats, formatsFromProfile); 2238 assertEquals(channelMasks, channelMasksFromProfile); 2239 assertEquals(channelIndexMasks, channelIndexMasksFromProfile); 2240 assertEquals(sampleRates, sampleRatesFromProfile); 2241 } 2242 } 2243 testGetDirectPlaybackSupport()2244 public void testGetDirectPlaybackSupport() { 2245 assertEquals(AudioManager.DIRECT_PLAYBACK_NOT_SUPPORTED, 2246 AudioManager.getDirectPlaybackSupport( 2247 new AudioFormat.Builder().build(), 2248 new AudioAttributes.Builder().build())); 2249 AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS); 2250 AudioAttributes attr = new AudioAttributes.Builder() 2251 .setUsage(AudioAttributes.USAGE_MEDIA) 2252 .setLegacyStreamType(STREAM_MUSIC).build(); 2253 for (AudioDeviceInfo device : devices) { 2254 for (int encoding : device.getEncodings()) { 2255 for (int channelMask : device.getChannelMasks()) { 2256 for (int sampleRate : device.getSampleRates()) { 2257 AudioFormat format = new AudioFormat.Builder() 2258 .setEncoding(encoding) 2259 .setChannelMask(channelMask) 2260 .setSampleRate(sampleRate).build(); 2261 final int directPlaybackSupport = 2262 AudioManager.getDirectPlaybackSupport(format, attr); 2263 assertEquals( 2264 AudioTrack.isDirectPlaybackSupported(format, attr), 2265 directPlaybackSupport 2266 != AudioManager.DIRECT_PLAYBACK_NOT_SUPPORTED); 2267 if (directPlaybackSupport == AudioManager.DIRECT_PLAYBACK_NOT_SUPPORTED) { 2268 assertEquals( 2269 DIRECT_OFFLOAD_MAP.getOrDefault( 2270 AudioManager.getPlaybackOffloadSupport(format, attr), 2271 INVALID_DIRECT_PLAYBACK_MODE).intValue(), 2272 directPlaybackSupport); 2273 } else if ((directPlaybackSupport 2274 & AudioManager.DIRECT_PLAYBACK_OFFLOAD_SUPPORTED) 2275 != AudioManager.DIRECT_PLAYBACK_NOT_SUPPORTED) { 2276 // AudioManager.getPlaybackOffloadSupport can only query offload 2277 // support but not other direct support like passthrough. 2278 assertNotEquals( 2279 AudioManager.DIRECT_PLAYBACK_NOT_SUPPORTED, 2280 DIRECT_OFFLOAD_MAP.getOrDefault( 2281 AudioManager.getPlaybackOffloadSupport(format, attr), 2282 AudioManager.DIRECT_PLAYBACK_NOT_SUPPORTED) 2283 & directPlaybackSupport); 2284 } 2285 } 2286 } 2287 } 2288 } 2289 } 2290 2291 @AppModeFull(reason = "Instant apps cannot hold permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED") testIndependentStreamTypes()2292 public void testIndependentStreamTypes() throws Exception { 2293 Log.i(TAG, "starting testIndependentStreamTypes"); 2294 getInstrumentation().getUiAutomation() 2295 .adoptShellPermissionIdentity(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED); 2296 try { 2297 final List<Integer> independentStreamTypes = mAudioManager.getIndependentStreamTypes(); 2298 assertNotNull("Null list of independent stream types", independentStreamTypes); 2299 final boolean usesGroups = mAudioManager.isVolumeControlUsingVolumeGroups(); 2300 Log.i(TAG, "testIndependentStreamTypes: usesGroups:" + usesGroups 2301 + " independentTypes" + independentStreamTypes); 2302 if (usesGroups) { 2303 assertTrue("Empty list of independent stream types with volume groups", 2304 independentStreamTypes.size() > 0); 2305 return; 2306 } 2307 assertTrue("Unexpected number of independent stream types " 2308 + independentStreamTypes.size(), independentStreamTypes.size() > 0); 2309 // verify independent streams are not aliased 2310 for (int indepStream : independentStreamTypes) { 2311 final int alias = mAudioManager.getStreamTypeAlias(indepStream); 2312 assertEquals("Independent stream " + indepStream + " has alias " + alias, 2313 indepStream, alias); 2314 } 2315 // verify aliased streams are not independent, and non-aliased streams are 2316 for (int stream : PUBLIC_STREAM_TYPES) { 2317 final int alias = mAudioManager.getStreamTypeAlias(stream); 2318 if (alias != stream) { 2319 assertFalse("Stream" + stream + " aliased to " + alias 2320 + " but marked independent", independentStreamTypes.contains(stream)); 2321 } else { 2322 // independent stream 2323 assertTrue("Stream " + stream 2324 + " has no alias but is not marked as independent", 2325 independentStreamTypes.contains(stream)); 2326 } 2327 } 2328 } finally { 2329 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 2330 } 2331 } 2332 2333 @AppModeFull(reason = "Instant apps cannot hold permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED") testStreamTypeAliasChange()2334 public void testStreamTypeAliasChange() throws Exception { 2335 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 2336 Log.i(TAG, "skipping testStreamTypeAliasChange, not a phone"); 2337 return; 2338 } 2339 Log.i(TAG, "starting testStreamTypeAliasChange"); 2340 getInstrumentation().getUiAutomation() 2341 .adoptShellPermissionIdentity(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED); 2342 2343 // get initial state 2344 final int notifAliasAtStart = mAudioManager.getStreamTypeAlias(STREAM_NOTIFICATION); 2345 if (notifAliasAtStart != STREAM_NOTIFICATION && notifAliasAtStart != STREAM_RING) { 2346 // skipping test because it can't take advantage of the test API to modify 2347 // the notification alias 2348 Log.i(TAG, "skipping testStreamTypeAliasChange: NOTIFICATION aliased to stream " 2349 + notifAliasAtStart); 2350 return; 2351 } 2352 boolean notifAliasedToRingAtStart = (notifAliasAtStart == STREAM_RING); 2353 final MyBlockingRunnableListener streamAliasCb = new MyBlockingRunnableListener(); 2354 Runnable onStreamAliasChanged = () -> streamAliasCb.onSomeEventThatsExpected(); 2355 try { 2356 if (!notifAliasedToRingAtStart) { 2357 // if notif and ring are not aliased, they should each be independent streams 2358 final List<Integer> indies = mAudioManager.getIndependentStreamTypes(); 2359 assertTrue("NOTIFICATION not in independent streams " + indies, 2360 indies.contains(STREAM_NOTIFICATION)); 2361 assertTrue("RING not in independent streams " + indies, 2362 indies.contains(STREAM_RING)); 2363 } 2364 mAudioManager.addOnStreamAliasingChangedListener( 2365 Executors.newSingleThreadExecutor(), 2366 onStreamAliasChanged); 2367 mAudioManager.setNotifAliasRingForTest(!notifAliasedToRingAtStart); 2368 final String aliasing = notifAliasedToRingAtStart ? "unaliasing" : "aliasing"; 2369 assertTrue(aliasing + " RING and NOTIFICATION didn't trigger callback", 2370 streamAliasCb.waitForExpectedEvent(TIME_TO_WAIT_CALLBACK_MS)); 2371 final int expectedNotifAlias = notifAliasedToRingAtStart ? STREAM_NOTIFICATION 2372 : STREAM_RING; 2373 assertEquals("After " + aliasing + " alias incorrect", 2374 expectedNotifAlias, mAudioManager.getStreamTypeAlias(STREAM_NOTIFICATION)); 2375 if (notifAliasedToRingAtStart) { 2376 // if notif and ring were aliased, they should now be independent streams 2377 final List<Integer> indies = mAudioManager.getIndependentStreamTypes(); 2378 assertTrue("After alias change, NOTIFICATION not in independent streams " 2379 + indies, 2380 indies.contains(STREAM_NOTIFICATION)); 2381 assertTrue("After alias change, RING not in independent streams " + indies, 2382 indies.contains(STREAM_RING)); 2383 } 2384 2385 } finally { 2386 mAudioManager.setNotifAliasRingForTest(notifAliasedToRingAtStart); 2387 mAudioManager.removeOnStreamAliasingChangedListener(onStreamAliasChanged); 2388 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 2389 } 2390 } 2391 testAssistantUidRouting()2392 public void testAssistantUidRouting() { 2393 try { 2394 mAudioManager.addAssistantServicesUids(new int[0]); 2395 fail("addAssistantServicesUids must fail due to no permission"); 2396 } catch (SecurityException e) { 2397 } 2398 2399 try { 2400 mAudioManager.removeAssistantServicesUids(new int[0]); 2401 fail("removeAssistantServicesUids must fail due to no permission"); 2402 } catch (SecurityException e) { 2403 } 2404 2405 try { 2406 int[] uids = mAudioManager.getAssistantServicesUids(); 2407 fail("getAssistantServicesUids must fail due to no permission"); 2408 } catch (SecurityException e) { 2409 } 2410 2411 try { 2412 mAudioManager.setActiveAssistantServiceUids(new int[0]); 2413 fail("setActiveAssistantServiceUids must fail due to no permission"); 2414 } catch (SecurityException e) { 2415 } 2416 2417 try { 2418 int[] activeUids = mAudioManager.getActiveAssistantServicesUids(); 2419 fail("getActiveAssistantServicesUids must fail due to no permission"); 2420 } catch (SecurityException e) { 2421 } 2422 } 2423 2424 @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_ROUTING") testBluetoothVariableLatency()2425 public void testBluetoothVariableLatency() throws Exception { 2426 assertThrows(SecurityException.class, 2427 () -> mAudioManager.supportsBluetoothVariableLatency()); 2428 assertThrows(SecurityException.class, 2429 () -> mAudioManager.setBluetoothVariableLatencyEnabled(false)); 2430 assertThrows(SecurityException.class, 2431 () -> mAudioManager.setBluetoothVariableLatencyEnabled(true)); 2432 assertThrows(SecurityException.class, 2433 () -> mAudioManager.isBluetoothVariableLatencyEnabled()); 2434 2435 getInstrumentation().getUiAutomation() 2436 .adoptShellPermissionIdentity(Manifest.permission.MODIFY_AUDIO_ROUTING); 2437 if (mAudioManager.supportsBluetoothVariableLatency()) { 2438 boolean savedEnabled = mAudioManager.isBluetoothVariableLatencyEnabled(); 2439 mAudioManager.setBluetoothVariableLatencyEnabled(false); 2440 assertFalse(mAudioManager.isBluetoothVariableLatencyEnabled()); 2441 mAudioManager.setBluetoothVariableLatencyEnabled(true); 2442 assertTrue(mAudioManager.isBluetoothVariableLatencyEnabled()); 2443 mAudioManager.setBluetoothVariableLatencyEnabled(savedEnabled); 2444 } 2445 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 2446 } 2447 testGetHalVersion()2448 public void testGetHalVersion() { 2449 AudioHalVersionInfo halVersion = AudioManager.getHalVersion(); 2450 assertNotEquals(null, halVersion); 2451 assertTrue( 2452 AudioHalVersionInfo.AUDIO_HAL_TYPE_AIDL == halVersion.getHalType() 2453 || AudioHalVersionInfo.AUDIO_HAL_TYPE_HIDL == halVersion.getHalType()); 2454 assertTrue(halVersion.getMajorVersion() > 0); 2455 assertTrue(halVersion.getMinorVersion() >= 0); 2456 } 2457 testPreferredMixerAttributes()2458 public void testPreferredMixerAttributes() { 2459 final AudioAttributes attr = new AudioAttributes.Builder() 2460 .setUsage(AudioAttributes.USAGE_MEDIA).build(); 2461 final AudioMixerAttributes defaultMixerAttributes = new AudioMixerAttributes.Builder( 2462 new AudioFormat.Builder() 2463 .setEncoding(AudioFormat.ENCODING_PCM_16BIT) 2464 .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO) 2465 .setSampleRate(48000) 2466 .build()) 2467 .setMixerBehavior(AudioMixerAttributes.MIXER_BEHAVIOR_DEFAULT) 2468 .build(); 2469 for (AudioDeviceInfo device : mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL)) { 2470 MyPreferredMixerAttrListener listener = 2471 new MyPreferredMixerAttrListener(attr, device.getId()); 2472 mAudioManager.addOnPreferredMixerAttributesChangedListener( 2473 Executors.newSingleThreadExecutor(), listener); 2474 List<AudioMixerAttributes> supportedMixerAttributes = 2475 mAudioManager.getSupportedMixerAttributes(device); 2476 if (supportedMixerAttributes.isEmpty()) { 2477 // Setting preferred mixer attributes is not supported 2478 assertFalse(mAudioManager.setPreferredMixerAttributes( 2479 attr, device, defaultMixerAttributes)); 2480 } else { 2481 for (AudioMixerAttributes mixerAttr : supportedMixerAttributes) { 2482 assertNotNull(mixerAttr.getFormat()); 2483 assertTrue(ALL_MIXER_BEHAVIORS.contains(mixerAttr.getMixerBehavior())); 2484 listener.reset(); 2485 assertTrue(mAudioManager.setPreferredMixerAttributes(attr, device, mixerAttr)); 2486 try { 2487 // Wait a while for callback to be called. 2488 Thread.sleep(TIME_TO_WAIT_CALLBACK_MS); 2489 } catch (InterruptedException e) { 2490 } 2491 assertTrue(listener.isPreferredMixerAttributesChanged()); 2492 final AudioMixerAttributes mixerAttrFromQuery = 2493 mAudioManager.getPreferredMixerAttributes(attr, device); 2494 assertEquals(mixerAttr, mixerAttrFromQuery); 2495 listener.reset(); 2496 assertTrue(mAudioManager.clearPreferredMixerAttributes(attr, device)); 2497 try { 2498 // Wait a while for callback to be called. 2499 Thread.sleep(TIME_TO_WAIT_CALLBACK_MS); 2500 } catch (InterruptedException e) { 2501 } 2502 assertTrue(listener.isPreferredMixerAttributesChanged()); 2503 assertNull(mAudioManager.getPreferredMixerAttributes(attr, device)); 2504 } 2505 } 2506 mAudioManager.removeOnPreferredMixerAttributesChangedListener(listener); 2507 } 2508 } 2509 testAdjustVolumeGroupVolume()2510 public void testAdjustVolumeGroupVolume() { 2511 getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( 2512 Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED, 2513 Manifest.permission.MODIFY_AUDIO_ROUTING, 2514 Manifest.permission.QUERY_AUDIO_STATE, 2515 Manifest.permission.MODIFY_PHONE_STATE); 2516 2517 List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups(); 2518 assertTrue(audioVolumeGroups.size() > 0); 2519 2520 final AudioAttributes callAa = new AudioAttributes.Builder() 2521 .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) 2522 .build(); 2523 int voiceCallVolumeGroup = mAudioManager.getVolumeGroupIdForAttributes(callAa); 2524 2525 assertNotEquals(voiceCallVolumeGroup, AudioVolumeGroup.DEFAULT_VOLUME_GROUP); 2526 2527 AudioVolumeGroupCallbackHelper vgCbReceiver = new AudioVolumeGroupCallbackHelper(); 2528 mAudioManager.registerVolumeGroupCallback(mContext.getMainExecutor(), vgCbReceiver); 2529 2530 try { 2531 // Validate Audio Volume Groups callback reception 2532 for (final AudioVolumeGroup audioVolumeGroup : audioVolumeGroups) { 2533 int volumeGroupId = audioVolumeGroup.getId(); 2534 int[] avgStreamTypes = audioVolumeGroup.getLegacyStreamTypes(); 2535 if (avgStreamTypes.length != 0) { 2536 // filters out bijective as API is dispatched to stream. 2537 // Following compatibility test will ensure API are dispatched 2538 continue; 2539 } 2540 int indexMax = mAudioManager.getVolumeGroupMaxVolumeIndex(volumeGroupId); 2541 int indexMin = mAudioManager.getVolumeGroupMinVolumeIndex(volumeGroupId); 2542 boolean isMutable = (indexMin == 0) || (volumeGroupId == voiceCallVolumeGroup); 2543 2544 // Set the receiver to filter only the current group callback 2545 int index = resetVolumeIndex(indexMin, indexMax); 2546 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2547 mAudioManager.setVolumeGroupVolumeIndex(volumeGroupId, index, 0/*flags*/); 2548 assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2549 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2550 int readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2551 assertEquals("Failed to set volume for group id " 2552 + volumeGroupId, readIndex, index); 2553 2554 while (index < indexMax) { 2555 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2556 mAudioManager.adjustVolumeGroupVolume( 2557 volumeGroupId, AudioManager.ADJUST_RAISE, 0/*flags*/); 2558 assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2559 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2560 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2561 index += 1; 2562 assertEquals(readIndex, index); 2563 } 2564 // Max reached 2565 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2566 mAudioManager.adjustVolumeGroupVolume( 2567 volumeGroupId, AudioManager.ADJUST_RAISE, 0/*flags*/); 2568 assertTrue("Cb expected for group " 2569 + volumeGroupId, vgCbReceiver.waitForExpectedVolumeGroupChanged( 2570 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2571 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2572 assertEquals(readIndex, indexMax); 2573 2574 while (index > indexMin) { 2575 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2576 mAudioManager.adjustVolumeGroupVolume( 2577 volumeGroupId, AudioManager.ADJUST_LOWER, 0/*flags*/); 2578 assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2579 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2580 index -= 1; 2581 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2582 assertEquals("Failed to decrease volume for group id " 2583 + volumeGroupId, readIndex, index); 2584 } 2585 // Min reached 2586 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2587 mAudioManager.adjustVolumeGroupVolume( 2588 volumeGroupId, AudioManager.ADJUST_LOWER, 0/*flags*/); 2589 assertTrue("Cb expected for group " 2590 + volumeGroupId, vgCbReceiver.waitForExpectedVolumeGroupChanged( 2591 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2592 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2593 assertEquals("Failed to decrease volume for group id " 2594 + volumeGroupId, readIndex, indexMin); 2595 2596 // Mute/Unmute 2597 if (isMutable) { 2598 int lastAudibleIndex; 2599 index = resetVolumeIndex(indexMin, indexMax); 2600 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2601 mAudioManager.setVolumeGroupVolumeIndex(volumeGroupId, index, 0/*flags*/); 2602 assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2603 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2604 2605 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2606 assertEquals("Failed to set volume for group id " 2607 + volumeGroupId, readIndex, index); 2608 2609 lastAudibleIndex = 2610 mAudioManager.getLastAudibleVolumeForVolumeGroup(volumeGroupId); 2611 assertEquals(lastAudibleIndex, index); 2612 assertFalse(mAudioManager.isVolumeGroupMuted(volumeGroupId)); 2613 2614 // Mute 2615 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2616 mAudioManager.adjustVolumeGroupVolume( 2617 volumeGroupId, AudioManager.ADJUST_MUTE, 0/*flags*/); 2618 assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2619 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2620 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2621 assertEquals("Failed to mute volume for group id " 2622 + volumeGroupId, readIndex, indexMin); 2623 assertEquals(lastAudibleIndex, 2624 mAudioManager.getLastAudibleVolumeForVolumeGroup(volumeGroupId)); 2625 assertTrue(mAudioManager.isVolumeGroupMuted(volumeGroupId)); 2626 2627 // Unmute 2628 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2629 mAudioManager.adjustVolumeGroupVolume( 2630 volumeGroupId, AudioManager.ADJUST_UNMUTE, 0/*flags*/); 2631 assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2632 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2633 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2634 assertEquals("Failed to unmute volume for group id " 2635 + volumeGroupId, readIndex, lastAudibleIndex); 2636 assertEquals(lastAudibleIndex, 2637 mAudioManager.getLastAudibleVolumeForVolumeGroup(volumeGroupId)); 2638 assertFalse(mAudioManager.isVolumeGroupMuted(volumeGroupId)); 2639 2640 // Toggle Mute (from unmuted) 2641 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2642 mAudioManager.adjustVolumeGroupVolume( 2643 volumeGroupId, AudioManager.ADJUST_TOGGLE_MUTE, 0/*flags*/); 2644 assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2645 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2646 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2647 assertEquals("Failed to mute volume for group id " 2648 + volumeGroupId, readIndex, indexMin); 2649 assertEquals(lastAudibleIndex, 2650 mAudioManager.getLastAudibleVolumeForVolumeGroup(volumeGroupId)); 2651 assertTrue(mAudioManager.isVolumeGroupMuted(volumeGroupId)); 2652 2653 // Toggle Mute (from muted) 2654 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2655 mAudioManager.adjustVolumeGroupVolume( 2656 volumeGroupId, AudioManager.ADJUST_TOGGLE_MUTE, 0/*flags*/); 2657 assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2658 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2659 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2660 assertEquals("Failed to unmute volume for group id " 2661 + volumeGroupId, readIndex, lastAudibleIndex); 2662 assertEquals(lastAudibleIndex, 2663 mAudioManager.getLastAudibleVolumeForVolumeGroup(volumeGroupId)); 2664 assertFalse(mAudioManager.isVolumeGroupMuted(volumeGroupId)); 2665 } else { 2666 int lastAudibleIndex; 2667 index = resetVolumeIndex(indexMin, indexMax); 2668 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2669 mAudioManager.setVolumeGroupVolumeIndex(volumeGroupId, index, 0/*flags*/); 2670 assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2671 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2672 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2673 assertEquals(readIndex, index); 2674 2675 lastAudibleIndex = 2676 mAudioManager.getLastAudibleVolumeForVolumeGroup(volumeGroupId); 2677 assertEquals(lastAudibleIndex, index); 2678 assertFalse(mAudioManager.isVolumeGroupMuted(volumeGroupId)); 2679 2680 // Mute 2681 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2682 mAudioManager.adjustVolumeGroupVolume( 2683 volumeGroupId, AudioManager.ADJUST_MUTE, 0/*flags*/); 2684 assertFalse(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2685 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2686 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2687 assertEquals("Unexpected volume mute for group id " + volumeGroupId 2688 + " readIndex=" + readIndex, readIndex, lastAudibleIndex); 2689 assertEquals(lastAudibleIndex, 2690 mAudioManager.getLastAudibleVolumeForVolumeGroup(volumeGroupId)); 2691 assertFalse(mAudioManager.isVolumeGroupMuted(volumeGroupId)); 2692 2693 // Unmute 2694 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2695 mAudioManager.adjustVolumeGroupVolume( 2696 volumeGroupId, AudioManager.ADJUST_UNMUTE, 0/*flags*/); 2697 assertFalse(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2698 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2699 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2700 assertEquals(readIndex, lastAudibleIndex); 2701 assertEquals(lastAudibleIndex, 2702 mAudioManager.getLastAudibleVolumeForVolumeGroup(volumeGroupId)); 2703 assertFalse(mAudioManager.isVolumeGroupMuted(volumeGroupId)); 2704 2705 // Toggle Mute (from unmuted) 2706 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2707 mAudioManager.adjustVolumeGroupVolume( 2708 volumeGroupId, AudioManager.ADJUST_TOGGLE_MUTE, 0/*flags*/); 2709 assertFalse(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2710 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2711 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2712 assertEquals(readIndex, lastAudibleIndex); 2713 assertEquals(lastAudibleIndex, 2714 mAudioManager.getLastAudibleVolumeForVolumeGroup(volumeGroupId)); 2715 assertFalse(mAudioManager.isVolumeGroupMuted(volumeGroupId)); 2716 2717 // Toggle Mute (from muted) 2718 vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); 2719 mAudioManager.adjustVolumeGroupVolume( 2720 volumeGroupId, AudioManager.ADJUST_TOGGLE_MUTE, 0/*flags*/); 2721 assertFalse(vgCbReceiver.waitForExpectedVolumeGroupChanged( 2722 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 2723 readIndex = mAudioManager.getVolumeGroupVolumeIndex(volumeGroupId); 2724 assertEquals(readIndex, lastAudibleIndex); 2725 assertEquals(lastAudibleIndex, 2726 mAudioManager.getLastAudibleVolumeForVolumeGroup(volumeGroupId)); 2727 assertFalse(mAudioManager.isVolumeGroupMuted(volumeGroupId)); 2728 } 2729 } 2730 } finally { 2731 mAudioManager.unregisterVolumeGroupCallback(vgCbReceiver); 2732 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 2733 } 2734 } 2735 2736 private final class MyPreferredMixerAttrListener 2737 implements AudioManager.OnPreferredMixerAttributesChangedListener { 2738 private final AudioAttributes mAttr; 2739 private final int mDeviceId; 2740 2741 private AtomicBoolean mIsCalled = new AtomicBoolean(); 2742 MyPreferredMixerAttrListener(AudioAttributes attr, int deviceId)2743 MyPreferredMixerAttrListener(AudioAttributes attr, int deviceId) { 2744 mAttr = attr; 2745 mDeviceId = deviceId; 2746 } 2747 2748 @Override onPreferredMixerAttributesChanged(AudioAttributes attributes, AudioDeviceInfo device, AudioMixerAttributes mixerAttr)2749 public void onPreferredMixerAttributesChanged(AudioAttributes attributes, 2750 AudioDeviceInfo device, 2751 AudioMixerAttributes mixerAttr) { 2752 if (device.getId() == mDeviceId && mAttr.equals(attributes)) { 2753 mIsCalled.set(true); 2754 } 2755 } 2756 reset()2757 public void reset() { 2758 mIsCalled.set(false); 2759 } 2760 isPreferredMixerAttributesChanged()2761 public boolean isPreferredMixerAttributesChanged() { 2762 return mIsCalled.get(); 2763 } 2764 } 2765 assertStreamVolumeEquals(int stream, int expectedVolume)2766 private void assertStreamVolumeEquals(int stream, int expectedVolume) throws Exception { 2767 assertStreamVolumeEquals(stream, expectedVolume, 2768 "Unexpected stream volume for stream=" + stream); 2769 } 2770 2771 // volume adjustments are asynchronous, we poll the volume in case the volume state hasn't 2772 // been adjusted yet assertStreamVolumeEquals(int stream, int expectedVolume, String msg)2773 private void assertStreamVolumeEquals(int stream, int expectedVolume, String msg) 2774 throws Exception { 2775 final long startPoll = SystemClock.uptimeMillis(); 2776 int actualVolume = mAudioManager.getStreamVolume(stream); 2777 while (SystemClock.uptimeMillis() - startPoll < POLL_TIME_VOLUME_ADJUST 2778 && expectedVolume != actualVolume) { 2779 actualVolume = mAudioManager.getStreamVolume(stream); 2780 } 2781 assertEquals(msg, expectedVolume, actualVolume); 2782 } 2783 2784 // volume adjustments are asynchronous, we poll the volume in case the mute state hasn't 2785 // changed yet assertStreamMuted(int stream, boolean expectedMuteState, String msg)2786 private void assertStreamMuted(int stream, boolean expectedMuteState, String msg) 2787 throws Exception{ 2788 final long startPoll = SystemClock.uptimeMillis(); 2789 boolean actualMuteState = mAudioManager.isStreamMute(stream); 2790 while (SystemClock.uptimeMillis() - startPoll < POLL_TIME_VOLUME_ADJUST 2791 && expectedMuteState != actualMuteState) { 2792 actualMuteState = mAudioManager.isStreamMute(stream); 2793 } 2794 assertEquals(msg, expectedMuteState, actualMuteState); 2795 } 2796 assertMusicActive(boolean expectedIsMusicActive)2797 private void assertMusicActive(boolean expectedIsMusicActive) throws Exception { 2798 final long startPoll = SystemClock.uptimeMillis(); 2799 boolean actualIsMusicActive = mAudioManager.isMusicActive(); 2800 while (SystemClock.uptimeMillis() - startPoll < POLL_TIME_PLAY_MUSIC 2801 && expectedIsMusicActive != actualIsMusicActive) { 2802 actualIsMusicActive = mAudioManager.isMusicActive(); 2803 } 2804 assertEquals(actualIsMusicActive, actualIsMusicActive); 2805 } 2806 2807 private static final long REPEATED_CHECK_POLL_PERIOD_MS = 100; // 100ms 2808 private static final long DEFAULT_ASYNC_CALL_TIMEOUT_MS = 5 * REPEATED_CHECK_POLL_PERIOD_MS; 2809 2810 /** 2811 * Makes multiple attempts over a given timeout period to test the predicate on an AudioManager 2812 * instance. Test success is evaluated against a true predicate result. 2813 * @param am the AudioManager instance to use for the test 2814 * @param predicate the test to run either until it returns true, or until the timeout expires 2815 * @param timeoutMs the maximum time allowed for the test to pass 2816 * @param errorString the string to be displayed in case of failure 2817 * @throws Exception 2818 */ assertTrueCheckTimeout(AudioManager am, Predicate<AudioManager> predicate, long timeoutMs, String errorString)2819 private void assertTrueCheckTimeout(AudioManager am, Predicate<AudioManager> predicate, 2820 long timeoutMs, String errorString) throws Exception { 2821 long checkStart = SystemClock.uptimeMillis(); 2822 boolean result = false; 2823 while (SystemClock.uptimeMillis() - checkStart < timeoutMs) { 2824 result = predicate.test(am); 2825 if (result) { 2826 break; 2827 } 2828 Thread.sleep(REPEATED_CHECK_POLL_PERIOD_MS); 2829 } 2830 assertTrue(errorString, result); 2831 } 2832 isAutomotive()2833 private boolean isAutomotive() { 2834 PackageManager pm = mContext.getPackageManager(); 2835 return pm.hasSystemFeature(pm.FEATURE_AUTOMOTIVE); 2836 } 2837 2838 // getParameters() & setParameters() are deprecated, so don't test 2839 2840 // setAdditionalOutputDeviceDelay(), getAudioVolumeGroups(), getVolumeIndexForAttributes() 2841 // getMinVolumeIndexForAttributes(), getMaxVolumeIndexForAttributes() & 2842 // setVolumeIndexForAttributes() require privledged permission MODIFY_AUDIO_ROUTING 2843 // and thus cannot be tested here. 2844 } 2845