summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSung-jae Park <nicesj.park@samsung.com>2015-04-22 20:39:37 +0900
committerSung-jae Park <nicesj.park@samsung.com>2015-04-23 16:51:27 +0900
commit966ca2df07baf9a1e58962bb6f4bb7483422116c (patch)
tree9ef89107b4fa5b5323b475f0dd0c77d565cc2687
parent120bb25a35f59a22ef3a8792a58af0d188630367 (diff)
downloadwidget-service-966ca2df07baf9a1e58962bb6f4bb7483422116c.tar.gz
widget-service-966ca2df07baf9a1e58962bb6f4bb7483422116c.tar.bz2
widget-service-966ca2df07baf9a1e58962bb6f4bb7483422116c.zip
[DONE] Start implementation for monitoring states of instances
in progress [model] Redwood,Kiran,B3(Wearable) [binary_type] AP [customer] Docomo/Orange/ATT/Open [issue#] N/A [problem] [cause] [solution] [team] HomeTF [request] [horizontal_expansion] Change-Id: Iedd0b99406e8c4667a098080f573456c6832d7b1
-rw-r--r--CMakeLists.txt1
-rw-r--r--include/util.h1
-rw-r--r--include/widget_cmd_list.h22
-rwxr-xr-xinclude/widget_service.h17
-rw-r--r--src/widget_monitor.c395
-rw-r--r--src/widget_service.c1
6 files changed, 428 insertions, 9 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6152874..60eeac6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,6 +63,7 @@ SET(BUILD_SOURCE
src/util.c
src/widget_conf.c
src/widget_abi.c
+ src/widget_monitor.c
)
IF (X11_SUPPORT)
diff --git a/include/util.h b/include/util.h
index a8c1009..e0fc24b 100644
--- a/include/util.h
+++ b/include/util.h
@@ -44,6 +44,7 @@ extern char *util_id_to_uri(const char *id); /* For FILENAME id */
extern int util_update_resolution(struct service_info *info, struct supported_size_list *SIZE_LIST);
extern int util_screen_size_get(unsigned int *width, unsigned int *height);
+#define DEFAULT_TIMEOUT 2.0
#define SCHEMA_FILE "file://"
#define SCHEMA_PIXMAP "pixmap://"
#define SCHEMA_SHM "shm://"
diff --git a/include/widget_cmd_list.h b/include/widget_cmd_list.h
index 03d95ba..a9249f1 100644
--- a/include/widget_cmd_list.h
+++ b/include/widget_cmd_list.h
@@ -384,10 +384,32 @@ extern "C" {
#define CMD_SERVICE_UPDATE 0x00000001
#define CMD_SERVICE_CHANGE_PERIOD 0x00000101
#define CMD_SERVICE_INST_CNT 0x00000201
+#define CMD_MONITOR_REGISTER 0x00000301
+#define CMD_MONITOR_UNREGISTER 0x00000401
+#define CMD_SERVICE_GET_CONTENT 0x00000501
+#define CMD_SERVICE_GET_INST_LIST 0x00000601
#define CMD_STR_SERVICE_UPDATE "service_update"
#define CMD_STR_SERVICE_CHANGE_PERIOD "service_change_period"
#define CMD_STR_SERVICE_INST_CNT "service_inst_cnt"
+#define CMD_STR_MONITOR_REGISTER "monitor_register"
+#define CMD_STR_MONITOR_UNREGISTER "monitor_unregister"
+#define CMD_STR_SERVICE_GET_CONTENT "service_get_content"
+#define CMD_STR_SERVICE_GET_INST_LIST "service_get_inst_list"
+
+/**
+ * @internal
+ * @brief Master to Service (Monitor)
+ */
+#define CMD_MONITOR_CREATE 0x00000001
+#define CMD_MONITOR_DESTROY 0x00000101
+#define CMD_MONITOR_PAUSE 0x00000201
+#define CMD_MONITOR_RESUME 0x00000301
+
+#define CMD_STR_MONITOR_CREATE "monitor_create"
+#define CMD_STR_MONITOR_DESTROY "monitor_destroy"
+#define CMD_STR_MONITOR_PAUSE "monitor_pause"
+#define CMD_STR_MONITOR_RESUME "monitor_resume"
#ifdef __cplusplus
}
diff --git a/include/widget_service.h b/include/widget_service.h
index 2f889da..4dd368e 100755
--- a/include/widget_service.h
+++ b/include/widget_service.h
@@ -500,18 +500,16 @@ extern int widget_service_get_nodisplay(const char *widgetid);
*/
extern int widget_service_get_supported_sizes(const char *widgetid, int *cnt, int **w, int **h);
-
/**
* @brief Callback function for getting result of widget_service_get_widget_instance_list
* @since_tizen 2.3.1
* @param[in] widget_id widget app id
* @param[in] widget_instance_id widget instance id
- * @param[in] content content information of the widget
* @param[in] data user data
* @return WIDGET_ERROR_NONE to continue with the next iteration of the loop, other error values to break out of the loop
* @see #widget_service_get_widget_instance_list
*/
-typedef int (*widget_instance_list_cb)(const char *widget_id, const char *instance_id, const char *content, void *data);
+typedef int (*widget_instance_list_cb)(const char *widget_id, const char *instance_id, void *data);
/**
* @brief Gets widget instances of given widget_id.
@@ -534,12 +532,15 @@ extern int widget_service_get_widget_instance_list(const char *widget_id, widget
*/
typedef enum widget_lifecycle_event {
WIDGET_LIFE_CYCLE_EVENT_CREATE = 1,
- WIDGET_LIFE_CYCLE_EVENT_DESTROY = 2
+ WIDGET_LIFE_CYCLE_EVENT_DESTROY = 2,
+ WIDGET_LIFE_CYCLE_EVENT_PAUSE = 3,
+ WIDGET_LIFE_CYCLE_EVENT_RESUME = 4,
+ WIDGET_LIFE_CYCLE_EVENT_MAX = 5
} widget_lifecycle_event_e;
/**
* @brief Called when a widget is created or destroyed
- * @since_tizen 2.3.1
+ * @since_tizen 2.3.
* @param[in] widget_id widget app id
* @param[in] lifecycle_event type of event
* @param[in] widget_instance_id widget instance id
@@ -549,7 +550,6 @@ typedef enum widget_lifecycle_event {
*/
typedef int (*widget_lifecycle_event_cb)(const char *widget_id, widget_lifecycle_event_e lifecycle_event, const char *widget_instance_id, void *data);
-
/**
* @brief Registers event handler callback function for life-cycle events of widgets
* @since_tizen 2.3.1
@@ -568,12 +568,13 @@ extern int widget_service_set_lifecycle_event_cb(const char *widget_id, widget_l
* @brief Unregisters event handler callback function for life-cycle events of widgets
* @since_tizen 2.3.1
* @param[in] widget_id widget app id
+ * @param[out] user_data user callback data
* @return 0 on success, otherwise a negative error value
* @retval #WIDGET_ERROR_INVALID_PARAMETER Invalid argument
* @retval #WIDGET_ERROR_PERMISSION_DENIED Permission denied
* @see #widget_service_set_lifecycle_event_cb
*/
-extern int widget_service_unset_lifecycle_event_cb(const char *widget_id);
+extern int widget_service_unset_lifecycle_event_cb(const char *widget_id, void **user_data);
/**
* @brief Gets content of the widget instance
@@ -585,7 +586,7 @@ extern int widget_service_unset_lifecycle_event_cb(const char *widget_id);
* @retval #WIDGET_ERROR_INVALID_PARAMETER Invalid argument
* @retval #WIDGET_ERROR_PERMISSION_DENIED Permission denied
*/
-extern int widget_service_get_content_of_widget_instance(const char *widget_instance_id, char **content);
+extern int widget_service_get_content_of_widget_instance(const char *widget_id, const char *widget_instance_id, char **content);
/**
* @}
*/
diff --git a/src/widget_monitor.c b/src/widget_monitor.c
new file mode 100644
index 0000000..307493a
--- /dev/null
+++ b/src/widget_monitor.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright 2013 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 <stdio.h>
+#include <errno.h>
+#include <stdlib.h> /* malloc */
+#include <string.h> /* strdup, strerror */
+
+#include <sqlite3.h>
+#include <unicode/uloc.h>
+
+#include <com-core_packet.h>
+#include <packet.h>
+#include <dlog.h>
+
+#include "dlist.h"
+#include "widget_errno.h"
+#include "debug.h"
+#include "widget_service.h"
+#include "widget_cmd_list.h"
+#include "util.h"
+
+int errno;
+
+struct lifecycle_monitor_item {
+ char *widget_id;
+ widget_lifecycle_event_cb cb;
+ void *data;
+};
+
+static struct info {
+ struct dlist *lifecycle_monitor_list;
+ int lifecycle_monitor_handle;
+} s_info = {
+ .lifecycle_monitor_list = NULL,
+ .lifecycle_monitor_handle = -1,
+};
+
+static inline void send_monitor_command(unsigned int cmd, const char *widget_id)
+{
+ struct packet *packet;
+
+ if (s_info.lifecycle_monitor_handle < 0) {
+ ErrPrint("Not yet initialized\n");
+ return;
+ }
+
+ packet = packet_create_noack((const char *)&cmd, "s", widget_id ? widget_id : "*");
+ if (!packet) {
+ ErrPrint("Failed to create a packet\n");
+ } else {
+ if (com_core_packet_send_only(s_info.lifecycle_monitor_handle, packet) < 0) {
+ ErrPrint("Failed to send packet\n");
+ }
+ packet_destroy(packet);
+ }
+}
+
+static inline void invoke_handler(widget_lifecycle_event_e event, const char *widget_id, const char *instance_id)
+{
+ struct lifecycle_monitor_item *item;
+ struct dlist *l;
+
+ DbgPrint("%s %s\n", widget_id, instance_id);
+ dlist_foreach(s_info.lifecycle_monitor_list, l, item) {
+ if (item->widget_id == NULL) {
+ item->cb(widget_id, event, instance_id, item->data);
+ } else if (!strcmp(item->widget_id, widget_id)) {
+ item->cb(widget_id, event, instance_id, item->data);
+ }
+ }
+}
+
+static struct packet *monitor_create_handler(pid_t pid, int handle, const struct packet *packet)
+{
+ const char *widget_id;
+ const char *instance_id;
+ const char *content_info;
+ double timestamp;
+
+ if (packet_get(packet, "dsss", &timestamp, &widget_id, &instance_id, &content_info) != 4) {
+ ErrPrint("Invalid packet\n");
+ } else {
+ invoke_handler(WIDGET_LIFE_CYCLE_EVENT_CREATE, widget_id, instance_id);
+ }
+
+ return NULL;
+}
+
+static struct packet *monitor_destroy_handler(pid_t pid, int handle, const struct packet *packet)
+{
+ const char *widget_id;
+ const char *instance_id;
+ const char *content_info;
+ double timestamp;
+
+ if (packet_get(packet, "dsss", &timestamp, &widget_id, &instance_id, &content_info) != 4) {
+ ErrPrint("Invalid packet\n");
+ } else {
+ invoke_handler(WIDGET_LIFE_CYCLE_EVENT_DESTROY, widget_id, instance_id);
+ }
+
+ return NULL;
+}
+
+static struct packet *monitor_pause_handler(pid_t pid, int handle, const struct packet *packet)
+{
+ const char *widget_id;
+ const char *instance_id;
+ const char *content_info;
+ double timestamp;
+
+ if (packet_get(packet, "dsss", &timestamp, &widget_id, &instance_id, &content_info) != 4) {
+ ErrPrint("Invalid packet\n");
+ } else {
+ invoke_handler(WIDGET_LIFE_CYCLE_EVENT_PAUSE, widget_id, instance_id);
+ }
+
+ return NULL;
+}
+
+static struct packet *monitor_resume_handler(pid_t pid, int handle, const struct packet *packet)
+{
+ const char *widget_id;
+ const char *instance_id;
+ const char *content_info;
+ double timestamp;
+
+ if (packet_get(packet, "dsss", &timestamp, &widget_id, &instance_id, &content_info) != 4) {
+ ErrPrint("Invalid packet\n");
+ } else {
+ invoke_handler(WIDGET_LIFE_CYCLE_EVENT_RESUME, widget_id, instance_id);
+ }
+
+ return NULL;
+}
+
+EAPI int widget_service_set_lifecycle_event_cb(const char *widget_id, widget_lifecycle_event_cb cb, void *data)
+{
+ struct lifecycle_monitor_item *item;
+ struct dlist *l;
+
+ if (!cb) {
+ return WIDGET_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!widget_id) {
+ DbgPrint("Register monitor for all widgets\n");
+ }
+
+ dlist_foreach(s_info.lifecycle_monitor_list, l, item) {
+ if (item->widget_id == NULL && widget_id == NULL) {
+ return WIDGET_ERROR_ALREADY_EXIST;
+ } else if (item->widget_id && widget_id) {
+ if (!strcmp(widget_id, item->widget_id)) {
+ return WIDGET_ERROR_ALREADY_EXIST;
+ }
+ }
+ }
+
+ item = calloc(1, sizeof(*item));
+ if (!item) {
+ ErrPrint("calloc: %d\n", errno);
+ return WIDGET_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (widget_id) {
+ item->widget_id = strdup(widget_id);
+ if (!item->widget_id) {
+ ErrPrint("strdup: %d\n", errno);
+ free(item);
+ return WIDGET_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ item->widget_id = NULL;
+ }
+
+ item->cb = cb;
+ item->data = data;
+
+ s_info.lifecycle_monitor_list = dlist_append(s_info.lifecycle_monitor_list, item);
+
+ if (s_info.lifecycle_monitor_handle < 0) {
+ static struct method table[] = {
+ {
+ .cmd = CMD_STR_MONITOR_CREATE,
+ .handler = monitor_create_handler,
+ },
+ {
+ .cmd = CMD_STR_MONITOR_DESTROY,
+ .handler = monitor_destroy_handler,
+ },
+ {
+ .cmd = CMD_STR_MONITOR_PAUSE,
+ .handler = monitor_pause_handler,
+ },
+ {
+ .cmd = CMD_STR_MONITOR_RESUME,
+ .handler = monitor_resume_handler,
+ },
+ {
+ .cmd = NULL,
+ .handler = NULL,
+ },
+ };
+
+ /**
+ * @todo
+ * Send service_register command to master
+ */
+ s_info.lifecycle_monitor_handle = com_core_packet_client_init(SERVICE_SOCKET, 0, table);
+ DbgPrint("Monitor handle: %d\n", s_info.lifecycle_monitor_handle);
+ }
+
+ send_monitor_command(CMD_MONITOR_REGISTER, widget_id);
+
+ return WIDGET_ERROR_NONE;
+}
+
+EAPI int widget_service_unset_lifecycle_event_cb(const char *widget_id, void **user_data)
+{
+ struct dlist *l;
+ struct dlist *n;
+ struct lifecycle_monitor_item *item;
+
+ dlist_foreach_safe(s_info.lifecycle_monitor_list, l, n, item) {
+ if (widget_id == NULL && item->widget_id == NULL) {
+ s_info.lifecycle_monitor_list = dlist_remove(s_info.lifecycle_monitor_list, l);
+ if (user_data) {
+ *user_data = item->data;
+ }
+ free(item);
+
+ /**
+ * @todo
+ * Send service_unregister command to master
+ */
+ send_monitor_command(CMD_MONITOR_UNREGISTER, widget_id);
+ break;
+ } else if (widget_id && item->widget_id) {
+ if (!strcmp(item->widget_id, widget_id)) {
+ s_info.lifecycle_monitor_list = dlist_remove(s_info.lifecycle_monitor_list, l);
+ if (user_data) {
+ *user_data = item->data;
+ }
+ free(item->widget_id);
+ free(item);
+
+ /**
+ * @todo
+ * Send service_unregister command to master
+ */
+ send_monitor_command(CMD_MONITOR_UNREGISTER, widget_id);
+ break;
+ }
+ }
+ }
+
+ if (s_info.lifecycle_monitor_handle >= 0 && !s_info.lifecycle_monitor_list) {
+ com_core_packet_client_fini(s_info.lifecycle_monitor_handle);
+ s_info.lifecycle_monitor_handle = -1;
+ }
+
+ return WIDGET_ERROR_NOT_EXIST;
+}
+
+EAPI int widget_service_get_content_of_widget_instance(const char *widget_id, const char *widget_instance_id, char **content)
+{
+ struct packet *packet;
+ struct packet *result;
+ unsigned int cmd = CMD_SERVICE_GET_CONTENT;
+ char *uri;
+ const char *_content;
+ int ret;
+
+ if (!widget_instance_id || !content) {
+ ErrPrint("Invalid argument\n");
+ return WIDGET_ERROR_INVALID_PARAMETER;
+ }
+
+ uri = util_id_to_uri(widget_instance_id);
+ if (!uri) {
+ return WIDGET_ERROR_OUT_OF_MEMORY;
+ }
+
+ packet = packet_create((const char *)&cmd, "ss", widget_id, uri);
+ free(uri);
+ if (!packet) {
+ ErrPrint("Failed to create a packet for period changing\n");
+ return WIDGET_ERROR_FAULT;
+ }
+
+ result = com_core_packet_oneshot_send(SERVICE_SOCKET, packet, DEFAULT_TIMEOUT);
+ packet_unref(packet);
+
+ if (result) {
+ if (packet_get(result, "is", &ret, &_content) != 2) {
+ ErrPrint("Failed to parse a result packet\n");
+ ret = WIDGET_ERROR_INVALID_PARAMETER;
+ } else if (ret == WIDGET_ERROR_NONE) {
+ *content = strdup(_content);
+ if (!*content) {
+ ErrPrint("strdup: %s [%d]\n", _content, errno);
+ }
+ } else {
+ ErrPrint("ret: %d\n", ret);
+ }
+ packet_unref(result);
+ } else {
+ ErrPrint("Failed to get result packet\n");
+ ret = WIDGET_ERROR_FAULT;
+ }
+
+ return ret;
+}
+
+EAPI int widget_service_get_widget_instance_list(const char *widget_id, widget_instance_list_cb cb, void *data)
+{
+ struct packet *packet;
+ struct packet *result;
+ unsigned int cmd = CMD_SERVICE_GET_INST_LIST;
+ const char *list;
+ int ret;
+
+ if (!widget_id || !cb) {
+ ErrPrint("Invalid argument\n");
+ return WIDGET_ERROR_INVALID_PARAMETER;
+ }
+
+ packet = packet_create((const char *)&cmd, "s", widget_id);
+ if (!packet) {
+ ErrPrint("Failed to create a packet for period changing\n");
+ return WIDGET_ERROR_FAULT;
+ }
+
+ result = com_core_packet_oneshot_send(SERVICE_SOCKET, packet, DEFAULT_TIMEOUT);
+ packet_unref(packet);
+
+ if (result) {
+ int cnt;
+ if (packet_get(result, "iis", &ret, &cnt, &list) != 3) {
+ ErrPrint("Failed to parse a result packet\n");
+ ret = WIDGET_ERROR_INVALID_PARAMETER;
+ } else if (ret == WIDGET_ERROR_NONE) {
+ const char *ptr;
+ register int i;
+ /**
+ * Parse the list
+ */
+ ptr = list;
+ i = 0;
+ do {
+ switch (list[i]) {
+ case '\0':
+ if (ptr != list + i) {
+ cb(widget_id, ptr, data);
+ }
+ break;
+ case '\n':
+ *((char *)list + i) = '\0';
+ cb(widget_id, ptr, data);
+ ptr = list + i + 1;
+ default:
+ i++;
+ break;
+ }
+ } while (list[i]);
+
+ if (i != cnt) {
+ DbgPrint("Total count is not valid: %d <> %d\n", i, cnt);
+ }
+ }
+ packet_unref(result);
+ } else {
+ ErrPrint("Failed to get result packet\n");
+ ret = WIDGET_ERROR_FAULT;
+ }
+
+ return ret;
+}
+
+/* End of a file */
diff --git a/src/widget_service.c b/src/widget_service.c
index 5f995e7..469d184 100644
--- a/src/widget_service.c
+++ b/src/widget_service.c
@@ -47,7 +47,6 @@
#include "widget_util.h"
#define WIDGET_ID_PREFIX "org.tizen."
-#define DEFAULT_TIMEOUT 2.0
/* "/shared/res/" */
#define RESOURCE_PATH "/"