1 /* 2 * Copyright (C) 2017 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.telecom; 18 19 import android.content.Context; 20 import android.media.AudioAttributes; 21 import android.media.AudioManager; 22 import android.media.MediaPlayer; 23 import android.telecom.CallAudioState; 24 import android.telecom.Connection; 25 import android.telecom.DisconnectCause; 26 import android.telecom.VideoProfile; 27 28 import com.android.cts.verifier.R; 29 30 import java.util.concurrent.CountDownLatch; 31 import java.util.concurrent.TimeUnit; 32 33 /** 34 * An implementation of the {@link android.telecom.Connection} class used by the 35 * {@link CtsConnectionService}. 36 */ 37 public class CtsConnection extends Connection { 38 /** 39 * Listener used to inform the CtsVerifier app of changes to a connection. 40 */ 41 public static abstract class Listener { onDestroyed(CtsConnection connection)42 void onDestroyed(CtsConnection connection) { }; onDisconnect(CtsConnection connection)43 void onDisconnect(CtsConnection connection) { }; onHold(CtsConnection connection)44 void onHold(CtsConnection connection) { }; onUnhold(CtsConnection connection)45 void onUnhold(CtsConnection connection) { }; onAnswer(CtsConnection connection, int videoState)46 void onAnswer(CtsConnection connection, int videoState) { }; onReject(CtsConnection connection)47 void onReject(CtsConnection connection) { }; onShowIncomingCallUi(CtsConnection connection)48 void onShowIncomingCallUi(CtsConnection connection) { }; 49 } 50 51 public static final String EXTRA_PLAY_CS_AUDIO = 52 "com.android.cts.verifier.telecom.PLAY_CS_AUDIO"; 53 54 private final boolean mIsIncomingCall; 55 private final Listener mListener; 56 private final MediaPlayer mMediaPlayer; 57 private final Context mContext; 58 private CountDownLatch mWaitForCallAudioStateChanged = new CountDownLatch(1); 59 CtsConnection(Context context, boolean isIncomingCall, Listener listener, boolean hasAudio)60 public CtsConnection(Context context, boolean isIncomingCall, 61 Listener listener, boolean hasAudio) { 62 mContext = context; 63 mIsIncomingCall = isIncomingCall; 64 mListener = listener; 65 if (hasAudio) { 66 mMediaPlayer = createMediaPlayer(); 67 } else { 68 mMediaPlayer = null; 69 } 70 } 71 isIncomingCall()72 public boolean isIncomingCall() { 73 return mIsIncomingCall; 74 } 75 76 @Override onDisconnect()77 public void onDisconnect() { 78 setDisconnectedAndDestroy(new DisconnectCause(DisconnectCause.LOCAL)); 79 80 if (mListener != null) { 81 mListener.onDisconnect(this); 82 } 83 } 84 85 86 @Override onHold()87 public void onHold() { 88 setOnHold(); 89 90 if (mListener != null) { 91 mListener.onHold(this); 92 } 93 } 94 95 @Override onUnhold()96 public void onUnhold() { 97 setActive(); 98 99 if (mListener != null) { 100 mListener.onUnhold(this); 101 } 102 } 103 104 @Override onAnswer(int videoState)105 public void onAnswer(int videoState) { 106 setVideoState(videoState); 107 setActive(); 108 109 if (mMediaPlayer != null && !mMediaPlayer.isPlaying()) { 110 mMediaPlayer.start(); 111 } 112 113 if (mListener != null) { 114 mListener.onAnswer(this, videoState); 115 } 116 } 117 118 @Override onAnswer()119 public void onAnswer() { 120 onAnswer(VideoProfile.STATE_AUDIO_ONLY); 121 } 122 123 @Override onReject()124 public void onReject() { 125 setDisconnectedAndDestroy(new DisconnectCause(DisconnectCause.REJECTED)); 126 127 if (mListener != null) { 128 mListener.onReject(this); 129 } 130 } 131 132 @Override onShowIncomingCallUi()133 public void onShowIncomingCallUi() { 134 if (mListener != null) { 135 mListener.onShowIncomingCallUi(this); 136 } 137 } 138 onCallAudioStateChanged(CallAudioState state)139 public void onCallAudioStateChanged(CallAudioState state) { 140 mWaitForCallAudioStateChanged.countDown(); 141 mWaitForCallAudioStateChanged = new CountDownLatch(1); 142 143 } 144 waitForAudioStateChanged()145 public void waitForAudioStateChanged() { 146 try { 147 mWaitForCallAudioStateChanged.await(CtsConnectionService.TIMEOUT_MILLIS, 148 TimeUnit.MILLISECONDS); 149 } catch (InterruptedException e) { 150 } 151 } 152 setDisconnectedAndDestroy(DisconnectCause cause)153 private void setDisconnectedAndDestroy(DisconnectCause cause) { 154 setDisconnected(cause); 155 destroy(); 156 157 if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { 158 mMediaPlayer.stop(); 159 } 160 161 if (mListener != null) { 162 mListener.onDestroyed(this); 163 } 164 } 165 createMediaPlayer()166 private MediaPlayer createMediaPlayer() { 167 AudioAttributes voiceCallAttributes = new AudioAttributes.Builder() 168 .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) 169 .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) 170 .build(); 171 int audioSessionId = ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE)) 172 .generateAudioSessionId(); 173 // Prepare the media player to play a tone when there is a call. 174 MediaPlayer mediaPlayer = MediaPlayer.create(mContext, R.raw.telecom_test_call_audio, 175 voiceCallAttributes, audioSessionId); 176 mediaPlayer.setLooping(true); 177 return mediaPlayer; 178 } 179 } 180