Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4824da4 authored by Hall Liu's avatar Hall Liu Committed by Automerger Merge Worker
Browse files

Merge "Improve implementation of call recording tone" into rvc-dev am: 7b2d15f4 am: e7a4b1dc

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/services/Telecomm/+/11829040

Change-Id: I4f20f11c6d3b990d9eb0beb1d44008f47edb20df
parents 8a641540 e7a4b1dc
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ android_test {
    static_libs: [
        "android-ex-camera2",
        "guava",
        "mockito-target-inline",
        "mockito-target-extended",
        "androidx.test.rules",
        "platform-test-annotations",
        "androidx.legacy_legacy-support-core-ui",
@@ -70,7 +70,10 @@ android_test {
        "android.test.runner",
    ],

    jni_libs: ["libdexmakerjvmtiagent"],
    jni_libs: [
        "libdexmakerjvmtiagent",
        "libstaticjvmtiagent",
    ],

    aaptflags: [
        "--auto-add-overlay",
−99.3 KiB (5.14 KiB)

File changed.

No diff preview for this file type.

+2 −1
Original line number Diff line number Diff line
@@ -2569,7 +2569,8 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        }
    }

    boolean isActive() {
    @VisibleForTesting
    public boolean isActive() {
        return mState == CallState.ACTIVE;
    }

+65 −23
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.media.AudioRecordingConfiguration;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.MediaStore;
import android.telecom.Log;

@@ -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 Context mContext;
    private final TelecomSystem.SyncRoot mLock;
    private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
    private final long mRepeatInterval;
    private boolean mIsRecording = false;
    private MediaPlayer mRecordingTonePlayer = null;
    private LoopingTonePlayer mLoopingTonePlayer;
    private List<Call> mCalls = new ArrayList<>();

    public CallRecordingTonePlayer(Context context, AudioManager audioManager,
            Timeouts.Adapter timeouts,
            TelecomSystem.SyncRoot lock) {
        mContext = context;
        mAudioManager = audioManager;
        mLock = lock;
        mRepeatInterval = timeouts.getCallRecordingToneRepeatIntervalMillis(
                context.getContentResolver());
    }

    @Override
@@ -163,7 +216,7 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase {
     */
    private void maybeStartCallAudioTone() {
        if (mIsRecording && hasActiveCall()) {
            startCallRecordingTone(mContext);
            startCallRecordingTone();
        }
    }

@@ -231,26 +284,15 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase {
     * 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
     * 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) {
        if (mRecordingTonePlayer != null) {
    private void startCallRecordingTone() {
        if (mLoopingTonePlayer != null) {
            Log.w(this, "Tone is already playing");
            return;
        }
        AudioDeviceInfo telephonyDevice = getTelephonyDevice(mAudioManager);
        if (telephonyDevice != null) {
            Log.i(this ,"startCallRecordingTone: playing call recording tone to remote end.");
            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.");
        mLoopingTonePlayer = new LoopingTonePlayer();
        if (!mLoopingTonePlayer.start()) {
            mLoopingTonePlayer = null;
        }
    }

@@ -258,10 +300,10 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase {
     * Attempts to stop the call recording tone if it is playing.
     */
    private void stopCallRecordingTone() {
        if (mRecordingTonePlayer != null) {
        if (mLoopingTonePlayer != null) {
            Log.i(this, "stopCallRecordingTone: stopping call recording tone.");
            mRecordingTonePlayer.stop();
            mRecordingTonePlayer = null;
            mLoopingTonePlayer.stop();
            mLoopingTonePlayer = null;
        }
    }

+2 −1
Original line number Diff line number Diff line
@@ -543,7 +543,8 @@ public class CallsManager extends Call.ListenerBase
        mRinger = new Ringer(playerFactory, context, systemSettingsUtil, asyncRingtonePlayer,
                ringtoneFactory, systemVibrator,
                new Ringer.VibrationEffectProxy(), mInCallController);
        mCallRecordingTonePlayer = new CallRecordingTonePlayer(mContext, audioManager, mLock);
        mCallRecordingTonePlayer = new CallRecordingTonePlayer(mContext, audioManager,
                mTimeoutsAdapter, mLock);
        mCallAudioManager = new CallAudioManager(callAudioRouteStateMachine,
                this, callAudioModeStateMachineFactory.create(systemStateHelper,
                (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE)),
Loading