• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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