1 /* 2 * Copyright (C) 2021 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.server.telecom.callaudiotest; 18 19 import android.content.Intent; 20 import android.content.SharedPreferences; 21 import android.media.AudioAttributes; 22 import android.media.AudioDeviceInfo; 23 import android.media.AudioManager; 24 import android.media.MediaPlayer; 25 import android.net.Uri; 26 import android.os.IBinder; 27 import android.telecom.Call; 28 import android.telecom.InCallService; 29 import android.telecom.Log; 30 import android.telecom.VideoProfile; 31 32 import java.io.IOException; 33 import java.lang.String; 34 35 /** 36 * Simple test InCallService which answers a call automatically and plays back some looping audio. 37 * Intended for testing call audio between devices. 38 */ 39 public class CallAudioTestInCallService extends InCallService { 40 private Call mIncomingCall; 41 private boolean mIsAutoAnswerEnabled = false; 42 private MediaPlayer mMediaPlayer; 43 private Call.Callback mCallback = new Call.Callback() { 44 @Override 45 public void onStateChanged(Call call, int state) { 46 if (state == Call.STATE_ACTIVE) { 47 startPlaying(); 48 } 49 } 50 }; 51 52 @Override onBind(Intent intent)53 public IBinder onBind(Intent intent) { 54 SharedPreferences prefs = getSharedPreferences(CallAudioTestActivity.AUDIO_TEST_PREFS, 55 MODE_PRIVATE); 56 mIsAutoAnswerEnabled = prefs.getBoolean(CallAudioTestActivity.AUTO_ANSWER_ENABLED, false); 57 return super.onBind(intent); 58 } 59 60 @Override onCallAdded(Call call)61 public void onCallAdded(Call call) { 62 if (!mIsAutoAnswerEnabled) { 63 Log.i(this, "onCallAdded - autoanswer disabled, skip"); 64 return; 65 } 66 if (call.getDetails().getState() == Call.STATE_RINGING) { 67 mIncomingCall = call; 68 mIncomingCall.registerCallback(mCallback); 69 mIncomingCall.answer(VideoProfile.STATE_AUDIO_ONLY); 70 71 Log.i(this, "onCallAdded - ringing call"); 72 } else { 73 Log.i(this, "onCallAdded - nonringing call"); 74 } 75 } 76 77 @Override onCallRemoved(Call call)78 public void onCallRemoved(Call call) { 79 if (mIncomingCall == call) { 80 mIncomingCall = null; 81 if (mMediaPlayer != null) { 82 mMediaPlayer.stop(); 83 mMediaPlayer.release(); 84 } 85 } 86 } 87 startPlaying()88 private void startPlaying() { 89 AudioDeviceInfo telephonyDevice = getTelephonyDevice(getSystemService(AudioManager.class)); 90 if (telephonyDevice != null) { 91 Log.i(this, "startPlaying: create player for speech"); 92 mMediaPlayer = new MediaPlayer(); 93 mMediaPlayer.setOnCompletionListener(mediaPlayer -> Log.w(this, "startPlaying: done")); 94 mMediaPlayer.setOnErrorListener( 95 (mediaPlayer, what, extra) -> { 96 Log.w(this, "startPlaying: playback failed!"); 97 return true; // Error handled 98 }); 99 mMediaPlayer.setLooping(true); 100 mMediaPlayer.setVolume(1.0f); 101 AudioAttributes audioAttributes = new AudioAttributes.Builder() 102 .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build(); 103 mMediaPlayer.setAudioAttributes(audioAttributes); 104 try { 105 mMediaPlayer.setDataSource(getResources().openRawResourceFd(R.raw.speech)); 106 mMediaPlayer.prepare(); 107 } catch (IOException e) { 108 mMediaPlayer.release(); 109 throw new IllegalStateException(e); 110 } 111 if (!mMediaPlayer.setPreferredDevice(telephonyDevice)) { 112 Log.w(this, "startPlaying: setPreferredDevice failed"); 113 } 114 mMediaPlayer.start(); 115 116 } 117 } 118 getTelephonyDevice(AudioManager audioManager)119 private AudioDeviceInfo getTelephonyDevice(AudioManager audioManager) { 120 AudioDeviceInfo[] deviceList = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS); 121 for (AudioDeviceInfo device: deviceList) { 122 if (device.getType() == AudioDeviceInfo.TYPE_TELEPHONY) { 123 return device; 124 } 125 } 126 return null; 127 } 128 } 129