Loading OWNERS +1 −0 Original line number Original line Diff line number Diff line # Project owners # Project owners sattiraju@google.com sattiraju@google.com siyuanh@google.com siyuanh@google.com sungsoo@google.com zachoverflow@google.com zachoverflow@google.com # Per-file ownership # Per-file ownership Loading android/app/AndroidManifest.xml +1 −0 Original line number Original line Diff line number Diff line Loading @@ -76,6 +76,7 @@ <uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS"/> <uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS"/> <uses-permission android:name="android.permission.QUERY_AUDIO_STATE"/> <uses-permission android:name="android.permission.QUERY_AUDIO_STATE"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.WRITE_SECURITY_LOG"/> <uses-sdk android:minSdkVersion="14"/> <uses-sdk android:minSdkVersion="14"/> Loading android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp +33 −0 Original line number Original line Diff line number Diff line Loading @@ -71,6 +71,7 @@ static jmethodID method_pinRequestCallback; static jmethodID method_sspRequestCallback; static jmethodID method_sspRequestCallback; static jmethodID method_bondStateChangeCallback; static jmethodID method_bondStateChangeCallback; static jmethodID method_addressConsolidateCallback; static jmethodID method_addressConsolidateCallback; static jmethodID method_leAddressAssociateCallback; static jmethodID method_aclStateChangeCallback; static jmethodID method_aclStateChangeCallback; static jmethodID method_discoveryStateChangeCallback; static jmethodID method_discoveryStateChangeCallback; static jmethodID method_linkQualityReportCallback; static jmethodID method_linkQualityReportCallback; Loading Loading @@ -336,6 +337,34 @@ static void address_consolidate_callback(RawAddress* main_bd_addr, main_addr.get(), secondary_addr.get()); main_addr.get(), secondary_addr.get()); } } static void le_address_associate_callback(RawAddress* main_bd_addr, RawAddress* secondary_bd_addr) { CallbackEnv sCallbackEnv(__func__); ScopedLocalRef<jbyteArray> main_addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!main_addr.get()) { ALOGE("Address allocation failed in %s", __func__); return; } sCallbackEnv->SetByteArrayRegion(main_addr.get(), 0, sizeof(RawAddress), (jbyte*)main_bd_addr); ScopedLocalRef<jbyteArray> secondary_addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!secondary_addr.get()) { ALOGE("Address allocation failed in %s", __func__); return; } sCallbackEnv->SetByteArrayRegion(secondary_addr.get(), 0, sizeof(RawAddress), (jbyte*)secondary_bd_addr); sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_leAddressAssociateCallback, main_addr.get(), secondary_addr.get()); } static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr, static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr, bt_acl_state_t state, bt_acl_state_t state, int transport_link_type, int transport_link_type, Loading Loading @@ -696,6 +725,7 @@ static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks), ssp_request_callback, ssp_request_callback, bond_state_changed_callback, bond_state_changed_callback, address_consolidate_callback, address_consolidate_callback, le_address_associate_callback, acl_state_changed_callback, acl_state_changed_callback, callback_thread_event, callback_thread_event, dut_mode_recv_callback, dut_mode_recv_callback, Loading Loading @@ -922,6 +952,9 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_addressConsolidateCallback = env->GetMethodID( method_addressConsolidateCallback = env->GetMethodID( jniCallbackClass, "addressConsolidateCallback", "([B[B)V"); jniCallbackClass, "addressConsolidateCallback", "([B[B)V"); method_leAddressAssociateCallback = env->GetMethodID( jniCallbackClass, "leAddressAssociateCallback", "([B[B)V"); method_aclStateChangeCallback = method_aclStateChangeCallback = env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BIII)V"); env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BIII)V"); Loading android/app/jni/com_android_bluetooth_gatt.cpp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -1587,6 +1587,7 @@ static void gattClientScanFilterAddNative(JNIEnv* env, jobject object, jfieldID nameFid = env->GetFieldID(entryClazz, "name", "Ljava/lang/String;"); jfieldID nameFid = env->GetFieldID(entryClazz, "name", "Ljava/lang/String;"); jfieldID companyFid = env->GetFieldID(entryClazz, "company", "I"); jfieldID companyFid = env->GetFieldID(entryClazz, "company", "I"); jfieldID companyMaskFid = env->GetFieldID(entryClazz, "company_mask", "I"); jfieldID companyMaskFid = env->GetFieldID(entryClazz, "company_mask", "I"); jfieldID adTypeFid = env->GetFieldID(entryClazz, "ad_type", "I"); jfieldID dataFid = env->GetFieldID(entryClazz, "data", "[B"); jfieldID dataFid = env->GetFieldID(entryClazz, "data", "[B"); jfieldID dataMaskFid = env->GetFieldID(entryClazz, "data_mask", "[B"); jfieldID dataMaskFid = env->GetFieldID(entryClazz, "data_mask", "[B"); Loading Loading @@ -1657,6 +1658,8 @@ static void gattClientScanFilterAddNative(JNIEnv* env, jobject object, curr.company_mask = env->GetIntField(current.get(), companyMaskFid); curr.company_mask = env->GetIntField(current.get(), companyMaskFid); curr.ad_type = env->GetByteField(current.get(), adTypeFid); ScopedLocalRef<jbyteArray> data( ScopedLocalRef<jbyteArray> data( env, (jbyteArray)env->GetObjectField(current.get(), dataFid)); env, (jbyteArray)env->GetObjectField(current.get(), dataFid)); if (data.get() != NULL) { if (data.get() != NULL) { Loading android/app/jni/com_android_bluetooth_le_audio.cpp +44 −11 Original line number Original line Diff line number Diff line Loading @@ -25,7 +25,6 @@ #include "com_android_bluetooth.h" #include "com_android_bluetooth.h" #include "hardware/bt_le_audio.h" #include "hardware/bt_le_audio.h" using bluetooth::le_audio::BroadcastAudioProfile; using bluetooth::le_audio::BroadcastId; using bluetooth::le_audio::BroadcastId; using bluetooth::le_audio::BroadcastState; using bluetooth::le_audio::BroadcastState; using bluetooth::le_audio::btle_audio_codec_config_t; using bluetooth::le_audio::btle_audio_codec_config_t; Loading Loading @@ -533,6 +532,16 @@ static void setCcidInformationNative(JNIEnv* env, jobject object, jint ccid, sLeAudioClientInterface->SetCcidInformation(ccid, contextType); sLeAudioClientInterface->SetCcidInformation(ccid, contextType); } } static void setInCallNative(JNIEnv* env, jobject object, jboolean inCall) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sLeAudioClientInterface) { LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface"; return; } sLeAudioClientInterface->SetInCall(inCall); } static JNINativeMethod sMethods[] = { static JNINativeMethod sMethods[] = { {"classInitNative", "()V", (void*)classInitNative}, {"classInitNative", "()V", (void*)classInitNative}, {"initNative", "([Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V", {"initNative", "([Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V", Loading @@ -548,6 +557,7 @@ static JNINativeMethod sMethods[] = { "BluetoothLeAudioCodecConfig;)V", "BluetoothLeAudioCodecConfig;)V", (void*)setCodecConfigPreferenceNative}, (void*)setCodecConfigPreferenceNative}, {"setCcidInformationNative", "(II)V", (void*)setCcidInformationNative}, {"setCcidInformationNative", "(II)V", (void*)setCcidInformationNative}, {"setInCallNative", "(Z)V", (void*)setInCallNative}, }; }; /* Le Audio Broadcaster */ /* Le Audio Broadcaster */ Loading Loading @@ -595,7 +605,7 @@ jbyteArray prepareRawLtvArray( (const jbyte*)&kv_pair.first); (const jbyte*)&kv_pair.first); offset += 1; offset += 1; // Value // Value env->SetByteArrayRegion(raw_metadata, offset, 1, env->SetByteArrayRegion(raw_metadata, offset, kv_pair.second.size(), (const jbyte*)kv_pair.second.data()); (const jbyte*)kv_pair.second.data()); offset += kv_pair.second.size(); offset += kv_pair.second.size(); } } Loading Loading @@ -829,7 +839,19 @@ jobject prepareBluetoothLeBroadcastMetadataObject( return nullptr; return nullptr; } } ScopedLocalRef<jbyteArray> code(env, env->NewByteArray(sizeof(RawAddress))); // Skip the leading null char bytes int nativeCodeSize = 16; int nativeCodeLeadingZeros = 0; if (broadcast_metadata.broadcast_code) { auto& nativeCode = broadcast_metadata.broadcast_code.value(); nativeCodeLeadingZeros = std::find_if(nativeCode.cbegin(), nativeCode.cend(), [](int x) { return x != 0x00; }) - nativeCode.cbegin(); nativeCodeSize = nativeCode.size() - nativeCodeLeadingZeros; } ScopedLocalRef<jbyteArray> code(env, env->NewByteArray(nativeCodeSize)); if (!code.get()) { if (!code.get()) { LOG(ERROR) << "Failed to create new jbyteArray for the broadcast code"; LOG(ERROR) << "Failed to create new jbyteArray for the broadcast code"; return nullptr; return nullptr; Loading @@ -837,8 +859,10 @@ jobject prepareBluetoothLeBroadcastMetadataObject( if (broadcast_metadata.broadcast_code) { if (broadcast_metadata.broadcast_code) { env->SetByteArrayRegion( env->SetByteArrayRegion( code.get(), 0, sizeof(RawAddress), code.get(), 0, nativeCodeSize, (jbyte*)broadcast_metadata.broadcast_code.value().data()); (const jbyte*)broadcast_metadata.broadcast_code->data() + nativeCodeLeadingZeros); CHECK(!env->ExceptionCheck()); } } return env->NewObject( return env->NewObject( Loading Loading @@ -1125,20 +1149,29 @@ static void BroadcasterCleanupNative(JNIEnv* env, jobject object) { } } static void CreateBroadcastNative(JNIEnv* env, jobject object, static void CreateBroadcastNative(JNIEnv* env, jobject object, jbyteArray metadata, jint audio_profile, jbyteArray metadata, jbyteArray broadcast_code) { jbyteArray broadcast_code) { LOG(INFO) << __func__; LOG(INFO) << __func__; std::shared_lock<std::shared_timed_mutex> lock(sBroadcasterInterfaceMutex); std::shared_lock<std::shared_timed_mutex> lock(sBroadcasterInterfaceMutex); if (!sLeAudioBroadcasterInterface) return; if (!sLeAudioBroadcasterInterface) return; std::array<uint8_t, 16> code_array; std::array<uint8_t, 16> code_array{0}; if (broadcast_code) if (broadcast_code) { env->GetByteArrayRegion(broadcast_code, 0, 16, (jbyte*)code_array.data()); jsize size = env->GetArrayLength(broadcast_code); if (size > 16) { ALOGE("%s: broadcast code to long", __func__); return; } // Padding with zeros on LSB positions if code is shorter than 16 octets env->GetByteArrayRegion( broadcast_code, 0, size, (jbyte*)code_array.data() + code_array.size() - size); } jbyte* meta = env->GetByteArrayElements(metadata, nullptr); jbyte* meta = env->GetByteArrayElements(metadata, nullptr); sLeAudioBroadcasterInterface->CreateBroadcast( sLeAudioBroadcasterInterface->CreateBroadcast( std::vector<uint8_t>(meta, meta + env->GetArrayLength(metadata)), std::vector<uint8_t>(meta, meta + env->GetArrayLength(metadata)), static_cast<BroadcastAudioProfile>(audio_profile), broadcast_code ? std::optional<std::array<uint8_t, 16>>(code_array) broadcast_code ? std::optional<std::array<uint8_t, 16>>(code_array) : std::nullopt); : std::nullopt); env->ReleaseByteArrayElements(metadata, meta, 0); env->ReleaseByteArrayElements(metadata, meta, 0); Loading Loading @@ -1198,7 +1231,7 @@ static JNINativeMethod sBroadcasterMethods[] = { {"initNative", "()V", (void*)BroadcasterInitNative}, {"initNative", "()V", (void*)BroadcasterInitNative}, {"stopNative", "()V", (void*)BroadcasterStopNative}, {"stopNative", "()V", (void*)BroadcasterStopNative}, {"cleanupNative", "()V", (void*)BroadcasterCleanupNative}, {"cleanupNative", "()V", (void*)BroadcasterCleanupNative}, {"createBroadcastNative", "([BI[B)V", (void*)CreateBroadcastNative}, {"createBroadcastNative", "([B[B)V", (void*)CreateBroadcastNative}, {"updateMetadataNative", "(I[B)V", (void*)UpdateMetadataNative}, {"updateMetadataNative", "(I[B)V", (void*)UpdateMetadataNative}, {"startBroadcastNative", "(I)V", (void*)StartBroadcastNative}, {"startBroadcastNative", "(I)V", (void*)StartBroadcastNative}, {"stopBroadcastNative", "(I)V", (void*)StopBroadcastNative}, {"stopBroadcastNative", "(I)V", (void*)StopBroadcastNative}, Loading Loading
OWNERS +1 −0 Original line number Original line Diff line number Diff line # Project owners # Project owners sattiraju@google.com sattiraju@google.com siyuanh@google.com siyuanh@google.com sungsoo@google.com zachoverflow@google.com zachoverflow@google.com # Per-file ownership # Per-file ownership Loading
android/app/AndroidManifest.xml +1 −0 Original line number Original line Diff line number Diff line Loading @@ -76,6 +76,7 @@ <uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS"/> <uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS"/> <uses-permission android:name="android.permission.QUERY_AUDIO_STATE"/> <uses-permission android:name="android.permission.QUERY_AUDIO_STATE"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.WRITE_SECURITY_LOG"/> <uses-sdk android:minSdkVersion="14"/> <uses-sdk android:minSdkVersion="14"/> Loading
android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp +33 −0 Original line number Original line Diff line number Diff line Loading @@ -71,6 +71,7 @@ static jmethodID method_pinRequestCallback; static jmethodID method_sspRequestCallback; static jmethodID method_sspRequestCallback; static jmethodID method_bondStateChangeCallback; static jmethodID method_bondStateChangeCallback; static jmethodID method_addressConsolidateCallback; static jmethodID method_addressConsolidateCallback; static jmethodID method_leAddressAssociateCallback; static jmethodID method_aclStateChangeCallback; static jmethodID method_aclStateChangeCallback; static jmethodID method_discoveryStateChangeCallback; static jmethodID method_discoveryStateChangeCallback; static jmethodID method_linkQualityReportCallback; static jmethodID method_linkQualityReportCallback; Loading Loading @@ -336,6 +337,34 @@ static void address_consolidate_callback(RawAddress* main_bd_addr, main_addr.get(), secondary_addr.get()); main_addr.get(), secondary_addr.get()); } } static void le_address_associate_callback(RawAddress* main_bd_addr, RawAddress* secondary_bd_addr) { CallbackEnv sCallbackEnv(__func__); ScopedLocalRef<jbyteArray> main_addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!main_addr.get()) { ALOGE("Address allocation failed in %s", __func__); return; } sCallbackEnv->SetByteArrayRegion(main_addr.get(), 0, sizeof(RawAddress), (jbyte*)main_bd_addr); ScopedLocalRef<jbyteArray> secondary_addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!secondary_addr.get()) { ALOGE("Address allocation failed in %s", __func__); return; } sCallbackEnv->SetByteArrayRegion(secondary_addr.get(), 0, sizeof(RawAddress), (jbyte*)secondary_bd_addr); sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_leAddressAssociateCallback, main_addr.get(), secondary_addr.get()); } static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr, static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr, bt_acl_state_t state, bt_acl_state_t state, int transport_link_type, int transport_link_type, Loading Loading @@ -696,6 +725,7 @@ static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks), ssp_request_callback, ssp_request_callback, bond_state_changed_callback, bond_state_changed_callback, address_consolidate_callback, address_consolidate_callback, le_address_associate_callback, acl_state_changed_callback, acl_state_changed_callback, callback_thread_event, callback_thread_event, dut_mode_recv_callback, dut_mode_recv_callback, Loading Loading @@ -922,6 +952,9 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_addressConsolidateCallback = env->GetMethodID( method_addressConsolidateCallback = env->GetMethodID( jniCallbackClass, "addressConsolidateCallback", "([B[B)V"); jniCallbackClass, "addressConsolidateCallback", "([B[B)V"); method_leAddressAssociateCallback = env->GetMethodID( jniCallbackClass, "leAddressAssociateCallback", "([B[B)V"); method_aclStateChangeCallback = method_aclStateChangeCallback = env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BIII)V"); env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BIII)V"); Loading
android/app/jni/com_android_bluetooth_gatt.cpp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -1587,6 +1587,7 @@ static void gattClientScanFilterAddNative(JNIEnv* env, jobject object, jfieldID nameFid = env->GetFieldID(entryClazz, "name", "Ljava/lang/String;"); jfieldID nameFid = env->GetFieldID(entryClazz, "name", "Ljava/lang/String;"); jfieldID companyFid = env->GetFieldID(entryClazz, "company", "I"); jfieldID companyFid = env->GetFieldID(entryClazz, "company", "I"); jfieldID companyMaskFid = env->GetFieldID(entryClazz, "company_mask", "I"); jfieldID companyMaskFid = env->GetFieldID(entryClazz, "company_mask", "I"); jfieldID adTypeFid = env->GetFieldID(entryClazz, "ad_type", "I"); jfieldID dataFid = env->GetFieldID(entryClazz, "data", "[B"); jfieldID dataFid = env->GetFieldID(entryClazz, "data", "[B"); jfieldID dataMaskFid = env->GetFieldID(entryClazz, "data_mask", "[B"); jfieldID dataMaskFid = env->GetFieldID(entryClazz, "data_mask", "[B"); Loading Loading @@ -1657,6 +1658,8 @@ static void gattClientScanFilterAddNative(JNIEnv* env, jobject object, curr.company_mask = env->GetIntField(current.get(), companyMaskFid); curr.company_mask = env->GetIntField(current.get(), companyMaskFid); curr.ad_type = env->GetByteField(current.get(), adTypeFid); ScopedLocalRef<jbyteArray> data( ScopedLocalRef<jbyteArray> data( env, (jbyteArray)env->GetObjectField(current.get(), dataFid)); env, (jbyteArray)env->GetObjectField(current.get(), dataFid)); if (data.get() != NULL) { if (data.get() != NULL) { Loading
android/app/jni/com_android_bluetooth_le_audio.cpp +44 −11 Original line number Original line Diff line number Diff line Loading @@ -25,7 +25,6 @@ #include "com_android_bluetooth.h" #include "com_android_bluetooth.h" #include "hardware/bt_le_audio.h" #include "hardware/bt_le_audio.h" using bluetooth::le_audio::BroadcastAudioProfile; using bluetooth::le_audio::BroadcastId; using bluetooth::le_audio::BroadcastId; using bluetooth::le_audio::BroadcastState; using bluetooth::le_audio::BroadcastState; using bluetooth::le_audio::btle_audio_codec_config_t; using bluetooth::le_audio::btle_audio_codec_config_t; Loading Loading @@ -533,6 +532,16 @@ static void setCcidInformationNative(JNIEnv* env, jobject object, jint ccid, sLeAudioClientInterface->SetCcidInformation(ccid, contextType); sLeAudioClientInterface->SetCcidInformation(ccid, contextType); } } static void setInCallNative(JNIEnv* env, jobject object, jboolean inCall) { std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sLeAudioClientInterface) { LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface"; return; } sLeAudioClientInterface->SetInCall(inCall); } static JNINativeMethod sMethods[] = { static JNINativeMethod sMethods[] = { {"classInitNative", "()V", (void*)classInitNative}, {"classInitNative", "()V", (void*)classInitNative}, {"initNative", "([Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V", {"initNative", "([Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V", Loading @@ -548,6 +557,7 @@ static JNINativeMethod sMethods[] = { "BluetoothLeAudioCodecConfig;)V", "BluetoothLeAudioCodecConfig;)V", (void*)setCodecConfigPreferenceNative}, (void*)setCodecConfigPreferenceNative}, {"setCcidInformationNative", "(II)V", (void*)setCcidInformationNative}, {"setCcidInformationNative", "(II)V", (void*)setCcidInformationNative}, {"setInCallNative", "(Z)V", (void*)setInCallNative}, }; }; /* Le Audio Broadcaster */ /* Le Audio Broadcaster */ Loading Loading @@ -595,7 +605,7 @@ jbyteArray prepareRawLtvArray( (const jbyte*)&kv_pair.first); (const jbyte*)&kv_pair.first); offset += 1; offset += 1; // Value // Value env->SetByteArrayRegion(raw_metadata, offset, 1, env->SetByteArrayRegion(raw_metadata, offset, kv_pair.second.size(), (const jbyte*)kv_pair.second.data()); (const jbyte*)kv_pair.second.data()); offset += kv_pair.second.size(); offset += kv_pair.second.size(); } } Loading Loading @@ -829,7 +839,19 @@ jobject prepareBluetoothLeBroadcastMetadataObject( return nullptr; return nullptr; } } ScopedLocalRef<jbyteArray> code(env, env->NewByteArray(sizeof(RawAddress))); // Skip the leading null char bytes int nativeCodeSize = 16; int nativeCodeLeadingZeros = 0; if (broadcast_metadata.broadcast_code) { auto& nativeCode = broadcast_metadata.broadcast_code.value(); nativeCodeLeadingZeros = std::find_if(nativeCode.cbegin(), nativeCode.cend(), [](int x) { return x != 0x00; }) - nativeCode.cbegin(); nativeCodeSize = nativeCode.size() - nativeCodeLeadingZeros; } ScopedLocalRef<jbyteArray> code(env, env->NewByteArray(nativeCodeSize)); if (!code.get()) { if (!code.get()) { LOG(ERROR) << "Failed to create new jbyteArray for the broadcast code"; LOG(ERROR) << "Failed to create new jbyteArray for the broadcast code"; return nullptr; return nullptr; Loading @@ -837,8 +859,10 @@ jobject prepareBluetoothLeBroadcastMetadataObject( if (broadcast_metadata.broadcast_code) { if (broadcast_metadata.broadcast_code) { env->SetByteArrayRegion( env->SetByteArrayRegion( code.get(), 0, sizeof(RawAddress), code.get(), 0, nativeCodeSize, (jbyte*)broadcast_metadata.broadcast_code.value().data()); (const jbyte*)broadcast_metadata.broadcast_code->data() + nativeCodeLeadingZeros); CHECK(!env->ExceptionCheck()); } } return env->NewObject( return env->NewObject( Loading Loading @@ -1125,20 +1149,29 @@ static void BroadcasterCleanupNative(JNIEnv* env, jobject object) { } } static void CreateBroadcastNative(JNIEnv* env, jobject object, static void CreateBroadcastNative(JNIEnv* env, jobject object, jbyteArray metadata, jint audio_profile, jbyteArray metadata, jbyteArray broadcast_code) { jbyteArray broadcast_code) { LOG(INFO) << __func__; LOG(INFO) << __func__; std::shared_lock<std::shared_timed_mutex> lock(sBroadcasterInterfaceMutex); std::shared_lock<std::shared_timed_mutex> lock(sBroadcasterInterfaceMutex); if (!sLeAudioBroadcasterInterface) return; if (!sLeAudioBroadcasterInterface) return; std::array<uint8_t, 16> code_array; std::array<uint8_t, 16> code_array{0}; if (broadcast_code) if (broadcast_code) { env->GetByteArrayRegion(broadcast_code, 0, 16, (jbyte*)code_array.data()); jsize size = env->GetArrayLength(broadcast_code); if (size > 16) { ALOGE("%s: broadcast code to long", __func__); return; } // Padding with zeros on LSB positions if code is shorter than 16 octets env->GetByteArrayRegion( broadcast_code, 0, size, (jbyte*)code_array.data() + code_array.size() - size); } jbyte* meta = env->GetByteArrayElements(metadata, nullptr); jbyte* meta = env->GetByteArrayElements(metadata, nullptr); sLeAudioBroadcasterInterface->CreateBroadcast( sLeAudioBroadcasterInterface->CreateBroadcast( std::vector<uint8_t>(meta, meta + env->GetArrayLength(metadata)), std::vector<uint8_t>(meta, meta + env->GetArrayLength(metadata)), static_cast<BroadcastAudioProfile>(audio_profile), broadcast_code ? std::optional<std::array<uint8_t, 16>>(code_array) broadcast_code ? std::optional<std::array<uint8_t, 16>>(code_array) : std::nullopt); : std::nullopt); env->ReleaseByteArrayElements(metadata, meta, 0); env->ReleaseByteArrayElements(metadata, meta, 0); Loading Loading @@ -1198,7 +1231,7 @@ static JNINativeMethod sBroadcasterMethods[] = { {"initNative", "()V", (void*)BroadcasterInitNative}, {"initNative", "()V", (void*)BroadcasterInitNative}, {"stopNative", "()V", (void*)BroadcasterStopNative}, {"stopNative", "()V", (void*)BroadcasterStopNative}, {"cleanupNative", "()V", (void*)BroadcasterCleanupNative}, {"cleanupNative", "()V", (void*)BroadcasterCleanupNative}, {"createBroadcastNative", "([BI[B)V", (void*)CreateBroadcastNative}, {"createBroadcastNative", "([B[B)V", (void*)CreateBroadcastNative}, {"updateMetadataNative", "(I[B)V", (void*)UpdateMetadataNative}, {"updateMetadataNative", "(I[B)V", (void*)UpdateMetadataNative}, {"startBroadcastNative", "(I)V", (void*)StartBroadcastNative}, {"startBroadcastNative", "(I)V", (void*)StartBroadcastNative}, {"stopBroadcastNative", "(I)V", (void*)StopBroadcastNative}, {"stopBroadcastNative", "(I)V", (void*)StopBroadcastNative}, Loading