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

Commit b09b9292 authored by Danny Baumann's avatar Danny Baumann
Browse files

Fix ringing audio focus handling.

Test case:
- enable increasing ringtone starting at volume 0
- start any music player
- get an incoming call

Previous behaviour:
When ringtone volume is increased from 0 to 1, music continues playing
even
though ring tone is playing as well.

New behaviour:
When ringtone starts, music is attenuated to make user aware of incoming
call. When ringtone volume is increased to 1, music stops playing.

Change-Id: Ifc32ea162d4527572be0574024116d10ee9bca66
parent c08256a1
Loading
Loading
Loading
Loading
+48 −13
Original line number Diff line number Diff line
@@ -18,7 +18,10 @@ package com.android.internal.telephony;

import com.android.internal.telephony.sip.SipPhone;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.AsyncResult;
import android.os.Handler;
@@ -170,6 +173,20 @@ public final class CallManager {
    protected final RegistrantList mPostDialCharacterRegistrants
    = new RegistrantList();

    private BroadcastReceiver mRingVolumeChangeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
            if (getState() == PhoneConstants.State.RINGING && streamType == AudioManager.STREAM_RING) {
                int oldVolume = intent.getIntExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, -1);
                int newVolume = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
                if (oldVolume == 0 || newVolume == 0) {
                    updateRingingAudioFocus(context);
                }
            }
        }
    };

    private CallManager() {
        mPhones = new ArrayList<Phone>();
        mRingingCalls = new ArrayList<Call>();
@@ -378,25 +395,21 @@ public final class CallManager {
        if (context == null) return;
        AudioManager audioManager = (AudioManager)
                context.getSystemService(Context.AUDIO_SERVICE);
        PhoneConstants.State state = getState();
        int lastAudioMode = audioManager.getMode();

        // change the audio mode and request/abandon audio focus according to phone state,
        // but only on audio mode transitions
        switch (getState()) {
        switch (state) {
            case RINGING:
                int curAudioMode = audioManager.getMode();
                if (curAudioMode != AudioManager.MODE_RINGTONE) {
                    // only request audio focus if the ringtone is going to be heard
                    if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
                        if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING");
                        audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING,
                                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
                    }
                if (lastAudioMode != AudioManager.MODE_RINGTONE) {
                    updateRingingAudioFocus(context);
                    if (!mSpeedUpAudioForMtCall) {
                        audioManager.setMode(AudioManager.MODE_RINGTONE);
                    }
                }

                if (mSpeedUpAudioForMtCall && (curAudioMode != AudioManager.MODE_IN_CALL)) {
                if (mSpeedUpAudioForMtCall && lastAudioMode != AudioManager.MODE_IN_CALL) {
                    audioManager.setMode(AudioManager.MODE_IN_CALL);
                }
                break;
@@ -413,7 +426,7 @@ public final class CallManager {
                    // enable IN_COMMUNICATION audio mode instead for sipPhone
                    newAudioMode = AudioManager.MODE_IN_COMMUNICATION;
                }
                if (audioManager.getMode() != newAudioMode || mSpeedUpAudioForMtCall) {
                if (lastAudioMode != newAudioMode || mSpeedUpAudioForMtCall) {
                    // request audio focus before setting the new mode
                    if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL");
                    audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL,
@@ -423,7 +436,7 @@ public final class CallManager {
                mSpeedUpAudioForMtCall = false;
                break;
            case IDLE:
                if (audioManager.getMode() != AudioManager.MODE_NORMAL) {
                if (lastAudioMode != AudioManager.MODE_NORMAL) {
                    audioManager.setMode(AudioManager.MODE_NORMAL);
                    if (VDBG) Log.d(LOG_TAG, "abandonAudioFocus");
                    // abandon audio focus after the mode has been set back to normal
@@ -432,6 +445,28 @@ public final class CallManager {
                mSpeedUpAudioForMtCall = false;
                break;
        }

        if (state == PhoneConstants.State.RINGING && lastAudioMode != AudioManager.MODE_RINGTONE) {
            context.registerReceiver(mRingVolumeChangeReceiver,
                    new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
        } else if (state != PhoneConstants.State.RINGING && lastAudioMode == AudioManager.MODE_RINGTONE) {
            context.unregisterReceiver(mRingVolumeChangeReceiver);
        }
    }

    private void updateRingingAudioFocus(Context context) {
        AudioManager audioManager = (AudioManager)
                context.getSystemService(Context.AUDIO_SERVICE);
        int hint = audioManager.getStreamVolume(AudioManager.STREAM_RING) == 0
                // make user aware of an incoming call by
                // attenuating the music he may be listening to
                ? AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
                // if we're going to play the ring tone, silence
                // other sound sources
                : AudioManager.AUDIOFOCUS_GAIN_TRANSIENT;

        if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING");
        audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING, hint);
    }

    private Context getContext() {