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