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

Commit 0ca64667 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Fix NPE in setActiveDevice if HFP audio is not allowed" am: 968184db

Original change: https://android-review.googlesource.com/c/platform/packages/apps/Bluetooth/+/1843135

Change-Id: I5c0a035df6225e64414862d706887682620e37a5
parents 496f0f58 968184db
Loading
Loading
Loading
Loading
+41 −24
Original line number Diff line number Diff line
@@ -1158,36 +1158,45 @@ public class HeadsetService extends ProfileService {
    }

    /**
     * Set the active device.
     *
     * @param device the active device
     * @return true on success, otherwise false
     * Remove the active device
     */
    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
    public boolean setActiveDevice(BluetoothDevice device) {
        Log.i(TAG, "setActiveDevice: device=" + device + ", " + Utils.getUidPidString());
    private void removeActiveDevice() {
        synchronized (mStateMachines) {
            if (device == null) {
            // Clear the active device
            if (mVoiceRecognitionStarted) {
                if (!stopVoiceRecognition(mActiveDevice)) {
                        Log.w(TAG, "setActiveDevice: fail to stopVoiceRecognition from "
                    Log.w(TAG, "removeActiveDevice: fail to stopVoiceRecognition from "
                            + mActiveDevice);
                }
            }
            if (mVirtualCallStarted) {
                if (!stopScoUsingVirtualVoiceCall()) {
                        Log.w(TAG, "setActiveDevice: fail to stopScoUsingVirtualVoiceCall from "
                    Log.w(TAG, "removeActiveDevice: fail to stopScoUsingVirtualVoiceCall from "
                            + mActiveDevice);
                }
            }
            if (getAudioState(mActiveDevice) != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
                if (!disconnectAudio(mActiveDevice)) {
                        Log.w(TAG, "setActiveDevice: disconnectAudio failed on " + mActiveDevice);
                    Log.w(TAG, "removeActiveDevice: disconnectAudio failed on " + mActiveDevice);
                }
            }
            mActiveDevice = null;
            broadcastActiveDevice(null);
        }
    }

    /**
     * Set the active device.
     *
     * @param device the active device
     * @return true on success, otherwise false
     */
    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
    public boolean setActiveDevice(BluetoothDevice device) {
        Log.i(TAG, "setActiveDevice: device=" + device + ", " + Utils.getUidPidString());
        synchronized (mStateMachines) {
            if (device == null) {
                removeActiveDevice();
                return true;
            }
            if (device.equals(mActiveDevice)) {
@@ -1209,8 +1218,12 @@ public class HeadsetService extends ProfileService {
                if (!disconnectAudio(previousActiveDevice)) {
                    Log.e(TAG, "setActiveDevice: fail to disconnectAudio from "
                            + previousActiveDevice);
                    if (previousActiveDevice == null) {
                        removeActiveDevice();
                    } else {
                        mActiveDevice = previousActiveDevice;
                        mNativeInterface.setActiveDevice(previousActiveDevice);
                    }
                    return false;
                }
                broadcastActiveDevice(mActiveDevice);
@@ -1218,8 +1231,12 @@ public class HeadsetService extends ProfileService {
                broadcastActiveDevice(mActiveDevice);
                if (!connectAudio(mActiveDevice)) {
                    Log.e(TAG, "setActiveDevice: fail to connectAudio to " + mActiveDevice);
                    if (previousActiveDevice == null) {
                        removeActiveDevice();
                    } else {
                        mActiveDevice = previousActiveDevice;
                        mNativeInterface.setActiveDevice(previousActiveDevice);
                    }
                    return false;
                }
            } else {
+25 −0
Original line number Diff line number Diff line
@@ -900,6 +900,31 @@ public class HeadsetServiceTest {
        Assert.assertEquals(mCurrentDevice, mHeadsetService.getActiveDevice());
    }

    /**
     * Test that whether active device been removed after enable silence mode
     */
    @Test
    public void testSetActiveDevice_AudioNotAllowed() {
        when(mDatabaseManager.getProfileConnectionPolicy(any(BluetoothDevice.class),
                eq(BluetoothProfile.HEADSET)))
                .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
        mCurrentDevice = TestUtils.getTestDevice(mAdapter, 0);
        mHeadsetService.setForceScoAudio(false);

        Assert.assertTrue(mHeadsetService.connect(mCurrentDevice));
        when(mStateMachines.get(mCurrentDevice).getDevice()).thenReturn(mCurrentDevice);
        when(mStateMachines.get(mCurrentDevice).getConnectionState()).thenReturn(
                BluetoothProfile.STATE_CONNECTED);

        Assert.assertTrue(mHeadsetService.setActiveDevice(null));
        when(mSystemInterface.isInCall()).thenReturn(true);
        mHeadsetService.setAudioRouteAllowed(false);

        // Test that active device should not be changed if audio is not allowed
        Assert.assertFalse(mHeadsetService.setActiveDevice(mCurrentDevice));
        Assert.assertEquals(null, mHeadsetService.getActiveDevice());
    }

    /*
     *  Helper function to test okToAcceptConnection() method
     *