2 * Copyright 2016 Samsung Electronics Co., Ltd
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <shortcut_db.h>
20 #include "service_common.h"
21 #include "shortcut_service.h"
24 #define PROVIDER_SHORTCUT_INTERFACE_NAME "org.tizen.data_provider_shortcut_service"
25 #define SHORTCUT_INVOCATION_KEY_POS 0
27 static GHashTable *_monitoring_hash;
28 static GHashTable *_invocation_hash;
30 static void _on_name_appeared(GDBusConnection *connection,
32 const gchar *name_owner,
35 DBG("name [%s]", name);
38 static void _on_name_vanished(GDBusConnection *connection,
42 DBG("name [%s]", name);
43 monitoring_info_s *info = (monitoring_info_s *)user_data;
46 DBG("vanished uid [%d]", info->uid);
47 g_bus_unwatch_name(info->watcher_id);
48 delete_monitoring_list(&_monitoring_hash, name, info->uid);
56 static void _shortcut_dbus_method_call_handler(GDBusConnection *conn,
57 const gchar *sender, const gchar *object_path,
58 const gchar *iface_name, const gchar *method_name,
59 GVariant *parameters, GDBusMethodInvocation *invocation,
62 /* TODO : sender authority(privilege) check */
63 DBG("shortcut method_name [%s]", method_name);
64 GVariant *reply_body = NULL;
65 int ret = SHORTCUT_ERROR_NOT_SUPPORTED;
66 uid_t uid = get_sender_uid(sender);
68 if (g_strcmp0(method_name, "shortcut_service_register") == 0) {
69 ret = service_register(parameters, &reply_body, sender,
70 _on_name_appeared, _on_name_vanished, &_monitoring_hash, uid);
71 } else if (g_strcmp0(method_name, "add_shortcut") == 0) {
72 shortcut_add(parameters, invocation, uid);
74 } else if (g_strcmp0(method_name, "add_shortcut_widget") == 0) {
75 shortcut_add_widget(parameters, invocation, uid);
77 } else if (g_strcmp0(method_name, "remove_shortcut") == 0) {
78 shortcut_remove(parameters, invocation, uid);
80 } else if (g_strcmp0(method_name, "get_list") == 0) {
81 ret = shortcut_get_shortcut_service_list(parameters, &reply_body, uid);
82 } else if (g_strcmp0(method_name, "check_privilege") == 0) {
83 ret = shortcut_check_privilege();
84 } else if (g_strcmp0(method_name, "send_return_value") == 0) {
85 ret = shortcut_send_return_value(parameters, &reply_body);
88 if (ret == SERVICE_COMMON_ERROR_NONE) {
89 DBG("shortcut service success, method[%s]", method_name);
90 g_dbus_method_invocation_return_value(
91 invocation, reply_body);
93 DBG("shortcut service fail, method_name[%s] err[%d]",
95 g_dbus_method_invocation_return_error(
99 "shortcut service error");
103 static const GDBusInterfaceVTable _shortcut_interface_vtable = {
104 _shortcut_dbus_method_call_handler,
109 int shortcut_register_dbus_interface(void)
111 static gchar introspection_xml[] =
113 " <interface name='org.tizen.data_provider_shortcut_service'>"
114 " <method name='shortcut_service_register'>"
115 " <arg type='i' name='uid' direction='in'/>"
118 " <method name='get_list'>"
119 " <arg type='v' name='package_name' direction='in'/>"
120 " <arg type='i' name='shortcut_cnt' direction='out'/>"
121 " <arg type='a(v)' name='shortcut_list' direction='out'/>"
124 " <method name='add_shortcut'>"
125 " <arg type='s' name='request_id' direction='in'/>"
126 " <arg type='i' name='pid' direction='in'/>"
127 " <arg type='s' name='appid' direction='in'/>"
128 " <arg type='s' name='name' direction='in'/>"
129 " <arg type='i' name='type' direction='in'/>"
130 " <arg type='s' name='uri' direction='in'/>"
131 " <arg type='s' name='icon' direction='in'/>"
132 " <arg type='i' name='allow_duplicate' direction='in'/>"
133 " <arg type='i' name='return_value' direction='out'/>"
136 " <method name='add_shortcut_widget'>"
137 " <arg type='s' name='request_id' direction='in'/>"
138 " <arg type='i' name='pid' direction='in'/>"
139 " <arg type='s' name='widget_id' direction='in'/>"
140 " <arg type='s' name='name' direction='in'/>"
141 " <arg type='i' name='size' direction='in'/>"
142 " <arg type='s' name='uri' direction='in'/>"
143 " <arg type='s' name='icon' direction='in'/>"
144 " <arg type='d' name='period' direction='in'/>"
145 " <arg type='i' name='allow_duplicate' direction='in'/>"
146 " <arg type='i' name='return_value' direction='out'/>"
149 " <method name='remove_shortcut'>"
150 " <arg type='s' name='request_id' direction='in'/>"
151 " <arg type='i' name='pid' direction='in'/>"
152 " <arg type='s' name='appid' direction='in'/>"
153 " <arg type='s' name='name' direction='in'/>"
154 " <arg type='i' name='return_value' direction='out'/>"
157 " <method name='check_privilege'>"
160 " <method name='send_return_value'>"
161 " <arg type='i' name='return_value' direction='in'/>"
162 " <arg type='s' name='request_id' direction='in'/>"
167 return service_common_register_dbus_interface(introspection_xml, _shortcut_interface_vtable);
170 static void _release_shortcut_info(gpointer data)
175 shortcut_info_s *shortcut = (shortcut_info_s *)data;
177 if (shortcut->package_name)
178 free(shortcut->package_name);
180 free(shortcut->icon);
182 free(shortcut->name);
183 if (shortcut->extra_key)
184 free(shortcut->extra_key);
185 if (shortcut->extra_data)
186 free(shortcut->extra_data);
191 int shortcut_get_shortcut_service_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
194 GList *shortcut_list = NULL;
195 GList *iter_list = NULL;
196 GVariant *param_body = NULL;
197 GVariant *body = NULL;
198 shortcut_info_s *shortcut;
200 char *package_name = NULL;
201 GVariantBuilder *builder;
203 g_variant_get(parameters, "(v)", ¶m_body);
204 g_variant_dict_init(&dict, param_body);
205 g_variant_dict_lookup(&dict, "package_name", "&s", &package_name);
206 g_variant_dict_end(&dict);
208 count = shortcut_db_get_list(package_name, &shortcut_list);
209 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
211 iter_list = g_list_first(shortcut_list);
212 for (; iter_list != NULL; iter_list = iter_list->next) {
213 shortcut = iter_list->data;
214 body = g_variant_new("(sssss)",
215 shortcut->package_name, shortcut->icon, shortcut->name, shortcut->extra_key, shortcut->extra_data);
216 g_variant_builder_add(builder, "(v)", body);
218 g_list_free_full(shortcut_list, (GDestroyNotify)_release_shortcut_info);
221 *reply_body = g_variant_new("(ia(v))", count, builder);
222 g_variant_builder_unref(builder);
224 if (*reply_body == NULL) {
225 ERR("Failed to make reply");
226 return SHORTCUT_ERROR_OUT_OF_MEMORY;
229 INFO("count[%d]", count);
230 return SERVICE_COMMON_ERROR_NONE;
233 static GDBusMethodInvocation *_get_invocation(char *request_id)
235 GDBusMethodInvocation *find_invocation;
237 find_invocation = (GDBusMethodInvocation *)g_hash_table_lookup(_invocation_hash, request_id);
238 if (!find_invocation)
241 return find_invocation;
244 static void _add_invocation(GDBusMethodInvocation *invocation, char *request_id)
246 GDBusMethodInvocation *find_invocation;
248 if (request_id == NULL)
251 find_invocation = _get_invocation(request_id);
255 g_hash_table_insert(_invocation_hash, strdup(request_id), invocation);
257 DBG("Invocation key [%s]", request_id);
260 static void _remove_invocation(char *request_id)
262 if (request_id == NULL)
265 g_hash_table_remove(_invocation_hash, request_id);
267 DBG("Invocation key [%s]", request_id);
271 void shortcut_add(GVariant *parameters, GDBusMethodInvocation *invocation, uid_t uid)
273 int ret = SERVICE_COMMON_ERROR_NONE;
274 char *request_id = NULL;
276 g_variant_get_child(parameters, SHORTCUT_INVOCATION_KEY_POS, "&s", &request_id);
278 _add_invocation(invocation, request_id);
280 ret = send_notify(parameters, "add_shortcut_notify", &_monitoring_hash, PROVIDER_SHORTCUT_INTERFACE_NAME, uid);
281 if (ret != SERVICE_COMMON_ERROR_NONE)
282 ERR("Failed to send notify [%d]", ret);
284 DBG("Success to send notify");
288 /* add_shortcut_widget */
289 void shortcut_add_widget(GVariant *parameters, GDBusMethodInvocation *invocation, uid_t uid)
291 int ret = SERVICE_COMMON_ERROR_NONE;
292 char *request_id = NULL;
294 g_variant_get_child(parameters, SHORTCUT_INVOCATION_KEY_POS, "&s", &request_id);
296 _add_invocation(invocation, request_id);
298 ret = send_notify(parameters, "add_shortcut_widget_notify", &_monitoring_hash, PROVIDER_SHORTCUT_INTERFACE_NAME, uid);
299 if (ret != SERVICE_COMMON_ERROR_NONE)
300 ERR("Failed to send notify [%d]", ret);
302 DBG("Success to send notify");
305 /* remove_shortcut */
306 void shortcut_remove(GVariant *parameters, GDBusMethodInvocation *invocation, uid_t uid)
308 int ret = SERVICE_COMMON_ERROR_NONE;
309 char *request_id = NULL;
311 g_variant_get_child(parameters, SHORTCUT_INVOCATION_KEY_POS, "&s", &request_id);
313 _add_invocation(invocation, request_id);
315 ret = send_notify(parameters, "remove_shortcut_notify", &_monitoring_hash, PROVIDER_SHORTCUT_INTERFACE_NAME, uid);
316 if (ret != SERVICE_COMMON_ERROR_NONE)
317 ERR("Failed to send notify [%d]", ret);
319 DBG("Success to send notify");
322 /* check shortcut privilege */
323 int shortcut_check_privilege(void)
325 return SERVICE_COMMON_ERROR_NONE;
328 int shortcut_send_return_value(GVariant *parameters, GVariant **reply_body)
331 char *request_id = NULL;
332 GDBusMethodInvocation *invocation = NULL;
334 g_variant_get(parameters, "(i&s)", &return_value, &request_id);
336 if (request_id == NULL)
337 return SHORTCUT_ERROR_INVALID_PARAMETER;
339 invocation = _get_invocation(request_id);
341 return SHORTCUT_ERROR_INVALID_PARAMETER;
343 g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", return_value));
344 _remove_invocation(request_id);
346 *reply_body = g_variant_new("()");
347 if (*reply_body == NULL) {
348 ERR("Failed to make reply");
349 return SHORTCUT_ERROR_OUT_OF_MEMORY;
352 DBG("Success to send return value");
353 return SHORTCUT_ERROR_NONE;
358 * Do not try to do anyother operation in these functions
360 HAPI int shortcut_service_init(void)
364 _monitoring_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
365 _invocation_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
367 result = shortcut_db_init();
368 if (result != SHORTCUT_ERROR_NONE) {
369 ERR("Failed to init DB[%d]", result);
373 result = shortcut_register_dbus_interface();
374 if (result != SERVICE_COMMON_ERROR_NONE) {
375 ERR("Failed to register dbus interface [%d]", result);
379 INFO("Initialization success");
383 HAPI int shortcut_service_fini(void)
385 g_hash_table_destroy(_invocation_hash);
387 DBG("Finalization success");
388 return SERVICE_COMMON_ERROR_NONE;