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

Commit c9513e7d authored by William Escande's avatar William Escande
Browse files

HeadsetTest: localAdapter & not depend on intent

instead of relying on intent being sent and received, directly check the
context to see what is ask to be sent

Bug: 338303046
Test: atest HeadsetServiceAndStateMachineTest
Test: atest HeadsetServiceTest
Flag: Exempt, test only
Change-Id: I5d5ce45a0190bd41b7967cd9a8074b035cdb524a
parent 5d3c398c
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -95,13 +95,4 @@ public class HeadsetObjectsFactory {
    public HeadsetSystemInterface makeSystemInterface(HeadsetService service) {
        return new HeadsetSystemInterface(service);
    }

    /**
     * Get a singleton native interface
     *
     * @return the singleton native interface
     */
    public HeadsetNativeInterface getNativeInterface() {
        return HeadsetNativeInterface.getInstance();
    }
}
+19 −16
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import static android.Manifest.permission.MODIFY_PHONE_STATE;
import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;
import static com.android.modules.utils.build.SdkLevel.isAtLeastU;

import static java.util.Objects.requireNonNull;

import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothClass;
@@ -128,16 +130,17 @@ public class HeadsetService extends ProfileService {
    // Timeout for state machine thread join, to prevent potential ANR.
    private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;

    private final AdapterService mAdapterService;
    private final DatabaseManager mDatabaseManager;
    private final HeadsetNativeInterface mNativeInterface;
    private final HashMap<BluetoothDevice, HeadsetStateMachine> mStateMachines = new HashMap<>();

    private int mMaxHeadsetConnections = 1;
    private BluetoothDevice mActiveDevice;
    private AdapterService mAdapterService;
    private DatabaseManager mDatabaseManager;
    private HandlerThread mStateMachinesThread;
    private Handler mStateMachinesThreadHandler;
    private Handler mHandler;
    // This is also used as a lock for shared data in HeadsetService
    private final HashMap<BluetoothDevice, HeadsetStateMachine> mStateMachines = new HashMap<>();
    private HeadsetNativeInterface mNativeInterface;
    private HeadsetSystemInterface mSystemInterface;
    private boolean mAudioRouteAllowed = true;
    // Indicates whether SCO audio needs to be forced to open regardless ANY OTHER restrictions
@@ -160,9 +163,18 @@ public class HeadsetService extends ProfileService {

    @VisibleForTesting ServiceFactory mFactory = new ServiceFactory();

    public HeadsetService(Context ctx) {
        super(ctx);
    public HeadsetService(AdapterService adapterService) {
        this(adapterService, HeadsetNativeInterface.getInstance());
    }

    @VisibleForTesting
    HeadsetService(AdapterService adapterService, HeadsetNativeInterface nativeInterface) {
        super(requireNonNull(adapterService));
        mAdapterService = adapterService;
        mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
        mNativeInterface = requireNonNull(nativeInterface);
    }

    public static boolean isEnabled() {
        return BluetoothProperties.isProfileHfpAgEnabled().orElse(false);
    }
@@ -181,11 +193,6 @@ public class HeadsetService extends ProfileService {

        setComponentAvailable(HFP_AG_IN_CALL_SERVICE, true);

        // Step 1: Get AdapterService and DatabaseManager, should never be null
        mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(),
                "AdapterService cannot be null when HeadsetService starts");
        mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(),
                "DatabaseManager cannot be null when HeadsetService starts");
        // Step 2: Start handler thread for state machines
        mHandler = new Handler(Looper.getMainLooper());
        mStateMachinesThread = new HandlerThread("HeadsetService.StateMachines");
@@ -204,7 +211,6 @@ public class HeadsetService extends ProfileService {
        }
        setHeadsetService(this);
        mMaxHeadsetConnections = mAdapterService.getMaxConnectedAudioDevices();
        mNativeInterface = HeadsetObjectsFactory.getInstance().getNativeInterface();
        // Add 1 to allow a pending device to be connecting or disconnecting
        mNativeInterface.init(mMaxHeadsetConnections + 1, isInbandRingingEnabled());
        if (Flags.hfpCodecAptxVoice()) {
@@ -294,9 +300,6 @@ public class HeadsetService extends ProfileService {
        }

        // Step 1: Clear
        synchronized (mStateMachines) {
            mAdapterService = null;
        }
        setComponentAvailable(HFP_AG_IN_CALL_SERVICE, false);
    }

@@ -930,7 +933,7 @@ public class HeadsetService extends ProfileService {
    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
        ArrayList<BluetoothDevice> devices = new ArrayList<>();
        synchronized (mStateMachines) {
            if (states == null || mAdapterService == null) {
            if (states == null) {
                return devices;
            }
            final BluetoothDevice[] bondedDevices = mAdapterService.getBondedDevices();
+14 −17
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static android.Manifest.permission.BLUETOOTH_CONNECT;

import static com.android.modules.utils.build.SdkLevel.isAtLeastU;

import static java.util.Objects.requireNonNull;

import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAssignedNumbers;
@@ -84,9 +86,8 @@ import java.util.Scanner;
 *                           V      |
 *                           (AudioOn)
 */
@VisibleForTesting
public class HeadsetStateMachine extends StateMachine {
    private static final String TAG = "HeadsetStateMachine";
class HeadsetStateMachine extends StateMachine {
    private static final String TAG = HeadsetStateMachine.class.getSimpleName();

    static final int CONNECT = 1;
    static final int DISCONNECT = 2;
@@ -123,8 +124,6 @@ public class HeadsetStateMachine extends StateMachine {
    private static final HeadsetAgIndicatorEnableState DEFAULT_AG_INDICATOR_ENABLE_STATE =
            new HeadsetAgIndicatorEnableState(true, true, true, true);

    private final BluetoothDevice mDevice;

    // State machine states
    private final Disconnected mDisconnected = new Disconnected();
    private final Connecting mConnecting = new Connecting();
@@ -137,11 +136,12 @@ public class HeadsetStateMachine extends StateMachine {
    private HeadsetStateBase mCurrentState;

    // Run time dependencies
    private final BluetoothDevice mDevice;
    private final HeadsetService mHeadsetService;
    private final AdapterService mAdapterService;
    private final HeadsetNativeInterface mNativeInterface;
    private final HeadsetSystemInterface mSystemInterface;
    private DatabaseManager mDatabaseManager;
    private final DatabaseManager mDatabaseManager;

    // Runtime states
    @VisibleForTesting
@@ -201,22 +201,19 @@ public class HeadsetStateMachine extends StateMachine {
    private HeadsetStateMachine(BluetoothDevice device, Looper looper,
            HeadsetService headsetService, AdapterService adapterService,
            HeadsetNativeInterface nativeInterface, HeadsetSystemInterface systemInterface) {
        super(TAG, Objects.requireNonNull(looper, "looper cannot be null"));
        super(TAG, requireNonNull(looper));

        // Let the logging framework enforce the log level. TAG is set above in the parent
        // constructor.
        setDbg(true);

        mDevice = Objects.requireNonNull(device, "device cannot be null");
        mHeadsetService = Objects.requireNonNull(headsetService, "headsetService cannot be null");
        mNativeInterface =
                Objects.requireNonNull(nativeInterface, "nativeInterface cannot be null");
        mSystemInterface =
                Objects.requireNonNull(systemInterface, "systemInterface cannot be null");
        mAdapterService = Objects.requireNonNull(adapterService, "AdapterService cannot be null");
        mDatabaseManager = Objects.requireNonNull(
            AdapterService.getAdapterService().getDatabase(),
            "DatabaseManager cannot be null when HeadsetClientStateMachine is created");
        mDevice = requireNonNull(device);
        mHeadsetService = requireNonNull(headsetService);
        mNativeInterface = requireNonNull(nativeInterface);
        mSystemInterface = requireNonNull(systemInterface);
        mAdapterService = requireNonNull(adapterService);
        mDatabaseManager = requireNonNull(adapterService.getDatabase());

        mDeviceSilenced = false;

        BluetoothSinkAudioPolicy storedAudioPolicy =
+99 −167

File changed.

Preview size limit exceeded, changes collapsed.

+5 −5
Original line number Diff line number Diff line
@@ -104,7 +104,10 @@ public class HeadsetServiceTest {

    @Before
    public void setUp() throws Exception {
        TestUtils.setAdapterService(mAdapterService);
        doReturn(mTargetContext.getPackageName()).when(mAdapterService).getPackageName();
        doReturn(mTargetContext.getPackageManager()).when(mAdapterService).getPackageManager();
        doReturn(mTargetContext.getResources()).when(mAdapterService).getResources();

        HeadsetObjectsFactory.setInstanceForTesting(mObjectsFactory);
        doReturn(MAX_HEADSET_CONNECTIONS).when(mAdapterService).getMaxConnectedAudioDevices();
        doReturn(new ParcelUuid[] {BluetoothUuid.HFP})
@@ -164,13 +167,11 @@ public class HeadsetServiceTest {
                .when(mObjectsFactory)
                .makeStateMachine(any(), any(), any(), any(), any(), any());
        doReturn(mSystemInterface).when(mObjectsFactory).makeSystemInterface(any());
        doReturn(mNativeInterface).when(mObjectsFactory).getNativeInterface();
        HeadsetNativeInterface.setInstance(mNativeInterface);
        mHeadsetService = new HeadsetService(mTargetContext);
        mHeadsetService = new HeadsetService(mAdapterService, mNativeInterface);
        mHeadsetService.start();
        mHeadsetService.setAvailable(true);
        verify(mObjectsFactory).makeSystemInterface(mHeadsetService);
        verify(mObjectsFactory).getNativeInterface();
        mHeadsetService.setForceScoAudio(true);
    }

@@ -183,7 +184,6 @@ public class HeadsetServiceTest {
        mStateMachines.clear();
        mCurrentDevice = null;
        HeadsetObjectsFactory.setInstanceForTesting(null);
        TestUtils.clearAdapterService(mAdapterService);
    }

    /** Test to verify that HeadsetService can be successfully started */