diff options
Diffstat (limited to 'testapps/callaudiotest')
| -rw-r--r-- | testapps/callaudiotest/Android.bp | 31 | ||||
| -rw-r--r-- | testapps/callaudiotest/AndroidManifest.xml | 58 | ||||
| -rw-r--r-- | testapps/callaudiotest/res/layout/call_audio_test_activity.xml | 41 | ||||
| -rw-r--r-- | testapps/callaudiotest/res/raw/speech.m4a | bin | 0 -> 285126 bytes | |||
| -rw-r--r-- | testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestActivity.java | 61 | ||||
| -rw-r--r-- | testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestInCallService.java | 128 |
6 files changed, 319 insertions, 0 deletions
diff --git a/testapps/callaudiotest/Android.bp b/testapps/callaudiotest/Android.bp new file mode 100644 index 000000000..81164e6f4 --- /dev/null +++ b/testapps/callaudiotest/Android.bp @@ -0,0 +1,31 @@ +// +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_test { + name: "TelecomCallAudioTestApp", + static_libs: [ + "androidx.legacy_legacy-support-v4", + "guava", + ], + srcs: ["src/**/*.java"], + platform_apis: true, + certificate: "platform", + privileged: true, +} diff --git a/testapps/callaudiotest/AndroidManifest.xml b/testapps/callaudiotest/AndroidManifest.xml new file mode 100644 index 000000000..014ab2909 --- /dev/null +++ b/testapps/callaudiotest/AndroidManifest.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + coreApp="true" + package="com.android.server.telecom.callaudiotest"> + + <uses-sdk android:minSdkVersion="28" + android:targetSdkVersion="29"/> + <uses-permission android:name="android.permission.BLUETOOTH"/> + <uses-permission android:name="android.permission.CALL_PHONE"/> + <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"/> + <uses-permission android:name="android.permission.READ_CALL_LOG"/> + <uses-permission android:name="android.permission.READ_PHONE_STATE"/> + <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> + <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING"/> + <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/> + <uses-permission android:name="android.permission.WRITE_CALL_LOG"/> + + <application android:label="Telecom Call Audio Test"> + <uses-library android:name="android.test.runner"/> + + <service android:name="com.android.server.telecom.callaudiotest.CallAudioTestInCallService" + android:permission="android.permission.BIND_INCALL_SERVICE" + android:exported="true"> + <meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI" + android:value="false"/> + <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS" + android:value="false"/> + <intent-filter> + <action android:name="android.telecom.InCallService"/> + </intent-filter> + </service> + + <activity android:name="com.android.server.telecom.callaudiotest.CallAudioTestActivity" + android:label="Call Audio Test" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.DEFAULT"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/testapps/callaudiotest/res/layout/call_audio_test_activity.xml b/testapps/callaudiotest/res/layout/call_audio_test_activity.xml new file mode 100644 index 000000000..0d847f07a --- /dev/null +++ b/testapps/callaudiotest/res/layout/call_audio_test_activity.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" > + <TextView + android:id="@+id/appLabel" + android:layout_gravity="left" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="25dp" + android:text="Call Audio Testing" /> + <TextView + android:id="@+id/appDescription" + android:layout_gravity="left" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="12dp" + android:text="You can enabled auto answer and calls will be answered and some awesome audio will be looped to the caller." /> + <CheckBox + android:id="@+id/enableAutoAnswer" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Answer calls and loop audio" /> +</LinearLayout> diff --git a/testapps/callaudiotest/res/raw/speech.m4a b/testapps/callaudiotest/res/raw/speech.m4a Binary files differnew file mode 100644 index 000000000..4161ad694 --- /dev/null +++ b/testapps/callaudiotest/res/raw/speech.m4a diff --git a/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestActivity.java b/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestActivity.java new file mode 100644 index 000000000..b75a4989a --- /dev/null +++ b/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestActivity.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.telecom.callaudiotest; + +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.EditText; + +/** + * Activity to configure the auto answer behavior. + */ +public class CallAudioTestActivity extends Activity { + private static final int RESULT_PICK_FILE = 1; + public static final String AUDIO_TEST_PREFS = "audio_test_prefs"; + public static final String AUTO_ANSWER_ENABLED = "auto_answer_enabled"; + private CheckBox mEnable; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.call_audio_test_activity); + mEnable = findViewById(R.id.enableAutoAnswer); + mEnable.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SharedPreferences prefs = getSharedPreferences(AUDIO_TEST_PREFS, MODE_PRIVATE); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean(AUTO_ANSWER_ENABLED, isChecked); + edit.apply(); + } + }); + loadPreferences(); + } + + private void loadPreferences() { + SharedPreferences prefs = getSharedPreferences(AUDIO_TEST_PREFS, MODE_PRIVATE); + mEnable.setChecked(prefs.getBoolean(AUTO_ANSWER_ENABLED, false)); + } +} diff --git a/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestInCallService.java b/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestInCallService.java new file mode 100644 index 000000000..bd98a7f02 --- /dev/null +++ b/testapps/callaudiotest/src/com/android/server/telecom/callaudiotest/CallAudioTestInCallService.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server.telecom.callaudiotest; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.media.AudioAttributes; +import android.media.AudioDeviceInfo; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.net.Uri; +import android.os.IBinder; +import android.telecom.Call; +import android.telecom.InCallService; +import android.telecom.Log; +import android.telecom.VideoProfile; + +import java.io.IOException; +import java.lang.String; + +/** + * Simple test InCallService which answers a call automatically and plays back some looping audio. + * Intended for testing call audio between devices. + */ +public class CallAudioTestInCallService extends InCallService { + private Call mIncomingCall; + private boolean mIsAutoAnswerEnabled = false; + private MediaPlayer mMediaPlayer; + private Call.Callback mCallback = new Call.Callback() { + @Override + public void onStateChanged(Call call, int state) { + if (state == Call.STATE_ACTIVE) { + startPlaying(); + } + } + }; + + @Override + public IBinder onBind(Intent intent) { + SharedPreferences prefs = getSharedPreferences(CallAudioTestActivity.AUDIO_TEST_PREFS, + MODE_PRIVATE); + mIsAutoAnswerEnabled = prefs.getBoolean(CallAudioTestActivity.AUTO_ANSWER_ENABLED, false); + return super.onBind(intent); + } + + @Override + public void onCallAdded(Call call) { + if (!mIsAutoAnswerEnabled) { + Log.i(this, "onCallAdded - autoanswer disabled, skip"); + return; + } + if (call.getDetails().getState() == Call.STATE_RINGING) { + mIncomingCall = call; + mIncomingCall.registerCallback(mCallback); + mIncomingCall.answer(VideoProfile.STATE_AUDIO_ONLY); + + Log.i(this, "onCallAdded - ringing call"); + } else { + Log.i(this, "onCallAdded - nonringing call"); + } + } + + @Override + public void onCallRemoved(Call call) { + if (mIncomingCall == call) { + mIncomingCall = null; + if (mMediaPlayer != null) { + mMediaPlayer.stop(); + mMediaPlayer.release(); + } + } + } + + private void startPlaying() { + AudioDeviceInfo telephonyDevice = getTelephonyDevice(getSystemService(AudioManager.class)); + if (telephonyDevice != null) { + Log.i(this, "startPlaying: create player for speech"); + mMediaPlayer = new MediaPlayer(); + mMediaPlayer.setOnCompletionListener(mediaPlayer -> Log.w(this, "startPlaying: done")); + mMediaPlayer.setOnErrorListener( + (mediaPlayer, what, extra) -> { + Log.w(this, "startPlaying: playback failed!"); + return true; // Error handled + }); + mMediaPlayer.setLooping(true); + mMediaPlayer.setVolume(1.0f); + AudioAttributes audioAttributes = new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build(); + mMediaPlayer.setAudioAttributes(audioAttributes); + try { + mMediaPlayer.setDataSource(getResources().openRawResourceFd(R.raw.speech)); + mMediaPlayer.prepare(); + } catch (IOException e) { + mMediaPlayer.release(); + throw new IllegalStateException(e); + } + if (!mMediaPlayer.setPreferredDevice(telephonyDevice)) { + Log.w(this, "startPlaying: setPreferredDevice failed"); + } + mMediaPlayer.start(); + + } + } + + private AudioDeviceInfo getTelephonyDevice(AudioManager audioManager) { + AudioDeviceInfo[] deviceList = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS); + for (AudioDeviceInfo device: deviceList) { + if (device.getType() == AudioDeviceInfo.TYPE_TELEPHONY) { + return device; + } + } + return null; + } +} |
