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

Commit 47433a1b authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 11949167 from e110efe6 to 24Q3-release

Change-Id: Ia99c9a041f9f5c550955d13d8db30ad761c172ba
parents 8d2601b9 e110efe6
Loading
Loading
Loading
Loading
+17 −11
Original line number Diff line number Diff line
@@ -91,9 +91,10 @@ public class A2dpService extends ProfileService {
    private final AudioManager mAudioManager;
    private final DatabaseManager mDatabaseManager;
    private final CompanionDeviceManager mCompanionDeviceManager;
    private final Looper mLooper;
    private final Handler mHandler;

    private HandlerThread mStateMachinesThread;
    private Handler mHandler = null;

    @VisibleForTesting ServiceFactory mFactory = new ServiceFactory();
    private A2dpCodecConfig mA2dpCodecConfig;
@@ -122,19 +123,21 @@ public class A2dpService extends ProfileService {
            new AudioManagerAudioDeviceCallback();

    public A2dpService(AdapterService adapterService) {
        this(adapterService, A2dpNativeInterface.getInstance());
        this(adapterService, A2dpNativeInterface.getInstance(), Looper.getMainLooper());
    }

    @VisibleForTesting
    A2dpService(AdapterService adapterService, A2dpNativeInterface nativeInterface) {
    A2dpService(AdapterService adapterService, A2dpNativeInterface nativeInterface, Looper looper) {
        super(requireNonNull(adapterService));
        mAdapterService = adapterService;
        mNativeInterface = requireNonNull(nativeInterface);
        mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
        mAudioManager = requireNonNull(getSystemService(AudioManager.class));
        mLooper = requireNonNull(looper);

        // Some platform may not have the FEATURE_COMPANION_DEVICE_SETUP
        mCompanionDeviceManager = getSystemService(CompanionDeviceManager.class);
        mHandler = new Handler(mLooper);
    }

    public static boolean isEnabled() {
@@ -163,10 +166,12 @@ public class A2dpService extends ProfileService {

        // Step 3: Start handler thread for state machines
        // Setup Handler.
        mHandler = new Handler(Looper.getMainLooper());
        mStateMachines.clear();

        if (!Flags.a2dpServiceLooper()) {
            mStateMachinesThread = new HandlerThread("A2dpService.StateMachines");
            mStateMachinesThread.start();
        }

        // Step 4: Setup codec config
        mA2dpCodecConfig = new A2dpCodecConfig(this, mNativeInterface);
@@ -232,10 +237,8 @@ public class A2dpService extends ProfileService {
                // Do not rethrow as we are shutting down anyway
            }
        }
        if (mHandler != null) {

        mHandler.removeCallbacksAndMessages(null);
            mHandler = null;
        }

        // Step 2: Reset maximum number of connected audio devices
        mMaxConnectedAudioDevices = 1;
@@ -1040,7 +1043,10 @@ public class A2dpService extends ProfileService {
            Log.d(TAG, "Creating a new state machine for " + device);
            sm =
                    A2dpStateMachine.make(
                            device, this, mNativeInterface, mStateMachinesThread.getLooper());
                            device,
                            this,
                            mNativeInterface,
                            Flags.a2dpServiceLooper() ? mLooper : mStateMachinesThread.getLooper());
            mStateMachines.put(device, sm);
            return sm;
        }
+29 −0
Original line number Diff line number Diff line
@@ -3137,6 +3137,7 @@ public class AdapterService extends Service {
            // Only allow setting a pin in bonding state, or bonded state in case of security
            // upgrade.
            if (deviceProp == null || !deviceProp.isBondingOrBonded()) {
                Log.e(TAG, "setPin: device=" + device + ", not bonding");
                return false;
            }
            if (pinCode.length != len) {
@@ -3146,6 +3147,14 @@ public class AdapterService extends Service {
            }
            service.logUserBondResponse(
                    device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_PIN_REPLIED);
            Log.i(
                    TAG,
                    "setPin: device="
                            + device
                            + ", accept="
                            + accept
                            + ", from "
                            + Utils.getUidPidString());
            return service.mNativeInterface.pinReply(
                    getBytesFromAddress(device.getAddress()), accept, len, pinCode);
        }
@@ -3167,6 +3176,7 @@ public class AdapterService extends Service {

            DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
            if (deviceProp == null || !deviceProp.isBonding()) {
                Log.e(TAG, "setPasskey: device=" + device + ", not bonding");
                return false;
            }
            if (passkey.length != len) {
@@ -3176,6 +3186,15 @@ public class AdapterService extends Service {
            }
            service.logUserBondResponse(
                    device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REPLIED);
            Log.i(
                    TAG,
                    "setPasskey: device="
                            + device
                            + ", accept="
                            + accept
                            + ", from "
                            + Utils.getUidPidString());

            return service.mNativeInterface.sspReply(
                    getBytesFromAddress(device.getAddress()),
                    AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY,
@@ -3197,10 +3216,20 @@ public class AdapterService extends Service {

            DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device);
            if (deviceProp == null || !deviceProp.isBonding()) {
                Log.e(TAG, "setPairingConfirmation: device=" + device + ", not bonding");
                return false;
            }
            service.logUserBondResponse(
                    device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REPLIED);
            Log.i(
                    TAG,
                    "setPairingConfirmation: device="
                            + device
                            + ", accept="
                            + accept
                            + ", from "
                            + Utils.getUidPidString());

            return service.mNativeInterface.sspReply(
                    getBytesFromAddress(device.getAddress()),
                    AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION,
+3 −1
Original line number Diff line number Diff line
@@ -488,13 +488,15 @@ final class BondStateMachine extends StateMachine {
    }

    private void sendDisplayPinIntent(byte[] address, Optional<Integer> maybePin, int variant) {
        BluetoothDevice device = mRemoteDevices.getDevice(address);
        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevices.getDevice(address));
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        maybePin.ifPresent(pin -> intent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, pin));
        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, variant);
        intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        // Workaround for Android Auto until pre-accepting pairing requests is added.
        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        Log.i(TAG, "sendDisplayPinIntent: device=" + device + ", variant=" + variant);
        mAdapterService.sendOrderedBroadcast(
                intent,
                BLUETOOTH_CONNECT,
+20 −12
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.Log;

import androidx.annotation.NonNull;

import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
@@ -1012,19 +1014,19 @@ public class RemoteDevices {
        // The device properties are already registered - we can send the intent
        // now
        BluetoothDevice device = getDevice(address);
        debugLog("deviceFoundCallback: Remote Address is:" + device);
        DeviceProperties deviceProp = getDeviceProperties(device);
        if (deviceProp == null) {
            errorLog("Device Properties is null for Device:" + device);
            errorLog("deviceFoundCallback: Device Properties is null for Device:" + device);
            return;
        }
        boolean restrict_device_found =
                SystemProperties.getBoolean("bluetooth.restrict_discovered_device.enabled", false);
        if (restrict_device_found && (deviceProp.mName == null || deviceProp.mName.isEmpty())) {
            debugLog("Device name is null or empty: " + device);
            warnLog("deviceFoundCallback: Device name is null or empty: " + device);
            return;
        }

        infoLog("deviceFoundCallback: Remote Address is:" + device);
        Intent intent = new Intent(BluetoothDevice.ACTION_FOUND);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.putExtra(
@@ -1173,15 +1175,7 @@ public class RemoteDevices {
            deviceProperties.setConnectionHandle(BluetoothDevice.ERROR, transportLinkType);
            if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
                // Send PAIRING_CANCEL intent to dismiss any dialog requesting bonding.
                intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL);
                intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
                intent.setPackage(
                        SystemProperties.get(
                                Utils.PAIRING_UI_PROPERTY,
                                mAdapterService.getString(R.string.pairing_ui_package)));

                mAdapterService.sendBroadcast(
                        intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle());
                sendPairingCancelIntent(device);
            } else if (device.getBondState() == BluetoothDevice.BOND_NONE) {
                removeAddressMapping(Utils.getAddressStringFromByte(address));
            }
@@ -1278,6 +1272,20 @@ public class RemoteDevices {
        }
    }

    @NonNull
    private void sendPairingCancelIntent(BluetoothDevice device) {
        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.setPackage(
                SystemProperties.get(
                        Utils.PAIRING_UI_PROPERTY,
                        mAdapterService.getString(R.string.pairing_ui_package)));

        Log.i(TAG, "sendPairingCancelIntent: device=" + device);
        mAdapterService.sendBroadcast(
                intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle());
    }

    private void removeAddressMapping(String address) {
        if (Flags.temporaryPairingDeviceProperties()) {
            DeviceProperties deviceProperties = mDevices.get(address);
+85 −9
Original line number Diff line number Diff line
@@ -36,16 +36,19 @@ import android.media.AudioManager;
import android.media.BluetoothProfileConnectionInfo;
import android.os.Looper;
import android.os.ParcelUuid;
import android.os.test.TestLooper;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.ActiveDeviceManager;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.SilenceDeviceManager;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.flags.Flags;

import org.hamcrest.Matcher;
import org.hamcrest.core.AllOf;
@@ -61,12 +64,15 @@ import org.mockito.hamcrest.MockitoHamcrest;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;

import java.time.Duration;
import java.util.Arrays;
import java.util.List;

@MediumTest
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedAndroidJunit4.class)
public class A2dpServiceTest {
    private static final int MAX_CONNECTED_AUDIO_DEVICES = 5;
    private static final Duration TIMEOUT = Duration.ofSeconds(1);
@@ -75,6 +81,7 @@ public class A2dpServiceTest {
    private static final BluetoothDevice sTestDevice =
            sAdapter.getRemoteDevice("00:01:02:03:04:05");

    @Rule public final SetFlagsRule mSetFlagsRule;
    @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();

    @Mock private A2dpNativeInterface mMockNativeInterface;
@@ -83,13 +90,25 @@ public class A2dpServiceTest {
    @Mock private AudioManager mAudioManager;
    @Mock private DatabaseManager mDatabaseManager;
    @Mock private SilenceDeviceManager mSilenceDeviceManager;

    private InOrder mInOrder = null;

    private TestLooper mLooper;
    private A2dpService mA2dpService;

    @Parameters(name = "{0}")
    public static List<FlagsParameterization> getParams() {
        return FlagsParameterization.allCombinationsOf(Flags.FLAG_A2DP_SERVICE_LOOPER);
    }

    public A2dpServiceTest(FlagsParameterization flags) {
        mSetFlagsRule = new SetFlagsRule(flags);
    }

    @Before
    public void setUp() throws Exception {
        mInOrder = inOrder(mAdapterService);
        mLooper = new TestLooper();

        TestUtils.mockGetSystemService(
                mAdapterService, Context.AUDIO_SERVICE, AudioManager.class, mAudioManager);
@@ -108,7 +127,7 @@ public class A2dpServiceTest {
        doReturn(mActiveDeviceManager).when(mAdapterService).getActiveDeviceManager();
        doReturn(mSilenceDeviceManager).when(mAdapterService).getSilenceDeviceManager();

        mA2dpService = new A2dpService(mAdapterService, mMockNativeInterface);
        mA2dpService = new A2dpService(mAdapterService, mMockNativeInterface, mLooper.getLooper());
        mA2dpService.start();
        mA2dpService.setAvailable(true);

@@ -122,15 +141,20 @@ public class A2dpServiceTest {
        doReturn(new ParcelUuid[] {BluetoothUuid.A2DP_SINK})
                .when(mAdapterService)
                .getRemoteUuids(any(BluetoothDevice.class));

        if (!Flags.a2dpServiceLooper()) {
            mLooper.startAutoDispatch();
        }
    }

    @After
    public void tearDown() {
        // A2dpService handler is running on main looper. Calling `stop` remove the messages but
        // assume it is already on the correct thread.
        // Calling it from another thread may lead to having messages still being processed and
        // executed after tearDown is called.
        InstrumentationRegistry.getInstrumentation().runOnMainSync(mA2dpService::stop);
        if (Flags.a2dpServiceLooper()) {
            assertThat(mLooper.dispatchAll()).isEqualTo(0);
        } else {
            mLooper.stopAutoDispatchAndIgnoreExceptions();
        }
        mA2dpService.stop();
    }

    @SafeVarargs
@@ -161,6 +185,7 @@ public class A2dpServiceTest {
        verify(mMockNativeInterface).setActiveDevice(sTestDevice);

        mA2dpService.stop();
        dispatchAtLeastOneMessage();

        // Verify that setActiveDevice(null) was called during shutdown
        verify(mMockNativeInterface).setActiveDevice(null);
@@ -291,6 +316,7 @@ public class A2dpServiceTest {

        // Send a connect request
        assertThat(mA2dpService.connect(sTestDevice)).isTrue();
        dispatchAtLeastOneMessage();

        // Verify the connection state broadcast, and that we are in Connecting state
        verifyConnectionStateIntent(
@@ -300,6 +326,10 @@ public class A2dpServiceTest {
        assertThat(mA2dpService.getConnectionState(sTestDevice))
                .isEqualTo(BluetoothProfile.STATE_CONNECTING);

        // Verify a timeout after 1sec.
        moveTimeForward(TIMEOUT.toMillis());
        dispatchAtLeastOneMessage();

        // Verify the connection state broadcast, and that we are in Disconnected state
        verifyConnectionStateIntent(
                sTestDevice,
@@ -322,6 +352,7 @@ public class A2dpServiceTest {

        // Send a connect request
        assertThat(mA2dpService.connect(sTestDevice)).isTrue();
        dispatchAtLeastOneMessage();

        // Verify the connection state broadcast, and that we are in Connecting state
        verifyConnectionStateIntent(
@@ -336,6 +367,7 @@ public class A2dpServiceTest {
        connCompletedEvent.device = sTestDevice;
        connCompletedEvent.valueInt = A2dpStackEvent.CONNECTION_STATE_CONNECTED;
        mA2dpService.messageFromNative(connCompletedEvent);
        dispatchAtLeastOneMessage();

        // Verify the connection state broadcast, and that we are in Connected state
        verifyConnectionStateIntent(
@@ -348,6 +380,7 @@ public class A2dpServiceTest {

        // Send a disconnect request
        assertThat(mA2dpService.disconnect(sTestDevice)).isTrue();
        dispatchAtLeastOneMessage();

        // Verify the connection state broadcast, and that we are in Disconnecting state
        verifyConnectionStateIntent(
@@ -362,6 +395,7 @@ public class A2dpServiceTest {
        connCompletedEvent.device = sTestDevice;
        connCompletedEvent.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED;
        mA2dpService.messageFromNative(connCompletedEvent);
        dispatchAtLeastOneMessage();

        // Verify the connection state broadcast, and that we are in Disconnected state
        verifyConnectionStateIntent(
@@ -393,6 +427,7 @@ public class A2dpServiceTest {
                    .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
            // Send a connect request
            assertThat(mA2dpService.connect(testDevice)).isTrue();
            dispatchAtLeastOneMessage();
            // Verify the connection state broadcast, and that we are in Connecting state
            verifyConnectionStateIntent(
                    testDevice,
@@ -406,7 +441,7 @@ public class A2dpServiceTest {
            connCompletedEvent.device = testDevice;
            connCompletedEvent.valueInt = A2dpStackEvent.CONNECTION_STATE_CONNECTED;
            mA2dpService.messageFromNative(connCompletedEvent);

            dispatchAtLeastOneMessage();
            // Verify the connection state broadcast, and that we are in Connected state
            verifyConnectionStateIntent(
                    testDevice,
@@ -455,7 +490,9 @@ public class A2dpServiceTest {
        assertThat(mA2dpService.getConnectionState(sTestDevice))
                .isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mA2dpService.getDevices()).contains(sTestDevice);

        mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE);
        dispatchAtLeastOneMessage();
        assertThat(mA2dpService.getDevices()).doesNotContain(sTestDevice);

        // A2DP stack event: CONNECTION_STATE_CONNECTED - state machine should be created
@@ -481,7 +518,9 @@ public class A2dpServiceTest {
        assertThat(mA2dpService.getConnectionState(sTestDevice))
                .isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mA2dpService.getDevices()).contains(sTestDevice);

        mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE);
        dispatchAtLeastOneMessage();
        assertThat(mA2dpService.getDevices()).doesNotContain(sTestDevice);

        // A2DP stack event: CONNECTION_STATE_DISCONNECTING - state machine should not be created
@@ -584,6 +623,7 @@ public class A2dpServiceTest {
                .isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
        assertThat(mA2dpService.getDevices()).contains(sTestDevice);
        mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE);
        dispatchAtLeastOneMessage();
        assertThat(mA2dpService.getDevices()).doesNotContain(sTestDevice);
    }

@@ -645,6 +685,7 @@ public class A2dpServiceTest {
        assertThat(mA2dpService.getDevices()).contains(sTestDevice);
        // Device unbond - state machine is removed
        mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE);
        dispatchAtLeastOneMessage();
        assertThat(mA2dpService.getDevices()).doesNotContain(sTestDevice);
    }

@@ -757,6 +798,8 @@ public class A2dpServiceTest {
        assertThat(mA2dpService.getActiveDevice()).isEqualTo(sTestDevice);

        assertThat(mA2dpService.disconnect(sTestDevice)).isTrue();
        dispatchAtLeastOneMessage();

        verifyConnectionStateIntent(
                sTestDevice,
                BluetoothProfile.STATE_DISCONNECTING,
@@ -785,6 +828,8 @@ public class A2dpServiceTest {
        assertThat(mA2dpService.getActiveDevice()).isEqualTo(sTestDevice);

        assertThat(mA2dpService.disconnect(sTestDevice)).isTrue();
        dispatchAtLeastOneMessage();

        verifyConnectionStateIntent(
                sTestDevice,
                BluetoothProfile.STATE_DISCONNECTING,
@@ -1009,6 +1054,7 @@ public class A2dpServiceTest {

        // Send a connect request
        assertThat(mA2dpService.connect(device)).isTrue();
        dispatchAtLeastOneMessage();

        // Verify the connection state broadcast, and that we are in Connecting state
        verifyConnectionStateIntent(
@@ -1025,6 +1071,7 @@ public class A2dpServiceTest {
        connCompletedEvent.device = device;
        connCompletedEvent.valueInt = A2dpStackEvent.CONNECTION_STATE_CONNECTED;
        mA2dpService.messageFromNative(connCompletedEvent);
        dispatchAtLeastOneMessage();

        // Verify the connection state broadcast, and that we are in Connected state
        verifyConnectionStateIntent(
@@ -1038,6 +1085,8 @@ public class A2dpServiceTest {
        for (BluetoothDevice prevDevice : prevConnectedDevices) {
            assertThat(mA2dpService.getConnectedDevices()).contains(prevDevice);
        }

        dispatchNoMessages();
    }

    private void generateConnectionMessageFromNative(
@@ -1047,8 +1096,10 @@ public class A2dpServiceTest {
        stackEvent.device = device;
        stackEvent.valueInt = newConnectionState;
        mA2dpService.messageFromNative(stackEvent);
        dispatchAtLeastOneMessage();
        // Verify the connection state broadcast
        verifyConnectionStateIntent(device, newConnectionState, oldConnectionState);
        dispatchNoMessages();
    }

    private void generateUnexpectedConnectionMessageFromNative(
@@ -1061,6 +1112,7 @@ public class A2dpServiceTest {
        // Verify the connection state broadcast
        mInOrder.verify(mAdapterService, timeout(TIMEOUT.toMillis()).times(0))
                .sendBroadcast(any(), any(), any());
        dispatchNoMessages();
    }

    private void generateAudioMessageFromNative(
@@ -1070,12 +1122,14 @@ public class A2dpServiceTest {
        stackEvent.device = device;
        stackEvent.valueInt = audioStackEvent;
        mA2dpService.messageFromNative(stackEvent);
        dispatchAtLeastOneMessage();
        // Verify the audio state broadcast
        verifyIntentSent(
                hasAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED),
                hasExtra(BluetoothDevice.EXTRA_DEVICE, device),
                hasExtra(BluetoothProfile.EXTRA_STATE, newAudioState),
                hasExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, oldAudioState));
        dispatchNoMessages();
    }

    private void generateUnexpectedAudioMessageFromNative(
@@ -1097,6 +1151,7 @@ public class A2dpServiceTest {
        stackEvent.device = device;
        stackEvent.codecStatus = codecStatus;
        mA2dpService.messageFromNative(stackEvent);
        dispatchAtLeastOneMessage();
        verifyIntentSent(
                hasAction(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED),
                hasExtra(BluetoothDevice.EXTRA_DEVICE, device),
@@ -1263,4 +1318,25 @@ public class A2dpServiceTest {
                .setCodecSpecific4(codecSpecific4)
                .build();
    }

    // Dispatch messages for the A2dpService looper, and validate
    // that at least one message was handled.
    private void dispatchAtLeastOneMessage() {
        if (Flags.a2dpServiceLooper()) {
            assertThat(mLooper.dispatchAll()).isGreaterThan(0);
        }
    }

    // Validate that no messages are pending on the A2dpService looper.
    private void dispatchNoMessages() {
        if (Flags.a2dpServiceLooper()) {
            assertThat(mLooper.dispatchAll()).isEqualTo(0);
        }
    }

    private void moveTimeForward(long millis) {
        if (Flags.a2dpServiceLooper()) {
            mLooper.moveTimeForward(millis);
        }
    }
}
Loading