sensord: detect that a sensor is added or removed in runtime (client-side) 52/126552/4
authorkibak.yoon <kibak.yoon@samsung.com>
Mon, 24 Apr 2017 06:48:07 +0000 (15:48 +0900)
committerKibak Yoon <kibak.yoon@samsung.com>
Mon, 24 Apr 2017 07:39:11 +0000 (07:39 +0000)
Change-Id: Ie9c4e93ca77f911226bce6b72f9517185bb43dd2
Signed-off-by: kibak.yoon <kibak.yoon@samsung.com>
src/client/sensor_manager.cpp
src/client/sensor_manager.h
src/client/sensor_manager_handler.cpp [new file with mode: 0644]
src/client/sensor_manager_handler.h [new file with mode: 0644]

index 2d14a4ddc53de10bae0f60ffe86acf49c9328cb3..11c61d98eb54270541482a938449af5d1b3b7efb 100644 (file)
 
 using namespace sensor;
 
-class manager_handler : public ipc::channel_handler
-{
-public:
-       manager_handler(sensor_manager *manager)
-       : m_manager(manager)
-       {}
-       void connected(ipc::channel *ch) {}
-       void disconnected(ipc::channel *ch)
-       {
-               /* If channel->disconnect() is not explicitly called, it will be restored */
-               m_manager->restore();
-       }
-
-       void read(ipc::channel *ch, ipc::message &msg)
-       {
-               /* TODO: if dynamic sensor is loaded,
-                * it will be called with the sensor information */
-       }
-
-       void read_complete(ipc::channel *ch) {}
-       void error_caught(ipc::channel *ch, int error) {}
-
-private:
-       sensor_manager *m_manager;
-};
-
 sensor_manager::sensor_manager()
 : m_client(NULL)
-, m_handler(NULL)
 , m_channel(NULL)
 , m_connected(false)
+, m_handler(NULL)
 {
        init();
 }
@@ -71,16 +45,6 @@ sensor_manager::~sensor_manager()
        deinit();
 }
 
-int sensor_manager::get_sensor(sensor_type_t type, sensor_t *sensor)
-{
-       return get_sensor(utils::get_uri(type), sensor);
-}
-
-int sensor_manager::get_sensors(sensor_type_t type, sensor_t **list, int *count)
-{
-       return get_sensors(utils::get_uri(type), list, count);
-}
-
 int sensor_manager::get_sensor(const char *uri, sensor_t *sensor)
 {
        if (!is_supported(uri)) {
@@ -143,12 +107,65 @@ bool sensor_manager::is_supported(const char *uri)
        return false;
 }
 
+int sensor_manager::add_sensor(sensor_info &info)
+{
+       retv_if(is_supported(info.get_uri().c_str()), OP_ERROR);
+
+       m_sensors.push_back(info);
+
+       return OP_SUCCESS;
+}
+
+int sensor_manager::add_sensor(sensor_provider *provider)
+{
+       retvm_if(!provider, -EINVAL, "Invalid parameter");
+       return add_sensor(*(provider->get_sensor_info()));
+}
+
+int sensor_manager::remove_sensor(const char *uri)
+{
+       for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) {
+               if ((*it).get_uri() == uri) {
+                       m_sensors.erase(it);
+                       return OP_SUCCESS;
+               }
+       }
+
+       return OP_ERROR;
+}
+
+int sensor_manager::remove_sensor(sensor_provider *provider)
+{
+       retvm_if(!provider, -EINVAL, "Invalid parameter");
+       return remove_sensor(provider->get_uri());
+}
+
+void sensor_manager::add_sensor_added_cb(sensord_added_cb cb, void *user_data)
+{
+       m_handler->add_sensor_added_cb(cb, user_data);
+}
+
+void sensor_manager::remove_sensor_added_cb(sensord_added_cb cb)
+{
+       m_handler->remove_sensor_added_cb(cb);
+}
+
+void sensor_manager::add_sensor_removed_cb(sensord_removed_cb cb, void *user_data)
+{
+       m_handler->add_sensor_removed_cb(cb, user_data);
+}
+
+void sensor_manager::remove_sensor_removed_cb(sensord_removed_cb cb)
+{
+       m_handler->remove_sensor_removed_cb(cb);
+}
+
 bool sensor_manager::init(void)
 {
        m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
        retvm_if(!m_client, false, "Failed to allocate memory");
 
-       m_handler = new(std::nothrow) manager_handler(this);
+       m_handler = new(std::nothrow) sensor_manager_handler(this);
        if (!m_handler) {
                delete m_client;
                m_client = NULL;
@@ -174,6 +191,16 @@ bool sensor_manager::connect_channel(void)
        m_channel = m_client->connect(m_handler, &m_loop);
        retvm_if(!m_channel, false, "Failed to connect to server");
 
+       ipc::message msg;
+       msg.set_type(CMD_MANAGER_CONNECT);
+       m_channel->send_sync(&msg);
+       m_channel->read_sync(msg);
+
+       if (msg.header()->err < 0) {
+               /* TODO: if failed, disconnect channel */
+               return false;
+       }
+
        m_connected.store(true);
 
        _D("Connected");
@@ -192,6 +219,14 @@ void sensor_manager::disconnect(void)
 {
        ret_if(!is_connected());
 
+       ipc::message msg;
+       ipc::message reply;
+       msg.set_type(CMD_MANAGER_DISCONNECT);
+
+       m_channel->send_sync(&msg);
+       m_channel->read_sync(reply);
+       retm_if(reply.header()->err < 0, "Failed to disconnect");
+
        m_connected.store(false);
        m_channel->disconnect();
 
index 88399438439925ff8e3910e89b18e48302e778d1..d0fabf8063b0ea32af9ec7b1d7713cbb7e296d85 100644 (file)
@@ -28,6 +28,8 @@
 #include <atomic>
 
 #include "sensor_internal.h"
+#include "sensor_provider.h"
+#include "sensor_manager_handler.h"
 
 namespace sensor {
 
@@ -38,20 +40,25 @@ public:
 
        bool connect(void);
        void disconnect(void);
+       void restore(void);
 
-       int get_sensor(sensor_type_t type, sensor_t *sensor);
-       int get_sensors(sensor_type_t type, sensor_t **list, int *count);
        int get_sensor(const char *uri, sensor_t *sensor);
        int get_sensors(const char *uri, sensor_t **list, int *count);
 
        bool is_supported(sensor_t sensor);
        bool is_supported(const char *uri);
 
-       void restore(void);
+       /* sensor provider */
+       int add_sensor(sensor_info &info);
+       int add_sensor(sensor_provider *provider);
+       int remove_sensor(const char *uri);
+       int remove_sensor(sensor_provider *provider);
+
+       void add_sensor_added_cb(sensord_added_cb cb, void *user_data);
+       void remove_sensor_added_cb(sensord_added_cb cb);
 
-       /* TODO: register sensor_provider by using manager */
-       /* int register_sensor(sensor_provider *provider); */
-       /* int unregister_sensor(const char *uri) */
+       void add_sensor_removed_cb(sensord_removed_cb cb, void *user_data);
+       void remove_sensor_removed_cb(sensord_removed_cb cb);
 
 private:
        typedef std::vector<sensor_info> sensor_list_t;
@@ -70,10 +77,10 @@ private:
        std::vector<sensor_info *> get_infos(const char *uri);
 
        ipc::ipc_client *m_client;
-       ipc::channel_handler *m_handler;
        ipc::channel *m_channel;
        ipc::event_loop m_loop;
        std::atomic<bool> m_connected;
+       sensor_manager_handler *m_handler;
 
        sensor_list_t m_sensors;
 };
diff --git a/src/client/sensor_manager_handler.cpp b/src/client/sensor_manager_handler.cpp
new file mode 100644 (file)
index 0000000..5ba2acb
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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 "sensor_manager_handler.h"
+
+#include <sensor_log.h>
+#include <command_types.h>
+#include "sensor_manager.h"
+
+using namespace sensor;
+
+sensor_manager_handler::sensor_manager_handler(sensor_manager *manager)
+: m_manager(manager)
+{
+}
+
+void sensor_manager_handler::connected(ipc::channel *ch)
+{
+}
+
+void sensor_manager_handler::disconnected(ipc::channel *ch)
+{
+       /* If channel->disconnect() is not explicitly called, it will be restored */
+       m_manager->restore();
+}
+
+void sensor_manager_handler::read(ipc::channel *ch, ipc::message &msg)
+{
+       switch (msg.header()->type) {
+       case CMD_MANAGER_SENSOR_ADDED:
+               on_sensor_added(ch, msg);
+               break;
+       case CMD_MANAGER_SENSOR_REMOVED:
+               on_sensor_removed(ch, msg);
+               break;
+       }
+}
+
+void sensor_manager_handler::read_complete(ipc::channel *ch)
+{
+}
+
+void sensor_manager_handler::error_caught(ipc::channel *ch, int error)
+{
+}
+
+void sensor_manager_handler::on_sensor_added(ipc::channel *ch, ipc::message &msg)
+{
+       ret_if(msg.header()->err < OP_SUCCESS);
+
+       sensor_info info;
+       info.clear();
+       info.deserialize(msg.body(), msg.size());
+
+       m_manager->add_sensor(info);
+
+       auto it = m_sensor_added_callbacks.begin();
+       while (it != m_sensor_added_callbacks.end()) {
+               it->first(info.get_uri().c_str(), it->second);
+               ++it;
+       }
+}
+
+void sensor_manager_handler::on_sensor_removed(ipc::channel *ch, ipc::message &msg)
+{
+       ret_if(msg.header()->err < 0);
+       char uri[NAME_MAX] = {0, };
+
+       msg.disclose(uri);
+       m_manager->remove_sensor(uri);
+
+       auto it = m_sensor_removed_callbacks.begin();
+       while (it != m_sensor_removed_callbacks.end()) {
+               it->first(uri, it->second);
+               ++it;
+       }
+}
+
+void sensor_manager_handler::add_sensor_added_cb(sensord_added_cb cb, void *user_data)
+{
+       m_sensor_added_callbacks.emplace(cb, user_data);
+}
+
+void sensor_manager_handler::remove_sensor_added_cb(sensord_added_cb cb)
+{
+       m_sensor_added_callbacks.erase(cb);
+}
+
+void sensor_manager_handler::add_sensor_removed_cb(sensord_removed_cb cb, void *user_data)
+{
+       m_sensor_removed_callbacks.emplace(cb, user_data);
+}
+
+void sensor_manager_handler::remove_sensor_removed_cb(sensord_removed_cb cb)
+{
+       m_sensor_removed_callbacks.erase(cb);
+}
diff --git a/src/client/sensor_manager_handler.h b/src/client/sensor_manager_handler.h
new file mode 100644 (file)
index 0000000..4f1ac73
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __SENSOR_MANAGER_HANDLER__
+#define __SENSOR_MANAGER_HANDLER__
+
+#include <sensor_internal.h>
+#include <channel_handler.h>
+#include <map>
+
+namespace sensor {
+
+class sensor_manager;
+
+class sensor_manager_handler : public ipc::channel_handler
+{
+public:
+       sensor_manager_handler(sensor_manager *manager);
+       void connected(ipc::channel *ch);
+       void disconnected(ipc::channel *ch);
+       void read(ipc::channel *ch, ipc::message &msg);
+       void read_complete(ipc::channel *ch);
+       void error_caught(ipc::channel *ch, int error);
+
+       void on_sensor_added(ipc::channel *ch, ipc::message &msg);
+       void on_sensor_removed(ipc::channel *ch, ipc::message &msg);
+
+       void add_sensor_added_cb(sensord_added_cb cb, void *user_data);
+       void remove_sensor_added_cb(sensord_added_cb cb);
+
+       void add_sensor_removed_cb(sensord_removed_cb cb, void *user_data);
+       void remove_sensor_removed_cb(sensord_removed_cb cb);
+
+private:
+       typedef std::map<sensord_added_cb, void *> sensor_added_cb_list_t;
+       typedef std::map<sensord_removed_cb, void *> sensor_removed_cb_list_t;
+
+       sensor_manager *m_manager;
+       sensor_added_cb_list_t m_sensor_added_callbacks;
+       sensor_removed_cb_list_t m_sensor_removed_callbacks;
+};
+
+}
+
+#endif /* __SENSOR_MANAGER_HANDLER__ */