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

Commit daef4550 authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "AudioService: fix overlapping speakerphone + Bluetooth SCO routing...

Merge "AudioService: fix overlapping speakerphone + Bluetooth SCO routing requests" into rvc-qpr-dev
parents b4e06d01 3dc1a09a
Loading
Loading
Loading
Loading
+37 −0
Original line number Original line Diff line number Diff line
@@ -224,12 +224,35 @@ import java.util.concurrent.atomic.AtomicBoolean;
            if (!addSpeakerphoneClient(cb, pid, on)) {
            if (!addSpeakerphoneClient(cb, pid, on)) {
                return false;
                return false;
            }
            }
            if (on) {
                // Cancel BT SCO ON request by this same client: speakerphone and BT SCO routes
                // are mutually exclusive.
                // See symmetrical operation for startBluetoothScoForClient_Sync().
                mBtHelper.stopBluetoothScoForPid(pid);
            }
            final boolean wasOn = isSpeakerphoneOn();
            final boolean wasOn = isSpeakerphoneOn();
            updateSpeakerphoneOn(eventSource);
            updateSpeakerphoneOn(eventSource);
            return (wasOn != isSpeakerphoneOn());
            return (wasOn != isSpeakerphoneOn());
        }
        }
    }
    }


    /**
     * Turns speakerphone off for a given pid and update speakerphone state.
     * @param pid
     */
    @GuardedBy("mDeviceStateLock")
    private void setSpeakerphoneOffForPid(int pid) {
        SpeakerphoneClient client = getSpeakerphoneClientForPid(pid);
        if (client == null) {
            return;
        }
        client.unregisterDeathRecipient();
        mSpeakerphoneClients.remove(client);
        final String eventSource = new StringBuilder("setSpeakerphoneOffForPid(")
                .append(pid).append(")").toString();
        updateSpeakerphoneOn(eventSource);
    }

    @GuardedBy("mDeviceStateLock")
    @GuardedBy("mDeviceStateLock")
    private void updateSpeakerphoneOn(String eventSource) {
    private void updateSpeakerphoneOn(String eventSource) {
        if (isSpeakerphoneOnRequested()) {
        if (isSpeakerphoneOnRequested()) {
@@ -488,6 +511,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
    /*package*/ void startBluetoothScoForClient_Sync(IBinder cb, int scoAudioMode,
    /*package*/ void startBluetoothScoForClient_Sync(IBinder cb, int scoAudioMode,
                @NonNull String eventSource) {
                @NonNull String eventSource) {
        synchronized (mDeviceStateLock) {
        synchronized (mDeviceStateLock) {
            // Cancel speakerphone ON request by this same client: speakerphone and BT SCO routes
            // are mutually exclusive.
            // See symmetrical operation for setSpeakerphoneOn(true).
            setSpeakerphoneOffForPid(Binder.getCallingPid());
            mBtHelper.startBluetoothScoForClient(cb, scoAudioMode, eventSource);
            mBtHelper.startBluetoothScoForClient(cb, scoAudioMode, eventSource);
        }
        }
    }
    }
@@ -1381,6 +1408,16 @@ import java.util.concurrent.atomic.AtomicBoolean;
        return false;
        return false;
    }
    }


    @GuardedBy("mDeviceStateLock")
    private SpeakerphoneClient getSpeakerphoneClientForPid(int pid) {
        for (SpeakerphoneClient cl : mSpeakerphoneClients) {
            if (cl.getPid() == pid) {
                return cl;
            }
        }
        return null;
    }

    // List of clients requesting speakerPhone ON
    // List of clients requesting speakerPhone ON
    @GuardedBy("mDeviceStateLock")
    @GuardedBy("mDeviceStateLock")
    private final @NonNull ArrayList<SpeakerphoneClient> mSpeakerphoneClients =
    private final @NonNull ArrayList<SpeakerphoneClient> mSpeakerphoneClients =
+36 −9
Original line number Original line Diff line number Diff line
@@ -432,19 +432,36 @@ public class BtHelper {
        // and this must be done on behalf of system server to make sure permissions are granted.
        // and this must be done on behalf of system server to make sure permissions are granted.
        final long ident = Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();
        if (client != null) {
        if (client != null) {
            stopAndRemoveClient(client, eventSource);
        }
        Binder.restoreCallingIdentity(ident);
    }

    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
    /*package*/ synchronized void stopBluetoothScoForPid(int pid) {
        ScoClient client = getScoClientForPid(pid);
        if (client == null) {
            return;
        }
        final String eventSource = new StringBuilder("stopBluetoothScoForPid(")
                .append(pid).append(")").toString();
        stopAndRemoveClient(client, eventSource);
    }

    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
    // @GuardedBy("BtHelper.this")
    private void stopAndRemoveClient(ScoClient client, @NonNull String eventSource) {
        AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(eventSource));
        AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(eventSource));
        client.requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
        client.requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
                SCO_MODE_VIRTUAL_CALL);
                SCO_MODE_VIRTUAL_CALL);
            // If a disconnection is pending, the client will be removed whne clearAllScoClients()
        // If a disconnection is pending, the client will be removed when clearAllScoClients()
        // is called form receiveBtEvent()
        // is called form receiveBtEvent()
        if (mScoAudioState != SCO_STATE_DEACTIVATE_REQ
        if (mScoAudioState != SCO_STATE_DEACTIVATE_REQ
                && mScoAudioState != SCO_STATE_DEACTIVATING) {
                && mScoAudioState != SCO_STATE_DEACTIVATING) {
            client.remove(false /*stop */, true /*unregister*/);
            client.remove(false /*stop */, true /*unregister*/);
        }
        }
    }
    }
        Binder.restoreCallingIdentity(ident);
    }



    /*package*/ synchronized void setHearingAidVolume(int index, int streamType) {
    /*package*/ synchronized void setHearingAidVolume(int index, int streamType) {
        if (mHearingAid == null) {
        if (mHearingAid == null) {
@@ -974,6 +991,16 @@ public class BtHelper {
        return null;
        return null;
    }
    }


    @GuardedBy("BtHelper.this")
    private ScoClient getScoClientForPid(int pid) {
        for (ScoClient cl : mScoClients) {
            if (cl.getPid() == pid) {
                return cl;
            }
        }
        return null;
    }

    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
    //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
    //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
    @GuardedBy("BtHelper.this")
    @GuardedBy("BtHelper.this")