From: Dawid Juszczak Date: Mon, 8 Jun 2020 18:14:47 +0000 (+0200) Subject: [Bluetooth] Fix onvisibilitychanged callback X-Git-Tag: submit/tizen/20200708.105445~9^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dc4ef2e4616be440024a7d71b494af31049bec16;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Bluetooth] Fix onvisibilitychanged callback https://code.sec.samsung.net/jira/browse/XWALK-2065 [Description] + removed unnecessary calls of onvisibilitychanged of BluetoothAdapterChangeCallback + refactor setVisible function [Verification] + tested manually on chrome console + tct-bluetooth-tizen-tests (auto) - 100% PASS Change-Id: I7edcb5a1028fec68d917a9b0e91a18c4d0d5294c Signed-off-by: Dawid Juszczak --- diff --git a/src/bluetooth/bluetooth_adapter.cc b/src/bluetooth/bluetooth_adapter.cc index d56079cf..8a4bed42 100644 --- a/src/bluetooth/bluetooth_adapter.cc +++ b/src/bluetooth/bluetooth_adapter.cc @@ -192,7 +192,7 @@ void BluetoothAdapter::VisibilityChangedCB(int result, bt_adapter_visibility_mod bool previous_visible = adapter->is_visible_; adapter->is_visible_ = visible; - if (previous_visible != visible) { + if (adapter->is_callback_set_ && previous_visible != visible) { picojson::value value = picojson::value(picojson::object()); picojson::object* data_obj = &value.get(); @@ -342,6 +342,7 @@ void BluetoothAdapter::DiscoveryStateChangedCB(int result, BluetoothAdapter::BluetoothAdapter(BluetoothInstance& instance) : is_response_sent_(false), + is_visible_response_sent_(false), is_callback_set_(false), is_visible_(false), is_powered_(false), @@ -670,139 +671,162 @@ void BluetoothAdapter::SetVisible(const picojson::value& data, picojson::object& if (!this->is_initialized()) { ret = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Bluetooth service is not initialized."); + instance_.AsyncResponse(callback_handle, ret); + return; } - if (ret.IsSuccess() && this->user_request_list_[SET_VISIBLE]) { + if (this->user_request_list_[SET_VISIBLE]) { ret = LogAndCreateResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR, "Already requested"); + instance_.AsyncResponse(callback_handle, ret); + return; } - if (ret.IsSuccess() && this->get_powered()) { - bt_adapter_visibility_mode_e new_mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE; - if (visible) { - if (0 == new_timeout) { - new_mode = BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE; - } else { - new_mode = BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE; - } + if (!this->get_powered()) { + ret = + LogAndCreateResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR, "Bluetooth device is turned off"); + instance_.AsyncResponse(callback_handle, ret); + return; + } + + bt_adapter_visibility_mode_e new_mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE; + if (visible) { + if (0 == new_timeout) { + new_mode = BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE; + } else { + new_mode = BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE; } + } - bt_adapter_visibility_mode_e cur_mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE; - int cur_timeout = 0; - int ntv_ret = bt_adapter_get_visibility(&cur_mode, &cur_timeout); - if (BT_ERROR_NONE != ntv_ret) { - ret = LogAndCreateResult( - ErrorCode::UNKNOWN_ERR, "Unknown exception", - ("bt_adapter_get_visibility error: %d (%s)", ntv_ret, get_error_message(ntv_ret))); + bt_adapter_visibility_mode_e cur_mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE; + int cur_timeout = 0; + int ntv_ret = bt_adapter_get_visibility(&cur_mode, &cur_timeout); + if (BT_ERROR_NONE != ntv_ret) { + ret = LogAndCreateResult( + ErrorCode::UNKNOWN_ERR, "Unknown exception", + ("bt_adapter_get_visibility error: %d (%s)", ntv_ret, get_error_message(ntv_ret))); + instance_.AsyncResponse(callback_handle, ret); + return; + } + + if (new_mode == cur_mode && (BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE != new_mode || + (unsigned int)cur_timeout == new_timeout)) { + instance_.AsyncResponse(callback_handle, ret); + return; + } + + this->requested_visibility_ = new_mode; + this->user_request_callback_[SET_VISIBLE] = callback_handle; +#ifdef APP_CONTROL_SETTINGS_SUPPORT + app_control_h tmp_service{nullptr}; + int err = app_control_create(&tmp_service); + if (err != APP_CONTROL_ERROR_NONE) { + ret = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown exception", + ("app_control_create() failed: %d (%s)", err, get_error_message(err))); + instance_.AsyncResponse(callback_handle, ret); + return; + } + + std::unique_ptr::type, decltype(&app_control_destroy)> service( + tmp_service, &app_control_destroy); + + err = app_control_set_operation(service.get(), "http://tizen.org/appcontrol/operation/edit"); + if (err != APP_CONTROL_ERROR_NONE) { + ret = LogAndCreateResult( + ErrorCode::UNKNOWN_ERR, "Unknown exception", + ("app_control_set_operation() failed: %d (%s)", err, get_error_message(err))); + instance_.AsyncResponse(callback_handle, ret); + return; + } + + err = app_control_set_mime(service.get(), "application/x-bluetooth-visibility"); + if (err != APP_CONTROL_ERROR_NONE) { + ret = + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown exception", + ("app_control_set_mime() failed: %d (%s)", err, get_error_message(err))); + instance_.AsyncResponse(callback_handle, ret); + return; + } + + this->is_response_sent_ = false; + app_control_reply_cb reply_cb = [](app_control_h request, app_control_h reply, + app_control_result_e app_res, void* user_data) { + LoggerD("Inside app_control_send_launch_request_async() reply callback"); + BluetoothAdapter* adapter = static_cast(user_data); + + if (adapter->is_visible_response_sent_) { + LoggerE("response already sent"); + return; } - if (ret.IsSuccess() && new_mode == cur_mode) { - if (BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE != new_mode || - (unsigned int)cur_timeout == new_timeout) { - instance_.AsyncResponse(callback_handle, ret); - return; - } + if (app_res < APP_CONTROL_RESULT_SUCCEEDED) { + LoggerE("app control setVisible failed"); + adapter->is_visible_response_sent_ = true; + adapter->instance_.AsyncResponse( + adapter->user_request_callback_[SET_VISIBLE], + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown exception")); + } else { + adapter->user_request_list_[SET_VISIBLE] = true; } + }; - if (ret.IsSuccess()) { -#ifdef APP_CONTROL_SETTINGS_SUPPORT - app_control_h service; - int err = 0; + app_control_result_cb result_cb = [](app_control_h request, app_control_error_e app_res, + void* user_data) { + LoggerD("Inside app_control_send_launch_request_async() result callback"); - if ((err = app_control_create(&service)) != APP_CONTROL_ERROR_NONE) { - ret = - LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "app control create failed", - ("app control create failed: %d (%s)", err, get_error_message(err))); - } + BluetoothAdapter* adapter = static_cast(user_data); - if (ret.IsSuccess()) { - err = app_control_set_operation(service, "http://tizen.org/appcontrol/operation/edit"); - if (err != APP_CONTROL_ERROR_NONE) { - ret = LogAndCreateResult( - ErrorCode::UNKNOWN_ERR, "app control set operation failed", - ("app control set operation failed: %d (%s)", err, get_error_message(err))); - } - } + if (adapter->is_visible_response_sent_) { + LoggerE("response already sent"); + return; + } - if (ret.IsSuccess()) { - err = app_control_set_mime(service, "application/x-bluetooth-visibility"); - if (err != APP_CONTROL_ERROR_NONE) { - ret = LogAndCreateResult( - ErrorCode::UNKNOWN_ERR, "app control set mime failed", - ("app control set mime failed: %d (%s)", err, get_error_message(err))); - } - } + if (APP_CONTROL_ERROR_NONE != app_res) { + LoggerE("app control setVisible failed"); + adapter->user_request_list_[SET_VISIBLE] = false; + adapter->is_visible_response_sent_ = true; + adapter->instance_.AsyncResponse( + adapter->user_request_callback_[SET_VISIBLE], + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown exception")); + } else { + adapter->user_request_list_[SET_VISIBLE] = true; + } + }; - if (ret.IsSuccess()) { - const void* t_param[] = {this, &ret, &new_mode, &callback_handle}; - - err = app_control_send_launch_request( - service, - [](app_control_h request, app_control_h reply, app_control_result_e r, - void* user_data) { - BluetoothAdapter* self = static_cast(((void**)user_data)[0]); - PlatformResult* p_ret = static_cast(((void**)user_data)[1]); - bt_adapter_visibility_mode_e* p_new_mode = - static_cast(((void**)user_data)[2]); - double* p_callback_handle = static_cast(((void**)user_data)[3]); - - char* result = nullptr; - app_control_get_extra_data(reply, "result", &result); - LoggerD("bt visibility onoff: %s", result); - - if (strcmp(result, "success") == 0) { - self->requested_visibility_ = *p_new_mode; - self->user_request_list_[SET_VISIBLE] = true; - self->user_request_callback_[SET_VISIBLE] = *p_callback_handle; - } else { - *p_ret = - LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "app control setVisible failed"); - } - free(result); - }, - t_param); - - if (err != APP_CONTROL_ERROR_NONE) { - ret = LogAndCreateResult( - ErrorCode::UNKNOWN_ERR, "app control set launch request failed", - ("app control set launch request failed: %d (%s)", err, get_error_message(err))); - } - } + err = app_control_send_launch_request_async(service.get(), result_cb, reply_cb, this); + if (err != APP_CONTROL_ERROR_NONE) { + ret = LogAndCreateResult( + ErrorCode::UNKNOWN_ERR, "Unknown exception", + ("app_control_send_launch_request_async() failed: %d (%s)", err, get_error_message(err))); + instance_.AsyncResponse(callback_handle, ret); + return; + } - err = app_control_destroy(service); - if (err != APP_CONTROL_ERROR_NONE) { - ret = LogAndCreateResult( - ErrorCode::UNKNOWN_ERR, "app control destroy failed", - ("app control destroy failed: %d (%s)", err, get_error_message(err))); - } #else - this->requested_visibility_ = new_mode; - this->user_request_list_[SET_VISIBLE] = true; - this->user_request_callback_[SET_VISIBLE] = callback_handle; - int ntv_ret = bt_adapter_set_visibility(new_mode, new_timeout); - - switch (ntv_ret) { - case BT_ERROR_NONE: - // bt_adapter_visibility_mode_changed_cb() will be invoked - // if this function returns #BT_ERROR_NONE - break; - case BT_ERROR_INVALID_PARAMETER: - ret = LogAndCreateResult( - ErrorCode::INVALID_VALUES_ERR, "Invalid value", - ("bt_adapter_set_visibility error: %d (%s)", ntv_ret, get_error_message(ntv_ret))); - break; - default: - ret = LogAndCreateResult( - ErrorCode::UNKNOWN_ERR, "Unknown exception", - ("bt_adapter_set_visibility error: %d (%s)", ntv_ret, get_error_message(ntv_ret))); - } -#endif - } - } else if (ret.IsSuccess()) { - ret = - LogAndCreateResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR, "Bluetooth device is turned off"); + this->user_request_list_[SET_VISIBLE] = true; + int ntv_ret = bt_adapter_set_visibility(new_mode, new_timeout); + + switch (ntv_ret) { + case BT_ERROR_NONE: + // bt_adapter_visibility_mode_changed_cb() will be invoked + // if this function returns #BT_ERROR_NONE + break; + case BT_ERROR_INVALID_PARAMETER: + ret = LogAndCreateResult( + ErrorCode::INVALID_VALUES_ERR, "Invalid value", + ("bt_adapter_set_visibility error: %d (%s)", ntv_ret, get_error_message(ntv_ret))); + break; + default: + ret = LogAndCreateResult( + ErrorCode::UNKNOWN_ERR, "Unknown exception", + ("bt_adapter_set_visibility error: %d (%s)", ntv_ret, get_error_message(ntv_ret))); } - instance_.AsyncResponse(callback_handle, ret); + if (!ret) { + instance_.AsyncResponse(callback_handle, ret); + this->user_request_list_[SET_VISIBLE] = false; + return; + } +#endif } void BluetoothAdapter::DiscoverDevices(const picojson::value& /* data */, picojson::object& out) { diff --git a/src/bluetooth/bluetooth_adapter.h b/src/bluetooth/bluetooth_adapter.h index 5a759a23..caee94c2 100644 --- a/src/bluetooth/bluetooth_adapter.h +++ b/src/bluetooth/bluetooth_adapter.h @@ -332,6 +332,7 @@ class BluetoothAdapter { void InvokeSocketOnCloseEvent(int id); bool is_response_sent_; + bool is_visible_response_sent_; bool is_callback_set_; bool is_visible_; bool is_powered_;