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

Commit 7b2d15f4 authored by Hall Liu's avatar Hall Liu Committed by Android (Google) Code Review
Browse files

Merge "Improve implementation of call recording tone" into rvc-dev

parents 65fc44b7 481641d2
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -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",
@@ -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",
−99.3 KiB (5.14 KiB)

File changed.

No diff preview for this file type.

+2 −1
Original line number Original line 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;
        return mState == CallState.ACTIVE;
    }
    }


+65 −23
Original line number Original line Diff line number Diff line
@@ -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;


@@ -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
@@ -163,7 +216,7 @@ public class CallRecordingTonePlayer extends CallsManagerListenerBase {
     */
     */
    private void maybeStartCallAudioTone() {
    private void maybeStartCallAudioTone() {
        if (mIsRecording && hasActiveCall()) {
        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.
     * 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.");
        }
        }
    }
    }


@@ -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;
        }
        }
    }
    }


+2 −1
Original line number Original line Diff line number Diff line
@@ -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