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

Commit 9bf56c74 authored by Ted Wang's avatar Ted Wang Committed by android-build-merger
Browse files

Merge "Store volume when the active device is set to null"

am: 52038919

Change-Id: I67eece47fde07302bd3fad70711dba0c7c32b888
parents d2d9e16b 52038919
Loading
Loading
Loading
Loading
+25 −23
Original line number Diff line number Diff line
@@ -34,10 +34,10 @@ import android.util.StatsLog;

import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.Utils;
import com.android.bluetooth.avrcp.AvrcpTargetService;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

@@ -62,6 +62,8 @@ public class A2dpService extends ProfileService {

    @VisibleForTesting
    A2dpNativeInterface mA2dpNativeInterface;
    @VisibleForTesting
    ServiceFactory mFactory = new ServiceFactory();
    private AudioManager mAudioManager;
    private A2dpCodecConfig mA2dpCodecConfig;

@@ -156,11 +158,6 @@ public class A2dpService extends ProfileService {
            return true;
        }

        // Step 10: Store volume if there is an active device
        if (mActiveDevice != null && AvrcpTargetService.get() != null) {
            AvrcpTargetService.get().storeVolumeForDevice(mActiveDevice);
        }

        // Step 9: Clear active device and stop playing audio
        removeActiveDevice(true);

@@ -436,9 +433,19 @@ public class A2dpService extends ProfileService {
        }
    }

    private void storeActiveDeviceVolume() {
        // Make sure volume has been stored before been removed from active.
        if (mFactory.getAvrcpTargetService() != null && mActiveDevice != null) {
            mFactory.getAvrcpTargetService().storeVolumeForDevice(mActiveDevice);
        }
    }

    private void removeActiveDevice(boolean forceStopPlayingAudio) {
        BluetoothDevice previousActiveDevice = mActiveDevice;
        synchronized (mStateMachines) {
            // Make sure volume has been store before device been remove from active.
            storeActiveDeviceVolume();

            // This needs to happen before we inform the audio manager that the device
            // disconnected. Please see comment in updateAndBroadcastActiveDevice() for why.
            updateAndBroadcastActiveDevice(null);
@@ -480,9 +487,6 @@ public class A2dpService extends ProfileService {
            Log.d(TAG, "setSilenceMode(" + device + "): " + silence);
        }
        if (silence && Objects.equals(mActiveDevice, device)) {
            if (mActiveDevice != null && AvrcpTargetService.get() != null) {
                AvrcpTargetService.get().storeVolumeForDevice(mActiveDevice);
            }
            removeActiveDevice(true);
        } else if (!silence && mActiveDevice == null) {
            // Set the device as the active device if currently no active device.
@@ -503,13 +507,11 @@ public class A2dpService extends ProfileService {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");

        synchronized (mStateMachines) {
            if ((mActiveDevice != null) && (AvrcpTargetService.get() != null)) {
            // Switch active device from A2DP to Hearing Aids.
            if (DBG) {
                Log.d(TAG, "earlyNotifyHearingAidActive: Save volume for " + mActiveDevice);
            }
                AvrcpTargetService.get().storeVolumeForDevice(mActiveDevice);
            }
            storeActiveDeviceVolume();
        }
    }

@@ -552,12 +554,12 @@ public class A2dpService extends ProfileService {
            codecStatus = sm.getCodecStatus();

            boolean deviceChanged = !Objects.equals(device, mActiveDevice);
            if ((AvrcpTargetService.get() != null) && (mActiveDevice != null) && deviceChanged) {
            if (deviceChanged) {
                // Switch from one A2DP to another A2DP device
                if (DBG) {
                    Log.d(TAG, "Switch A2DP devices to " + device + " from " + mActiveDevice);
                }
                AvrcpTargetService.get().storeVolumeForDevice(mActiveDevice);
                storeActiveDeviceVolume();
            }

            // This needs to happen before we inform the audio manager that the device
@@ -584,8 +586,8 @@ public class A2dpService extends ProfileService {
                }

                int rememberedVolume = -1;
                if (AvrcpTargetService.get() != null) {
                    rememberedVolume = AvrcpTargetService.get()
                if (mFactory.getAvrcpTargetService() != null) {
                    rememberedVolume = mFactory.getAvrcpTargetService()
                            .getRememberedVolumeForDevice(mActiveDevice);
                }

@@ -649,8 +651,8 @@ public class A2dpService extends ProfileService {
    public void setAvrcpAbsoluteVolume(int volume) {
        // TODO (apanicke): Instead of using A2DP as a middleman for volume changes, add a binder
        // service to the new AVRCP Profile and have the audio manager use that instead.
        if (AvrcpTargetService.get() != null) {
            AvrcpTargetService.get().sendVolumeChanged(volume);
        if (mFactory.getAvrcpTargetService() != null) {
            mFactory.getAvrcpTargetService().sendVolumeChanged(volume);
            return;
        }
    }
@@ -929,8 +931,8 @@ public class A2dpService extends ProfileService {
        }

        synchronized (mStateMachines) {
            if (AvrcpTargetService.get() != null) {
                AvrcpTargetService.get().volumeDeviceSwitched(device);
            if (mFactory.getAvrcpTargetService() != null) {
                mFactory.getAvrcpTargetService().volumeDeviceSwitched(device);
            }

            mActiveDevice = device;
+5 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.bluetooth.btservice;

import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.avrcp.AvrcpTargetService;
import com.android.bluetooth.hearingaid.HearingAidService;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.hid.HidDeviceService;
@@ -48,4 +49,8 @@ public class ServiceFactory {
    public HearingAidService getHearingAidService() {
        return HearingAidService.getHearingAidService();
    }

    public AvrcpTargetService getAvrcpTargetService() {
        return AvrcpTargetService.get();
    }
}
+34 −0
Original line number Diff line number Diff line
@@ -38,7 +38,9 @@ import android.support.test.runner.AndroidJUnit4;

import com.android.bluetooth.R;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.avrcp.AvrcpTargetService;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.btservice.storage.DatabaseManager;

import org.junit.After;
@@ -75,6 +77,8 @@ public class A2dpServiceTest {
    @Mock private AdapterService mAdapterService;
    @Mock private A2dpNativeInterface mA2dpNativeInterface;
    @Mock private DatabaseManager mDatabaseManager;
    @Mock private AvrcpTargetService mAvrcpTargetService;
    @Mock private ServiceFactory mFactory;

    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();

@@ -93,11 +97,13 @@ public class A2dpServiceTest {
        TestUtils.setAdapterService(mAdapterService);
        doReturn(MAX_CONNECTED_AUDIO_DEVICES).when(mAdapterService).getMaxConnectedAudioDevices();
        doReturn(false).when(mAdapterService).isQuietModeEnabled();
        doReturn(mAvrcpTargetService).when(mFactory).getAvrcpTargetService();

        mAdapter = BluetoothAdapter.getDefaultAdapter();

        startService();
        mA2dpService.mA2dpNativeInterface = mA2dpNativeInterface;
        mA2dpService.mFactory = mFactory;

        // Override the timeout value to speed up the test
        A2dpStateMachine.sConnectTimeoutMs = TIMEOUT_MS;    // 1s
@@ -245,6 +251,8 @@ public class A2dpServiceTest {
        });
        // Verify that setActiveDevice(null) was called during shutdown
        verify(mA2dpNativeInterface).setActiveDevice(null);
        // Verify that storeVolumeForDevice(mTestDevice) was called during shutdown
        verify(mAvrcpTargetService).storeVolumeForDevice(mTestDevice);
        // Try to restart the service. Note: must be done on the main thread.
        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
            public void run() {
@@ -787,11 +795,13 @@ public class A2dpServiceTest {
        Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice());
        Assert.assertTrue(mA2dpService.setSilenceMode(mTestDevice, true));
        verify(mA2dpNativeInterface).setSilenceDevice(mTestDevice, true);
        verify(mAvrcpTargetService).storeVolumeForDevice(mTestDevice);
        Assert.assertNull(mA2dpService.getActiveDevice());

        // Test whether active device been resumeed after disable silence mode.
        Assert.assertTrue(mA2dpService.setSilenceMode(mTestDevice, false));
        verify(mA2dpNativeInterface).setSilenceDevice(mTestDevice, false);
        verify(mAvrcpTargetService).storeVolumeForDevice(mTestDevice);
        Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice());

        // Test that active device should not be changed when silence a non-active device
@@ -799,11 +809,13 @@ public class A2dpServiceTest {
        Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice());
        Assert.assertTrue(mA2dpService.setSilenceMode(otherDevice, true));
        verify(mA2dpNativeInterface).setSilenceDevice(otherDevice, true);
        verify(mAvrcpTargetService).storeVolumeForDevice(mTestDevice);
        Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice());

        // Test that active device should not be changed when another device exits silence mode
        Assert.assertTrue(mA2dpService.setSilenceMode(otherDevice, false));
        verify(mA2dpNativeInterface).setSilenceDevice(otherDevice, false);
        verify(mAvrcpTargetService).storeVolumeForDevice(mTestDevice);
        Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice());
    }

@@ -893,6 +905,28 @@ public class A2dpServiceTest {
                verifySupportTime, verifyNotSupportTime, verifyEnabledTime);
    }

    /**
     * Test that volume level of previous active device will be stored after set active device.
     */
    @Test
    public void testStoreVolumeAfterSetActiveDevice() {
        BluetoothDevice otherDevice = mAdapter.getRemoteDevice("05:04:03:02:01:00");
        connectDevice(otherDevice);
        connectDevice(mTestDevice);
        doReturn(true).when(mA2dpNativeInterface).setActiveDevice(any(BluetoothDevice.class));
        doReturn(true).when(mA2dpNativeInterface).setActiveDevice(null);
        Assert.assertTrue(mA2dpService.setActiveDevice(mTestDevice));

        // Test volume stored for previous active device an adjust for current active device
        Assert.assertTrue(mA2dpService.setActiveDevice(otherDevice));
        verify(mAvrcpTargetService).storeVolumeForDevice(mTestDevice);
        verify(mAvrcpTargetService).getRememberedVolumeForDevice(otherDevice);

        // Test volume store for previous active device when set active device to null
        Assert.assertTrue(mA2dpService.setActiveDevice(null));
        verify(mAvrcpTargetService).storeVolumeForDevice(otherDevice);
    }

    private void connectDevice(BluetoothDevice device) {
        connectDeviceWithCodecStatus(device, null);
    }