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

Commit 66d93e84 authored by Poompatai Puntitpong's avatar Poompatai Puntitpong Committed by Automerger Merge Worker
Browse files

Merge "Add additional HFP AT commands that return device information to...

Merge "Add additional HFP AT commands that return device information to enhance IOP with remote devices" into main am: 25552a3e am: 60b8e6ae am: 9f7d5d85

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



Change-Id: Id8310d97cf5c88b56dd41651c24adadf2ed6c6eb
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents cf6f8a40 9f7d5d85
Loading
Loading
Loading
Loading
+80 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.bluetooth.BluetoothStatusCodes;
import android.bluetooth.hfp.BluetoothHfpProtoEnums;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Build;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
@@ -181,6 +182,18 @@ public class HeadsetStateMachine extends StateMachine {
        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put(
                BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV,
                BluetoothAssignedNumbers.APPLE);
        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put(
                BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGMI,
                BluetoothAssignedNumbers.GOOGLE);
        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put(
                BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGMR,
                BluetoothAssignedNumbers.GOOGLE);
        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put(
                BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGMM,
                BluetoothAssignedNumbers.GOOGLE);
        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put(
                BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGSN,
                BluetoothAssignedNumbers.GOOGLE);
    }

    private HeadsetStateMachine(BluetoothDevice device, Looper looper,
@@ -2030,7 +2043,32 @@ public class HeadsetStateMachine extends StateMachine {
    void processVendorSpecificAt(String atString, BluetoothDevice device) {
        log("processVendorSpecificAt - atString = " + atString);

        // Currently we accept only SET type commands.
        // Currently we accept only SET type commands, except the 4 AT commands
        // which requests the device's information: +CGMI, +CGMM, +CGMR and +CGSN, which we
        // responds to right away without any further processing.
        boolean isIopInfoRequestAt = true;
        switch (atString) {
            case BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGMI:
                processAtCgmi(device);
                break;
            case BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGMM:
                processAtCgmm(device);
                break;
            case BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGMR:
                processAtCgmr(device);
                break;
            case BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGSN:
                processAtCgsn(device);
                break;
            default:
                isIopInfoRequestAt = false;
        }
        if (isIopInfoRequestAt) {
            mNativeInterface.atResponseCode(device, HeadsetHalConstants.AT_RESPONSE_OK, 0);
            return;
        }

        // Check if the command is a SET type command.
        int indexOfEqual = atString.indexOf("=");
        if (indexOfEqual == -1) {
            Log.w(TAG, "processVendorSpecificAt: command type error in " + atString);
@@ -2221,6 +2259,47 @@ public class HeadsetStateMachine extends StateMachine {
        mNativeInterface.atResponseString(device, "+XAPL=iPhone," + String.valueOf(2));
    }

    /**
     * Process AT+CGMI AT command
     *
     * @param device Remote device that has sent this command
     */
    @VisibleForTesting
    void processAtCgmi(BluetoothDevice device) {
        mNativeInterface.atResponseString(device, Build.MANUFACTURER);
    }

    /**
     * Process AT+CGMM AT command
     *
     * @param device Remote device that has sent this command
     */
    @VisibleForTesting
    void processAtCgmm(BluetoothDevice device) {
        mNativeInterface.atResponseString(device, Build.MODEL);
    }

    /**
     * Process AT+CGMR AT command
     *
     * @param device Remote device that has sent this command
     */
    @VisibleForTesting
    void processAtCgmr(BluetoothDevice device) {
        mNativeInterface.atResponseString(
                device, String.format("%s (%s)", Build.VERSION.RELEASE, Build.VERSION.INCREMENTAL));
    }

    /**
     * Process AT+CGSN AT command
     *
     * @param device Remote device that has sent this command
     */
    @VisibleForTesting
    void processAtCgsn(BluetoothDevice device) {
        mNativeInterface.atResponseString(device, Build.getSerial());
    }

    @VisibleForTesting
    void processUnknownAt(String atString, BluetoothDevice device) {
        if (device == null) {
+45 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.content.ServiceConnection;
import android.database.Cursor;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.HandlerThread;
@@ -1374,7 +1375,7 @@ public class HeadsetStateMachineTest {
    }

    @Test
    public void testProcessVendorSpecificAt_withNoEqualSignCommand() {
    public void testProcessVendorSpecificAt_withNonExceptedNoEqualSignCommand() {
        String atString = "invalid_command";

        mHeadsetStateMachine.processVendorSpecificAt(atString, mTestDevice);
@@ -1413,6 +1414,49 @@ public class HeadsetStateMachineTest {
        verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
    }

    @Test
    public void testProcessVendorSpecificAt_withExceptedNoEqualSignCommandCGMI() {
        String atString = BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGMI;

        mHeadsetStateMachine.processVendorSpecificAt(atString, mTestDevice);

        verify(mNativeInterface).atResponseString(mTestDevice, Build.MANUFACTURER);
        verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
    }

    @Test
    public void testProcessVendorSpecificAt_withExceptedNoEqualSignCommandCGMM() {
        String atString = BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGMM;

        mHeadsetStateMachine.processVendorSpecificAt(atString, mTestDevice);

        verify(mNativeInterface).atResponseString(mTestDevice, Build.MODEL);
        verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
    }

    @Test
    public void testProcessVendorSpecificAt_withExceptedNoEqualSignCommandCGMR() {
        String atString = BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGMR;

        mHeadsetStateMachine.processVendorSpecificAt(atString, mTestDevice);

        verify(mNativeInterface)
                .atResponseString(
                        mTestDevice,
                        String.format("%s (%s)", Build.VERSION.RELEASE, Build.VERSION.INCREMENTAL));
        verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
    }

    @Test
    public void testProcessVendorSpecificAt_withExceptedNoEqualSignCommandCGSN() {
        String atString = BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_CGSN;

        mHeadsetStateMachine.processVendorSpecificAt(atString, mTestDevice);

        verify(mNativeInterface).atResponseString(mTestDevice, Build.getSerial());
        verify(mNativeInterface).atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
    }

    @Test
    public void testProcessVolumeEvent_withVolumeTypeMic() {
        when(mHeadsetService.getActiveDevice()).thenReturn(mTestDevice);
+29 −0
Original line number Diff line number Diff line
@@ -270,6 +270,35 @@ public final class BluetoothHeadset implements BluetoothProfile {
     */
    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT_BATTERY_LEVEL = "BATTERY";

    /**
     * A vendor-specific AT command that asks for the information about device manufacturer.
     *
     * @hide
     */
    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_CGMI = "+CGMI";

    /**
     * A vendor-specific AT command that asks for the information about the model of the device.
     *
     * @hide
     */
    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_CGMM = "+CGMM";

    /**
     * A vendor-specific AT command that asks for the revision information, for Android we will
     * return the OS version and build number.
     *
     * @hide
     */
    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_CGMR = "+CGMR";

    /**
     * A vendor-specific AT command that asks for the device's serial number.
     *
     * @hide
     */
    public static final String VENDOR_SPECIFIC_HEADSET_EVENT_CGSN = "+CGSN";

    /**
     * Headset state when SCO audio is not connected.
     * This state can be one of