diff --git a/system/btif/Android.bp b/system/btif/Android.bp index fb80afc44fd4999bcaa05f16faa9e691766b65c2..ad64e866eb81f94ec1c40e8ecf5da3744559e439 100644 --- a/system/btif/Android.bp +++ b/system/btif/Android.bp @@ -188,6 +188,7 @@ cc_library_static { "src/btif_gatt_test.cc", "src/btif_gatt_util.cc", "src/btif_iot_config.cc", + "src/btif_jni_task.cc", "src/btif_keystore.cc", "src/btif_metrics_logging.cc", "src/btif_profile_queue.cc", diff --git a/system/btif/BUILD.gn b/system/btif/BUILD.gn index 155dc28234e5efb090eec5d7da282ef7f8bde7be..87d19502cd4059724228bfecabb384aa124fc0b8 100644 --- a/system/btif/BUILD.gn +++ b/system/btif/BUILD.gn @@ -69,6 +69,7 @@ static_library("btif") { "src/btif_hf_client.cc", "src/btif_hh.cc", "src/btif_iot_config.cc", + "src/btif_jni_task.cc", "src/btif_keystore.cc", "src/btif_le_audio.cc", "src/btif_metrics_logging.cc", diff --git a/system/btif/include/btif_jni_task.h b/system/btif/include/btif_jni_task.h new file mode 100644 index 0000000000000000000000000000000000000000..e2771db2a4f04cbff5ddba3794ab3fe98a9423cf --- /dev/null +++ b/system/btif/include/btif_jni_task.h @@ -0,0 +1,57 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "btif/include/btif_common.h" +#include "include/hardware/bluetooth.h" + +void jni_thread_startup(); +void jni_thread_shutdown(); + +/******************************************************************************* + * + * Function btif_transfer_context + * + * Description This function switches context to btif task + * + * p_cback : callback used to process message in btif context + * event : event id of message + * p_params : parameter area passed to callback (copied) + * param_len : length of parameter area + * p_copy_cback : If set this function will be invoked for deep + * copy + * + * Returns void + * + ******************************************************************************/ + +bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event, + char* p_params, int param_len, + tBTIF_COPY_CBACK* p_copy_cback); + +/** + * This function posts a task into the btif message loop, that executes it in + * the JNI message loop. + **/ +bt_status_t do_in_jni_thread(const base::Location& from_here, + base::OnceClosure task); + +bt_status_t do_in_jni_thread(base::OnceClosure task); + +bool is_on_jni_thread(); + +void post_on_bt_jni(BtJniClosure closure); diff --git a/system/btif/src/btif_core.cc b/system/btif/src/btif_core.cc index 55532bdc73a14ff6c357a91d424bfe1b13cb6736..9327194e608a7d2a80f2095bb0cd5bc2efe8d3fa 100644 --- a/system/btif/src/btif_core.cc +++ b/system/btif/src/btif_core.cc @@ -42,6 +42,7 @@ #include "btif/include/btif_common.h" #include "btif/include/btif_config.h" #include "btif/include/btif_dm.h" +#include "btif/include/btif_jni_task.h" #include "btif/include/btif_pan.h" #include "btif/include/btif_profile_queue.h" #include "btif/include/btif_sock.h" @@ -65,8 +66,6 @@ using base::PlatformThread; using bluetooth::Uuid; using bluetooth::common::MessageLoopThread; -static void bt_jni_msg_ready(void* context); - /******************************************************************************* * Constants & Macros ******************************************************************************/ @@ -102,7 +101,6 @@ static tBTA_SERVICE_MASK btif_enabled_services = 0; */ static uint8_t btif_dut_mode = 0; -static MessageLoopThread jni_thread("bt_jni_thread"); static base::AtExitManager* exit_manager; static uid_set_t* uid_set; @@ -114,77 +112,6 @@ void btif_dm_enable_service(tBTA_SERVICE_ID service_id, bool enable); void btif_dm_load_local_oob(void); #endif -/******************************************************************************* - * - * Function btif_transfer_context - * - * Description This function switches context to btif task - * - * p_cback : callback used to process message in btif context - * event : event id of message - * p_params : parameter area passed to callback (copied) - * param_len : length of parameter area - * p_copy_cback : If set this function will be invoked for deep - * copy - * - * Returns void - * - ******************************************************************************/ - -bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event, - char* p_params, int param_len, - tBTIF_COPY_CBACK* p_copy_cback) { - tBTIF_CONTEXT_SWITCH_CBACK* p_msg = (tBTIF_CONTEXT_SWITCH_CBACK*)osi_malloc( - sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len); - - BTIF_TRACE_VERBOSE("btif_transfer_context event %d, len %d", event, - param_len); - - /* allocate and send message that will be executed in btif context */ - p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */ - p_msg->p_cb = p_cback; - - p_msg->event = event; /* callback event */ - - /* check if caller has provided a copy callback to do the deep copy */ - if (p_copy_cback) { - p_copy_cback(event, p_msg->p_param, p_params); - } else if (p_params) { - memcpy(p_msg->p_param, p_params, param_len); /* callback parameter data */ - } - - return do_in_jni_thread(base::BindOnce(&bt_jni_msg_ready, p_msg)); -} - -/** - * This function posts a task into the btif message loop, that executes it in - * the JNI message loop. - **/ -bt_status_t do_in_jni_thread(const base::Location& from_here, - base::OnceClosure task) { - if (!jni_thread.DoInThread(from_here, std::move(task))) { - LOG(ERROR) << __func__ << ": Post task to task runner failed!"; - return BT_STATUS_FAIL; - } - return BT_STATUS_SUCCESS; -} - -bt_status_t do_in_jni_thread(base::OnceClosure task) { - return do_in_jni_thread(FROM_HERE, std::move(task)); -} - -bool is_on_jni_thread() { - return jni_thread.GetThreadId() == PlatformThread::CurrentId(); -} - -static void do_post_on_bt_jni(BtJniClosure closure) { closure(); } - -void post_on_bt_jni(BtJniClosure closure) { - ASSERT(do_in_jni_thread(FROM_HERE, base::BindOnce(do_post_on_bt_jni, - std::move(closure))) == - BT_STATUS_SUCCESS); -} - /******************************************************************************* * * Function btif_is_dut_mode @@ -216,22 +143,6 @@ void btif_init_ok() { btif_dm_load_ble_local_keys(); } -/******************************************************************************* - * - * Function btif_task - * - * Description BTIF task handler managing all messages being passed - * Bluetooth HAL and BTA. - * - * Returns void - * - ******************************************************************************/ -static void bt_jni_msg_ready(void* context) { - tBTIF_CONTEXT_SWITCH_CBACK* p = (tBTIF_CONTEXT_SWITCH_CBACK*)context; - if (p->p_cb) p->p_cb(p->event, p->p_param); - osi_free(p); -} - /******************************************************************************* * * Function btif_init_bluetooth @@ -244,7 +155,7 @@ static void bt_jni_msg_ready(void* context) { bt_status_t btif_init_bluetooth() { LOG_INFO("%s entered", __func__); exit_manager = new base::AtExitManager(); - jni_thread.StartUp(); + jni_thread_startup(); GetInterfaceToProfiles()->events->invoke_thread_evt_cb(ASSOCIATE_JVM); LOG_INFO("%s finished", __func__); return BT_STATUS_SUCCESS; @@ -326,7 +237,7 @@ bt_status_t btif_cleanup_bluetooth() { btif_dm_cleanup(); GetInterfaceToProfiles()->events->invoke_thread_evt_cb(DISASSOCIATE_JVM); btif_queue_release(); - jni_thread.ShutDown(); + jni_thread_shutdown(); delete exit_manager; exit_manager = nullptr; btif_dut_mode = 0; diff --git a/system/btif/src/btif_jni_task.cc b/system/btif/src/btif_jni_task.cc new file mode 100644 index 0000000000000000000000000000000000000000..3e83c877979befc3da3f07b0d26443ce8f329d80 --- /dev/null +++ b/system/btif/src/btif_jni_task.cc @@ -0,0 +1,119 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "btif/include/btif_jni_task.h" + +#include <base/logging.h> +#include <base/threading/platform_thread.h> + +#include "common/message_loop_thread.h" +#include "include/hardware/bluetooth.h" +#include "osi/include/allocator.h" + +using base::PlatformThread; + +static bluetooth::common::MessageLoopThread jni_thread("bt_jni_thread"); + +void jni_thread_startup() { jni_thread.StartUp(); } + +void jni_thread_shutdown() { jni_thread.ShutDown(); } + +/******************************************************************************* + * + * Function btif_task + * + * Description BTIF task handler managing all messages being passed + * Bluetooth HAL and BTA. + * + * Returns void + * + ******************************************************************************/ +static void bt_jni_msg_ready(void* context) { + tBTIF_CONTEXT_SWITCH_CBACK* p = (tBTIF_CONTEXT_SWITCH_CBACK*)context; + if (p->p_cb) p->p_cb(p->event, p->p_param); + osi_free(p); +} + +/******************************************************************************* + * + * Function btif_transfer_context + * + * Description This function switches context to btif task + * + * p_cback : callback used to process message in btif context + * event : event id of message + * p_params : parameter area passed to callback (copied) + * param_len : length of parameter area + * p_copy_cback : If set this function will be invoked for deep + * copy + * + * Returns void + * + ******************************************************************************/ + +bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event, + char* p_params, int param_len, + tBTIF_COPY_CBACK* p_copy_cback) { + tBTIF_CONTEXT_SWITCH_CBACK* p_msg = (tBTIF_CONTEXT_SWITCH_CBACK*)osi_malloc( + sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len); + + BTIF_TRACE_VERBOSE("btif_transfer_context event %d, len %d", event, + param_len); + + /* allocate and send message that will be executed in btif context */ + p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */ + p_msg->p_cb = p_cback; + + p_msg->event = event; /* callback event */ + + /* check if caller has provided a copy callback to do the deep copy */ + if (p_copy_cback) { + p_copy_cback(event, p_msg->p_param, p_params); + } else if (p_params) { + memcpy(p_msg->p_param, p_params, param_len); /* callback parameter data */ + } + + return do_in_jni_thread(base::BindOnce(&bt_jni_msg_ready, p_msg)); +} + +/** + * This function posts a task into the btif message loop, that executes it in + * the JNI message loop. + **/ +bt_status_t do_in_jni_thread(const base::Location& from_here, + base::OnceClosure task) { + if (!jni_thread.DoInThread(from_here, std::move(task))) { + LOG(ERROR) << __func__ << ": Post task to task runner failed!"; + return BT_STATUS_FAIL; + } + return BT_STATUS_SUCCESS; +} + +bt_status_t do_in_jni_thread(base::OnceClosure task) { + return do_in_jni_thread(FROM_HERE, std::move(task)); +} + +bool is_on_jni_thread() { + return jni_thread.GetThreadId() == PlatformThread::CurrentId(); +} + +static void do_post_on_bt_jni(BtJniClosure closure) { closure(); } + +void post_on_bt_jni(BtJniClosure closure) { + ASSERT(do_in_jni_thread(FROM_HERE, base::BindOnce(do_post_on_bt_jni, + std::move(closure))) == + BT_STATUS_SUCCESS); +}