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