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