Loading Android.bp +5 −2 Original line number Original line Diff line number Diff line Loading @@ -41,7 +41,7 @@ android_test { static_libs: [ static_libs: [ "android-ex-camera2", "android-ex-camera2", "guava", "guava", "mockito-target-inline", "mockito-target-extended", "androidx.test.rules", "androidx.test.rules", "platform-test-annotations", "platform-test-annotations", "androidx.legacy_legacy-support-core-ui", "androidx.legacy_legacy-support-core-ui", Loading Loading @@ -70,7 +70,10 @@ android_test { "android.test.runner", "android.test.runner", ], ], jni_libs: ["libdexmakerjvmtiagent"], jni_libs: [ "libdexmakerjvmtiagent", "libstaticjvmtiagent", ], aaptflags: [ aaptflags: [ "--auto-add-overlay", "--auto-add-overlay", Loading res/raw/record.ogg −99.3 KiB (5.14 KiB) File changed.No diff preview for this file type. View original file View changed file src/com/android/server/telecom/Call.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -2569,7 +2569,8 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, } } } } boolean isActive() { @VisibleForTesting public boolean isActive() { return mState == CallState.ACTIVE; return mState == CallState.ACTIVE; } } Loading src/com/android/server/telecom/CallRecordingTonePlayer.java +65 −23 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.media.AudioRecordingConfiguration; import android.media.MediaPlayer; import android.media.MediaPlayer; import android.os.Handler; import android.os.Handler; import android.os.Looper; import android.os.Looper; import android.os.Message; import android.provider.MediaStore; import android.provider.MediaStore; import android.telecom.Log; import android.telecom.Log; Loading Loading @@ -61,19 +62,71 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase { } } }; }; private class LoopingTonePlayer extends Handler { private Runnable mPlayToneRunnable = new Runnable() { @Override public void run() { if (mRecordingTonePlayer != null) { mRecordingTonePlayer.start(); postDelayed(this, mRepeatInterval); } } }; private MediaPlayer mRecordingTonePlayer = null; LoopingTonePlayer() { // We're using the main looper here to avoid creating more threads and risking a thread // leak. The actual playing of the tone doesn't take up much time on the calling // thread, so it's okay to use the main thread for this. super(Looper.getMainLooper()); } private boolean start() { if (mRecordingTonePlayer != null) { Log.w(CallRecordingTonePlayer.this, "Can't start looping tone player more than" + " once"); return false; } AudioDeviceInfo telephonyDevice = getTelephonyDevice(mAudioManager); if (telephonyDevice != null) { mRecordingTonePlayer = MediaPlayer.create(mContext, R.raw.record); mRecordingTonePlayer.setPreferredDevice(telephonyDevice); mRecordingTonePlayer.setVolume(0.1f); AudioAttributes audioAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build(); mRecordingTonePlayer.setAudioAttributes(audioAttributes); post(mPlayToneRunnable); return true; } else { Log.w(this ,"startCallRecordingTone: can't find telephony audio device."); return false; } } private void stop() { mRecordingTonePlayer.release(); mRecordingTonePlayer = null; } } private final AudioManager mAudioManager; private final AudioManager mAudioManager; private final Context mContext; private final Context mContext; private final TelecomSystem.SyncRoot mLock; private final TelecomSystem.SyncRoot mLock; private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper()); private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper()); private final long mRepeatInterval; private boolean mIsRecording = false; private boolean mIsRecording = false; private MediaPlayer mRecordingTonePlayer = null; private LoopingTonePlayer mLoopingTonePlayer; private List<Call> mCalls = new ArrayList<>(); private List<Call> mCalls = new ArrayList<>(); public CallRecordingTonePlayer(Context context, AudioManager audioManager, public CallRecordingTonePlayer(Context context, AudioManager audioManager, Timeouts.Adapter timeouts, TelecomSystem.SyncRoot lock) { TelecomSystem.SyncRoot lock) { mContext = context; mContext = context; mAudioManager = audioManager; mAudioManager = audioManager; mLock = lock; mLock = lock; mRepeatInterval = timeouts.getCallRecordingToneRepeatIntervalMillis( context.getContentResolver()); } } @Override @Override Loading Loading @@ -163,7 +216,7 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase { */ */ private void maybeStartCallAudioTone() { private void maybeStartCallAudioTone() { if (mIsRecording && hasActiveCall()) { if (mIsRecording && hasActiveCall()) { startCallRecordingTone(mContext); startCallRecordingTone(); } } } } Loading Loading @@ -231,26 +284,15 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase { * Begins playing the call recording tone to the remote end of the call. * Begins playing the call recording tone to the remote end of the call. * The call recording tone is played via the telephony audio output device; this means that it * The call recording tone is played via the telephony audio output device; this means that it * will only be audible to the remote end of the call, not the local side. * will only be audible to the remote end of the call, not the local side. * * @param context required for obtaining media player. */ */ private void startCallRecordingTone(Context context) { private void startCallRecordingTone() { if (mRecordingTonePlayer != null) { if (mLoopingTonePlayer != null) { Log.w(this, "Tone is already playing"); return; return; } } AudioDeviceInfo telephonyDevice = getTelephonyDevice(mAudioManager); mLoopingTonePlayer = new LoopingTonePlayer(); if (telephonyDevice != null) { if (!mLoopingTonePlayer.start()) { Log.i(this ,"startCallRecordingTone: playing call recording tone to remote end."); mLoopingTonePlayer = null; mRecordingTonePlayer = MediaPlayer.create(context, R.raw.record); mRecordingTonePlayer.setLooping(true); mRecordingTonePlayer.setPreferredDevice(telephonyDevice); mRecordingTonePlayer.setVolume(0.1f); AudioAttributes audioAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build(); mRecordingTonePlayer.setAudioAttributes(audioAttributes); mRecordingTonePlayer.start(); } else { Log.w(this ,"startCallRecordingTone: can't find telephony audio device."); } } } } Loading @@ -258,10 +300,10 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase { * Attempts to stop the call recording tone if it is playing. * Attempts to stop the call recording tone if it is playing. */ */ private void stopCallRecordingTone() { private void stopCallRecordingTone() { if (mRecordingTonePlayer != null) { if (mLoopingTonePlayer != null) { Log.i(this, "stopCallRecordingTone: stopping call recording tone."); Log.i(this, "stopCallRecordingTone: stopping call recording tone."); mRecordingTonePlayer.stop(); mLoopingTonePlayer.stop(); mRecordingTonePlayer = null; mLoopingTonePlayer = null; } } } } Loading src/com/android/server/telecom/CallsManager.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -543,7 +543,8 @@ public class CallsManager extends Call.ListenerBase mRinger = new Ringer(playerFactory, context, systemSettingsUtil, asyncRingtonePlayer, mRinger = new Ringer(playerFactory, context, systemSettingsUtil, asyncRingtonePlayer, ringtoneFactory, systemVibrator, ringtoneFactory, systemVibrator, new Ringer.VibrationEffectProxy(), mInCallController); new Ringer.VibrationEffectProxy(), mInCallController); mCallRecordingTonePlayer = new CallRecordingTonePlayer(mContext, audioManager, mLock); mCallRecordingTonePlayer = new CallRecordingTonePlayer(mContext, audioManager, mTimeoutsAdapter, mLock); mCallAudioManager = new CallAudioManager(callAudioRouteStateMachine, mCallAudioManager = new CallAudioManager(callAudioRouteStateMachine, this, callAudioModeStateMachineFactory.create(systemStateHelper, this, callAudioModeStateMachineFactory.create(systemStateHelper, (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE)), (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE)), Loading Loading
Android.bp +5 −2 Original line number Original line Diff line number Diff line Loading @@ -41,7 +41,7 @@ android_test { static_libs: [ static_libs: [ "android-ex-camera2", "android-ex-camera2", "guava", "guava", "mockito-target-inline", "mockito-target-extended", "androidx.test.rules", "androidx.test.rules", "platform-test-annotations", "platform-test-annotations", "androidx.legacy_legacy-support-core-ui", "androidx.legacy_legacy-support-core-ui", Loading Loading @@ -70,7 +70,10 @@ android_test { "android.test.runner", "android.test.runner", ], ], jni_libs: ["libdexmakerjvmtiagent"], jni_libs: [ "libdexmakerjvmtiagent", "libstaticjvmtiagent", ], aaptflags: [ aaptflags: [ "--auto-add-overlay", "--auto-add-overlay", Loading
res/raw/record.ogg −99.3 KiB (5.14 KiB) File changed.No diff preview for this file type. View original file View changed file
src/com/android/server/telecom/Call.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -2569,7 +2569,8 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, } } } } boolean isActive() { @VisibleForTesting public boolean isActive() { return mState == CallState.ACTIVE; return mState == CallState.ACTIVE; } } Loading
src/com/android/server/telecom/CallRecordingTonePlayer.java +65 −23 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.media.AudioRecordingConfiguration; import android.media.MediaPlayer; import android.media.MediaPlayer; import android.os.Handler; import android.os.Handler; import android.os.Looper; import android.os.Looper; import android.os.Message; import android.provider.MediaStore; import android.provider.MediaStore; import android.telecom.Log; import android.telecom.Log; Loading Loading @@ -61,19 +62,71 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase { } } }; }; private class LoopingTonePlayer extends Handler { private Runnable mPlayToneRunnable = new Runnable() { @Override public void run() { if (mRecordingTonePlayer != null) { mRecordingTonePlayer.start(); postDelayed(this, mRepeatInterval); } } }; private MediaPlayer mRecordingTonePlayer = null; LoopingTonePlayer() { // We're using the main looper here to avoid creating more threads and risking a thread // leak. The actual playing of the tone doesn't take up much time on the calling // thread, so it's okay to use the main thread for this. super(Looper.getMainLooper()); } private boolean start() { if (mRecordingTonePlayer != null) { Log.w(CallRecordingTonePlayer.this, "Can't start looping tone player more than" + " once"); return false; } AudioDeviceInfo telephonyDevice = getTelephonyDevice(mAudioManager); if (telephonyDevice != null) { mRecordingTonePlayer = MediaPlayer.create(mContext, R.raw.record); mRecordingTonePlayer.setPreferredDevice(telephonyDevice); mRecordingTonePlayer.setVolume(0.1f); AudioAttributes audioAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build(); mRecordingTonePlayer.setAudioAttributes(audioAttributes); post(mPlayToneRunnable); return true; } else { Log.w(this ,"startCallRecordingTone: can't find telephony audio device."); return false; } } private void stop() { mRecordingTonePlayer.release(); mRecordingTonePlayer = null; } } private final AudioManager mAudioManager; private final AudioManager mAudioManager; private final Context mContext; private final Context mContext; private final TelecomSystem.SyncRoot mLock; private final TelecomSystem.SyncRoot mLock; private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper()); private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper()); private final long mRepeatInterval; private boolean mIsRecording = false; private boolean mIsRecording = false; private MediaPlayer mRecordingTonePlayer = null; private LoopingTonePlayer mLoopingTonePlayer; private List<Call> mCalls = new ArrayList<>(); private List<Call> mCalls = new ArrayList<>(); public CallRecordingTonePlayer(Context context, AudioManager audioManager, public CallRecordingTonePlayer(Context context, AudioManager audioManager, Timeouts.Adapter timeouts, TelecomSystem.SyncRoot lock) { TelecomSystem.SyncRoot lock) { mContext = context; mContext = context; mAudioManager = audioManager; mAudioManager = audioManager; mLock = lock; mLock = lock; mRepeatInterval = timeouts.getCallRecordingToneRepeatIntervalMillis( context.getContentResolver()); } } @Override @Override Loading Loading @@ -163,7 +216,7 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase { */ */ private void maybeStartCallAudioTone() { private void maybeStartCallAudioTone() { if (mIsRecording && hasActiveCall()) { if (mIsRecording && hasActiveCall()) { startCallRecordingTone(mContext); startCallRecordingTone(); } } } } Loading Loading @@ -231,26 +284,15 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase { * Begins playing the call recording tone to the remote end of the call. * Begins playing the call recording tone to the remote end of the call. * The call recording tone is played via the telephony audio output device; this means that it * The call recording tone is played via the telephony audio output device; this means that it * will only be audible to the remote end of the call, not the local side. * will only be audible to the remote end of the call, not the local side. * * @param context required for obtaining media player. */ */ private void startCallRecordingTone(Context context) { private void startCallRecordingTone() { if (mRecordingTonePlayer != null) { if (mLoopingTonePlayer != null) { Log.w(this, "Tone is already playing"); return; return; } } AudioDeviceInfo telephonyDevice = getTelephonyDevice(mAudioManager); mLoopingTonePlayer = new LoopingTonePlayer(); if (telephonyDevice != null) { if (!mLoopingTonePlayer.start()) { Log.i(this ,"startCallRecordingTone: playing call recording tone to remote end."); mLoopingTonePlayer = null; mRecordingTonePlayer = MediaPlayer.create(context, R.raw.record); mRecordingTonePlayer.setLooping(true); mRecordingTonePlayer.setPreferredDevice(telephonyDevice); mRecordingTonePlayer.setVolume(0.1f); AudioAttributes audioAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build(); mRecordingTonePlayer.setAudioAttributes(audioAttributes); mRecordingTonePlayer.start(); } else { Log.w(this ,"startCallRecordingTone: can't find telephony audio device."); } } } } Loading @@ -258,10 +300,10 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase { * Attempts to stop the call recording tone if it is playing. * Attempts to stop the call recording tone if it is playing. */ */ private void stopCallRecordingTone() { private void stopCallRecordingTone() { if (mRecordingTonePlayer != null) { if (mLoopingTonePlayer != null) { Log.i(this, "stopCallRecordingTone: stopping call recording tone."); Log.i(this, "stopCallRecordingTone: stopping call recording tone."); mRecordingTonePlayer.stop(); mLoopingTonePlayer.stop(); mRecordingTonePlayer = null; mLoopingTonePlayer = null; } } } } Loading
src/com/android/server/telecom/CallsManager.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -543,7 +543,8 @@ public class CallsManager extends Call.ListenerBase mRinger = new Ringer(playerFactory, context, systemSettingsUtil, asyncRingtonePlayer, mRinger = new Ringer(playerFactory, context, systemSettingsUtil, asyncRingtonePlayer, ringtoneFactory, systemVibrator, ringtoneFactory, systemVibrator, new Ringer.VibrationEffectProxy(), mInCallController); new Ringer.VibrationEffectProxy(), mInCallController); mCallRecordingTonePlayer = new CallRecordingTonePlayer(mContext, audioManager, mLock); mCallRecordingTonePlayer = new CallRecordingTonePlayer(mContext, audioManager, mTimeoutsAdapter, mLock); mCallAudioManager = new CallAudioManager(callAudioRouteStateMachine, mCallAudioManager = new CallAudioManager(callAudioRouteStateMachine, this, callAudioModeStateMachineFactory.create(systemStateHelper, this, callAudioModeStateMachineFactory.create(systemStateHelper, (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE)), (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE)), Loading