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

Commit f373eebf authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

vc: Add AICS support

Initial support for the AICS

Bug: 291285174
Bug: 361263965
Test: atest bluetooth_vc_test VolumeControlNativeInterfaceTest
Flag: com.android.bluetooth.flags.leaudio_add_aics_support

Change-Id: I68dd438c03a68ffed51364a6d24737575717c41d
parent 353b6cdb
Loading
Loading
Loading
Loading
+336 −3
Original line number Original line Diff line number Diff line
@@ -36,6 +36,11 @@ static jmethodID method_onDeviceAvailable;
static jmethodID method_onExtAudioOutVolumeOffsetChanged;
static jmethodID method_onExtAudioOutVolumeOffsetChanged;
static jmethodID method_onExtAudioOutLocationChanged;
static jmethodID method_onExtAudioOutLocationChanged;
static jmethodID method_onExtAudioOutDescriptionChanged;
static jmethodID method_onExtAudioOutDescriptionChanged;
static jmethodID method_onExtAudioInStateChanged;
static jmethodID method_onExtAudioInStatusChanged;
static jmethodID method_onExtAudioInTypeChanged;
static jmethodID method_onExtAudioInGainPropsChanged;
static jmethodID method_onExtAudioInDescriptionChanged;


static VolumeControlInterface* sVolumeControlInterface = nullptr;
static VolumeControlInterface* sVolumeControlInterface = nullptr;
static std::shared_timed_mutex interface_mutex;
static std::shared_timed_mutex interface_mutex;
@@ -105,7 +110,8 @@ public:
                                 (jboolean)mute, group_id, (jboolean)isAutonomous);
                                 (jboolean)mute, group_id, (jboolean)isAutonomous);
  }
  }


  void OnDeviceAvailable(const RawAddress& bd_addr, uint8_t num_offsets) override {
  void OnDeviceAvailable(const RawAddress& bd_addr, uint8_t num_offsets,
                         uint8_t num_inputs) override {
    log::info("");
    log::info("");


    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
@@ -124,7 +130,7 @@ public:
    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
                                     reinterpret_cast<const jbyte*>(&bd_addr));
                                     reinterpret_cast<const jbyte*>(&bd_addr));
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDeviceAvailable, (jint)num_offsets,
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDeviceAvailable, (jint)num_offsets,
                                 addr.get());
                                 (jint)num_inputs, addr.get());
  }
  }


  void OnExtAudioOutVolumeOffsetChanged(const RawAddress& bd_addr, uint8_t ext_output_id,
  void OnExtAudioOutVolumeOffsetChanged(const RawAddress& bd_addr, uint8_t ext_output_id,
@@ -200,6 +206,122 @@ public:
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExtAudioOutDescriptionChanged,
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExtAudioOutDescriptionChanged,
                                 (jint)ext_output_id, description, addr.get());
                                 (jint)ext_output_id, description, addr.get());
  }
  }

  void OnExtAudioInStateChanged(const RawAddress& bd_addr, uint8_t ext_input_id, int8_t gain_val,
                                uint8_t gain_mode, bool mute) override {
    log::info("");

    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) {
      return;
    }

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(),
                                    sCallbackEnv->NewByteArray(sizeof(RawAddress)));
    if (!addr.get()) {
      log::error("Failed to get addr for {}", bd_addr);
      return;
    }

    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
                                     reinterpret_cast<const jbyte*>(&bd_addr));
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExtAudioInStateChanged, (jint)ext_input_id,
                                 (jint)gain_val, (jint)gain_mode, (jboolean)mute, addr.get());
  }

  void OnExtAudioInStatusChanged(const RawAddress& bd_addr, uint8_t ext_input_id,
                                 bluetooth::vc::VolumeInputStatus status) override {
    log::info("");

    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) {
      return;
    }

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(),
                                    sCallbackEnv->NewByteArray(sizeof(RawAddress)));
    if (!addr.get()) {
      log::error("Failed to get addr for {}", bd_addr);
      return;
    }

    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
                                     reinterpret_cast<const jbyte*>(&bd_addr));
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExtAudioInStatusChanged,
                                 (jint)ext_input_id, (jint)status, addr.get());
  }

  void OnExtAudioInTypeChanged(const RawAddress& bd_addr, uint8_t ext_input_id,
                               bluetooth::vc::VolumeInputType type) override {
    log::info("");

    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) {
      return;
    }

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(),
                                    sCallbackEnv->NewByteArray(sizeof(RawAddress)));
    if (!addr.get()) {
      log::error("Failed to get addr for {}", bd_addr);
      return;
    }

    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
                                     reinterpret_cast<const jbyte*>(&bd_addr));
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExtAudioInTypeChanged, (jint)ext_input_id,
                                 (jint)type, addr.get());
  }

  void OnExtAudioInGainPropsChanged(const RawAddress& bd_addr, uint8_t ext_input_id, uint8_t unit,
                                    int8_t min, int8_t max) override {
    log::info("");

    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) {
      return;
    }

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(),
                                    sCallbackEnv->NewByteArray(sizeof(RawAddress)));
    if (!addr.get()) {
      log::error("Failed to get addr for {}", bd_addr);
      return;
    }

    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
                                     reinterpret_cast<const jbyte*>(&bd_addr));
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExtAudioInGainPropsChanged,
                                 (jint)ext_input_id, (jint)unit, (jint)min, (jint)max, addr.get());
  }

  void OnExtAudioInDescriptionChanged(const RawAddress& bd_addr, uint8_t ext_input_id,
                                      std::string descr) override {
    log::info("");

    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) {
      return;
    }

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(),
                                    sCallbackEnv->NewByteArray(sizeof(RawAddress)));
    if (!addr.get()) {
      log::error("Failed to get addr for {}", bd_addr);
      return;
    }

    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
                                     reinterpret_cast<const jbyte*>(&bd_addr));
    jstring description = sCallbackEnv->NewStringUTF(descr.c_str());
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExtAudioInDescriptionChanged,
                                 (jint)ext_input_id, description, addr.get());
  }
};
};


static VolumeControlCallbacksImpl sVolumeControlCallbacks;
static VolumeControlCallbacksImpl sVolumeControlCallbacks;
@@ -514,6 +636,195 @@ static jboolean setExtAudioOutDescriptionNative(JNIEnv* env, jobject /* object *
  return JNI_TRUE;
  return JNI_TRUE;
}
}


/* Native methods for external audio inputs */
static jboolean getExtAudioInStateNative(JNIEnv* env, jobject /* object */, jbyteArray address,
                                         jint ext_input_id) {
  log::info("");
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sVolumeControlInterface) {
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  RawAddress* tmpraw = reinterpret_cast<RawAddress*>(addr);
  sVolumeControlInterface->GetExtAudioInState(*tmpraw, ext_input_id);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

static jboolean getExtAudioInStatusNative(JNIEnv* env, jobject /* object */, jbyteArray address,
                                          jint ext_input_id) {
  log::info("");
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sVolumeControlInterface) {
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  RawAddress* tmpraw = reinterpret_cast<RawAddress*>(addr);
  sVolumeControlInterface->GetExtAudioInStatus(*tmpraw, ext_input_id);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

static jboolean getExtAudioInTypeNative(JNIEnv* env, jobject /* object */, jbyteArray address,
                                        jint ext_input_id) {
  log::info("");
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sVolumeControlInterface) {
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  RawAddress* tmpraw = reinterpret_cast<RawAddress*>(addr);
  sVolumeControlInterface->GetExtAudioInType(*tmpraw, ext_input_id);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

static jboolean getExtAudioInGainPropsNative(JNIEnv* env, jobject /* object */, jbyteArray address,
                                             jint ext_input_id) {
  log::info("");
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sVolumeControlInterface) {
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  RawAddress* tmpraw = reinterpret_cast<RawAddress*>(addr);
  sVolumeControlInterface->GetExtAudioInGainProps(*tmpraw, ext_input_id);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

static jboolean getExtAudioInDescriptionNative(JNIEnv* env, jobject /* object */,
                                               jbyteArray address, jint ext_input_id) {
  log::info("");
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sVolumeControlInterface) {
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  RawAddress* tmpraw = reinterpret_cast<RawAddress*>(addr);
  sVolumeControlInterface->GetExtAudioInDescription(*tmpraw, ext_input_id);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

static jboolean setExtAudioInDescriptionNative(JNIEnv* env, jobject /* object */,
                                               jbyteArray address, jint ext_input_id,
                                               jstring descr) {
  log::info("");
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sVolumeControlInterface) {
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  std::string description;
  if (descr != nullptr) {
    const char* value = env->GetStringUTFChars(descr, nullptr);
    description = std::string(value);
    env->ReleaseStringUTFChars(descr, value);
  }

  RawAddress* tmpraw = reinterpret_cast<RawAddress*>(addr);
  sVolumeControlInterface->SetExtAudioInDescription(*tmpraw, ext_input_id, description);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

static jboolean setExtAudioInGainValueNative(JNIEnv* env, jobject /* object */, jbyteArray address,
                                             jint ext_input_id, jint gain_val) {
  log::info("");
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sVolumeControlInterface) {
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  RawAddress* tmpraw = reinterpret_cast<RawAddress*>(addr);
  sVolumeControlInterface->SetExtAudioInGainValue(*tmpraw, ext_input_id, gain_val);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

static jboolean setExtAudioInGainModeNative(JNIEnv* env, jobject /* object */, jbyteArray address,
                                            jint ext_input_id, jboolean mode_auto) {
  log::info("");
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sVolumeControlInterface) {
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  RawAddress* tmpraw = reinterpret_cast<RawAddress*>(addr);
  sVolumeControlInterface->SetExtAudioInGainMode(*tmpraw, ext_input_id, mode_auto);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

static jboolean setExtAudioInGainMuteNative(JNIEnv* env, jobject /* object */, jbyteArray address,
                                            jint ext_input_id, jboolean mute) {
  log::info("");
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sVolumeControlInterface) {
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  RawAddress* tmpraw = reinterpret_cast<RawAddress*>(addr);
  sVolumeControlInterface->SetExtAudioInGainMute(*tmpraw, ext_input_id, mute);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

int register_com_android_bluetooth_vc(JNIEnv* env) {
int register_com_android_bluetooth_vc(JNIEnv* env) {
  const JNINativeMethod methods[] = {
  const JNINativeMethod methods[] = {
          {"initNative", "()V", reinterpret_cast<void*>(initNative)},
          {"initNative", "()V", reinterpret_cast<void*>(initNative)},
@@ -540,6 +851,22 @@ int register_com_android_bluetooth_vc(JNIEnv* env) {
           reinterpret_cast<void*>(getExtAudioOutDescriptionNative)},
           reinterpret_cast<void*>(getExtAudioOutDescriptionNative)},
          {"setExtAudioOutDescriptionNative", "([BILjava/lang/String;)Z",
          {"setExtAudioOutDescriptionNative", "([BILjava/lang/String;)Z",
           reinterpret_cast<void*>(setExtAudioOutDescriptionNative)},
           reinterpret_cast<void*>(setExtAudioOutDescriptionNative)},
          {"getExtAudioInStateNative", "([BI)Z", reinterpret_cast<void*>(getExtAudioInStateNative)},
          {"getExtAudioInStatusNative", "([BI)Z",
           reinterpret_cast<void*>(getExtAudioInStatusNative)},
          {"getExtAudioInTypeNative", "([BI)Z", reinterpret_cast<void*>(getExtAudioInTypeNative)},
          {"getExtAudioInGainPropsNative", "([BI)Z",
           reinterpret_cast<void*>(getExtAudioInGainPropsNative)},
          {"getExtAudioInDescriptionNative", "([BI)Z",
           reinterpret_cast<void*>(getExtAudioInDescriptionNative)},
          {"setExtAudioInDescriptionNative", "([BILjava/lang/String;)Z",
           reinterpret_cast<void*>(setExtAudioInDescriptionNative)},
          {"setExtAudioInGainValueNative", "([BII)Z",
           reinterpret_cast<void*>(setExtAudioInGainValueNative)},
          {"setExtAudioInGainModeNative", "([BIZ)Z",
           reinterpret_cast<void*>(setExtAudioInGainModeNative)},
          {"setExtAudioInGainMuteNative", "([BIZ)Z",
           reinterpret_cast<void*>(setExtAudioInGainMuteNative)},
  };
  };
  const int result = REGISTER_NATIVE_METHODS(
  const int result = REGISTER_NATIVE_METHODS(
          env, "com/android/bluetooth/vc/VolumeControlNativeInterface", methods);
          env, "com/android/bluetooth/vc/VolumeControlNativeInterface", methods);
@@ -551,11 +878,17 @@ int register_com_android_bluetooth_vc(JNIEnv* env) {
          {"onConnectionStateChanged", "(I[B)V", &method_onConnectionStateChanged},
          {"onConnectionStateChanged", "(I[B)V", &method_onConnectionStateChanged},
          {"onVolumeStateChanged", "(IZI[BZ)V", &method_onVolumeStateChanged},
          {"onVolumeStateChanged", "(IZI[BZ)V", &method_onVolumeStateChanged},
          {"onGroupVolumeStateChanged", "(IZIZ)V", &method_onGroupVolumeStateChanged},
          {"onGroupVolumeStateChanged", "(IZIZ)V", &method_onGroupVolumeStateChanged},
          {"onDeviceAvailable", "(I[B)V", &method_onDeviceAvailable},
          {"onDeviceAvailable", "(II[B)V", &method_onDeviceAvailable},
          {"onExtAudioOutVolumeOffsetChanged", "(II[B)V", &method_onExtAudioOutVolumeOffsetChanged},
          {"onExtAudioOutVolumeOffsetChanged", "(II[B)V", &method_onExtAudioOutVolumeOffsetChanged},
          {"onExtAudioOutLocationChanged", "(II[B)V", &method_onExtAudioOutLocationChanged},
          {"onExtAudioOutLocationChanged", "(II[B)V", &method_onExtAudioOutLocationChanged},
          {"onExtAudioOutDescriptionChanged", "(ILjava/lang/String;[B)V",
          {"onExtAudioOutDescriptionChanged", "(ILjava/lang/String;[B)V",
           &method_onExtAudioOutDescriptionChanged},
           &method_onExtAudioOutDescriptionChanged},
          {"onExtAudioInStateChanged", "(IIIZ[B)V", &method_onExtAudioInStateChanged},
          {"onExtAudioInStatusChanged", "(II[B)V", &method_onExtAudioInStatusChanged},
          {"onExtAudioInTypeChanged", "(II[B)V", &method_onExtAudioInTypeChanged},
          {"onExtAudioInGainPropsChanged", "(IIII[B)V", &method_onExtAudioInGainPropsChanged},
          {"onExtAudioInDescriptionChanged", "(ILjava/lang/String;[B)V",
           &method_onExtAudioInDescriptionChanged},
  };
  };
  GET_JAVA_METHODS(env, "com/android/bluetooth/vc/VolumeControlNativeInterface", javaMethods);
  GET_JAVA_METHODS(env, "com/android/bluetooth/vc/VolumeControlNativeInterface", javaMethods);


+215 −1

File changed.

Preview size limit exceeded, changes collapsed.

+45 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,11 @@ public class VolumeControlStackEvent {
    public static final int EVENT_TYPE_EXT_AUDIO_OUT_VOL_OFFSET_CHANGED = 4;
    public static final int EVENT_TYPE_EXT_AUDIO_OUT_VOL_OFFSET_CHANGED = 4;
    public static final int EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED = 5;
    public static final int EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED = 5;
    public static final int EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED = 6;
    public static final int EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED = 6;
    public static final int EVENT_TYPE_EXT_AUDIO_IN_STATE_CHANGED = 7;
    public static final int EVENT_TYPE_EXT_AUDIO_IN_STATUS_CHANGED = 8;
    public static final int EVENT_TYPE_EXT_AUDIO_IN_TYPE_CHANGED = 9;
    public static final int EVENT_TYPE_EXT_AUDIO_IN_DESCR_CHANGED = 10;
    public static final int EVENT_TYPE_EXT_AUDIO_IN_GAIN_PROPS_CHANGED = 11;


    // Do not modify without updating the HAL bt_vc_aid.h files.
    // Do not modify without updating the HAL bt_vc_aid.h files.
    // Match up with enum class ConnectionState of bt_vc_aid.h.
    // Match up with enum class ConnectionState of bt_vc_aid.h.
@@ -41,6 +46,7 @@ public class VolumeControlStackEvent {
    public int valueInt1;
    public int valueInt1;
    public int valueInt2;
    public int valueInt2;
    public int valueInt3;
    public int valueInt3;
    public int valueInt4;
    public boolean valueBool1;
    public boolean valueBool1;
    public boolean valueBool2;
    public boolean valueBool2;
    public String valueString1;
    public String valueString1;
@@ -60,6 +66,7 @@ public class VolumeControlStackEvent {
        result.append(", valueInt1:").append(eventTypeValue1ToString(type, valueInt1));
        result.append(", valueInt1:").append(eventTypeValue1ToString(type, valueInt1));
        result.append(", valueInt2:").append(eventTypeValue2ToString(type, valueInt2));
        result.append(", valueInt2:").append(eventTypeValue2ToString(type, valueInt2));
        result.append(", valueInt3:").append(eventTypeValue3ToString(type, valueInt3));
        result.append(", valueInt3:").append(eventTypeValue3ToString(type, valueInt3));
        result.append(", valueInt4:").append(eventTypeValue4ToString(type, valueInt4));
        result.append(", valueBool1:").append(eventTypeValueBool1ToString(type, valueBool1));
        result.append(", valueBool1:").append(eventTypeValueBool1ToString(type, valueBool1));
        result.append(", valueBool2:").append(eventTypeValueBool2ToString(type, valueBool2));
        result.append(", valueBool2:").append(eventTypeValueBool2ToString(type, valueBool2));
        result.append(", valueString1:").append(eventTypeString1ToString(type, valueString1));
        result.append(", valueString1:").append(eventTypeString1ToString(type, valueString1));
@@ -83,6 +90,16 @@ public class VolumeControlStackEvent {
                return "EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED";
                return "EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED";
            case EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED:
                return "EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED";
                return "EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED";
            case EVENT_TYPE_EXT_AUDIO_IN_STATE_CHANGED:
                return "EVENT_TYPE_EXT_AUDIO_IN_STATE_CHANGED";
            case EVENT_TYPE_EXT_AUDIO_IN_STATUS_CHANGED:
                return "EVENT_TYPE_EXT_AUDIO_IN_STATUS_CHANGED";
            case EVENT_TYPE_EXT_AUDIO_IN_TYPE_CHANGED:
                return "EVENT_TYPE_EXT_AUDIO_IN_TYPE_CHANGED";
            case EVENT_TYPE_EXT_AUDIO_IN_DESCR_CHANGED:
                return "EVENT_TYPE_EXT_AUDIO_IN_DESCR_CHANGED";
            case EVENT_TYPE_EXT_AUDIO_IN_GAIN_PROPS_CHANGED:
                return "EVENT_TYPE_EXT_AUDIO_IN_GAIN_PROPS_CHANGED";
            default:
            default:
                return "EVENT_TYPE_UNKNOWN:" + type;
                return "EVENT_TYPE_UNKNOWN:" + type;
        }
        }
@@ -111,6 +128,12 @@ public class VolumeControlStackEvent {
            case EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED:
                return "{ext output id:" + value + "}";
                return "{ext output id:" + value + "}";
            case EVENT_TYPE_EXT_AUDIO_IN_STATE_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_IN_STATUS_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_IN_TYPE_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_IN_DESCR_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_IN_GAIN_PROPS_CHANGED:
                return "{ext input id:" + value + "}";
            default:
            default:
                break;
                break;
        }
        }
@@ -134,6 +157,14 @@ public class VolumeControlStackEvent {
                }
                }
            case EVENT_TYPE_VOLUME_STATE_CHANGED:
            case EVENT_TYPE_VOLUME_STATE_CHANGED:
                return "{volume:" + value + "}";
                return "{volume:" + value + "}";
            case EVENT_TYPE_DEVICE_AVAILABLE:
                return "{num_ext_inputs:" + value + "}";
            case EVENT_TYPE_EXT_AUDIO_IN_STATE_CHANGED:
                return "{ext gain val:" + value + "}";
            case EVENT_TYPE_EXT_AUDIO_IN_STATUS_CHANGED:
                return "{status:" + value + "}";
            case EVENT_TYPE_EXT_AUDIO_IN_TYPE_CHANGED:
                return "{type:" + value + "}";
            default:
            default:
                break;
                break;
        }
        }
@@ -142,6 +173,8 @@ public class VolumeControlStackEvent {


    private static String eventTypeValue3ToString(int type, int value) {
    private static String eventTypeValue3ToString(int type, int value) {
        switch (type) {
        switch (type) {
            case EVENT_TYPE_EXT_AUDIO_IN_STATE_CHANGED:
                return "{ext gain mode:" + value + "}";
            case EVENT_TYPE_VOLUME_STATE_CHANGED:
            case EVENT_TYPE_VOLUME_STATE_CHANGED:
                return "{flags:" + value + "}";
                return "{flags:" + value + "}";
            default:
            default:
@@ -150,9 +183,20 @@ public class VolumeControlStackEvent {
        return Integer.toString(value);
        return Integer.toString(value);
    }
    }


    private static String eventTypeValue4ToString(int type, int value) {
        switch (type) {
            case EVENT_TYPE_EXT_AUDIO_IN_GAIN_PROPS_CHANGED:
                return "{gain set max:" + value + "}";
            default:
                break;
        }
        return Integer.toString(value);
    }

    private static String eventTypeValueBool1ToString(int type, boolean value) {
    private static String eventTypeValueBool1ToString(int type, boolean value) {
        switch (type) {
        switch (type) {
            case EVENT_TYPE_VOLUME_STATE_CHANGED:
            case EVENT_TYPE_VOLUME_STATE_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_IN_STATE_CHANGED:
                return "{muted:" + value + "}";
                return "{muted:" + value + "}";
            default:
            default:
                break;
                break;
@@ -173,6 +217,7 @@ public class VolumeControlStackEvent {
    private static String eventTypeString1ToString(int type, String value) {
    private static String eventTypeString1ToString(int type, String value) {
        switch (type) {
        switch (type) {
            case EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED:
            case EVENT_TYPE_EXT_AUDIO_IN_DESCR_CHANGED:
                return "{description:" + value + "}";
                return "{description:" + value + "}";
            default:
            default:
                break;
                break;
+82 −1
Original line number Original line Diff line number Diff line
@@ -104,9 +104,10 @@ public class VolumeControlNativeInterfaceTest {
    @Test
    @Test
    public void onDeviceAvailable() {
    public void onDeviceAvailable() {
        int numOfExternalOutputs = 3;
        int numOfExternalOutputs = 3;
        int numOfExternalInputs = 0;
        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};


        mNativeInterface.onDeviceAvailable(numOfExternalOutputs, address);
        mNativeInterface.onDeviceAvailable(numOfExternalOutputs, numOfExternalInputs, address);


        ArgumentCaptor<VolumeControlStackEvent> event =
        ArgumentCaptor<VolumeControlStackEvent> event =
                ArgumentCaptor.forClass(VolumeControlStackEvent.class);
                ArgumentCaptor.forClass(VolumeControlStackEvent.class);
@@ -159,4 +160,84 @@ public class VolumeControlNativeInterfaceTest {
        assertThat(event.getValue().type)
        assertThat(event.getValue().type)
                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED);
                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED);
    }
    }

    @Test
    public void onExtAudioInStateChanged() {
        int externalInputId = 2;
        int gainValue = 1;
        int gainMode = 0;
        boolean mute = false;
        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};

        mNativeInterface.onExtAudioInStateChanged(
                externalInputId, gainValue, gainMode, mute, address);

        ArgumentCaptor<VolumeControlStackEvent> event =
                ArgumentCaptor.forClass(VolumeControlStackEvent.class);
        verify(mService).messageFromNative(event.capture());
        assertThat(event.getValue().type)
                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_IN_STATE_CHANGED);
    }

    @Test
    public void onExtAudioInStatusChanged() {
        int externalInputId = 2;
        int status = 1;
        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};

        mNativeInterface.onExtAudioInStatusChanged(externalInputId, status, address);

        ArgumentCaptor<VolumeControlStackEvent> event =
                ArgumentCaptor.forClass(VolumeControlStackEvent.class);
        verify(mService).messageFromNative(event.capture());
        assertThat(event.getValue().type)
                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_IN_STATUS_CHANGED);
    }

    @Test
    public void onExtAudioInTypeChanged() {
        int externalInputId = 2;
        int type = 1;
        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};

        mNativeInterface.onExtAudioInTypeChanged(externalInputId, type, address);

        ArgumentCaptor<VolumeControlStackEvent> event =
                ArgumentCaptor.forClass(VolumeControlStackEvent.class);
        verify(mService).messageFromNative(event.capture());
        assertThat(event.getValue().type)
                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_IN_TYPE_CHANGED);
    }

    @Test
    public void onExtAudioInDescriptionChanged() {
        int externalInputId = 2;
        String descr = "microphone";
        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};

        mNativeInterface.onExtAudioInDescriptionChanged(externalInputId, descr, address);

        ArgumentCaptor<VolumeControlStackEvent> event =
                ArgumentCaptor.forClass(VolumeControlStackEvent.class);
        verify(mService).messageFromNative(event.capture());
        assertThat(event.getValue().type)
                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_IN_DESCR_CHANGED);
    }

    @Test
    public void onExtAudioInGainPropsChanged() {
        int externalInputId = 2;
        int unit = 1;
        int min = 0;
        int max = 100;
        byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};

        mNativeInterface.onExtAudioInGainPropsChanged(externalInputId, unit, min, max, address);

        ArgumentCaptor<VolumeControlStackEvent> event =
                ArgumentCaptor.forClass(VolumeControlStackEvent.class);
        verify(mService).messageFromNative(event.capture());
        assertThat(event.getValue().type)
                .isEqualTo(VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_IN_GAIN_PROPS_CHANGED);
    }
}
}
+15 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading