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.cts.verifier.audio; 18 19 import static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode; 20 import static com.android.cts.verifier.TestListAdapter.setTestNameSuffix; 21 22 import android.media.AudioDeviceInfo; 23 import android.media.AudioManager; 24 import android.media.AudioTrack; 25 import android.os.Bundle; 26 import android.os.Handler; 27 import android.util.Log; 28 import android.widget.TextView; 29 30 import com.android.cts.verifier.R; 31 import com.android.cts.verifier.audio.audiolib.AudioDeviceUtils; 32 33 import org.hyphonate.megaaudio.common.BuilderBase; 34 import org.hyphonate.megaaudio.common.StreamBase; 35 import org.hyphonate.megaaudio.player.JavaPlayer; 36 import org.hyphonate.megaaudio.player.PlayerBuilder; 37 import org.hyphonate.megaaudio.player.sources.SilenceAudioSourceProvider; 38 39 /** 40 * Tests AudioTrack and AudioRecord (re)Routing messages. 41 */ 42 public class AudioOutputRoutingNotificationsActivity extends AudioNotificationsBaseActivity { 43 private static final String TAG = "AudioOutputRoutingNotificationsActivity"; 44 45 static final int NUM_CHANNELS = 2; 46 static final int SAMPLE_RATE = 48000; 47 48 int mNumRoutingNotifications; 49 50 // ignore messages sent as a consequence of starting the player 51 private static final int NUM_IGNORE_MESSAGES = 1; 52 53 // Mega Player 54 private JavaPlayer mAudioPlayer; 55 private AudioTrackRoutingChangeListener mRoutingChangeListener; 56 private boolean mIsPlaying; 57 58 private boolean mInitialRoutingMessageHandled; 59 60 // ReportLog schema 61 private static final String SECTION_OUTPUT_ROUTING = "audio_out_routing_notifications"; 62 AudioOutputRoutingNotificationsActivity()63 public AudioOutputRoutingNotificationsActivity() { 64 super(AudioManager.GET_DEVICES_OUTPUTS); 65 } 66 67 @Override onCreate(Bundle savedInstanceState)68 protected void onCreate(Bundle savedInstanceState) { 69 setContentView(R.layout.audio_routingnotifications_test); 70 super.onCreate(savedInstanceState); 71 72 ((TextView) findViewById(R.id.audio_routingnotification_instructions)) 73 .setText(getText(R.string.audio_output_routingnotification_instructions)); 74 75 // Setup Player 76 // 77 // Allocate the source provider for the sort of signal we want to play 78 // 79 int numExchangeFrames = StreamBase.getNumBurstFrames(BuilderBase.TYPE_NONE); 80 try { 81 PlayerBuilder builder = new PlayerBuilder(); 82 builder.setSourceProvider(new SilenceAudioSourceProvider()) 83 .setPlayerType(PlayerBuilder.TYPE_JAVA) 84 .setChannelCount(NUM_CHANNELS) 85 .setSampleRate(SAMPLE_RATE) 86 .setNumExchangeFrames(numExchangeFrames); 87 mAudioPlayer = (JavaPlayer) builder.build(); 88 } catch (PlayerBuilder.BadStateException ex) { 89 Log.e(TAG, "Failed MegaPlayer build."); 90 } 91 92 setInfoResources(R.string.audio_output_routingnotifications_test, 93 R.string.audio_output_routingnotification_instructions, -1); 94 95 mRoutingChangeListener = new AudioTrackRoutingChangeListener(); 96 97 startAudio(); 98 } 99 100 @Override startAudio()101 void startAudio() { 102 if (mAudioPlayer == null) { 103 return; // failed to create the player 104 } 105 if (!mIsPlaying) { 106 mNumRoutingNotifications = 0; 107 108 mAudioPlayer.startStream(); 109 110 AudioTrack audioTrack = mAudioPlayer.getAudioTrack(); 111 audioTrack.addOnRoutingChangedListener(mRoutingChangeListener, 112 new Handler()); 113 114 mIsPlaying = true; 115 } 116 } 117 118 @Override stopAudio()119 void stopAudio() { 120 if (mAudioPlayer == null) { 121 return; // failed to create the player 122 } 123 if (mIsPlaying) { 124 mAudioPlayer.stopStream(); 125 126 AudioTrack audioTrack = mAudioPlayer.getAudioTrack(); 127 audioTrack.removeOnRoutingChangedListener(mRoutingChangeListener); 128 129 mIsPlaying = false; 130 } 131 } 132 133 private class AudioTrackRoutingChangeListener implements AudioTrack.OnRoutingChangedListener { onRoutingChanged(AudioTrack audioTrack)134 public void onRoutingChanged(AudioTrack audioTrack) { 135 // Starting playback triggers a message, so ignore the first one. 136 mNumRoutingNotifications++; 137 if (mNumRoutingNotifications <= NUM_IGNORE_MESSAGES) { 138 return; 139 } 140 141 TextView textView = 142 (TextView) findViewById(R.id.audio_routingnotification_change); 143 String msg = mContext.getString( 144 R.string.audio_routingnotification_trackRoutingMsg); 145 AudioDeviceInfo routedDevice = audioTrack.getRoutedDevice(); 146 mConnectedPeripheralName = AudioDeviceUtils.formatDeviceName(routedDevice); 147 textView.setText(msg + ": " + mConnectedPeripheralName); 148 mRoutingNotificationReceived = true; 149 stopAudio(); 150 calculatePass(); 151 } 152 } 153 154 @Override getReportSectionName()155 public final String getReportSectionName() { 156 return setTestNameSuffix(sCurrentDisplayMode, SECTION_OUTPUT_ROUTING); 157 } 158 } 159