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

Commit 5829b905 authored by Rahul Sabnis's avatar Rahul Sabnis
Browse files

Propagate the request for whether a headset device supports voice

recognition as well as echo cancellation and/or noise reduction from the
java layer to the native stack

Tag: #feature
Bug: 172960943
Test: Manual
Change-Id: Ic602713191ba0e71d46c0e3584d5356dca161952
parent 90786a07
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -593,6 +593,44 @@ static jboolean disconnectAudioNative(JNIEnv* env, jobject object,
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean isNoiseReductionSupportedNative(JNIEnv* env, jobject object,
                                                jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  bt_status_t status =
      sBluetoothHfpInterface->isNoiseReductionSupported((RawAddress*)addr);
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean isVoiceRecognitionSupportedNative(JNIEnv* env, jobject object,
                                                  jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  bt_status_t status =
      sBluetoothHfpInterface->isVoiceRecognitionSupported((RawAddress*)addr);
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object,
                                            jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
@@ -924,6 +962,10 @@ static JNINativeMethod sMethods[] = {
    {"disconnectHfpNative", "([B)Z", (void*)disconnectHfpNative},
    {"connectAudioNative", "([B)Z", (void*)connectAudioNative},
    {"disconnectAudioNative", "([B)Z", (void*)disconnectAudioNative},
    {"isNoiseReductionSupportedNative", "([B)Z",
     (void*)isNoiseReductionSupportedNative},
    {"isVoiceRecognitionSupportedNative", "([B)Z",
     (void*)isVoiceRecognitionSupportedNative},
    {"startVoiceRecognitionNative", "([B)Z",
     (void*)startVoiceRecognitionNative},
    {"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative},
+25 −0
Original line number Diff line number Diff line
@@ -297,6 +297,27 @@ public class HeadsetNativeInterface {
        return disconnectAudioNative(Utils.getByteAddress(device));
    }

    /**
     * Checks whether the device support echo cancellation and/or noise reduction via the AT+BRSF
     * bitmask
     *
     * @param device target headset
     * @return true if the device support echo cancellation or noise reduction, false otherwise
     */
    public boolean isNoiseReductionSupported(BluetoothDevice device) {
        return isNoiseReductionSupportedNative(Utils.getByteAddress(device));
    }

    /**
     * Checks whether the device supports voice recognition via the AT+BRSF bitmask
     *
     * @param device target headset
     * @return true if the device supports voice recognition, false otherwise
     */
    public boolean isVoiceRecognitionSupported(BluetoothDevice device) {
        return isVoiceRecognitionSupportedNative(Utils.getByteAddress(device));
    }

    /**
     * Start voice recognition
     *
@@ -475,6 +496,10 @@ public class HeadsetNativeInterface {

    private native boolean disconnectAudioNative(byte[] address);

    private native boolean isNoiseReductionSupportedNative(byte[] address);

    private native boolean isVoiceRecognitionSupportedNative(byte[] address);

    private native boolean startVoiceRecognitionNative(byte[] address);

    private native boolean stopVoiceRecognitionNative(byte[] address);
+28 −0
Original line number Diff line number Diff line
@@ -523,6 +523,26 @@ public class HeadsetService extends ProfileService {
            return service.getConnectionPolicy(device);
        }

        @Override
        public boolean isNoiseReductionSupported(BluetoothDevice device) {
            HeadsetService service = getService();
            if (service == null) {
                return false;
            }
            enforceBluetoothPermission(service);
            return service.isNoiseReductionSupported(device);
        }

        @Override
        public boolean isVoiceRecognitionSupported(BluetoothDevice device) {
            HeadsetService service = getService();
            if (service == null) {
                return false;
            }
            enforceBluetoothPermission(service);
            return service.isVoiceRecognitionSupported(device);
        }

        @Override
        public boolean startVoiceRecognition(BluetoothDevice device) {
            HeadsetService service = getService();
@@ -894,6 +914,14 @@ public class HeadsetService extends ProfileService {
                .getProfileConnectionPolicy(device, BluetoothProfile.HEADSET);
    }

    boolean isNoiseReductionSupported(BluetoothDevice device) {
        return mNativeInterface.isNoiseReductionSupported(device);
    }

    boolean isVoiceRecognitionSupported(BluetoothDevice device) {
        return mNativeInterface.isVoiceRecognitionSupported(device);
    }

    boolean startVoiceRecognition(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        Log.i(TAG, "startVoiceRecognition: device=" + device + ", " + Utils.getUidPidString());