1 /* 2 * Copyright (C) 2015 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.tests; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertTrue; 21 22 import android.content.Context; 23 import android.media.AudioAttributes; 24 import android.media.AudioFormat; 25 import android.media.AudioManager; 26 import android.media.AudioPatch; 27 import android.media.AudioPort; 28 import android.media.audiopolicy.AudioMix; 29 import android.media.audiopolicy.AudioMixingRule; 30 import android.media.audiopolicy.AudioPolicy; 31 import android.os.Handler; 32 import android.os.Looper; 33 import android.support.test.InstrumentationRegistry; 34 import android.support.test.filters.MediumTest; 35 import android.support.test.runner.AndroidJUnit4; 36 import android.util.Log; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.util.ArrayList; 43 import java.util.concurrent.Semaphore; 44 import java.util.concurrent.TimeUnit; 45 46 @RunWith(AndroidJUnit4.class) 47 @MediumTest 48 public class AudioPolicyTest { 49 private static final String TAG = AudioPolicyTest.class.getSimpleName(); 50 private static final long WAIT_TIMEOUT_MS = 1000; 51 private AudioManager mAudioManager; 52 private Handler mHandler; 53 private Context mContext = InstrumentationRegistry.getContext(); 54 55 @Before setUp()56 public void setUp() throws Exception { 57 mHandler = new Handler(Looper.getMainLooper()); 58 final Semaphore mWaitSemaphore = new Semaphore(0); 59 mHandler.post(() -> { 60 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 61 mWaitSemaphore.release(); 62 }); 63 assertTrue(mWaitSemaphore.tryAcquire(WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); 64 } 65 66 @Test testAudioPorts()67 public void testAudioPorts() throws Exception { 68 AudioPortUpdateListener listener = new AudioPortUpdateListener(); 69 mAudioManager.registerAudioPortUpdateListener(listener); 70 ArrayList<AudioPort> initialPorts = dumpAudioPorts("initial state"); 71 AudioMix mediaMix = createAudioMix(AudioAttributes.CONTENT_TYPE_UNKNOWN, 72 AudioAttributes.CONTENT_TYPE_MUSIC); 73 AudioPolicy audioPolicy = new AudioPolicy.Builder(mContext) 74 .addMix(mediaMix) 75 .setLooper(Looper.getMainLooper()) 76 .build(); 77 mAudioManager.registerAudioPolicy(audioPolicy); 78 dumpAudioPorts("policy set"); 79 mAudioManager.unregisterAudioPolicyAsync(audioPolicy); 80 ArrayList<AudioPort> afterUnregisterPorts = dumpAudioPorts("policy unset"); 81 mAudioManager.unregisterAudioPortUpdateListener(listener); 82 } 83 dumpAudioPorts(String msg)84 private ArrayList<AudioPort> dumpAudioPorts(String msg) { 85 Log.i(TAG, msg + ", dump audio ports"); 86 ArrayList<AudioPort> ports = new ArrayList<>(); 87 assertEquals(AudioManager.SUCCESS, AudioManager.listAudioPorts(ports)); 88 for (AudioPort port : ports) { 89 Log.i(TAG, "port:" + port.toString() + " name:" + port.name()); 90 } 91 return ports; 92 } 93 createAudioMix(int contentType, int usage)94 private static AudioMix createAudioMix(int contentType, int usage) { 95 AudioAttributes.Builder audioAttributesBuilder = new AudioAttributes.Builder(); 96 audioAttributesBuilder.setContentType(contentType).setUsage(usage); 97 AudioAttributes audioAttributes = audioAttributesBuilder.build(); 98 AudioFormat audioFormat = new AudioFormat.Builder() 99 .setEncoding(AudioFormat.ENCODING_PCM_16BIT) 100 .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO) 101 .setSampleRate(48000) 102 .build(); 103 AudioMixingRule audioMixingRule = new AudioMixingRule.Builder() 104 .addRule(audioAttributes, AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE) 105 .build(); 106 return new AudioMix.Builder(audioMixingRule) 107 .setFormat(audioFormat) 108 .build(); 109 } 110 111 private class AudioPortUpdateListener implements AudioManager.OnAudioPortUpdateListener { 112 113 @Override onAudioPortListUpdate(AudioPort[] portList)114 public void onAudioPortListUpdate(AudioPort[] portList) { 115 Log.i(TAG, "onAudioPortListUpdate"); 116 for (AudioPort port : portList) { 117 Log.i(TAG, "port:" + port.toString() + " name:" + port.name()); 118 } 119 } 120 121 @Override onAudioPatchListUpdate(AudioPatch[] patchList)122 public void onAudioPatchListUpdate(AudioPatch[] patchList) { 123 Log.i(TAG, "onAudioPortListUpdate"); 124 for (AudioPatch patch : patchList) { 125 Log.i(TAG, "patch:" + patch.toString()); 126 } 127 } 128 129 @Override onServiceDied()130 public void onServiceDied() { 131 } 132 } 133 } 134