diff options
author | Sung-jae Park <nicesj.park@samsung.com> | 2015-04-22 20:39:37 +0900 |
---|---|---|
committer | Sung-jae Park <nicesj.park@samsung.com> | 2015-04-23 16:51:27 +0900 |
commit | 966ca2df07baf9a1e58962bb6f4bb7483422116c (patch) | |
tree | 9ef89107b4fa5b5323b475f0dd0c77d565cc2687 | |
parent | 120bb25a35f59a22ef3a8792a58af0d188630367 (diff) | |
download | widget-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.txt | 1 | ||||
-rw-r--r-- | include/util.h | 1 | ||||
-rw-r--r-- | include/widget_cmd_list.h | 22 | ||||
-rwxr-xr-x | include/widget_service.h | 17 | ||||
-rw-r--r-- | src/widget_monitor.c | 395 | ||||
-rw-r--r-- | src/widget_service.c | 1 |
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", ×tamp, &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", ×tamp, &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", ×tamp, &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", ×tamp, &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 "/" |