mmi: add initial development environment 11/264111/1
authorSung-Jin Park <sj76.park@samsung.com>
Sun, 20 Jun 2021 15:46:17 +0000 (00:46 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Mon, 13 Sep 2021 12:14:13 +0000 (21:14 +0900)
Change-Id: Ia1c73ecee31f3035bfc56f26c164fdec24279224

16 files changed:
CODEOWNERS [new file with mode: 0644]
COPYING [new file with mode: 0644]
README.md
meson.build [new file with mode: 0644]
meson_options.txt [new file with mode: 0644]
packaging/mmifw.manifest [new file with mode: 0644]
packaging/mmifw.spec [new file with mode: 0644]
src/interface/mmifw_proxy.c [new file with mode: 0644]
src/interface/mmifw_proxy.h [new file with mode: 0644]
src/meson.build [new file with mode: 0644]
src/mmifw.c [new file with mode: 0644]
src/mmifw.h [new file with mode: 0644]
tests/meson.build [new file with mode: 0644]
tests/mmifw-tests.cpp [new file with mode: 0644]
tests/mmifw-tests.h [new file with mode: 0644]
tidl/mmifw.tidl [new file with mode: 0644]

diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644 (file)
index 0000000..647c677
--- /dev/null
@@ -0,0 +1,5 @@
+# These owners will be the default owners for everything in
+# the repo. Unless a later match takes precedence,
+# @global-owner1 and @global-owner2 will be requested for
+# review when someone opens a pull request.
+*       @gl77-lee @dyamy-lee @sj76-park @duna-oh @ulgal-park
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..921be60
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,21 @@
+Copyright © 2021 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
index 47a369a..65866e9 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1 +1,26 @@
-# mmi-framework
\ No newline at end of file
+# MMI(Multi-modal Interaction) Framework  
+  
+[Source Tree]  
+.  
+├── CODEOWNERS  
+├── COPYING  
+├── meson.build  
+├── meson_options.txt  
+├── packaging  
+│   ├── mmifw.manifest  
+│   └── mmifw.spec  
+├── README.md  
+├── src  
+│   ├── interface  
+│   │   ├── mmifw_proxy.c  
+│   │   └── mmifw_proxy.h  
+│   ├── meson.build  
+│   ├── mmifw.c  
+│   └── mmifw.h  
+├── tests  
+│   ├── meson.build  
+│   ├── mmifw-tests.cpp  
+│   └── mmifw-tests.h  
+└── tidl  
+    └── mmifw.tidl  
+  
diff --git a/meson.build b/meson.build
new file mode 100644 (file)
index 0000000..3c2a327
--- /dev/null
@@ -0,0 +1,17 @@
+project(
+       'mmifw',
+       ['c', 'cpp'],
+       version : '0.0.1',
+       license : 'MIT',
+       default_options : ['c_std=c11', 'cpp_std=c++17', 'b_pie=true']
+)
+
+mmifw_version = meson.project_version().split('.')
+mmifw_prefix = get_option('prefix')
+mmifw_prefix_bindir = join_paths(mmifw_prefix, get_option('bindir'))
+mmifw_prefix_libdir = join_paths(mmifw_prefix, get_option('libdir'))
+
+pkgconfig = import('pkgconfig')
+
+subdir('src')
+subdir('tests')
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packaging/mmifw.manifest b/packaging/mmifw.manifest
new file mode 100644 (file)
index 0000000..75b0fa5
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <request>
+        <domain name="_"/>
+    </request>
+</manifest>
diff --git a/packaging/mmifw.spec b/packaging/mmifw.spec
new file mode 100644 (file)
index 0000000..91389d9
--- /dev/null
@@ -0,0 +1,78 @@
+Name:          mmifw
+Version:       0.0.1
+Release:       0
+Summary:       Multi-modal Interaction Framework Library
+License:       MIT
+URL:           http://www.tizen.org
+Source:                %{name}-%{version}.tar.xz
+Source1004:    %{name}.manifest
+
+BuildRequires: meson
+BuildRequires: tidl
+BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(bundle)
+BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(rpc-port)
+
+#Build dependencies for tests
+BuildRequires: pkgconfig(gmock)
+BuildRequires: pkgconfig(ecore)
+
+%description
+MMI(Multi-modal Interaction) Framework Library
+
+%package devel
+Summary:       Development package for MMI Framework
+Group:         Development/Libraries
+Requires:      %{name} = %{version}-%{release}
+%description devel
+Development package for MMI Framework
+
+%package tests
+Summary:       Testcases for MMI Framework
+Group:         System/Libraries
+%description tests
+Testcases for testing MMI Framework APIs
+
+%prep
+%setup -q
+cp %{SOURCE1004} .
+
+#generate mmi-proxy using TIDL Compiler
+tidlc -p -l C -i tidl/mmifw.tidl -o mmifw_proxy
+mv mmifw_proxy.* ./src/interface/
+
+%build
+meson setup --prefix=/usr \
+       --bindir %{_bindir} \
+       --libdir %{_libdir} \
+       builddir
+ninja -C builddir all
+
+%install
+DESTDIR=%{buildroot} ninja -C builddir install
+
+%post -p /sbin/ldconfig
+%postun -p /sbin/ldconfig
+
+%files
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%license COPYING
+%{_libdir}/*.so.*
+
+%files devel
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%license COPYING
+%{_includedir}/mmifw*.h
+%{_libdir}/*.so
+%{_libdir}/pkgconfig/*
+
+%files tests
+%defattr(-,root,root,-)
+%license COPYING
+%{_bindir}/mmifw-tests
+
diff --git a/src/interface/mmifw_proxy.c b/src/interface/mmifw_proxy.c
new file mode 100644 (file)
index 0000000..43f6451
--- /dev/null
@@ -0,0 +1,3609 @@
+/*
+ * Generated by tidlc 1.4.9.
+ */
+
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <glib.h>
+#include <dlog.h>
+#include <rpc-port.h>
+#include <rpc-port-parcel.h>
+
+#include "mmifw_proxy.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "RPC_PORT_PROXY"
+
+#ifdef _E
+#undef _E
+#endif
+
+#ifdef _W
+#undef _W
+#endif
+
+#ifdef _I
+#undef _I
+#endif
+
+#ifdef _D
+#undef _D
+#endif
+
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+typedef void (*proxy_delegate)(GList **list, rpc_port_parcel_h parcel, int seq_id, int id);
+
+struct focus_event_s {
+       rpc_port_parcelable_t parcelable;
+       int type;
+       int timestamp;
+       bool focus_in;
+};
+
+static void __focus_event_to(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_focus_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, h->type);
+       rpc_port_parcel_write_int32(parcel, h->timestamp);
+       rpc_port_parcel_write_bool(parcel, h->focus_in);
+}
+
+static void __focus_event_from(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_focus_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &h->type);
+       rpc_port_parcel_read_int32(parcel, &h->timestamp);
+       rpc_port_parcel_read_bool(parcel, &h->focus_in);
+}
+
+int rpc_port_focus_event_create(rpc_port_focus_event_h *h)
+{
+       struct focus_event_s *handle;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       handle = calloc(1, sizeof(struct focus_event_s));
+       if (!handle) {
+               _E("Out of memory");
+               return -1;
+       }
+
+       handle->parcelable.to = __focus_event_to;
+       handle->parcelable.from = __focus_event_from;
+
+       *h = handle;
+
+       return 0;
+}
+
+int rpc_port_focus_event_destroy(rpc_port_focus_event_h h)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       free(h);
+
+       return 0;
+}
+
+int rpc_port_focus_event_clone(rpc_port_focus_event_h h, rpc_port_focus_event_h *clone)
+{
+       rpc_port_focus_event_h handle = NULL;
+
+       if (!h || !clone) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       rpc_port_focus_event_create(&handle);
+       if (!handle) {
+               _E("Failed to create focus_event handle");
+               return -1;
+       }
+
+       handle->type = h->type;
+       handle->timestamp = h->timestamp;
+       handle->focus_in = h->focus_in;
+       *clone = handle;
+
+       return 0;
+}
+
+int rpc_port_focus_event_set_type(rpc_port_focus_event_h h, int type)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->type = type;
+       return 0;
+}
+
+int rpc_port_focus_event_set_timestamp(rpc_port_focus_event_h h, int timestamp)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->timestamp = timestamp;
+       return 0;
+}
+
+int rpc_port_focus_event_set_focus_in(rpc_port_focus_event_h h, bool focus_in)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->focus_in = focus_in;
+       return 0;
+}
+
+int rpc_port_focus_event_get_type(rpc_port_focus_event_h h, int *type)
+{
+       if (!h || !type) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *type = h->type;
+       return 0;
+}
+
+int rpc_port_focus_event_get_timestamp(rpc_port_focus_event_h h, int *timestamp)
+{
+       if (!h || !timestamp) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *timestamp = h->timestamp;
+       return 0;
+}
+
+int rpc_port_focus_event_get_focus_in(rpc_port_focus_event_h h, bool *focus_in)
+{
+       if (!h || !focus_in) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *focus_in = h->focus_in;
+       return 0;
+}
+
+struct state_change_event_s {
+       rpc_port_parcelable_t parcelable;
+       int type;
+       int timestamp;
+       int state;
+       int old_state;
+};
+
+static void __state_change_event_to(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_state_change_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, h->type);
+       rpc_port_parcel_write_int32(parcel, h->timestamp);
+       rpc_port_parcel_write_int32(parcel, h->state);
+       rpc_port_parcel_write_int32(parcel, h->old_state);
+}
+
+static void __state_change_event_from(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_state_change_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &h->type);
+       rpc_port_parcel_read_int32(parcel, &h->timestamp);
+       rpc_port_parcel_read_int32(parcel, &h->state);
+       rpc_port_parcel_read_int32(parcel, &h->old_state);
+}
+
+int rpc_port_state_change_event_create(rpc_port_state_change_event_h *h)
+{
+       struct state_change_event_s *handle;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       handle = calloc(1, sizeof(struct state_change_event_s));
+       if (!handle) {
+               _E("Out of memory");
+               return -1;
+       }
+
+       handle->parcelable.to = __state_change_event_to;
+       handle->parcelable.from = __state_change_event_from;
+
+       *h = handle;
+
+       return 0;
+}
+
+int rpc_port_state_change_event_destroy(rpc_port_state_change_event_h h)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       free(h);
+
+       return 0;
+}
+
+int rpc_port_state_change_event_clone(rpc_port_state_change_event_h h, rpc_port_state_change_event_h *clone)
+{
+       rpc_port_state_change_event_h handle = NULL;
+
+       if (!h || !clone) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       rpc_port_state_change_event_create(&handle);
+       if (!handle) {
+               _E("Failed to create state_change_event handle");
+               return -1;
+       }
+
+       handle->type = h->type;
+       handle->timestamp = h->timestamp;
+       handle->state = h->state;
+       handle->old_state = h->old_state;
+       *clone = handle;
+
+       return 0;
+}
+
+int rpc_port_state_change_event_set_type(rpc_port_state_change_event_h h, int type)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->type = type;
+       return 0;
+}
+
+int rpc_port_state_change_event_set_timestamp(rpc_port_state_change_event_h h, int timestamp)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->timestamp = timestamp;
+       return 0;
+}
+
+int rpc_port_state_change_event_set_state(rpc_port_state_change_event_h h, int state)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->state = state;
+       return 0;
+}
+
+int rpc_port_state_change_event_set_old_state(rpc_port_state_change_event_h h, int old_state)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->old_state = old_state;
+       return 0;
+}
+
+int rpc_port_state_change_event_get_type(rpc_port_state_change_event_h h, int *type)
+{
+       if (!h || !type) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *type = h->type;
+       return 0;
+}
+
+int rpc_port_state_change_event_get_timestamp(rpc_port_state_change_event_h h, int *timestamp)
+{
+       if (!h || !timestamp) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *timestamp = h->timestamp;
+       return 0;
+}
+
+int rpc_port_state_change_event_get_state(rpc_port_state_change_event_h h, int *state)
+{
+       if (!h || !state) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *state = h->state;
+       return 0;
+}
+
+int rpc_port_state_change_event_get_old_state(rpc_port_state_change_event_h h, int *old_state)
+{
+       if (!h || !old_state) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *old_state = h->old_state;
+       return 0;
+}
+
+struct wakeup_event_s {
+       rpc_port_parcelable_t parcelable;
+       int type;
+       int timestamp;
+       char *source;
+};
+
+static void __wakeup_event_to(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_wakeup_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, h->type);
+       rpc_port_parcel_write_int32(parcel, h->timestamp);
+       rpc_port_parcel_write_string(parcel, h->source ? h->source : "");
+}
+
+static void __wakeup_event_from(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_wakeup_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &h->type);
+       rpc_port_parcel_read_int32(parcel, &h->timestamp);
+       rpc_port_parcel_read_string(parcel, &h->source);
+}
+
+int rpc_port_wakeup_event_create(rpc_port_wakeup_event_h *h)
+{
+       struct wakeup_event_s *handle;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       handle = calloc(1, sizeof(struct wakeup_event_s));
+       if (!handle) {
+               _E("Out of memory");
+               return -1;
+       }
+
+       handle->parcelable.to = __wakeup_event_to;
+       handle->parcelable.from = __wakeup_event_from;
+
+       *h = handle;
+
+       return 0;
+}
+
+int rpc_port_wakeup_event_destroy(rpc_port_wakeup_event_h h)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->source)
+               free(h->source);
+
+       free(h);
+
+       return 0;
+}
+
+int rpc_port_wakeup_event_clone(rpc_port_wakeup_event_h h, rpc_port_wakeup_event_h *clone)
+{
+       rpc_port_wakeup_event_h handle = NULL;
+
+       if (!h || !clone) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       rpc_port_wakeup_event_create(&handle);
+       if (!handle) {
+               _E("Failed to create wakeup_event handle");
+               return -1;
+       }
+
+       handle->type = h->type;
+       handle->timestamp = h->timestamp;
+       if (h->source) {
+               handle->source = strdup(h->source);
+               if (!handle->source) {
+                       _E("Failed to duplicate h->source");
+                       rpc_port_wakeup_event_destroy(handle);
+                       return -1;
+               }
+       }
+
+       *clone = handle;
+
+       return 0;
+}
+
+int rpc_port_wakeup_event_set_type(rpc_port_wakeup_event_h h, int type)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->type = type;
+       return 0;
+}
+
+int rpc_port_wakeup_event_set_timestamp(rpc_port_wakeup_event_h h, int timestamp)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->timestamp = timestamp;
+       return 0;
+}
+
+int rpc_port_wakeup_event_set_source(rpc_port_wakeup_event_h h, const char *source)
+{
+       if (!h || !source) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->source) {
+               free(h->source);
+               h->source = NULL;
+       }
+
+       h->source = strdup(source);
+       if (!h->source) {
+               _E("Failed to duplicate data");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_wakeup_event_get_type(rpc_port_wakeup_event_h h, int *type)
+{
+       if (!h || !type) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *type = h->type;
+       return 0;
+}
+
+int rpc_port_wakeup_event_get_timestamp(rpc_port_wakeup_event_h h, int *timestamp)
+{
+       if (!h || !timestamp) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *timestamp = h->timestamp;
+       return 0;
+}
+
+int rpc_port_wakeup_event_get_source(rpc_port_wakeup_event_h h, char **source)
+{
+       if (!h || !source) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (!h->source) {
+               _E("Invalid parameter: h->source is NULL");
+               return -1;
+       }
+
+       *source = strdup(h->source);
+       if (*source == NULL) {
+               _E("Failed to duplicate source");
+               return -1;
+       }
+
+       return 0;
+}
+
+struct key_event_s {
+       rpc_port_parcelable_t parcelable;
+       int type;
+       int timestamp;
+       bool key_down;
+       int keycode;
+       char *keyname;
+       char *source;
+};
+
+static void __key_event_to(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_key_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, h->type);
+       rpc_port_parcel_write_int32(parcel, h->timestamp);
+       rpc_port_parcel_write_bool(parcel, h->key_down);
+       rpc_port_parcel_write_int32(parcel, h->keycode);
+       rpc_port_parcel_write_string(parcel, h->keyname ? h->keyname : "");
+       rpc_port_parcel_write_string(parcel, h->source ? h->source : "");
+}
+
+static void __key_event_from(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_key_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &h->type);
+       rpc_port_parcel_read_int32(parcel, &h->timestamp);
+       rpc_port_parcel_read_bool(parcel, &h->key_down);
+       rpc_port_parcel_read_int32(parcel, &h->keycode);
+       rpc_port_parcel_read_string(parcel, &h->keyname);
+       rpc_port_parcel_read_string(parcel, &h->source);
+}
+
+int rpc_port_key_event_create(rpc_port_key_event_h *h)
+{
+       struct key_event_s *handle;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       handle = calloc(1, sizeof(struct key_event_s));
+       if (!handle) {
+               _E("Out of memory");
+               return -1;
+       }
+
+       handle->parcelable.to = __key_event_to;
+       handle->parcelable.from = __key_event_from;
+
+       *h = handle;
+
+       return 0;
+}
+
+int rpc_port_key_event_destroy(rpc_port_key_event_h h)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->keyname)
+               free(h->keyname);
+
+       if (h->source)
+               free(h->source);
+
+       free(h);
+
+       return 0;
+}
+
+int rpc_port_key_event_clone(rpc_port_key_event_h h, rpc_port_key_event_h *clone)
+{
+       rpc_port_key_event_h handle = NULL;
+
+       if (!h || !clone) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       rpc_port_key_event_create(&handle);
+       if (!handle) {
+               _E("Failed to create key_event handle");
+               return -1;
+       }
+
+       handle->type = h->type;
+       handle->timestamp = h->timestamp;
+       handle->key_down = h->key_down;
+       handle->keycode = h->keycode;
+       if (h->keyname) {
+               handle->keyname = strdup(h->keyname);
+               if (!handle->keyname) {
+                       _E("Failed to duplicate h->keyname");
+                       rpc_port_key_event_destroy(handle);
+                       return -1;
+               }
+       }
+
+       if (h->source) {
+               handle->source = strdup(h->source);
+               if (!handle->source) {
+                       _E("Failed to duplicate h->source");
+                       rpc_port_key_event_destroy(handle);
+                       return -1;
+               }
+       }
+
+       *clone = handle;
+
+       return 0;
+}
+
+int rpc_port_key_event_set_type(rpc_port_key_event_h h, int type)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->type = type;
+       return 0;
+}
+
+int rpc_port_key_event_set_timestamp(rpc_port_key_event_h h, int timestamp)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->timestamp = timestamp;
+       return 0;
+}
+
+int rpc_port_key_event_set_key_down(rpc_port_key_event_h h, bool key_down)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->key_down = key_down;
+       return 0;
+}
+
+int rpc_port_key_event_set_keycode(rpc_port_key_event_h h, int keycode)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->keycode = keycode;
+       return 0;
+}
+
+int rpc_port_key_event_set_keyname(rpc_port_key_event_h h, const char *keyname)
+{
+       if (!h || !keyname) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->keyname) {
+               free(h->keyname);
+               h->keyname = NULL;
+       }
+
+       h->keyname = strdup(keyname);
+       if (!h->keyname) {
+               _E("Failed to duplicate data");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_key_event_set_source(rpc_port_key_event_h h, const char *source)
+{
+       if (!h || !source) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->source) {
+               free(h->source);
+               h->source = NULL;
+       }
+
+       h->source = strdup(source);
+       if (!h->source) {
+               _E("Failed to duplicate data");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_key_event_get_type(rpc_port_key_event_h h, int *type)
+{
+       if (!h || !type) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *type = h->type;
+       return 0;
+}
+
+int rpc_port_key_event_get_timestamp(rpc_port_key_event_h h, int *timestamp)
+{
+       if (!h || !timestamp) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *timestamp = h->timestamp;
+       return 0;
+}
+
+int rpc_port_key_event_get_key_down(rpc_port_key_event_h h, bool *key_down)
+{
+       if (!h || !key_down) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *key_down = h->key_down;
+       return 0;
+}
+
+int rpc_port_key_event_get_keycode(rpc_port_key_event_h h, int *keycode)
+{
+       if (!h || !keycode) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *keycode = h->keycode;
+       return 0;
+}
+
+int rpc_port_key_event_get_keyname(rpc_port_key_event_h h, char **keyname)
+{
+       if (!h || !keyname) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (!h->keyname) {
+               _E("Invalid parameter: h->keyname is NULL");
+               return -1;
+       }
+
+       *keyname = strdup(h->keyname);
+       if (*keyname == NULL) {
+               _E("Failed to duplicate keyname");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_key_event_get_source(rpc_port_key_event_h h, char **source)
+{
+       if (!h || !source) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (!h->source) {
+               _E("Invalid parameter: h->source is NULL");
+               return -1;
+       }
+
+       *source = strdup(h->source);
+       if (*source == NULL) {
+               _E("Failed to duplicate source");
+               return -1;
+       }
+
+       return 0;
+}
+
+struct gesture_event_s {
+       rpc_port_parcelable_t parcelable;
+       int type;
+       int timestamp;
+       char *source;
+};
+
+static void __gesture_event_to(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_gesture_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, h->type);
+       rpc_port_parcel_write_int32(parcel, h->timestamp);
+       rpc_port_parcel_write_string(parcel, h->source ? h->source : "");
+}
+
+static void __gesture_event_from(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_gesture_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &h->type);
+       rpc_port_parcel_read_int32(parcel, &h->timestamp);
+       rpc_port_parcel_read_string(parcel, &h->source);
+}
+
+int rpc_port_gesture_event_create(rpc_port_gesture_event_h *h)
+{
+       struct gesture_event_s *handle;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       handle = calloc(1, sizeof(struct gesture_event_s));
+       if (!handle) {
+               _E("Out of memory");
+               return -1;
+       }
+
+       handle->parcelable.to = __gesture_event_to;
+       handle->parcelable.from = __gesture_event_from;
+
+       *h = handle;
+
+       return 0;
+}
+
+int rpc_port_gesture_event_destroy(rpc_port_gesture_event_h h)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->source)
+               free(h->source);
+
+       free(h);
+
+       return 0;
+}
+
+int rpc_port_gesture_event_clone(rpc_port_gesture_event_h h, rpc_port_gesture_event_h *clone)
+{
+       rpc_port_gesture_event_h handle = NULL;
+
+       if (!h || !clone) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       rpc_port_gesture_event_create(&handle);
+       if (!handle) {
+               _E("Failed to create gesture_event handle");
+               return -1;
+       }
+
+       handle->type = h->type;
+       handle->timestamp = h->timestamp;
+       if (h->source) {
+               handle->source = strdup(h->source);
+               if (!handle->source) {
+                       _E("Failed to duplicate h->source");
+                       rpc_port_gesture_event_destroy(handle);
+                       return -1;
+               }
+       }
+
+       *clone = handle;
+
+       return 0;
+}
+
+int rpc_port_gesture_event_set_type(rpc_port_gesture_event_h h, int type)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->type = type;
+       return 0;
+}
+
+int rpc_port_gesture_event_set_timestamp(rpc_port_gesture_event_h h, int timestamp)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->timestamp = timestamp;
+       return 0;
+}
+
+int rpc_port_gesture_event_set_source(rpc_port_gesture_event_h h, const char *source)
+{
+       if (!h || !source) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->source) {
+               free(h->source);
+               h->source = NULL;
+       }
+
+       h->source = strdup(source);
+       if (!h->source) {
+               _E("Failed to duplicate data");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_gesture_event_get_type(rpc_port_gesture_event_h h, int *type)
+{
+       if (!h || !type) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *type = h->type;
+       return 0;
+}
+
+int rpc_port_gesture_event_get_timestamp(rpc_port_gesture_event_h h, int *timestamp)
+{
+       if (!h || !timestamp) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *timestamp = h->timestamp;
+       return 0;
+}
+
+int rpc_port_gesture_event_get_source(rpc_port_gesture_event_h h, char **source)
+{
+       if (!h || !source) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (!h->source) {
+               _E("Invalid parameter: h->source is NULL");
+               return -1;
+       }
+
+       *source = strdup(h->source);
+       if (*source == NULL) {
+               _E("Failed to duplicate source");
+               return -1;
+       }
+
+       return 0;
+}
+
+struct voice_event_s {
+       rpc_port_parcelable_t parcelable;
+       int type;
+       char *source;
+};
+
+static void __voice_event_to(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_voice_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, h->type);
+       rpc_port_parcel_write_string(parcel, h->source ? h->source : "");
+}
+
+static void __voice_event_from(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_voice_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &h->type);
+       rpc_port_parcel_read_string(parcel, &h->source);
+}
+
+int rpc_port_voice_event_create(rpc_port_voice_event_h *h)
+{
+       struct voice_event_s *handle;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       handle = calloc(1, sizeof(struct voice_event_s));
+       if (!handle) {
+               _E("Out of memory");
+               return -1;
+       }
+
+       handle->parcelable.to = __voice_event_to;
+       handle->parcelable.from = __voice_event_from;
+
+       *h = handle;
+
+       return 0;
+}
+
+int rpc_port_voice_event_destroy(rpc_port_voice_event_h h)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->source)
+               free(h->source);
+
+       free(h);
+
+       return 0;
+}
+
+int rpc_port_voice_event_clone(rpc_port_voice_event_h h, rpc_port_voice_event_h *clone)
+{
+       rpc_port_voice_event_h handle = NULL;
+
+       if (!h || !clone) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       rpc_port_voice_event_create(&handle);
+       if (!handle) {
+               _E("Failed to create voice_event handle");
+               return -1;
+       }
+
+       handle->type = h->type;
+       if (h->source) {
+               handle->source = strdup(h->source);
+               if (!handle->source) {
+                       _E("Failed to duplicate h->source");
+                       rpc_port_voice_event_destroy(handle);
+                       return -1;
+               }
+       }
+
+       *clone = handle;
+
+       return 0;
+}
+
+int rpc_port_voice_event_set_type(rpc_port_voice_event_h h, int type)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->type = type;
+       return 0;
+}
+
+int rpc_port_voice_event_set_source(rpc_port_voice_event_h h, const char *source)
+{
+       if (!h || !source) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->source) {
+               free(h->source);
+               h->source = NULL;
+       }
+
+       h->source = strdup(source);
+       if (!h->source) {
+               _E("Failed to duplicate data");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_voice_event_get_type(rpc_port_voice_event_h h, int *type)
+{
+       if (!h || !type) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *type = h->type;
+       return 0;
+}
+
+int rpc_port_voice_event_get_source(rpc_port_voice_event_h h, char **source)
+{
+       if (!h || !source) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (!h->source) {
+               _E("Invalid parameter: h->source is NULL");
+               return -1;
+       }
+
+       *source = strdup(h->source);
+       if (*source == NULL) {
+               _E("Failed to duplicate source");
+               return -1;
+       }
+
+       return 0;
+}
+
+struct action_event_s {
+       rpc_port_parcelable_t parcelable;
+       int type;
+       int timestamp;
+       char *cmd;
+       char **args;
+       int args_size;
+       int nargs;
+       char *source;
+};
+
+static void __action_event_to(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_action_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, h->type);
+       rpc_port_parcel_write_int32(parcel, h->timestamp);
+       rpc_port_parcel_write_string(parcel, h->cmd ? h->cmd : "");
+       rpc_port_parcel_write_array_count(parcel, h->args_size);
+       do {
+               for (int i = 0; i < h->args_size; i++) {
+                       rpc_port_parcel_write_string(parcel, h->args[i] ? h->args[i] : "");
+               }
+       } while (0);
+
+       rpc_port_parcel_write_int32(parcel, h->nargs);
+       rpc_port_parcel_write_string(parcel, h->source ? h->source : "");
+}
+
+static void __action_event_from(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_action_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &h->type);
+       rpc_port_parcel_read_int32(parcel, &h->timestamp);
+       rpc_port_parcel_read_string(parcel, &h->cmd);
+
+       do {
+               rpc_port_parcel_read_array_count(parcel, &h->args_size);
+
+               h->args = calloc(h->args_size, sizeof(*h->args));
+               if (!h->args) {
+                       _E("Out of memory");
+                       return;
+               }
+
+               for (int i = 0; i < h->args_size; i++) {
+                       char *value = NULL;
+
+                       rpc_port_parcel_read_string(parcel, &value);
+                       h->args[i] = value;
+               }
+       } while (0);
+
+       rpc_port_parcel_read_int32(parcel, &h->nargs);
+       rpc_port_parcel_read_string(parcel, &h->source);
+}
+
+int rpc_port_action_event_create(rpc_port_action_event_h *h)
+{
+       struct action_event_s *handle;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       handle = calloc(1, sizeof(struct action_event_s));
+       if (!handle) {
+               _E("Out of memory");
+               return -1;
+       }
+
+       handle->parcelable.to = __action_event_to;
+       handle->parcelable.from = __action_event_from;
+
+       *h = handle;
+
+       return 0;
+}
+
+int rpc_port_action_event_destroy(rpc_port_action_event_h h)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->cmd)
+               free(h->cmd);
+
+       do {
+               for (int j = 0; j < h->args_size; j++) {
+                       if (h->args[j])
+                               free(h->args[j]);
+               }
+               free(h->args);
+       } while (0);
+       if (h->source)
+               free(h->source);
+
+       free(h);
+
+       return 0;
+}
+
+int rpc_port_action_event_clone(rpc_port_action_event_h h, rpc_port_action_event_h *clone)
+{
+       rpc_port_action_event_h handle = NULL;
+
+       if (!h || !clone) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       rpc_port_action_event_create(&handle);
+       if (!handle) {
+               _E("Failed to create action_event handle");
+               return -1;
+       }
+
+       handle->type = h->type;
+       handle->timestamp = h->timestamp;
+       if (h->cmd) {
+               handle->cmd = strdup(h->cmd);
+               if (!handle->cmd) {
+                       _E("Failed to duplicate h->cmd");
+                       rpc_port_action_event_destroy(handle);
+                       return -1;
+               }
+       }
+
+       do {
+               if (h->args_size == 0) {
+                       _W("args is empty");
+                       break;
+               }
+
+               handle->args = calloc(h->args_size, sizeof(*h->args));
+               if (!handle->args) {
+                       _E("Out of memory");
+                       rpc_port_action_event_destroy(handle);
+                       return -1;
+               }
+               handle->args_size = h->args_size;
+
+               for (int i = 0; i < h->args_size; i++) {
+                       handle->args[i] = strdup(h->args[i]);
+               }
+       } while (0);
+
+       handle->nargs = h->nargs;
+       if (h->source) {
+               handle->source = strdup(h->source);
+               if (!handle->source) {
+                       _E("Failed to duplicate h->source");
+                       rpc_port_action_event_destroy(handle);
+                       return -1;
+               }
+       }
+
+       *clone = handle;
+
+       return 0;
+}
+
+int rpc_port_action_event_set_type(rpc_port_action_event_h h, int type)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->type = type;
+       return 0;
+}
+
+int rpc_port_action_event_set_timestamp(rpc_port_action_event_h h, int timestamp)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->timestamp = timestamp;
+       return 0;
+}
+
+int rpc_port_action_event_set_cmd(rpc_port_action_event_h h, const char *cmd)
+{
+       if (!h || !cmd) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->cmd) {
+               free(h->cmd);
+               h->cmd = NULL;
+       }
+
+       h->cmd = strdup(cmd);
+       if (!h->cmd) {
+               _E("Failed to duplicate data");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_action_event_set_args(rpc_port_action_event_h h, char **args, int args_size)
+{
+       if (!h || !args) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       do {
+               for (int j = 0; j < h->args_size; j++) {
+                       if (h->args[j])
+                               free(h->args[j]);
+               }
+               free(h->args);
+       } while (0);
+
+       h->args = NULL;
+
+       do {
+               h->args = calloc(args_size, sizeof(*args));
+               if (!h->args) {
+                       _E("Out of memory");
+                       return -1;
+               }
+               h->args_size = args_size;
+
+               for (int i = 0; i < h->args_size; i++) {
+                       h->args[i] = strdup(args[i]);
+               }
+       } while (0);
+
+       return 0;
+}
+
+int rpc_port_action_event_set_nargs(rpc_port_action_event_h h, int nargs)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->nargs = nargs;
+       return 0;
+}
+
+int rpc_port_action_event_set_source(rpc_port_action_event_h h, const char *source)
+{
+       if (!h || !source) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->source) {
+               free(h->source);
+               h->source = NULL;
+       }
+
+       h->source = strdup(source);
+       if (!h->source) {
+               _E("Failed to duplicate data");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_action_event_get_type(rpc_port_action_event_h h, int *type)
+{
+       if (!h || !type) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *type = h->type;
+       return 0;
+}
+
+int rpc_port_action_event_get_timestamp(rpc_port_action_event_h h, int *timestamp)
+{
+       if (!h || !timestamp) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *timestamp = h->timestamp;
+       return 0;
+}
+
+int rpc_port_action_event_get_cmd(rpc_port_action_event_h h, char **cmd)
+{
+       if (!h || !cmd) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (!h->cmd) {
+               _E("Invalid parameter: h->cmd is NULL");
+               return -1;
+       }
+
+       *cmd = strdup(h->cmd);
+       if (*cmd == NULL) {
+               _E("Failed to duplicate cmd");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_action_event_get_args(rpc_port_action_event_h h, char ***args, int *args_size)
+{
+       if (!h || !args || !args_size) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       do {
+               if (h->args_size == 0) {
+                       _W("args is empty");
+                       break;
+               }
+
+               *args = calloc(h->args_size, sizeof(*h->args));
+               if (!*args) {
+                       _E("Out of memory");
+                       return -1;
+               }
+               *args_size = h->args_size;
+
+               for (int i = 0; i < h->args_size; i++) {
+                       (*args)[i] = strdup(h->args[i]);
+               }
+       } while (0);
+
+       return 0;
+}
+
+int rpc_port_action_event_get_nargs(rpc_port_action_event_h h, int *nargs)
+{
+       if (!h || !nargs) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *nargs = h->nargs;
+       return 0;
+}
+
+int rpc_port_action_event_get_source(rpc_port_action_event_h h, char **source)
+{
+       if (!h || !source) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (!h->source) {
+               _E("Invalid parameter: h->source is NULL");
+               return -1;
+       }
+
+       *source = strdup(h->source);
+       if (*source == NULL) {
+               _E("Failed to duplicate source");
+               return -1;
+       }
+
+       return 0;
+}
+
+struct feedback_event_s {
+       rpc_port_parcelable_t parcelable;
+       int type;
+       int timestamp;
+       char *feedback;
+       char *comment;
+};
+
+static void __feedback_event_to(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_feedback_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, h->type);
+       rpc_port_parcel_write_int32(parcel, h->timestamp);
+       rpc_port_parcel_write_string(parcel, h->feedback ? h->feedback : "");
+       rpc_port_parcel_write_string(parcel, h->comment ? h->comment : "");
+}
+
+static void __feedback_event_from(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_feedback_event_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &h->type);
+       rpc_port_parcel_read_int32(parcel, &h->timestamp);
+       rpc_port_parcel_read_string(parcel, &h->feedback);
+       rpc_port_parcel_read_string(parcel, &h->comment);
+}
+
+int rpc_port_feedback_event_create(rpc_port_feedback_event_h *h)
+{
+       struct feedback_event_s *handle;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       handle = calloc(1, sizeof(struct feedback_event_s));
+       if (!handle) {
+               _E("Out of memory");
+               return -1;
+       }
+
+       handle->parcelable.to = __feedback_event_to;
+       handle->parcelable.from = __feedback_event_from;
+
+       *h = handle;
+
+       return 0;
+}
+
+int rpc_port_feedback_event_destroy(rpc_port_feedback_event_h h)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->feedback)
+               free(h->feedback);
+
+       if (h->comment)
+               free(h->comment);
+
+       free(h);
+
+       return 0;
+}
+
+int rpc_port_feedback_event_clone(rpc_port_feedback_event_h h, rpc_port_feedback_event_h *clone)
+{
+       rpc_port_feedback_event_h handle = NULL;
+
+       if (!h || !clone) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       rpc_port_feedback_event_create(&handle);
+       if (!handle) {
+               _E("Failed to create feedback_event handle");
+               return -1;
+       }
+
+       handle->type = h->type;
+       handle->timestamp = h->timestamp;
+       if (h->feedback) {
+               handle->feedback = strdup(h->feedback);
+               if (!handle->feedback) {
+                       _E("Failed to duplicate h->feedback");
+                       rpc_port_feedback_event_destroy(handle);
+                       return -1;
+               }
+       }
+
+       if (h->comment) {
+               handle->comment = strdup(h->comment);
+               if (!handle->comment) {
+                       _E("Failed to duplicate h->comment");
+                       rpc_port_feedback_event_destroy(handle);
+                       return -1;
+               }
+       }
+
+       *clone = handle;
+
+       return 0;
+}
+
+int rpc_port_feedback_event_set_type(rpc_port_feedback_event_h h, int type)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->type = type;
+       return 0;
+}
+
+int rpc_port_feedback_event_set_timestamp(rpc_port_feedback_event_h h, int timestamp)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       h->timestamp = timestamp;
+       return 0;
+}
+
+int rpc_port_feedback_event_set_feedback(rpc_port_feedback_event_h h, const char *feedback)
+{
+       if (!h || !feedback) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->feedback) {
+               free(h->feedback);
+               h->feedback = NULL;
+       }
+
+       h->feedback = strdup(feedback);
+       if (!h->feedback) {
+               _E("Failed to duplicate data");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_feedback_event_set_comment(rpc_port_feedback_event_h h, const char *comment)
+{
+       if (!h || !comment) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (h->comment) {
+               free(h->comment);
+               h->comment = NULL;
+       }
+
+       h->comment = strdup(comment);
+       if (!h->comment) {
+               _E("Failed to duplicate data");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_feedback_event_get_type(rpc_port_feedback_event_h h, int *type)
+{
+       if (!h || !type) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *type = h->type;
+       return 0;
+}
+
+int rpc_port_feedback_event_get_timestamp(rpc_port_feedback_event_h h, int *timestamp)
+{
+       if (!h || !timestamp) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       *timestamp = h->timestamp;
+       return 0;
+}
+
+int rpc_port_feedback_event_get_feedback(rpc_port_feedback_event_h h, char **feedback)
+{
+       if (!h || !feedback) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (!h->feedback) {
+               _E("Invalid parameter: h->feedback is NULL");
+               return -1;
+       }
+
+       *feedback = strdup(h->feedback);
+       if (*feedback == NULL) {
+               _E("Failed to duplicate feedback");
+               return -1;
+       }
+
+       return 0;
+}
+
+int rpc_port_feedback_event_get_comment(rpc_port_feedback_event_h h, char **comment)
+{
+       if (!h || !comment) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       if (!h->comment) {
+               _E("Invalid parameter: h->comment is NULL");
+               return -1;
+       }
+
+       *comment = strdup(h->comment);
+       if (*comment == NULL) {
+               _E("Failed to duplicate comment");
+               return -1;
+       }
+
+       return 0;
+}
+
+struct array_string_s {
+       rpc_port_parcelable_t parcelable;
+       char **array_strings;
+       int array_strings_size;
+};
+
+static void __array_string_to(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_array_string_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_array_count(parcel, h->array_strings_size);
+       do {
+               for (int i = 0; i < h->array_strings_size; i++) {
+                       rpc_port_parcel_write_string(parcel, h->array_strings[i] ? h->array_strings[i] : "");
+               }
+       } while (0);
+}
+
+static void __array_string_from(rpc_port_parcel_h parcel, void *data)
+{
+       rpc_port_array_string_h h = data;
+
+       if (!parcel || !h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       do {
+               rpc_port_parcel_read_array_count(parcel, &h->array_strings_size);
+
+               h->array_strings = calloc(h->array_strings_size, sizeof(*h->array_strings));
+               if (!h->array_strings) {
+                       _E("Out of memory");
+                       return;
+               }
+
+               for (int i = 0; i < h->array_strings_size; i++) {
+                       char *value = NULL;
+
+                       rpc_port_parcel_read_string(parcel, &value);
+                       h->array_strings[i] = value;
+               }
+       } while (0);
+}
+
+int rpc_port_array_string_create(rpc_port_array_string_h *h)
+{
+       struct array_string_s *handle;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       handle = calloc(1, sizeof(struct array_string_s));
+       if (!handle) {
+               _E("Out of memory");
+               return -1;
+       }
+
+       handle->parcelable.to = __array_string_to;
+       handle->parcelable.from = __array_string_from;
+
+       *h = handle;
+
+       return 0;
+}
+
+int rpc_port_array_string_destroy(rpc_port_array_string_h h)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       do {
+               for (int j = 0; j < h->array_strings_size; j++) {
+                       if (h->array_strings[j])
+                               free(h->array_strings[j]);
+               }
+               free(h->array_strings);
+       } while (0);
+
+       free(h);
+
+       return 0;
+}
+
+int rpc_port_array_string_clone(rpc_port_array_string_h h, rpc_port_array_string_h *clone)
+{
+       rpc_port_array_string_h handle = NULL;
+
+       if (!h || !clone) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       rpc_port_array_string_create(&handle);
+       if (!handle) {
+               _E("Failed to create array_string handle");
+               return -1;
+       }
+
+       do {
+               if (h->array_strings_size == 0) {
+                       _W("array_strings is empty");
+                       break;
+               }
+
+               handle->array_strings = calloc(h->array_strings_size, sizeof(*h->array_strings));
+               if (!handle->array_strings) {
+                       _E("Out of memory");
+                       rpc_port_array_string_destroy(handle);
+                       return -1;
+               }
+               handle->array_strings_size = h->array_strings_size;
+
+               for (int i = 0; i < h->array_strings_size; i++) {
+                       handle->array_strings[i] = strdup(h->array_strings[i]);
+               }
+       } while (0);
+
+       *clone = handle;
+
+       return 0;
+}
+
+int rpc_port_array_string_set_array_strings(rpc_port_array_string_h h, char **array_strings, int array_strings_size)
+{
+       if (!h || !array_strings) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       do {
+               for (int j = 0; j < h->array_strings_size; j++) {
+                       if (h->array_strings[j])
+                               free(h->array_strings[j]);
+               }
+               free(h->array_strings);
+       } while (0);
+
+       h->array_strings = NULL;
+
+       do {
+               h->array_strings = calloc(array_strings_size, sizeof(*array_strings));
+               if (!h->array_strings) {
+                       _E("Out of memory");
+                       return -1;
+               }
+               h->array_strings_size = array_strings_size;
+
+               for (int i = 0; i < h->array_strings_size; i++) {
+                       h->array_strings[i] = strdup(array_strings[i]);
+               }
+       } while (0);
+
+       return 0;
+}
+
+int rpc_port_array_string_get_array_strings(rpc_port_array_string_h h, char ***array_strings, int *array_strings_size)
+{
+       if (!h || !array_strings || !array_strings_size) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       do {
+               if (h->array_strings_size == 0) {
+                       _W("array_strings is empty");
+                       break;
+               }
+
+               *array_strings = calloc(h->array_strings_size, sizeof(*h->array_strings));
+               if (!*array_strings) {
+                       _E("Out of memory");
+                       return -1;
+               }
+               *array_strings_size = h->array_strings_size;
+
+               for (int i = 0; i < h->array_strings_size; i++) {
+                       (*array_strings)[i] = strdup(h->array_strings[i]);
+               }
+       } while (0);
+
+       return 0;
+}
+
+enum mmifw_method_e {
+       mmifw_METHOD_Result,
+       mmifw_METHOD_Callback,
+       mmifw_METHOD_register_cb,
+       mmifw_METHOD_deregister_cb,
+       mmifw_METHOD_get_focus,
+       mmifw_METHOD_set_state,
+};
+
+enum mmifw_delegate_e {
+       mmifw_DELEGATE_focus_event_cb = 1,
+       mmifw_DELEGATE_state_change_event_cb = 2,
+       mmifw_DELEGATE_wakeup_event_cb = 3,
+       mmifw_DELEGATE_key_event_cb = 4,
+       mmifw_DELEGATE_gesture_event_cb = 5,
+       mmifw_DELEGATE_voice_event_cb = 6,
+       mmifw_DELEGATE_action_event_cb = 7,
+       mmifw_DELEGATE_feedback_event_cb = 8,
+};
+
+struct mmifw_s {
+       char *stub_appid;
+       rpc_port_proxy_h proxy;
+       rpc_port_h port;
+       rpc_port_h callback_port;
+       rpc_port_proxy_mmifw_callback_s callback;
+       void *user_data;
+       GList *delegates;
+       GRecMutex mutex;
+};
+
+struct mmifw_focus_event_cb_s {
+       rpc_port_parcelable_t parcelable;
+       int id;
+       int seq_id;
+       mmifw_focus_event_cb callback;
+       bool once;
+       void *user_data;
+};
+
+static void __mmifw_focus_event_cb_to(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_focus_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, handle->id);
+       rpc_port_parcel_write_int32(parcel, handle->seq_id);
+       rpc_port_parcel_write_bool(parcel, handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+static void __mmifw_focus_event_cb_from(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_focus_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &handle->id);
+       rpc_port_parcel_read_int32(parcel, &handle->seq_id);
+       rpc_port_parcel_read_bool(parcel, &handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+rpc_port_mmifw_focus_event_cb_h rpc_port_mmifw_focus_event_cb_create(mmifw_focus_event_cb callback, bool once, void *user_data)
+{
+       struct mmifw_focus_event_cb_s *handle;
+       static int seq_num;
+
+       handle = calloc(1, sizeof(struct mmifw_focus_event_cb_s));
+       if (!handle) {
+               _E("Out of memory");
+               return NULL;
+       }
+
+       handle->parcelable.to = __mmifw_focus_event_cb_to;
+       handle->parcelable.from= __mmifw_focus_event_cb_from;
+       handle->id = mmifw_DELEGATE_focus_event_cb;
+       handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+       handle->callback = callback;
+       handle->once = once;
+       handle->user_data = user_data;
+       _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+       return handle;
+}
+
+int rpc_port_mmifw_focus_event_cb_destroy(rpc_port_mmifw_focus_event_cb_h delegate)
+{
+       if (!delegate) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       free(delegate);
+
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_focus_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_focus_event_cb_h delegate)
+{
+       struct mmifw_focus_event_cb_s *handle;
+       GList *iter;
+
+       if (!proxy || !delegate) {
+               _E("Invalid handle %p %p", proxy, delegate);
+               return -1;
+       }
+
+       iter = proxy->delegates;
+       while (iter) {
+               handle = (struct mmifw_focus_event_cb_s *)iter->data;
+               if (handle == delegate) {
+                       _W("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+                       proxy->delegates = g_list_remove_link(proxy->delegates, iter);
+                       free(handle);
+                       g_list_free(iter);
+                       return 0;
+               }
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
+static void __mmifw_delegate_focus_event_cb(GList **list, rpc_port_parcel_h parcel, int seq_id, int id)
+{
+       rpc_port_focus_event_h args = NULL;
+
+       rpc_port_focus_event_create(&args);
+       rpc_port_parcel_read(parcel, &args->parcelable, args);
+
+       do {
+               struct mmifw_focus_event_cb_s *handle;
+               GList *iter;
+
+               iter = *list;
+               while (iter) {
+                       handle = (struct mmifw_focus_event_cb_s *)iter->data;
+                       if (handle->seq_id == seq_id && handle->id == id) {
+                               bool once = handle->once;
+
+                               _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+                               handle->callback(handle->user_data, args);
+
+                               if (once) {
+                                       _W("Dispose");
+                                       *list = g_list_remove_link(*list, iter);
+                                       free(handle);
+                                       g_list_free(iter);
+                               }
+                               break;
+                       }
+                       iter = g_list_next(iter);
+               }
+       } while (0);
+       rpc_port_focus_event_destroy(args);
+}
+
+struct mmifw_state_change_event_cb_s {
+       rpc_port_parcelable_t parcelable;
+       int id;
+       int seq_id;
+       mmifw_state_change_event_cb callback;
+       bool once;
+       void *user_data;
+};
+
+static void __mmifw_state_change_event_cb_to(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_state_change_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, handle->id);
+       rpc_port_parcel_write_int32(parcel, handle->seq_id);
+       rpc_port_parcel_write_bool(parcel, handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+static void __mmifw_state_change_event_cb_from(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_state_change_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &handle->id);
+       rpc_port_parcel_read_int32(parcel, &handle->seq_id);
+       rpc_port_parcel_read_bool(parcel, &handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+rpc_port_mmifw_state_change_event_cb_h rpc_port_mmifw_state_change_event_cb_create(mmifw_state_change_event_cb callback, bool once, void *user_data)
+{
+       struct mmifw_state_change_event_cb_s *handle;
+       static int seq_num;
+
+       handle = calloc(1, sizeof(struct mmifw_state_change_event_cb_s));
+       if (!handle) {
+               _E("Out of memory");
+               return NULL;
+       }
+
+       handle->parcelable.to = __mmifw_state_change_event_cb_to;
+       handle->parcelable.from= __mmifw_state_change_event_cb_from;
+       handle->id = mmifw_DELEGATE_state_change_event_cb;
+       handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+       handle->callback = callback;
+       handle->once = once;
+       handle->user_data = user_data;
+       _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+       return handle;
+}
+
+int rpc_port_mmifw_state_change_event_cb_destroy(rpc_port_mmifw_state_change_event_cb_h delegate)
+{
+       if (!delegate) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       free(delegate);
+
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_state_change_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_state_change_event_cb_h delegate)
+{
+       struct mmifw_state_change_event_cb_s *handle;
+       GList *iter;
+
+       if (!proxy || !delegate) {
+               _E("Invalid handle %p %p", proxy, delegate);
+               return -1;
+       }
+
+       iter = proxy->delegates;
+       while (iter) {
+               handle = (struct mmifw_state_change_event_cb_s *)iter->data;
+               if (handle == delegate) {
+                       _W("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+                       proxy->delegates = g_list_remove_link(proxy->delegates, iter);
+                       free(handle);
+                       g_list_free(iter);
+                       return 0;
+               }
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
+static void __mmifw_delegate_state_change_event_cb(GList **list, rpc_port_parcel_h parcel, int seq_id, int id)
+{
+       rpc_port_state_change_event_h args = NULL;
+
+       rpc_port_state_change_event_create(&args);
+       rpc_port_parcel_read(parcel, &args->parcelable, args);
+
+       do {
+               struct mmifw_state_change_event_cb_s *handle;
+               GList *iter;
+
+               iter = *list;
+               while (iter) {
+                       handle = (struct mmifw_state_change_event_cb_s *)iter->data;
+                       if (handle->seq_id == seq_id && handle->id == id) {
+                               bool once = handle->once;
+
+                               _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+                               handle->callback(handle->user_data, args);
+
+                               if (once) {
+                                       _W("Dispose");
+                                       *list = g_list_remove_link(*list, iter);
+                                       free(handle);
+                                       g_list_free(iter);
+                               }
+                               break;
+                       }
+                       iter = g_list_next(iter);
+               }
+       } while (0);
+       rpc_port_state_change_event_destroy(args);
+}
+
+struct mmifw_wakeup_event_cb_s {
+       rpc_port_parcelable_t parcelable;
+       int id;
+       int seq_id;
+       mmifw_wakeup_event_cb callback;
+       bool once;
+       void *user_data;
+};
+
+static void __mmifw_wakeup_event_cb_to(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_wakeup_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, handle->id);
+       rpc_port_parcel_write_int32(parcel, handle->seq_id);
+       rpc_port_parcel_write_bool(parcel, handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+static void __mmifw_wakeup_event_cb_from(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_wakeup_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &handle->id);
+       rpc_port_parcel_read_int32(parcel, &handle->seq_id);
+       rpc_port_parcel_read_bool(parcel, &handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+rpc_port_mmifw_wakeup_event_cb_h rpc_port_mmifw_wakeup_event_cb_create(mmifw_wakeup_event_cb callback, bool once, void *user_data)
+{
+       struct mmifw_wakeup_event_cb_s *handle;
+       static int seq_num;
+
+       handle = calloc(1, sizeof(struct mmifw_wakeup_event_cb_s));
+       if (!handle) {
+               _E("Out of memory");
+               return NULL;
+       }
+
+       handle->parcelable.to = __mmifw_wakeup_event_cb_to;
+       handle->parcelable.from= __mmifw_wakeup_event_cb_from;
+       handle->id = mmifw_DELEGATE_wakeup_event_cb;
+       handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+       handle->callback = callback;
+       handle->once = once;
+       handle->user_data = user_data;
+       _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+       return handle;
+}
+
+int rpc_port_mmifw_wakeup_event_cb_destroy(rpc_port_mmifw_wakeup_event_cb_h delegate)
+{
+       if (!delegate) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       free(delegate);
+
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_wakeup_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_wakeup_event_cb_h delegate)
+{
+       struct mmifw_wakeup_event_cb_s *handle;
+       GList *iter;
+
+       if (!proxy || !delegate) {
+               _E("Invalid handle %p %p", proxy, delegate);
+               return -1;
+       }
+
+       iter = proxy->delegates;
+       while (iter) {
+               handle = (struct mmifw_wakeup_event_cb_s *)iter->data;
+               if (handle == delegate) {
+                       _W("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+                       proxy->delegates = g_list_remove_link(proxy->delegates, iter);
+                       free(handle);
+                       g_list_free(iter);
+                       return 0;
+               }
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
+static void __mmifw_delegate_wakeup_event_cb(GList **list, rpc_port_parcel_h parcel, int seq_id, int id)
+{
+       rpc_port_wakeup_event_h args = NULL;
+
+       rpc_port_wakeup_event_create(&args);
+       rpc_port_parcel_read(parcel, &args->parcelable, args);
+
+       do {
+               struct mmifw_wakeup_event_cb_s *handle;
+               GList *iter;
+
+               iter = *list;
+               while (iter) {
+                       handle = (struct mmifw_wakeup_event_cb_s *)iter->data;
+                       if (handle->seq_id == seq_id && handle->id == id) {
+                               bool once = handle->once;
+
+                               _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+                               handle->callback(handle->user_data, args);
+
+                               if (once) {
+                                       _W("Dispose");
+                                       *list = g_list_remove_link(*list, iter);
+                                       free(handle);
+                                       g_list_free(iter);
+                               }
+                               break;
+                       }
+                       iter = g_list_next(iter);
+               }
+       } while (0);
+       rpc_port_wakeup_event_destroy(args);
+}
+
+struct mmifw_key_event_cb_s {
+       rpc_port_parcelable_t parcelable;
+       int id;
+       int seq_id;
+       mmifw_key_event_cb callback;
+       bool once;
+       void *user_data;
+};
+
+static void __mmifw_key_event_cb_to(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_key_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, handle->id);
+       rpc_port_parcel_write_int32(parcel, handle->seq_id);
+       rpc_port_parcel_write_bool(parcel, handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+static void __mmifw_key_event_cb_from(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_key_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &handle->id);
+       rpc_port_parcel_read_int32(parcel, &handle->seq_id);
+       rpc_port_parcel_read_bool(parcel, &handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+rpc_port_mmifw_key_event_cb_h rpc_port_mmifw_key_event_cb_create(mmifw_key_event_cb callback, bool once, void *user_data)
+{
+       struct mmifw_key_event_cb_s *handle;
+       static int seq_num;
+
+       handle = calloc(1, sizeof(struct mmifw_key_event_cb_s));
+       if (!handle) {
+               _E("Out of memory");
+               return NULL;
+       }
+
+       handle->parcelable.to = __mmifw_key_event_cb_to;
+       handle->parcelable.from= __mmifw_key_event_cb_from;
+       handle->id = mmifw_DELEGATE_key_event_cb;
+       handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+       handle->callback = callback;
+       handle->once = once;
+       handle->user_data = user_data;
+       _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+       return handle;
+}
+
+int rpc_port_mmifw_key_event_cb_destroy(rpc_port_mmifw_key_event_cb_h delegate)
+{
+       if (!delegate) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       free(delegate);
+
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_key_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_key_event_cb_h delegate)
+{
+       struct mmifw_key_event_cb_s *handle;
+       GList *iter;
+
+       if (!proxy || !delegate) {
+               _E("Invalid handle %p %p", proxy, delegate);
+               return -1;
+       }
+
+       iter = proxy->delegates;
+       while (iter) {
+               handle = (struct mmifw_key_event_cb_s *)iter->data;
+               if (handle == delegate) {
+                       _W("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+                       proxy->delegates = g_list_remove_link(proxy->delegates, iter);
+                       free(handle);
+                       g_list_free(iter);
+                       return 0;
+               }
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
+static void __mmifw_delegate_key_event_cb(GList **list, rpc_port_parcel_h parcel, int seq_id, int id)
+{
+       rpc_port_key_event_h args = NULL;
+
+       rpc_port_key_event_create(&args);
+       rpc_port_parcel_read(parcel, &args->parcelable, args);
+
+       do {
+               struct mmifw_key_event_cb_s *handle;
+               GList *iter;
+
+               iter = *list;
+               while (iter) {
+                       handle = (struct mmifw_key_event_cb_s *)iter->data;
+                       if (handle->seq_id == seq_id && handle->id == id) {
+                               bool once = handle->once;
+
+                               _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+                               handle->callback(handle->user_data, args);
+
+                               if (once) {
+                                       _W("Dispose");
+                                       *list = g_list_remove_link(*list, iter);
+                                       free(handle);
+                                       g_list_free(iter);
+                               }
+                               break;
+                       }
+                       iter = g_list_next(iter);
+               }
+       } while (0);
+       rpc_port_key_event_destroy(args);
+}
+
+struct mmifw_gesture_event_cb_s {
+       rpc_port_parcelable_t parcelable;
+       int id;
+       int seq_id;
+       mmifw_gesture_event_cb callback;
+       bool once;
+       void *user_data;
+};
+
+static void __mmifw_gesture_event_cb_to(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_gesture_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, handle->id);
+       rpc_port_parcel_write_int32(parcel, handle->seq_id);
+       rpc_port_parcel_write_bool(parcel, handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+static void __mmifw_gesture_event_cb_from(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_gesture_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &handle->id);
+       rpc_port_parcel_read_int32(parcel, &handle->seq_id);
+       rpc_port_parcel_read_bool(parcel, &handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+rpc_port_mmifw_gesture_event_cb_h rpc_port_mmifw_gesture_event_cb_create(mmifw_gesture_event_cb callback, bool once, void *user_data)
+{
+       struct mmifw_gesture_event_cb_s *handle;
+       static int seq_num;
+
+       handle = calloc(1, sizeof(struct mmifw_gesture_event_cb_s));
+       if (!handle) {
+               _E("Out of memory");
+               return NULL;
+       }
+
+       handle->parcelable.to = __mmifw_gesture_event_cb_to;
+       handle->parcelable.from= __mmifw_gesture_event_cb_from;
+       handle->id = mmifw_DELEGATE_gesture_event_cb;
+       handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+       handle->callback = callback;
+       handle->once = once;
+       handle->user_data = user_data;
+       _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+       return handle;
+}
+
+int rpc_port_mmifw_gesture_event_cb_destroy(rpc_port_mmifw_gesture_event_cb_h delegate)
+{
+       if (!delegate) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       free(delegate);
+
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_gesture_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_gesture_event_cb_h delegate)
+{
+       struct mmifw_gesture_event_cb_s *handle;
+       GList *iter;
+
+       if (!proxy || !delegate) {
+               _E("Invalid handle %p %p", proxy, delegate);
+               return -1;
+       }
+
+       iter = proxy->delegates;
+       while (iter) {
+               handle = (struct mmifw_gesture_event_cb_s *)iter->data;
+               if (handle == delegate) {
+                       _W("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+                       proxy->delegates = g_list_remove_link(proxy->delegates, iter);
+                       free(handle);
+                       g_list_free(iter);
+                       return 0;
+               }
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
+static void __mmifw_delegate_gesture_event_cb(GList **list, rpc_port_parcel_h parcel, int seq_id, int id)
+{
+       rpc_port_gesture_event_h args = NULL;
+
+       rpc_port_gesture_event_create(&args);
+       rpc_port_parcel_read(parcel, &args->parcelable, args);
+
+       do {
+               struct mmifw_gesture_event_cb_s *handle;
+               GList *iter;
+
+               iter = *list;
+               while (iter) {
+                       handle = (struct mmifw_gesture_event_cb_s *)iter->data;
+                       if (handle->seq_id == seq_id && handle->id == id) {
+                               bool once = handle->once;
+
+                               _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+                               handle->callback(handle->user_data, args);
+
+                               if (once) {
+                                       _W("Dispose");
+                                       *list = g_list_remove_link(*list, iter);
+                                       free(handle);
+                                       g_list_free(iter);
+                               }
+                               break;
+                       }
+                       iter = g_list_next(iter);
+               }
+       } while (0);
+       rpc_port_gesture_event_destroy(args);
+}
+
+struct mmifw_voice_event_cb_s {
+       rpc_port_parcelable_t parcelable;
+       int id;
+       int seq_id;
+       mmifw_voice_event_cb callback;
+       bool once;
+       void *user_data;
+};
+
+static void __mmifw_voice_event_cb_to(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_voice_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, handle->id);
+       rpc_port_parcel_write_int32(parcel, handle->seq_id);
+       rpc_port_parcel_write_bool(parcel, handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+static void __mmifw_voice_event_cb_from(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_voice_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &handle->id);
+       rpc_port_parcel_read_int32(parcel, &handle->seq_id);
+       rpc_port_parcel_read_bool(parcel, &handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+rpc_port_mmifw_voice_event_cb_h rpc_port_mmifw_voice_event_cb_create(mmifw_voice_event_cb callback, bool once, void *user_data)
+{
+       struct mmifw_voice_event_cb_s *handle;
+       static int seq_num;
+
+       handle = calloc(1, sizeof(struct mmifw_voice_event_cb_s));
+       if (!handle) {
+               _E("Out of memory");
+               return NULL;
+       }
+
+       handle->parcelable.to = __mmifw_voice_event_cb_to;
+       handle->parcelable.from= __mmifw_voice_event_cb_from;
+       handle->id = mmifw_DELEGATE_voice_event_cb;
+       handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+       handle->callback = callback;
+       handle->once = once;
+       handle->user_data = user_data;
+       _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+       return handle;
+}
+
+int rpc_port_mmifw_voice_event_cb_destroy(rpc_port_mmifw_voice_event_cb_h delegate)
+{
+       if (!delegate) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       free(delegate);
+
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_voice_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_voice_event_cb_h delegate)
+{
+       struct mmifw_voice_event_cb_s *handle;
+       GList *iter;
+
+       if (!proxy || !delegate) {
+               _E("Invalid handle %p %p", proxy, delegate);
+               return -1;
+       }
+
+       iter = proxy->delegates;
+       while (iter) {
+               handle = (struct mmifw_voice_event_cb_s *)iter->data;
+               if (handle == delegate) {
+                       _W("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+                       proxy->delegates = g_list_remove_link(proxy->delegates, iter);
+                       free(handle);
+                       g_list_free(iter);
+                       return 0;
+               }
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
+static void __mmifw_delegate_voice_event_cb(GList **list, rpc_port_parcel_h parcel, int seq_id, int id)
+{
+       rpc_port_voice_event_h args = NULL;
+
+       rpc_port_voice_event_create(&args);
+       rpc_port_parcel_read(parcel, &args->parcelable, args);
+
+       do {
+               struct mmifw_voice_event_cb_s *handle;
+               GList *iter;
+
+               iter = *list;
+               while (iter) {
+                       handle = (struct mmifw_voice_event_cb_s *)iter->data;
+                       if (handle->seq_id == seq_id && handle->id == id) {
+                               bool once = handle->once;
+
+                               _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+                               handle->callback(handle->user_data, args);
+
+                               if (once) {
+                                       _W("Dispose");
+                                       *list = g_list_remove_link(*list, iter);
+                                       free(handle);
+                                       g_list_free(iter);
+                               }
+                               break;
+                       }
+                       iter = g_list_next(iter);
+               }
+       } while (0);
+       rpc_port_voice_event_destroy(args);
+}
+
+struct mmifw_action_event_cb_s {
+       rpc_port_parcelable_t parcelable;
+       int id;
+       int seq_id;
+       mmifw_action_event_cb callback;
+       bool once;
+       void *user_data;
+};
+
+static void __mmifw_action_event_cb_to(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_action_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, handle->id);
+       rpc_port_parcel_write_int32(parcel, handle->seq_id);
+       rpc_port_parcel_write_bool(parcel, handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+static void __mmifw_action_event_cb_from(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_action_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &handle->id);
+       rpc_port_parcel_read_int32(parcel, &handle->seq_id);
+       rpc_port_parcel_read_bool(parcel, &handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+rpc_port_mmifw_action_event_cb_h rpc_port_mmifw_action_event_cb_create(mmifw_action_event_cb callback, bool once, void *user_data)
+{
+       struct mmifw_action_event_cb_s *handle;
+       static int seq_num;
+
+       handle = calloc(1, sizeof(struct mmifw_action_event_cb_s));
+       if (!handle) {
+               _E("Out of memory");
+               return NULL;
+       }
+
+       handle->parcelable.to = __mmifw_action_event_cb_to;
+       handle->parcelable.from= __mmifw_action_event_cb_from;
+       handle->id = mmifw_DELEGATE_action_event_cb;
+       handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+       handle->callback = callback;
+       handle->once = once;
+       handle->user_data = user_data;
+       _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+       return handle;
+}
+
+int rpc_port_mmifw_action_event_cb_destroy(rpc_port_mmifw_action_event_cb_h delegate)
+{
+       if (!delegate) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       free(delegate);
+
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_action_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_action_event_cb_h delegate)
+{
+       struct mmifw_action_event_cb_s *handle;
+       GList *iter;
+
+       if (!proxy || !delegate) {
+               _E("Invalid handle %p %p", proxy, delegate);
+               return -1;
+       }
+
+       iter = proxy->delegates;
+       while (iter) {
+               handle = (struct mmifw_action_event_cb_s *)iter->data;
+               if (handle == delegate) {
+                       _W("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+                       proxy->delegates = g_list_remove_link(proxy->delegates, iter);
+                       free(handle);
+                       g_list_free(iter);
+                       return 0;
+               }
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
+static void __mmifw_delegate_action_event_cb(GList **list, rpc_port_parcel_h parcel, int seq_id, int id)
+{
+       rpc_port_action_event_h args = NULL;
+
+       rpc_port_action_event_create(&args);
+       rpc_port_parcel_read(parcel, &args->parcelable, args);
+
+       do {
+               struct mmifw_action_event_cb_s *handle;
+               GList *iter;
+
+               iter = *list;
+               while (iter) {
+                       handle = (struct mmifw_action_event_cb_s *)iter->data;
+                       if (handle->seq_id == seq_id && handle->id == id) {
+                               bool once = handle->once;
+
+                               _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+                               handle->callback(handle->user_data, args);
+
+                               if (once) {
+                                       _W("Dispose");
+                                       *list = g_list_remove_link(*list, iter);
+                                       free(handle);
+                                       g_list_free(iter);
+                               }
+                               break;
+                       }
+                       iter = g_list_next(iter);
+               }
+       } while (0);
+       rpc_port_action_event_destroy(args);
+}
+
+struct mmifw_feedback_event_cb_s {
+       rpc_port_parcelable_t parcelable;
+       int id;
+       int seq_id;
+       mmifw_feedback_event_cb callback;
+       bool once;
+       void *user_data;
+};
+
+static void __mmifw_feedback_event_cb_to(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_feedback_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_write_int32(parcel, handle->id);
+       rpc_port_parcel_write_int32(parcel, handle->seq_id);
+       rpc_port_parcel_write_bool(parcel, handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+static void __mmifw_feedback_event_cb_from(rpc_port_parcel_h parcel, void *data)
+{
+       struct mmifw_feedback_event_cb_s *handle = data;
+
+       if (!handle) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel, &handle->id);
+       rpc_port_parcel_read_int32(parcel, &handle->seq_id);
+       rpc_port_parcel_read_bool(parcel, &handle->once);
+       _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+}
+
+rpc_port_mmifw_feedback_event_cb_h rpc_port_mmifw_feedback_event_cb_create(mmifw_feedback_event_cb callback, bool once, void *user_data)
+{
+       struct mmifw_feedback_event_cb_s *handle;
+       static int seq_num;
+
+       handle = calloc(1, sizeof(struct mmifw_feedback_event_cb_s));
+       if (!handle) {
+               _E("Out of memory");
+               return NULL;
+       }
+
+       handle->parcelable.to = __mmifw_feedback_event_cb_to;
+       handle->parcelable.from= __mmifw_feedback_event_cb_from;
+       handle->id = mmifw_DELEGATE_feedback_event_cb;
+       handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+       handle->callback = callback;
+       handle->once = once;
+       handle->user_data = user_data;
+       _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+       return handle;
+}
+
+int rpc_port_mmifw_feedback_event_cb_destroy(rpc_port_mmifw_feedback_event_cb_h delegate)
+{
+       if (!delegate) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       free(delegate);
+
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_feedback_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_feedback_event_cb_h delegate)
+{
+       struct mmifw_feedback_event_cb_s *handle;
+       GList *iter;
+
+       if (!proxy || !delegate) {
+               _E("Invalid handle %p %p", proxy, delegate);
+               return -1;
+       }
+
+       iter = proxy->delegates;
+       while (iter) {
+               handle = (struct mmifw_feedback_event_cb_s *)iter->data;
+               if (handle == delegate) {
+                       _W("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+                       proxy->delegates = g_list_remove_link(proxy->delegates, iter);
+                       free(handle);
+                       g_list_free(iter);
+                       return 0;
+               }
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
+static void __mmifw_delegate_feedback_event_cb(GList **list, rpc_port_parcel_h parcel, int seq_id, int id)
+{
+       rpc_port_feedback_event_h args = NULL;
+
+       rpc_port_feedback_event_create(&args);
+       rpc_port_parcel_read(parcel, &args->parcelable, args);
+
+       do {
+               struct mmifw_feedback_event_cb_s *handle;
+               GList *iter;
+
+               iter = *list;
+               while (iter) {
+                       handle = (struct mmifw_feedback_event_cb_s *)iter->data;
+                       if (handle->seq_id == seq_id && handle->id == id) {
+                               bool once = handle->once;
+
+                               _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+                               handle->callback(handle->user_data, args);
+
+                               if (once) {
+                                       _W("Dispose");
+                                       *list = g_list_remove_link(*list, iter);
+                                       free(handle);
+                                       g_list_free(iter);
+                               }
+                               break;
+                       }
+                       iter = g_list_next(iter);
+               }
+       } while (0);
+       rpc_port_feedback_event_destroy(args);
+}
+
+static proxy_delegate __mmifw_delegate_table[] = {
+       [mmifw_DELEGATE_focus_event_cb] = __mmifw_delegate_focus_event_cb,
+       [mmifw_DELEGATE_state_change_event_cb] = __mmifw_delegate_state_change_event_cb,
+       [mmifw_DELEGATE_wakeup_event_cb] = __mmifw_delegate_wakeup_event_cb,
+       [mmifw_DELEGATE_key_event_cb] = __mmifw_delegate_key_event_cb,
+       [mmifw_DELEGATE_gesture_event_cb] = __mmifw_delegate_gesture_event_cb,
+       [mmifw_DELEGATE_voice_event_cb] = __mmifw_delegate_voice_event_cb,
+       [mmifw_DELEGATE_action_event_cb] = __mmifw_delegate_action_event_cb,
+       [mmifw_DELEGATE_feedback_event_cb] = __mmifw_delegate_feedback_event_cb,
+};
+
+static void __mmifw_process_received_event(GList **list, rpc_port_parcel_h parcel)
+{
+       int id;
+       int seq_id;
+       bool once;
+
+       rpc_port_parcel_read_int32(parcel, &id);
+       rpc_port_parcel_read_int32(parcel, &seq_id);
+       rpc_port_parcel_read_bool(parcel, &once);
+       _W("id(%d), seq_id(%d)", id, seq_id);
+
+       if (id > 0 && id < (sizeof(__mmifw_delegate_table) / sizeof(__mmifw_delegate_table[0]))) {
+               if (__mmifw_delegate_table[id])
+                       __mmifw_delegate_table[id](list, parcel, seq_id, id);
+       } else {
+               _W("Unknown id(%d)", id);
+       }
+}
+
+static rpc_port_parcel_h __mmifw_consume_command(rpc_port_proxy_mmifw_h h)
+{
+       rpc_port_parcel_h parcel = NULL;
+       int cmd = -1;
+
+       do {
+               rpc_port_parcel_create_from_port(&parcel, h->port);
+               if (!parcel)
+                       break;
+
+               rpc_port_parcel_read_int32(parcel, &cmd);
+               if (cmd == mmifw_METHOD_Result)
+                       return parcel;
+
+               rpc_port_parcel_destroy(parcel);
+               parcel = NULL;
+       } while (true);
+
+       return NULL;
+}
+
+static void __mmifw_on_connected(const char *endpoint, const char *port_name, rpc_port_h port, void *data)
+{
+       rpc_port_proxy_mmifw_h handle = data;
+
+       handle->port = port;
+       rpc_port_proxy_get_port(handle->proxy, RPC_PORT_PORT_CALLBACK, &handle->callback_port);
+       if (handle->callback.connected)
+               handle->callback.connected(handle, handle->user_data);
+       _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+}
+
+static void __mmifw_on_disconnected(const char *endpoint, const char *port_name, void *data)
+{
+       rpc_port_proxy_mmifw_h handle = data;
+
+       handle->port = NULL;
+       if (handle->callback.disconnected)
+               handle->callback.disconnected(handle, handle->user_data);
+       _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+}
+
+static void __mmifw_on_rejected(const char *endpoint, const char *port_name, void *data)
+{
+       rpc_port_proxy_mmifw_h handle = data;
+
+       handle->port = NULL;
+       if (handle->callback.rejected)
+               handle->callback.rejected(handle, handle->user_data);
+       _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+}
+
+static void __mmifw_on_received(const char *endpoint, const char *port_name, void *data)
+{
+       rpc_port_proxy_mmifw_h handle = data;
+       rpc_port_parcel_h parcel_received = NULL;
+       int cmd = -1;
+
+       rpc_port_parcel_create_from_port(&parcel_received, handle->callback_port);
+       if (!parcel_received) {
+               _E("Failed to create parcel from port(%s)", port_name);
+               return;
+       }
+
+       rpc_port_parcel_read_int32(parcel_received, &cmd);
+       if (cmd != mmifw_METHOD_Callback) {
+               _E("Invalid protocol");
+               rpc_port_parcel_destroy(parcel_received);
+               return;
+       }
+
+       __mmifw_process_received_event(&handle->delegates, parcel_received);
+       rpc_port_parcel_destroy(parcel_received);
+       _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+}
+
+int rpc_port_proxy_mmifw_invoke_register_cb(rpc_port_proxy_mmifw_h h, rpc_port_mmifw_focus_event_cb_h focus_cb, rpc_port_mmifw_state_change_event_cb_h state_cb, rpc_port_mmifw_wakeup_event_cb_h wakeup_cb, rpc_port_mmifw_key_event_cb_h key_cb, rpc_port_mmifw_gesture_event_cb_h gesture_cb, rpc_port_mmifw_voice_event_cb_h voice_cb, rpc_port_mmifw_action_event_cb_h action_cb, rpc_port_mmifw_feedback_event_cb_h feedback_cb)
+{
+       rpc_port_parcel_h parcel;
+       int r;
+       int ret = -1;
+
+       if (!h || !focus_cb || !state_cb || !wakeup_cb || !key_cb || !gesture_cb || !voice_cb || !action_cb || !feedback_cb) {
+               _E("Invalid parameter");
+               return ret;
+       }
+
+       if (!h->port) {
+               _E("Not connected");
+               return ret;
+       }
+
+       rpc_port_parcel_create(&parcel);
+       rpc_port_parcel_write_int32(parcel, mmifw_METHOD_register_cb);
+
+       do {
+               struct mmifw_focus_event_cb_s *handle = focus_cb;
+
+               rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+               h->delegates = g_list_append(h->delegates, handle);
+       } while (0);
+
+       do {
+               struct mmifw_state_change_event_cb_s *handle = state_cb;
+
+               rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+               h->delegates = g_list_append(h->delegates, handle);
+       } while (0);
+
+       do {
+               struct mmifw_wakeup_event_cb_s *handle = wakeup_cb;
+
+               rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+               h->delegates = g_list_append(h->delegates, handle);
+       } while (0);
+
+       do {
+               struct mmifw_key_event_cb_s *handle = key_cb;
+
+               rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+               h->delegates = g_list_append(h->delegates, handle);
+       } while (0);
+
+       do {
+               struct mmifw_gesture_event_cb_s *handle = gesture_cb;
+
+               rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+               h->delegates = g_list_append(h->delegates, handle);
+       } while (0);
+
+       do {
+               struct mmifw_voice_event_cb_s *handle = voice_cb;
+
+               rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+               h->delegates = g_list_append(h->delegates, handle);
+       } while (0);
+
+       do {
+               struct mmifw_action_event_cb_s *handle = action_cb;
+
+               rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+               h->delegates = g_list_append(h->delegates, handle);
+       } while (0);
+
+       do {
+               struct mmifw_feedback_event_cb_s *handle = feedback_cb;
+
+               rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+               h->delegates = g_list_append(h->delegates, handle);
+       } while (0);
+
+       r = rpc_port_parcel_send(parcel, h->port);
+       if (r != RPC_PORT_ERROR_NONE) {
+               _E("Failed to send parcel. result(%d)", r);
+               r = RPC_PORT_ERROR_IO_ERROR;
+       }
+
+       rpc_port_parcel_destroy(parcel);
+
+       g_rec_mutex_lock(&h->mutex);
+       do {
+               rpc_port_parcel_h parcel_received;
+
+               parcel_received = __mmifw_consume_command(h);
+               if (!parcel_received) {
+                       _E("Invalid protocol");
+                       r = RPC_PORT_ERROR_IO_ERROR;
+                       break;
+               }
+
+               rpc_port_parcel_read_int32(parcel_received, &ret);
+
+               rpc_port_parcel_destroy(parcel_received);
+       } while (0);
+       g_rec_mutex_unlock(&h->mutex);
+       set_last_result(r);
+
+       return ret;
+}
+
+void rpc_port_proxy_mmifw_invoke_deregister_cb(rpc_port_proxy_mmifw_h h)
+{
+       rpc_port_parcel_h parcel;
+       int r;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       if (!h->port) {
+               _E("Not connected");
+               return;
+       }
+
+       rpc_port_parcel_create(&parcel);
+       rpc_port_parcel_write_int32(parcel, mmifw_METHOD_deregister_cb);
+
+       r = rpc_port_parcel_send(parcel, h->port);
+       if (r != RPC_PORT_ERROR_NONE) {
+               _E("Failed to send parcel. result(%d)", r);
+               r = RPC_PORT_ERROR_IO_ERROR;
+       }
+
+       rpc_port_parcel_destroy(parcel);
+       set_last_result(r);
+}
+
+void rpc_port_proxy_mmifw_invoke_get_focus(rpc_port_proxy_mmifw_h h, const char *sender)
+{
+       rpc_port_parcel_h parcel;
+       int r;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       if (!h->port) {
+               _E("Not connected");
+               return;
+       }
+
+       rpc_port_parcel_create(&parcel);
+       rpc_port_parcel_write_int32(parcel, mmifw_METHOD_get_focus);
+       rpc_port_parcel_write_string(parcel, sender ? sender : "");
+
+       r = rpc_port_parcel_send(parcel, h->port);
+       if (r != RPC_PORT_ERROR_NONE) {
+               _E("Failed to send parcel. result(%d)", r);
+               r = RPC_PORT_ERROR_IO_ERROR;
+       }
+
+       rpc_port_parcel_destroy(parcel);
+       set_last_result(r);
+}
+
+void rpc_port_proxy_mmifw_invoke_set_state(rpc_port_proxy_mmifw_h h, const char *sender, int state)
+{
+       rpc_port_parcel_h parcel;
+       int r;
+
+       if (!h) {
+               _E("Invalid parameter");
+               return;
+       }
+
+       if (!h->port) {
+               _E("Not connected");
+               return;
+       }
+
+       rpc_port_parcel_create(&parcel);
+       rpc_port_parcel_write_int32(parcel, mmifw_METHOD_set_state);
+       rpc_port_parcel_write_string(parcel, sender ? sender : "");
+       rpc_port_parcel_write_int32(parcel, state);
+
+       r = rpc_port_parcel_send(parcel, h->port);
+       if (r != RPC_PORT_ERROR_NONE) {
+               _E("Failed to send parcel. result(%d)", r);
+               r = RPC_PORT_ERROR_IO_ERROR;
+       }
+
+       rpc_port_parcel_destroy(parcel);
+       set_last_result(r);
+}
+
+static struct mmifw_s *__create_mmifw(const char *stub_appid, rpc_port_proxy_mmifw_callback_s *callback, void *user_data)
+{
+       struct mmifw_s *handle;
+
+       handle = calloc(1, sizeof(struct mmifw_s));
+       if (!handle) {
+               _E("Out of memory");
+               return NULL;
+       }
+
+       handle->stub_appid = strdup(stub_appid);
+       if (!handle->stub_appid) {
+               _E("Out of memory");
+               free(handle);
+               return NULL;
+       }
+
+       rpc_port_proxy_create(&handle->proxy);
+       if (!handle->proxy) {
+               _E("Failed to create proxy");
+               free(handle->stub_appid);
+               free(handle);
+               return NULL;
+       }
+
+       g_rec_mutex_init(&handle->mutex);
+
+       handle->callback = *callback;
+       handle->user_data = user_data;
+
+       return handle;
+}
+
+static void __destroy_mmifw(struct mmifw_s *h)
+{
+       if (!h)
+               return;
+
+       g_rec_mutex_clear(&h->mutex);
+
+       if (h->delegates)
+               g_list_free_full(h->delegates, free);
+
+       if (h->proxy)
+               rpc_port_proxy_destroy(h->proxy);
+
+       if (h->stub_appid)
+               free(h->stub_appid);
+
+       free(h);
+}
+
+int rpc_port_proxy_mmifw_create(const char *stub_appid, rpc_port_proxy_mmifw_callback_s *callback, void *user_data, rpc_port_proxy_mmifw_h *h)
+{
+       struct mmifw_s *handle;
+       int r;
+
+       if (!stub_appid || !callback || !h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       handle = __create_mmifw(stub_appid, callback, user_data);
+       if (!handle)
+               return -1;
+
+       r = rpc_port_proxy_add_connected_event_cb(handle->proxy, __mmifw_on_connected, handle);
+       if (r != 0) {
+               _E("Failed to add connected event cb. err = %d", r);
+               __destroy_mmifw(handle);
+               return r;
+       }
+
+       r = rpc_port_proxy_add_disconnected_event_cb(handle->proxy, __mmifw_on_disconnected, handle);
+       if (r != 0) {
+               _E("Failed to add disconnected event cb. err = %d", r);
+               __destroy_mmifw(handle);
+               return r;
+       }
+
+       r = rpc_port_proxy_add_rejected_event_cb(handle->proxy, __mmifw_on_rejected, handle);
+       if (r != 0) {
+               _E("Failed to add rejected event cb. err = %d", r);
+               __destroy_mmifw(handle);
+               return r;
+       }
+
+       r = rpc_port_proxy_add_received_event_cb(handle->proxy, __mmifw_on_received, handle);
+       if (r != 0) {
+               _E("Failed to add received event cb. err = %d", r);
+               __destroy_mmifw(handle);
+               return r;
+       }
+
+       *h = handle;
+
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_connect(rpc_port_proxy_mmifw_h h)
+{
+       int r;
+
+       if (!h || !h->proxy) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       r = rpc_port_proxy_connect(h->proxy, h->stub_appid, "mmifw");
+       if (r != 0) {
+               _E("Failed to connect mmifw(%s)", h->stub_appid);
+               return r;
+       }
+
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_destroy(rpc_port_proxy_mmifw_h h)
+{
+       if (!h) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       __destroy_mmifw(h);
+       return 0;
+}
+
+int rpc_port_proxy_mmifw_connect_sync(rpc_port_proxy_mmifw_h h)
+{
+       int r;
+
+       if (!h || !h->proxy) {
+               _E("Invalid parameter");
+               return -1;
+       }
+
+       r = rpc_port_proxy_connect_sync(h->proxy, h->stub_appid, "mmifw");
+       if (r != 0) {
+               _E("Failed to connect sync mmifw(%s)", h->stub_appid);
+               return r;
+       }
+
+       return 0;
+}
diff --git a/src/interface/mmifw_proxy.h b/src/interface/mmifw_proxy.h
new file mode 100644 (file)
index 0000000..7f6cf88
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * Generated by tidlc 1.4.9.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct focus_event_s *rpc_port_focus_event_h;
+
+int rpc_port_focus_event_create(rpc_port_focus_event_h *h);
+
+int rpc_port_focus_event_destroy(rpc_port_focus_event_h h);
+
+int rpc_port_focus_event_clone(rpc_port_focus_event_h h, rpc_port_focus_event_h *clone);
+
+int rpc_port_focus_event_set_type(rpc_port_focus_event_h h, int type);
+
+int rpc_port_focus_event_set_timestamp(rpc_port_focus_event_h h, int timestamp);
+
+int rpc_port_focus_event_set_focus_in(rpc_port_focus_event_h h, bool focus_in);
+
+int rpc_port_focus_event_get_type(rpc_port_focus_event_h h, int *type);
+
+int rpc_port_focus_event_get_timestamp(rpc_port_focus_event_h h, int *timestamp);
+
+int rpc_port_focus_event_get_focus_in(rpc_port_focus_event_h h, bool *focus_in);
+
+typedef struct state_change_event_s *rpc_port_state_change_event_h;
+
+int rpc_port_state_change_event_create(rpc_port_state_change_event_h *h);
+
+int rpc_port_state_change_event_destroy(rpc_port_state_change_event_h h);
+
+int rpc_port_state_change_event_clone(rpc_port_state_change_event_h h, rpc_port_state_change_event_h *clone);
+
+int rpc_port_state_change_event_set_type(rpc_port_state_change_event_h h, int type);
+
+int rpc_port_state_change_event_set_timestamp(rpc_port_state_change_event_h h, int timestamp);
+
+int rpc_port_state_change_event_set_state(rpc_port_state_change_event_h h, int state);
+
+int rpc_port_state_change_event_set_old_state(rpc_port_state_change_event_h h, int old_state);
+
+int rpc_port_state_change_event_get_type(rpc_port_state_change_event_h h, int *type);
+
+int rpc_port_state_change_event_get_timestamp(rpc_port_state_change_event_h h, int *timestamp);
+
+int rpc_port_state_change_event_get_state(rpc_port_state_change_event_h h, int *state);
+
+int rpc_port_state_change_event_get_old_state(rpc_port_state_change_event_h h, int *old_state);
+
+typedef struct wakeup_event_s *rpc_port_wakeup_event_h;
+
+int rpc_port_wakeup_event_create(rpc_port_wakeup_event_h *h);
+
+int rpc_port_wakeup_event_destroy(rpc_port_wakeup_event_h h);
+
+int rpc_port_wakeup_event_clone(rpc_port_wakeup_event_h h, rpc_port_wakeup_event_h *clone);
+
+int rpc_port_wakeup_event_set_type(rpc_port_wakeup_event_h h, int type);
+
+int rpc_port_wakeup_event_set_timestamp(rpc_port_wakeup_event_h h, int timestamp);
+
+int rpc_port_wakeup_event_set_source(rpc_port_wakeup_event_h h, const char *source);
+
+int rpc_port_wakeup_event_get_type(rpc_port_wakeup_event_h h, int *type);
+
+int rpc_port_wakeup_event_get_timestamp(rpc_port_wakeup_event_h h, int *timestamp);
+
+int rpc_port_wakeup_event_get_source(rpc_port_wakeup_event_h h, char **source);
+
+typedef struct key_event_s *rpc_port_key_event_h;
+
+int rpc_port_key_event_create(rpc_port_key_event_h *h);
+
+int rpc_port_key_event_destroy(rpc_port_key_event_h h);
+
+int rpc_port_key_event_clone(rpc_port_key_event_h h, rpc_port_key_event_h *clone);
+
+int rpc_port_key_event_set_type(rpc_port_key_event_h h, int type);
+
+int rpc_port_key_event_set_timestamp(rpc_port_key_event_h h, int timestamp);
+
+int rpc_port_key_event_set_key_down(rpc_port_key_event_h h, bool key_down);
+
+int rpc_port_key_event_set_keycode(rpc_port_key_event_h h, int keycode);
+
+int rpc_port_key_event_set_keyname(rpc_port_key_event_h h, const char *keyname);
+
+int rpc_port_key_event_set_source(rpc_port_key_event_h h, const char *source);
+
+int rpc_port_key_event_get_type(rpc_port_key_event_h h, int *type);
+
+int rpc_port_key_event_get_timestamp(rpc_port_key_event_h h, int *timestamp);
+
+int rpc_port_key_event_get_key_down(rpc_port_key_event_h h, bool *key_down);
+
+int rpc_port_key_event_get_keycode(rpc_port_key_event_h h, int *keycode);
+
+int rpc_port_key_event_get_keyname(rpc_port_key_event_h h, char **keyname);
+
+int rpc_port_key_event_get_source(rpc_port_key_event_h h, char **source);
+
+typedef struct gesture_event_s *rpc_port_gesture_event_h;
+
+int rpc_port_gesture_event_create(rpc_port_gesture_event_h *h);
+
+int rpc_port_gesture_event_destroy(rpc_port_gesture_event_h h);
+
+int rpc_port_gesture_event_clone(rpc_port_gesture_event_h h, rpc_port_gesture_event_h *clone);
+
+int rpc_port_gesture_event_set_type(rpc_port_gesture_event_h h, int type);
+
+int rpc_port_gesture_event_set_timestamp(rpc_port_gesture_event_h h, int timestamp);
+
+int rpc_port_gesture_event_set_source(rpc_port_gesture_event_h h, const char *source);
+
+int rpc_port_gesture_event_get_type(rpc_port_gesture_event_h h, int *type);
+
+int rpc_port_gesture_event_get_timestamp(rpc_port_gesture_event_h h, int *timestamp);
+
+int rpc_port_gesture_event_get_source(rpc_port_gesture_event_h h, char **source);
+
+typedef struct voice_event_s *rpc_port_voice_event_h;
+
+int rpc_port_voice_event_create(rpc_port_voice_event_h *h);
+
+int rpc_port_voice_event_destroy(rpc_port_voice_event_h h);
+
+int rpc_port_voice_event_clone(rpc_port_voice_event_h h, rpc_port_voice_event_h *clone);
+
+int rpc_port_voice_event_set_type(rpc_port_voice_event_h h, int type);
+
+int rpc_port_voice_event_set_source(rpc_port_voice_event_h h, const char *source);
+
+int rpc_port_voice_event_get_type(rpc_port_voice_event_h h, int *type);
+
+int rpc_port_voice_event_get_source(rpc_port_voice_event_h h, char **source);
+
+typedef struct action_event_s *rpc_port_action_event_h;
+
+int rpc_port_action_event_create(rpc_port_action_event_h *h);
+
+int rpc_port_action_event_destroy(rpc_port_action_event_h h);
+
+int rpc_port_action_event_clone(rpc_port_action_event_h h, rpc_port_action_event_h *clone);
+
+int rpc_port_action_event_set_type(rpc_port_action_event_h h, int type);
+
+int rpc_port_action_event_set_timestamp(rpc_port_action_event_h h, int timestamp);
+
+int rpc_port_action_event_set_cmd(rpc_port_action_event_h h, const char *cmd);
+
+int rpc_port_action_event_set_args(rpc_port_action_event_h h, char **args, int args_size);
+
+int rpc_port_action_event_set_nargs(rpc_port_action_event_h h, int nargs);
+
+int rpc_port_action_event_set_source(rpc_port_action_event_h h, const char *source);
+
+int rpc_port_action_event_get_type(rpc_port_action_event_h h, int *type);
+
+int rpc_port_action_event_get_timestamp(rpc_port_action_event_h h, int *timestamp);
+
+int rpc_port_action_event_get_cmd(rpc_port_action_event_h h, char **cmd);
+
+int rpc_port_action_event_get_args(rpc_port_action_event_h h, char ***args, int *args_size);
+
+int rpc_port_action_event_get_nargs(rpc_port_action_event_h h, int *nargs);
+
+int rpc_port_action_event_get_source(rpc_port_action_event_h h, char **source);
+
+typedef struct feedback_event_s *rpc_port_feedback_event_h;
+
+int rpc_port_feedback_event_create(rpc_port_feedback_event_h *h);
+
+int rpc_port_feedback_event_destroy(rpc_port_feedback_event_h h);
+
+int rpc_port_feedback_event_clone(rpc_port_feedback_event_h h, rpc_port_feedback_event_h *clone);
+
+int rpc_port_feedback_event_set_type(rpc_port_feedback_event_h h, int type);
+
+int rpc_port_feedback_event_set_timestamp(rpc_port_feedback_event_h h, int timestamp);
+
+int rpc_port_feedback_event_set_feedback(rpc_port_feedback_event_h h, const char *feedback);
+
+int rpc_port_feedback_event_set_comment(rpc_port_feedback_event_h h, const char *comment);
+
+int rpc_port_feedback_event_get_type(rpc_port_feedback_event_h h, int *type);
+
+int rpc_port_feedback_event_get_timestamp(rpc_port_feedback_event_h h, int *timestamp);
+
+int rpc_port_feedback_event_get_feedback(rpc_port_feedback_event_h h, char **feedback);
+
+int rpc_port_feedback_event_get_comment(rpc_port_feedback_event_h h, char **comment);
+
+typedef struct array_string_s *rpc_port_array_string_h;
+
+int rpc_port_array_string_create(rpc_port_array_string_h *h);
+
+int rpc_port_array_string_destroy(rpc_port_array_string_h h);
+
+int rpc_port_array_string_clone(rpc_port_array_string_h h, rpc_port_array_string_h *clone);
+
+int rpc_port_array_string_set_array_strings(rpc_port_array_string_h h, char **array_strings, int array_strings_size);
+
+int rpc_port_array_string_get_array_strings(rpc_port_array_string_h h, char ***array_strings, int *array_strings_size);
+
+typedef struct mmifw_s *rpc_port_proxy_mmifw_h;
+
+typedef struct {
+       void (*connected)(rpc_port_proxy_mmifw_h h, void *user_data);
+       void (*disconnected)(rpc_port_proxy_mmifw_h h, void *user_data);
+       void (*rejected)(rpc_port_proxy_mmifw_h h, void *user_data);
+} rpc_port_proxy_mmifw_callback_s;
+
+typedef struct mmifw_focus_event_cb_s *rpc_port_mmifw_focus_event_cb_h;
+
+typedef void (*mmifw_focus_event_cb)(void *user_data, rpc_port_focus_event_h args);
+
+rpc_port_mmifw_focus_event_cb_h rpc_port_mmifw_focus_event_cb_create(mmifw_focus_event_cb callback, bool once, void *user_data);
+
+int rpc_port_mmifw_focus_event_cb_destroy(rpc_port_mmifw_focus_event_cb_h delegate);
+
+int rpc_port_proxy_mmifw_focus_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_focus_event_cb_h delegate);
+
+typedef struct mmifw_state_change_event_cb_s *rpc_port_mmifw_state_change_event_cb_h;
+
+typedef void (*mmifw_state_change_event_cb)(void *user_data, rpc_port_state_change_event_h args);
+
+rpc_port_mmifw_state_change_event_cb_h rpc_port_mmifw_state_change_event_cb_create(mmifw_state_change_event_cb callback, bool once, void *user_data);
+
+int rpc_port_mmifw_state_change_event_cb_destroy(rpc_port_mmifw_state_change_event_cb_h delegate);
+
+int rpc_port_proxy_mmifw_state_change_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_state_change_event_cb_h delegate);
+
+typedef struct mmifw_wakeup_event_cb_s *rpc_port_mmifw_wakeup_event_cb_h;
+
+typedef void (*mmifw_wakeup_event_cb)(void *user_data, rpc_port_wakeup_event_h args);
+
+rpc_port_mmifw_wakeup_event_cb_h rpc_port_mmifw_wakeup_event_cb_create(mmifw_wakeup_event_cb callback, bool once, void *user_data);
+
+int rpc_port_mmifw_wakeup_event_cb_destroy(rpc_port_mmifw_wakeup_event_cb_h delegate);
+
+int rpc_port_proxy_mmifw_wakeup_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_wakeup_event_cb_h delegate);
+
+typedef struct mmifw_key_event_cb_s *rpc_port_mmifw_key_event_cb_h;
+
+typedef void (*mmifw_key_event_cb)(void *user_data, rpc_port_key_event_h args);
+
+rpc_port_mmifw_key_event_cb_h rpc_port_mmifw_key_event_cb_create(mmifw_key_event_cb callback, bool once, void *user_data);
+
+int rpc_port_mmifw_key_event_cb_destroy(rpc_port_mmifw_key_event_cb_h delegate);
+
+int rpc_port_proxy_mmifw_key_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_key_event_cb_h delegate);
+
+typedef struct mmifw_gesture_event_cb_s *rpc_port_mmifw_gesture_event_cb_h;
+
+typedef void (*mmifw_gesture_event_cb)(void *user_data, rpc_port_gesture_event_h args);
+
+rpc_port_mmifw_gesture_event_cb_h rpc_port_mmifw_gesture_event_cb_create(mmifw_gesture_event_cb callback, bool once, void *user_data);
+
+int rpc_port_mmifw_gesture_event_cb_destroy(rpc_port_mmifw_gesture_event_cb_h delegate);
+
+int rpc_port_proxy_mmifw_gesture_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_gesture_event_cb_h delegate);
+
+typedef struct mmifw_voice_event_cb_s *rpc_port_mmifw_voice_event_cb_h;
+
+typedef void (*mmifw_voice_event_cb)(void *user_data, rpc_port_voice_event_h args);
+
+rpc_port_mmifw_voice_event_cb_h rpc_port_mmifw_voice_event_cb_create(mmifw_voice_event_cb callback, bool once, void *user_data);
+
+int rpc_port_mmifw_voice_event_cb_destroy(rpc_port_mmifw_voice_event_cb_h delegate);
+
+int rpc_port_proxy_mmifw_voice_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_voice_event_cb_h delegate);
+
+typedef struct mmifw_action_event_cb_s *rpc_port_mmifw_action_event_cb_h;
+
+typedef void (*mmifw_action_event_cb)(void *user_data, rpc_port_action_event_h args);
+
+rpc_port_mmifw_action_event_cb_h rpc_port_mmifw_action_event_cb_create(mmifw_action_event_cb callback, bool once, void *user_data);
+
+int rpc_port_mmifw_action_event_cb_destroy(rpc_port_mmifw_action_event_cb_h delegate);
+
+int rpc_port_proxy_mmifw_action_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_action_event_cb_h delegate);
+
+typedef struct mmifw_feedback_event_cb_s *rpc_port_mmifw_feedback_event_cb_h;
+
+typedef void (*mmifw_feedback_event_cb)(void *user_data, rpc_port_feedback_event_h args);
+
+rpc_port_mmifw_feedback_event_cb_h rpc_port_mmifw_feedback_event_cb_create(mmifw_feedback_event_cb callback, bool once, void *user_data);
+
+int rpc_port_mmifw_feedback_event_cb_destroy(rpc_port_mmifw_feedback_event_cb_h delegate);
+
+int rpc_port_proxy_mmifw_feedback_event_cb_dispose(rpc_port_proxy_mmifw_h proxy, rpc_port_mmifw_feedback_event_cb_h delegate);
+
+int rpc_port_proxy_mmifw_create(const char *stub_appid,
+        rpc_port_proxy_mmifw_callback_s *callback, void *user_data,
+        rpc_port_proxy_mmifw_h *h);
+
+int rpc_port_proxy_mmifw_connect(rpc_port_proxy_mmifw_h h);
+
+int rpc_port_proxy_mmifw_destroy(rpc_port_proxy_mmifw_h h);
+
+int rpc_port_proxy_mmifw_invoke_register_cb(rpc_port_proxy_mmifw_h h, rpc_port_mmifw_focus_event_cb_h focus_cb, rpc_port_mmifw_state_change_event_cb_h state_cb, rpc_port_mmifw_wakeup_event_cb_h wakeup_cb, rpc_port_mmifw_key_event_cb_h key_cb, rpc_port_mmifw_gesture_event_cb_h gesture_cb, rpc_port_mmifw_voice_event_cb_h voice_cb, rpc_port_mmifw_action_event_cb_h action_cb, rpc_port_mmifw_feedback_event_cb_h feedback_cb);
+
+void rpc_port_proxy_mmifw_invoke_deregister_cb(rpc_port_proxy_mmifw_h h);
+
+void rpc_port_proxy_mmifw_invoke_get_focus(rpc_port_proxy_mmifw_h h, const char *sender);
+
+void rpc_port_proxy_mmifw_invoke_set_state(rpc_port_proxy_mmifw_h h, const char *sender, int state);
+
+int rpc_port_proxy_mmifw_connect_sync(rpc_port_proxy_mmifw_h h);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/meson.build b/src/meson.build
new file mode 100644 (file)
index 0000000..3efa299
--- /dev/null
@@ -0,0 +1,46 @@
+mmifw_srcs = [
+       'mmifw.h',
+       'mmifw.c',
+       'interface/mmifw_proxy.h',
+       'interface/mmifw_proxy.c'
+       ]
+
+install_headers(
+       'mmifw.h'
+       )
+
+glib_dep = dependency('glib-2.0')
+gio_dep = dependency('gio-2.0')
+bundle_dep = dependency('bundle')
+dlog_dep = dependency('dlog')
+rpc_port_dep = dependency('rpc-port')
+libtzplatform_config_dep = dependency('libtzplatform-config')
+
+mmifw_deps = [glib_dep, gio_dep, bundle_dep, dlog_dep, rpc_port_dep, libtzplatform_config_dep]
+
+mmifw_include_dirs = include_directories(
+       '.'
+       )
+
+mmifw_lib = shared_library(
+       'mmifw',
+       mmifw_srcs,
+       dependencies : [mmifw_deps],
+       include_directories : [mmifw_include_dirs],
+       version : meson.project_version(),
+       install : true
+       )
+
+pkgconfig.generate(
+       filebase : 'mmifw',
+       name : 'mmifw',
+       description : 'Multi-modal Interaction Framework Library',
+       version : meson.project_version(),
+       libraries : mmifw_lib
+       )
+
+mmifw_declared_dep = declare_dependency(
+       link_with : mmifw_lib,
+       dependencies : [mmifw_deps],
+       include_directories : [mmifw_include_dirs]      
+       )
diff --git a/src/mmifw.c b/src/mmifw.c
new file mode 100644 (file)
index 0000000..dac2eaf
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+* Copyright © 2021 Samsung Electronics co., Ltd. All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice (including the next
+* paragraph) shall be included in all copies or substantial portions of the
+* Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+*/
+
+#include "mmifw.h"
+
+
diff --git a/src/mmifw.h b/src/mmifw.h
new file mode 100644 (file)
index 0000000..8d6b00b
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+* Copyright © 2021 Samsung Electronics co., Ltd. All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice (including the next
+* paragraph) shall be included in all copies or substantial portions of the
+* Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef __MMIFW_H__
+#define __MMIFW_H__
+
+#endif //__MMIFW_H__
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644 (file)
index 0000000..d98a2b7
--- /dev/null
@@ -0,0 +1,14 @@
+mmifw_tests_srcs = [
+       'mmifw-tests.cpp'
+       ]
+
+gmock_dep = dependency('gmock', method : 'pkg-config')
+ecore_dep = dependency('ecore', method : 'pkg-config')
+
+executable(
+       'mmifw-tests',
+       mmifw_tests_srcs,
+       dependencies : [mmifw_declared_dep, gmock_dep, ecore_dep],
+       install_dir : mmifw_prefix_bindir,
+       install : true
+       )
diff --git a/tests/mmifw-tests.cpp b/tests/mmifw-tests.cpp
new file mode 100644 (file)
index 0000000..29a65f8
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+* Copyright © 2021 Samsung Electronics co., Ltd. All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice (including the next
+* paragraph) shall be included in all copies or substantial portions of the
+* Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+*/
+
+#include "mmifw-tests.h"
+
+int main(int argc, char **argv)
+{
+       auto testResults = false;
+
+       try
+       {
+               ::testing::InitGoogleMock(&argc, argv);
+               ::testing::FLAGS_gtest_death_test_style = "fast";
+       }
+       catch ( ... )
+       {
+               PRINT("Error occurred while trying to initialize GoogleTest.\n");
+               exit(EXIT_FAILURE);
+       }
+
+       try
+       {
+               testResults = (RUN_ALL_TESTS() == 0) ? true : false;
+       }
+       catch (const ::testing::internal::GoogleTestFailureException &e)
+       {
+               testResults = false;
+               PRINT("GoogleTestFailureException has been thrown: %s\n", e.what());
+       }
+
+       return testResults;
+}
+
diff --git a/tests/mmifw-tests.h b/tests/mmifw-tests.h
new file mode 100644 (file)
index 0000000..d902a2b
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+* Copyright © 2021 Samsung Electronics co., Ltd. All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice (including the next
+* paragraph) shall be included in all copies or substantial portions of the
+* Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef __MMIFW_TESTS_H__
+#define __MMIFW_TESTS_H__
+
+#include <stdio.h>
+#include <gmock/gmock.h>
+#include <Ecore.h>
+
+#define PRINT printf
+
+using ::testing::TestWithParam;
+using ::testing::Bool;
+using ::testing::Values;
+using ::testing::Combine;
+
+#endif //__MMIFW_TESTS_H__
diff --git a/tidl/mmifw.tidl b/tidl/mmifw.tidl
new file mode 100644 (file)
index 0000000..3baca86
--- /dev/null
@@ -0,0 +1,78 @@
+struct focus_event {
+   int type;
+   int timestamp;
+   bool focus_in;
+}
+
+struct state_change_event {
+   int type;
+   int timestamp;
+   int state;
+   int old_state;
+}
+
+struct wakeup_event {
+   int type;
+   int timestamp;
+   string source;
+}
+
+struct key_event {
+   int type;
+   int timestamp;
+   bool key_down;
+   int keycode;
+   string keyname;
+   string source;
+}
+
+struct gesture_event {
+   int type;
+   int timestamp;
+   string source;
+}
+
+struct voice_event {
+   int type;
+   string source;
+}
+
+struct action_event {
+   int type;
+   int timestamp;
+   string cmd;
+   array<string> args;
+   int nargs;
+   string source;
+}
+
+struct feedback_event {
+   int type;
+   int timestamp;
+   string feedback;
+   string comment;
+}
+
+interface mmifw {
+   void focus_event_cb(focus_event args) delegate;
+   void state_change_event_cb(state_change_event args) delegate;
+   void wakeup_event_cb(wakeup_event args) delegate;
+   void key_event_cb(key_event args) delegate;
+   void gesture_event_cb(gesture_event args) delegate;
+   void voice_event_cb(voice_event args) delegate;
+   void action_event_cb(action_event args) delegate;
+   void feedback_event_cb(feedback_event args) delegate;
+
+   int register_cb(focus_event_cb focus_cb,
+                   state_change_event_cb state_cb,
+                   wakeup_event_cb wakeup_cb,
+                   key_event_cb key_cb,
+                   gesture_event_cb gesture_cb,
+                   voice_event_cb voice_cb,
+                   action_event_cb action_cb,
+                   feedback_event_cb feedback_cb);
+   void deregister_cb() async;
+   void get_focus(string sender) async;
+   void set_state(string sender, int state) async;
+}
+