From: Rafal Walczyna Date: Fri, 18 Sep 2020 11:25:33 +0000 (+0200) Subject: [Bluetooth] Add bluetooth power off listener for GATTServer X-Git-Tag: submit/tizen/20200918.124009^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=08d16b3ef73d82c23abb6bc11fdfd8e096cd0e4c;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Bluetooth] Add bluetooth power off listener for GATTServer GATTServer has to be stopped in case of bluetooth power off. [ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-263 [TASK] https://code.sec.samsung.net/jira/browse/XWALK-2161 [Verification] Tested in Chrome developer console Change-Id: I92cca9dec5b7847b5073e88845846ce5e8446474 Signed-off-by: Rafal Walczyna --- diff --git a/src/bluetooth/bluetooth_adapter.cc b/src/bluetooth/bluetooth_adapter.cc index f4aaf96c..17ad6c91 100644 --- a/src/bluetooth/bluetooth_adapter.cc +++ b/src/bluetooth/bluetooth_adapter.cc @@ -111,6 +111,8 @@ void BluetoothAdapter::StateChangedCB(int result, bt_adapter_state_e state, void bool previous_powered = adapter->is_powered_; adapter->is_powered_ = powered; + adapter->power_state_listeners_.FireAll(powered); + if (powered) { // update visible state if bluetooth device has been turned on adapter->is_visible_ = adapter->get_visible(); @@ -1803,5 +1805,13 @@ void BluetoothAdapter::SetChangeListenerCallback(bool val) { is_callback_set_ = val; } +int BluetoothAdapter::AddPowerStateListener(const std::function& listener) { + return power_state_listeners_.Add(listener); +} + +void BluetoothAdapter::RemovePowerStateListener(int id) { + power_state_listeners_.Remove(id); +} + } // namespace bluetooth } // namespace extension diff --git a/src/bluetooth/bluetooth_adapter.h b/src/bluetooth/bluetooth_adapter.h index caee94c2..f19107e9 100644 --- a/src/bluetooth/bluetooth_adapter.h +++ b/src/bluetooth/bluetooth_adapter.h @@ -17,6 +17,7 @@ #ifndef BLUETOOTH_BLUETOOTH_ADAPTER_H_ #define BLUETOOTH_BLUETOOTH_ADAPTER_H_ +#include #include #include #include @@ -35,6 +36,40 @@ enum AdapterAsyncEvent { SET_POWERED = 0, SET_NAME, SET_VISIBLE, DISCOVER_DEVICE class BluetoothInstance; +class PowerStateListenersManager { + public: + PowerStateListenersManager() : count_(0) { + ScopeLogger(); + } + + ~PowerStateListenersManager() { + ScopeLogger(); + power_state_listeners_map_.clear(); + } + + int Add(const std::function& listener) { + ScopeLogger(); + power_state_listeners_map_[count_] = listener; + return count_++; + } + + void Remove(int id) { + ScopeLogger(); + power_state_listeners_map_.erase(id); + } + + void FireAll(bool state) { + ScopeLogger(); + for (const auto& it : power_state_listeners_map_) { + it.second(state); + } + } + + private: + std::map> power_state_listeners_map_; + int count_; +}; + class BluetoothAdapter { public: /** @@ -305,11 +340,15 @@ class BluetoothAdapter { void UnregisterUUID(const std::string& uuid, int callback_handle); void SetChangeListenerCallback(bool val); + int AddPowerStateListener(const std::function& listener); + void RemovePowerStateListener(int id); private: BluetoothAdapter(const BluetoothAdapter&) = delete; BluetoothAdapter& operator=(const BluetoothAdapter&) = delete; + PowerStateListenersManager power_state_listeners_; + static void StateChangedCB(int result, bt_adapter_state_e state, void* user_data); static void NameChangedCB(char* name, void* user_data); static void VisibilityChangedCB(int result, bt_adapter_visibility_mode_e mode, void* user_data); diff --git a/src/bluetooth/bluetooth_api.js b/src/bluetooth/bluetooth_api.js index 290a4111..164784db 100755 --- a/src/bluetooth/bluetooth_api.js +++ b/src/bluetooth/bluetooth_api.js @@ -293,7 +293,7 @@ tizen.BluetoothLEAdvertiseData = function(dict) { if (T.isNull(v)) { servicesData_ = v; } else if (T.isArray(v)) { - var tmpArray = [] + var tmpArray = []; for (var i = 0; i < v.length; ++i) { if (v[i] instanceof tizen.BluetoothLEServiceData) { tmpArray.push(v[i]); @@ -2681,7 +2681,7 @@ var _setReadValueRequestCallbackCommon = function() { } ); _BluetoothGATTServerReadWriteValueRequestCallbacks[ - "ReadValueCallback" + entityId + 'ReadValueCallback' + entityId ] = readValueRequestCallback; native.callIfPossible(args.successCallback, native.getErrorObject(result)); } @@ -3773,6 +3773,12 @@ function _BluetoothGattServerIsRunningChangeListener(result) { _isBluetoothGATTServerRunning = result.state; } +function _BluetoothGattServerBluetoothAdapterStateChangeListener(result) { + if (_isBluetoothGATTServerRunning && false === result.state) { + _BluetoothGATTServerServicesRegisteredInNativeLayer = {}; + } +} + /* * This set is used in BluetoothGATTServer::start() to check which services * from BluetoothGATTServer::services have already been registered in native @@ -3803,6 +3809,12 @@ var BluetoothGATTServer = function() { 'BluetoothGattServerIsRunningChangeListener', _BluetoothGattServerIsRunningChangeListener ); + + // Register listener for managing BluetoothAdapter power off + native.addListener( + 'BluetoothGattServerBluetoothAdapterStateChangeListener', + _BluetoothGattServerBluetoothAdapterStateChangeListener + ); }; var BluetoothGATTServer_valid_registerService_errors = [ diff --git a/src/bluetooth/bluetooth_gatt_server.cc b/src/bluetooth/bluetooth_gatt_server.cc index d1a4bd67..fe331391 100644 --- a/src/bluetooth/bluetooth_gatt_server.cc +++ b/src/bluetooth/bluetooth_gatt_server.cc @@ -34,18 +34,27 @@ BluetoothGATTServer::BluetoothGATTServer(BluetoothInstance& instance, service_{service}, initialized_{false}, running_{false}, - handle_{nullptr} { + handle_{nullptr}, + power_state_change_callback_id_{-1} { ScopeLogger(); - /* - * TODO: register a callback, that deinitializes a server, unregisters its - * services, destroys handle_ and sets running_ to false - * when Bluetooth is turned off. - */ + + power_state_change_callback_id_ = + instance_.GetBluetoothAdapter().AddPowerStateListener([this](const int state) { + ScopeLogger("BluetoothGATTServer PowerStateListenerCallback: %d", state); + if ((false == state) && (true == running_)) { + UnregisterAllServicesImpl(); + DestroyAllGATTObjects(); + Deinitialize(); + PowerStateChangeCb(false); + SetRunningState(false); + } + }); } BluetoothGATTServer::~BluetoothGATTServer() { ScopeLogger(); + instance_.GetBluetoothAdapter().RemovePowerStateListener(power_state_change_callback_id_); UnregisterAllServicesImpl(); DestroyAllGATTObjects(); Deinitialize(); @@ -403,6 +412,18 @@ bool BluetoothGATTServer::DestroyDescriptor(int total, int index, bt_gatt_h hand return true; } +void BluetoothGATTServer::PowerStateChangeCb(bool state) { + ScopeLogger(); + picojson::value result{picojson::object{}}; + auto& obj = result.get(); + + obj.insert( + std::make_pair("listenerId", "BluetoothGattServerBluetoothAdapterStateChangeListener")); + obj.insert(std::make_pair("state", picojson::value(state))); + + Instance::PostMessage(&instance_, result.serialize().c_str()); +} + void BluetoothGATTServer::SetRunningState(bool state) { ScopeLogger(); if (state != running_) { diff --git a/src/bluetooth/bluetooth_gatt_server.h b/src/bluetooth/bluetooth_gatt_server.h index 9dc72be2..e63ce5b2 100644 --- a/src/bluetooth/bluetooth_gatt_server.h +++ b/src/bluetooth/bluetooth_gatt_server.h @@ -56,7 +56,9 @@ class BluetoothGATTServer { // always use SetRunningState(bool) to change value of running_ bool running_; bt_gatt_server_h handle_; + int power_state_change_callback_id_; + void PowerStateChangeCb(bool state); void SetRunningState(bool state); PlatformResult UnregisterAllServicesImpl(); diff --git a/src/bluetooth/bluetooth_instance.cc b/src/bluetooth/bluetooth_instance.cc index ad0e2b03..0a6bd70a 100644 --- a/src/bluetooth/bluetooth_instance.cc +++ b/src/bluetooth/bluetooth_instance.cc @@ -190,6 +190,10 @@ common::Worker& BluetoothInstance::GetWorker() { return worker; } +BluetoothAdapter& BluetoothInstance::GetBluetoothAdapter() { + return bluetooth_adapter_; +} + void BluetoothInstance::BluetoothAdapterSetName(const picojson::value& args, picojson::object& out) { ScopeLogger(); diff --git a/src/bluetooth/bluetooth_instance.h b/src/bluetooth/bluetooth_instance.h index a7043b2e..04156d00 100644 --- a/src/bluetooth/bluetooth_instance.h +++ b/src/bluetooth/bluetooth_instance.h @@ -51,6 +51,7 @@ class BluetoothInstance : public common::ParsedInstance { void FireEvent(const std::string& event, const std::shared_ptr& value); common::Worker& GetWorker(); + BluetoothAdapter& GetBluetoothAdapter(); private: void BluetoothAdapterSetName(const picojson::value& args, picojson::object& out);