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

Commit cb542d0c authored by Sal Savage's avatar Sal Savage
Browse files

Fix AvrcpControllerStateMachineTest NPEs on calls to service

The way services are stopped and started for tests was refactored some
time ago. It seems we forgot to hook up our mock A2DP and AVRCP services
during that refactor.

As well, the old method started a real service. When AVRCP Controller
started, it started up our BluetoothMediaBrowserService too. Our tests
all reference this object.

This change sets mock service instances for A2DP and AVRCP, and starts
up a real BluetoothMediaBrowserService.

Bug: 332900248
Flag: EXEMPT, test change with small mechanical refactor in AVRCP
Test: atest AvrcpControllerStateMachineTest
Change-Id: I27e1012d9513c52a98d52b1b796845f542a69a97
parent c4befe7d
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -156,7 +156,7 @@ public class AvrcpControllerService extends ProfileService {
            mCoverArtManager = new AvrcpCoverArtManager(this, new ImageDownloadCallback());
        }
        sBrowseTree = new BrowseTree(null);
        sService = this;
        setAvrcpControllerService(this);

        // Start the media browser service.
        Intent startIntent = new Intent(this, BluetoothMediaBrowserService.class);
@@ -174,7 +174,7 @@ public class AvrcpControllerService extends ProfileService {
        }
        mDeviceStateMap.clear();

        sService = null;
        setAvrcpControllerService(null);
        sBrowseTree = null;
        if (mCoverArtManager != null) {
            mCoverArtManager.cleanup();
@@ -185,10 +185,16 @@ public class AvrcpControllerService extends ProfileService {
        mNativeInterface.cleanup();
    }

    public static AvrcpControllerService getAvrcpControllerService() {
    public static synchronized AvrcpControllerService getAvrcpControllerService() {
        return sService;
    }

    /** Testing API to inject a mock AvrcpControllerService */
    @VisibleForTesting
    public static synchronized void setAvrcpControllerService(AvrcpControllerService service) {
        sService = service;
    }

    /**
     * Get the current active device
     */
+21 −22
Original line number Diff line number Diff line
@@ -42,10 +42,8 @@ import androidx.test.runner.AndroidJUnit4;

import com.android.bluetooth.R;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.a2dpsink.A2dpSinkNativeInterface;
import com.android.bluetooth.a2dpsink.A2dpSinkService;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.storage.DatabaseManager;

import org.hamcrest.core.IsInstanceOf;
import org.junit.After;
@@ -73,21 +71,22 @@ public class AvrcpControllerStateMachineTest {

    private BluetoothAdapter mAdapter;

    @Rule public final ServiceTestRule mAvrcpServiceRule = new ServiceTestRule();
    @Rule public final ServiceTestRule mA2dpServiceRule = new ServiceTestRule();
    @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();

    @Mock private AdapterService mA2dpAdapterService;
    @Mock private AdapterService mAvrcpAdapterService;
    @Mock private AdapterService mAdapterService;

    @Mock private A2dpSinkService mA2dpSinkService;
    @Mock private DatabaseManager mDatabaseManager;
    @Mock private AudioManager mAudioManager;
    @Mock private Resources mMockResources;
    private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class);

    @Mock private AvrcpControllerService mAvrcpControllerService;
    @Mock private AvrcpControllerNativeInterface mNativeInterface;
    @Mock private A2dpSinkNativeInterface mA2dpSinkNativeInterface;
    @Mock private AvrcpCoverArtManager mCoverArtManager;
    @Mock private AudioManager mAudioManager;

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

    private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class);

    private byte[] mTestAddress = new byte[]{01, 01, 01, 01, 01, 01};
    private BluetoothDevice mTestDevice = null;
@@ -100,17 +99,11 @@ public class AvrcpControllerStateMachineTest {
        }
        Assert.assertNotNull(Looper.myLooper());

        // Set a mock Adapter Service for profile state change notifications
        TestUtils.setAdapterService(mAdapterService);

        // Start a real A2dpSinkService so we can replace the static instance with our mock
        doReturn(mDatabaseManager).when(mA2dpAdapterService).getDatabase();
        TestUtils.setAdapterService(mA2dpAdapterService);
        A2dpSinkNativeInterface.setInstance(mA2dpSinkNativeInterface);
        // Set a mock A2dpSinkService for audio focus calls
        A2dpSinkService.setA2dpSinkService(mA2dpSinkService);
        TestUtils.clearAdapterService(mA2dpAdapterService);

        // Start an AvrcpControllerService to get a real BluetoothMediaBrowserService up
        TestUtils.setAdapterService(mAvrcpAdapterService);
        AvrcpControllerNativeInterface.setInstance(mNativeInterface);

        // Mock an AvrcpControllerService to give to all state machines
        doReturn(BluetoothProfile.STATE_DISCONNECTED).when(mCoverArtManager).getState(any());
@@ -126,6 +119,12 @@ public class AvrcpControllerStateMachineTest {
                .getSystemServiceName(AudioManager.class);
        doReturn(mCoverArtManager).when(mAvrcpControllerService).getCoverArtManager();
        mAvrcpControllerService.sBrowseTree = new BrowseTree(null);
        AvrcpControllerService.setAvrcpControllerService(mAvrcpControllerService);

        // Start the Bluetooth Media Browser Service
        final Intent bluetoothBrowserMediaServiceStartIntent =
                TestUtils.prepareIntentToStartBluetoothBrowserMediaService();
        mBluetoothBrowserMediaServiceTestRule.startService(bluetoothBrowserMediaServiceStartIntent);

        // Ensure our MediaBrowserService starts with a blank state
        BluetoothMediaBrowserService.reset();
@@ -142,9 +141,9 @@ public class AvrcpControllerStateMachineTest {
    @After
    public void tearDown() throws Exception {
        destroyStateMachine(mAvrcpStateMachine);
        TestUtils.clearAdapterService(mAvrcpAdapterService);
        A2dpSinkNativeInterface.setInstance(null);
        AvrcpControllerNativeInterface.setInstance(null);
        A2dpSinkService.setA2dpSinkService(null);
        AvrcpControllerService.setAvrcpControllerService(null);
        TestUtils.clearAdapterService(mAdapterService);
    }

    /**