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

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

Merge "AudioManager: add startBluetoothScoVirtualCall()"

parents 4d9950d1 83900754
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -13798,6 +13798,7 @@ package android.media {
    method public deprecated void setWiredHeadsetOn(boolean);
    method public deprecated boolean shouldVibrate(int);
    method public void startBluetoothSco();
    method public void startBluetoothScoVirtualCall();
    method public void stopBluetoothSco();
    method public void unloadSoundEffects();
    method public void unregisterMediaButtonEventReceiver(android.content.ComponentName);
+32 −7
Original line number Diff line number Diff line
@@ -1254,11 +1254,6 @@ public class AudioManager {
     * call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection.
     * <p>Even if a SCO connection is established, the following restrictions apply on audio
     * output streams so that they can be routed to SCO headset:
     * <p>NOTE: up to and including API version
     * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates a virtual
     * voice call to the bluetooth headset.
     * After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio
     * connection is established.
     * <ul>
     *   <li> the stream type must be {@link #STREAM_VOICE_CALL} </li>
     *   <li> the format must be mono </li>
@@ -1274,6 +1269,11 @@ public class AudioManager {
     * it will be ignored. Similarly, if a call is received or sent while an application
     * is using the SCO connection, the connection will be lost for the application and NOT
     * returned automatically when the call ends.
     * <p>NOTE: up to and including API version
     * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates a virtual
     * voice call to the bluetooth headset.
     * After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio
     * connection is established.
     * @see #stopBluetoothSco()
     * @see #ACTION_SCO_AUDIO_STATE_UPDATED
     */
@@ -1286,14 +1286,39 @@ public class AudioManager {
        }
    }

    /**
     * Start bluetooth SCO audio connection in virtual call mode.
     * <p>Requires Permission:
     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
     * <p>Similar to {@link #startBluetoothSco()} with explicit selection of virtual call mode.
     * Telephony and communication applications (VoIP, Video Chat) should preferably select
     * virtual call mode.
     * Applications using voice input for search or commands should first try raw audio connection
     * with {@link #startBluetoothSco()} and fall back to startBluetoothScoVirtualCall() in case of
     * failure.
     * @see #startBluetoothSco()
     * @see #stopBluetoothSco()
     * @see #ACTION_SCO_AUDIO_STATE_UPDATED
     */
    public void startBluetoothScoVirtualCall() {
        IAudioService service = getService();
        try {
            service.startBluetoothScoVirtualCall(mICallBack);
        } catch (RemoteException e) {
            Log.e(TAG, "Dead object in startBluetoothScoVirtualCall", e);
        }
    }

    /**
     * Stop bluetooth SCO audio connection.
     * <p>Requires Permission:
     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
     * <p>This method must be called by applications having requested the use of
     * bluetooth SCO audio with {@link #startBluetoothSco()}
     * when finished with the SCO connection or if connection fails.
     * bluetooth SCO audio with {@link #startBluetoothSco()} or
     * {@link #startBluetoothScoVirtualCall()} when finished with the SCO connection or
     * if connection fails.
     * @see #startBluetoothSco()
     * @see #startBluetoothScoVirtualCall()
     */
    public void stopBluetoothSco(){
        IAudioService service = getService();
+18 −8
Original line number Diff line number Diff line
@@ -2057,6 +2057,18 @@ public class AudioService extends IAudioService.Stub {

    /** @see AudioManager#startBluetoothSco() */
    public void startBluetoothSco(IBinder cb, int targetSdkVersion) {
        int scoAudioMode =
                (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
                        SCO_MODE_VIRTUAL_CALL : SCO_MODE_RAW;
        startBluetoothScoInt(cb, scoAudioMode);
    }

    /** @see AudioManager#startBluetoothScoVirtualCall() */
    public void startBluetoothScoVirtualCall(IBinder cb) {
        startBluetoothScoInt(cb, SCO_MODE_VIRTUAL_CALL);
    }

    void startBluetoothScoInt(IBinder cb, int scoAudioMode){
        if (!checkAudioSettingsPermission("startBluetoothSco()") ||
                !mSystemReady) {
            return;
@@ -2068,7 +2080,7 @@ public class AudioService extends IAudioService.Stub {
        // The caller identity must be cleared after getScoClient() because it is needed if a new
        // client is created.
        final long ident = Binder.clearCallingIdentity();
        client.incCount(targetSdkVersion);
        client.incCount(scoAudioMode);
        Binder.restoreCallingIdentity(ident);
    }

@@ -2114,9 +2126,9 @@ public class AudioService extends IAudioService.Stub {
            }
        }

        public void incCount(int targetSdkVersion) {
        public void incCount(int scoAudioMode) {
            synchronized(mScoClients) {
                requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, targetSdkVersion);
                requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode);
                if (mStartcount == 0) {
                    try {
                        mCb.linkToDeath(this, 0);
@@ -2186,7 +2198,7 @@ public class AudioService extends IAudioService.Stub {
            }
        }

        private void requestScoState(int state, int targetSdkVersion) {
        private void requestScoState(int state, int scoAudioMode) {
            checkScoAudioState();
            if (totalCount() == 0) {
                if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
@@ -2201,9 +2213,7 @@ public class AudioService extends IAudioService.Stub {
                                (mScoAudioState == SCO_STATE_INACTIVE ||
                                 mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) {
                            if (mScoAudioState == SCO_STATE_INACTIVE) {
                                mScoAudioMode =
                                        (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
                                                SCO_MODE_VIRTUAL_CALL : SCO_MODE_RAW;
                                mScoAudioMode = scoAudioMode;
                                if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
                                    boolean status;
                                    if (mScoAudioMode == SCO_MODE_RAW) {
+1 −0
Original line number Diff line number Diff line
@@ -217,6 +217,7 @@ interface IAudioService {
    oneway void registerRemoteVolumeObserverForRcc(int rccId, in IRemoteVolumeObserver rvo);

    void startBluetoothSco(IBinder cb, int targetSdkVersion);
    void startBluetoothScoVirtualCall(IBinder cb);
    void stopBluetoothSco(IBinder cb);

    void forceVolumeControlStream(int streamType, IBinder cb);