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 <r.walczyna@samsung.com>
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();
is_callback_set_ = val;
}
+int BluetoothAdapter::AddPowerStateListener(const std::function<void(const int)>& listener) {
+ return power_state_listeners_.Add(listener);
+}
+
+void BluetoothAdapter::RemovePowerStateListener(int id) {
+ power_state_listeners_.Remove(id);
+}
+
} // namespace bluetooth
} // namespace extension
#ifndef BLUETOOTH_BLUETOOTH_ADAPTER_H_
#define BLUETOOTH_BLUETOOTH_ADAPTER_H_
+#include <functional>
#include <list>
#include <map>
#include <memory>
class BluetoothInstance;
+class PowerStateListenersManager {
+ public:
+ PowerStateListenersManager() : count_(0) {
+ ScopeLogger();
+ }
+
+ ~PowerStateListenersManager() {
+ ScopeLogger();
+ power_state_listeners_map_.clear();
+ }
+
+ int Add(const std::function<void(const int)>& 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<int, std::function<void(const int)>> power_state_listeners_map_;
+ int count_;
+};
+
class BluetoothAdapter {
public:
/**
void UnregisterUUID(const std::string& uuid, int callback_handle);
void SetChangeListenerCallback(bool val);
+ int AddPowerStateListener(const std::function<void(const int)>& 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);
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]);
}
);
_BluetoothGATTServerReadWriteValueRequestCallbacks[
- "ReadValueCallback" + entityId
+ 'ReadValueCallback' + entityId
] = readValueRequestCallback;
native.callIfPossible(args.successCallback, native.getErrorObject(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
'BluetoothGattServerIsRunningChangeListener',
_BluetoothGattServerIsRunningChangeListener
);
+
+ // Register listener for managing BluetoothAdapter power off
+ native.addListener(
+ 'BluetoothGattServerBluetoothAdapterStateChangeListener',
+ _BluetoothGattServerBluetoothAdapterStateChangeListener
+ );
};
var BluetoothGATTServer_valid_registerService_errors = [
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();
return true;
}
+void BluetoothGATTServer::PowerStateChangeCb(bool state) {
+ ScopeLogger();
+ picojson::value result{picojson::object{}};
+ auto& obj = result.get<picojson::object>();
+
+ 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_) {
// 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();
return worker;
}
+BluetoothAdapter& BluetoothInstance::GetBluetoothAdapter() {
+ return bluetooth_adapter_;
+}
+
void BluetoothInstance::BluetoothAdapterSetName(const picojson::value& args,
picojson::object& out) {
ScopeLogger();
void FireEvent(const std::string& event, const std::shared_ptr<picojson::value>& value);
common::Worker& GetWorker();
+ BluetoothAdapter& GetBluetoothAdapter();
private:
void BluetoothAdapterSetName(const picojson::value& args, picojson::object& out);