Release version 0.8.16
[platform/core/appfw/shortcut.git] / lib / src / shortcut_manager.c
1 /*
2  * Copyright (c) 2011 - 2017 Samsung Electronics Co., Ltd. All rights reserved.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17 #include <gio/gio.h>
18 #include <stdlib.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <string.h>
23 #include <time.h>
24
25 #include <aul.h>
26 #include <dlog.h>
27 #include <glib.h>
28 #include <db-util.h>
29
30 #include "shortcut.h"
31 #include "shortcut_private.h"
32 #include "shortcut_db.h"
33 #include "shortcut_manager.h"
34 #include "shortcut_internal.h"
35
36 static int __shortcut_init_ipc_process(void)
37 {
38         int ret;
39
40         ret = _dbus_init();
41         if (ret != SHORTCUT_ERROR_NONE) {
42                 /* LCOV_EXCL_START */
43                 SHORTCUT_ERR("Can't init dbus %d", ret);
44                 return ret;
45                 /* LCOV_EXCL_STOP */
46         }
47
48         ret = _dbus_signal_init();
49         if (ret != SHORTCUT_ERROR_NONE) {
50                 /* LCOV_EXCL_START */
51                 SHORTCUT_ERR("Can't init dbus_signal %d", ret);
52                 return ret;
53                 /* LCOV_EXCL_STOP */
54         }
55
56         ret = _send_service_register();
57         if (ret != SHORTCUT_ERROR_NONE) {
58                 /* LCOV_EXCL_START */
59                 SHORTCUT_ERR("Can't init ipc_monitor_register %d", ret);
60                 return ret;
61                 /* LCOV_EXCL_STOP */
62         }
63
64         ret = _dbus_set_watch_name();
65         if (ret != SHORTCUT_ERROR_NONE) {
66                 /* LCOV_EXCL_START */
67                 SHORTCUT_ERR("Can't init _dbus_set_watch_name %d", ret);
68                 return ret;
69                 /* LCOV_EXCL_STOP */
70         }
71
72         return SHORTCUT_ERROR_NONE;
73 }
74
75 EAPI int shortcut_set_request_cb(shortcut_request_cb request_cb, void *data)
76 {
77         int ret;
78
79         CHECK_SHORTCUT_FEATURE();
80         if (request_cb == NULL)
81                 return SHORTCUT_ERROR_INVALID_PARAMETER; /* LCOV_EXCL_LINE */
82
83         ret = __shortcut_init_ipc_process();
84         if (ret != SHORTCUT_ERROR_NONE)
85                 return ret;
86
87         _set_request_cb(request_cb, data);
88
89         return SHORTCUT_ERROR_NONE;
90 }
91
92 EAPI void shortcut_unset_request_cb(void)
93 {
94         int ret;
95
96         CHECK_SHORTCUT_FEATURE_RET_LAST_RESULT();
97
98         ret = _check_privilege();
99         if (ret == SHORTCUT_ERROR_PERMISSION_DENIED) {
100                 set_last_result(SHORTCUT_ERROR_PERMISSION_DENIED);
101                 return;
102         }
103
104         _unset_request_cb();
105         set_last_result(SHORTCUT_ERROR_NONE);
106 }
107
108 EAPI int shortcut_set_remove_cb(shortcut_remove_cb remove_cb, void *data)
109 {
110         int ret;
111
112         CHECK_SHORTCUT_FEATURE();
113         if (remove_cb == NULL)
114                 return SHORTCUT_ERROR_INVALID_PARAMETER;
115
116         ret = __shortcut_init_ipc_process();
117         if (ret != SHORTCUT_ERROR_NONE)
118                 return ret;
119
120         _set_remove_cb(remove_cb, data);
121
122         return SHORTCUT_ERROR_NONE;
123 }
124
125 EAPI void shortcut_unset_remove_cb(void)
126 {
127         int ret;
128
129         CHECK_SHORTCUT_FEATURE_RET_LAST_RESULT();
130
131         ret = _check_privilege();
132         if (ret == SHORTCUT_ERROR_PERMISSION_DENIED) {
133                 set_last_result(SHORTCUT_ERROR_PERMISSION_DENIED);
134                 return;
135         }
136
137         _unset_remove_cb();
138         set_last_result(SHORTCUT_ERROR_NONE);
139 }
140
141 EAPI int shortcut_add_to_home(const char *name, shortcut_type type,
142                 const char *uri, const char *icon, int allow_duplicate,
143                 result_cb cb, void *data)
144 {
145         struct result_cb_item *item = NULL;
146         char *appid = NULL;
147         int ret;
148         GVariant *body = NULL;
149         char *request_id = NULL;
150
151         CHECK_SHORTCUT_FEATURE();
152
153         if (ADD_TO_HOME_IS_DYNAMICBOX(type)) {
154                 /* LCOV_EXCL_START */
155                 SHORTCUT_ERR("Invalid type used for adding a shortcut\n");
156                 return SHORTCUT_ERROR_INVALID_PARAMETER;
157                 /* LCOV_EXCL_STOP */
158         }
159
160         ret = _ready_to_send(&appid, &request_id);
161         if (ret != SHORTCUT_ERROR_NONE) {
162                 /* LCOV_EXCL_START */
163                 SHORTCUT_ERR("ready to send error [%d]", ret);
164                 goto out;
165                 /* LCOV_EXCL_STOP */
166         }
167
168         item = malloc(sizeof(struct result_cb_item));
169         if (!item) {
170                 /* LCOV_EXCL_START */
171                 SHORTCUT_ERR("Heap: %d\n", errno);
172                 ret = SHORTCUT_ERROR_OUT_OF_MEMORY;
173                 goto out;
174                 /* LCOV_EXCL_STOP */
175         }
176
177         item->result_cb = cb;
178         item->result_internal_cb = NULL;
179         item->data = data;
180
181         if (!name)
182                 name = "";
183
184         if (!uri)
185                 uri = "";
186
187         if (!icon)
188                 icon = "";
189
190         body = g_variant_new("(sississi)", request_id, getpid(), appid, name,
191                         type, uri, icon, allow_duplicate);
192
193         ret = _send_async_shortcut(body, item, "add_shortcut");
194
195 out:
196         if (appid)
197                 free(appid);
198         if (body)
199                 g_variant_unref(body);
200         if (request_id)
201                 free(request_id);
202         if (ret != SHORTCUT_ERROR_NONE && item)
203                 free(item);
204
205         return ret;
206 }
207
208 EAPI int shortcut_add_to_home_widget(const char *name, shortcut_widget_size_e size,
209                 const char *widget_id, const char *icon, double period,
210                 int allow_duplicate, result_cb cb, void *data)
211 {
212         struct result_cb_item *item = NULL;
213         char *appid = NULL;
214         int ret;
215         GVariant *body = NULL;
216         char *request_id = NULL;
217
218         CHECK_SHORTCUT_FEATURE();
219
220         if (name == NULL) {
221                 SHORTCUT_ERR("AppID is null\n");
222                 return SHORTCUT_ERROR_INVALID_PARAMETER;
223         }
224
225         if (!SHORTCUT_IS_WIDGET_SIZE(size)) {
226                 /* LCOV_EXCL_START */
227                 SHORTCUT_ERR("Invalid type used for adding a widget\n");
228                 return SHORTCUT_ERROR_INVALID_PARAMETER;
229                 /* LCOV_EXCL_STOP */
230         }
231
232         ret = _ready_to_send(&appid, &request_id);
233         if (ret != SHORTCUT_ERROR_NONE) {
234                 /* LCOV_EXCL_START */
235                 SHORTCUT_ERR("ready to send error [%d]", ret);
236                 goto out;
237                 /* LCOV_EXCL_STOP */
238         }
239
240         item = malloc(sizeof(struct result_cb_item));
241         if (!item) {
242                 /* LCOV_EXCL_START */
243                 SHORTCUT_ERR("Heap: %d\n", errno);
244                 ret = SHORTCUT_ERROR_OUT_OF_MEMORY;
245                 goto out;
246                 /* LCOV_EXCL_STOP */
247         }
248
249         item->result_cb = cb;
250         item->result_internal_cb = NULL;
251         item->data = data;
252
253         body = g_variant_new("(sississdi)", request_id, getpid(), widget_id,
254                         name, size, "", icon, period, allow_duplicate);
255
256         ret = _send_async_shortcut(body, item, "add_shortcut_widget");
257
258 out:
259         if (appid)
260                 free(appid);
261         if (body)
262                 g_variant_unref(body);
263         if (request_id)
264                 free(request_id);
265         if (ret != SHORTCUT_ERROR_NONE && item)
266                 free(item);
267
268         return ret;
269 }
270
271 EAPI int shortcut_remove_from_home(const char *name, result_cb cb, void *user_data)
272 {
273         struct result_cb_item *item = NULL;
274         char *appid = NULL;
275         int ret;
276         GVariant *body = NULL;
277         char *request_id = NULL;
278
279         CHECK_SHORTCUT_FEATURE();
280
281         if (name == NULL) {
282                 SHORTCUT_ERR("name is NULL.");
283                 return SHORTCUT_ERROR_INVALID_PARAMETER;
284         }
285
286         ret = _ready_to_send(&appid, &request_id);
287         if (ret != SHORTCUT_ERROR_NONE) {
288                 /* LCOV_EXCL_START */
289                 SHORTCUT_ERR("ready to send error [%d]", ret);
290                 goto out;
291                 /* LCOV_EXCL_STOP */
292         }
293
294         item = malloc(sizeof(struct result_cb_item));
295         if (!item) {
296                 /* LCOV_EXCL_START */
297                 SHORTCUT_ERR("Heap: %d\n", errno);
298                 ret = SHORTCUT_ERROR_OUT_OF_MEMORY;
299                 goto out;
300                 /* LCOV_EXCL_STOP */
301         }
302
303         item->result_cb = cb;
304         item->result_internal_cb = NULL;
305         item->data = user_data;
306
307         body = g_variant_new("(siss)", request_id, getpid(), appid, name);
308
309         ret = _send_async_shortcut(body, item, "remove_shortcut");
310
311 out:
312         if (appid)
313                 free(appid);
314         if (body)
315                 g_variant_unref(body);
316         if (request_id)
317                 free(request_id);
318         if (ret != SHORTCUT_ERROR_NONE && item)
319                 free(item);
320         return ret;
321 }
322
323 EAPI int shortcut_get_list(const char *package_name, shortcut_list_cb list_cb, void *data)
324 {
325         GDBusMessage *reply = NULL;
326         int result;
327         int ret = 0;
328         GVariant *body;
329         GVariant *reply_body;
330         GVariant *iter_body;
331         GVariantIter *iter;
332         GVariantBuilder *b;
333         shortcut_info_s shortcut;
334
335         CHECK_SHORTCUT_FEATURE();
336
337         if (list_cb == NULL)
338                 return SHORTCUT_ERROR_INVALID_PARAMETER;
339
340         result = _dbus_init();
341         if (result != SHORTCUT_ERROR_NONE) {
342                 /* LCOV_EXCL_START */
343                 SHORTCUT_ERR("Can't init dbus %d", result);
344                 return result;
345                 /* LCOV_EXCL_STOP */
346         }
347
348         b = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
349         if (package_name)
350                 g_variant_builder_add(b, "{sv}", "package_name", g_variant_new_string(package_name));
351         body = g_variant_builder_end(b);
352         result = _send_sync_shortcut(g_variant_new("(v)", body), &reply, "get_list");
353
354         if (result == SHORTCUT_ERROR_NONE) {
355                 reply_body = g_dbus_message_get_body(reply);
356                 g_variant_get(reply_body, "(ia(v))", &ret, &iter);
357                 SHORTCUT_DBG("shortcut count : %d", ret);
358                 while (g_variant_iter_loop(iter, "(v)", &iter_body)) {
359                         g_variant_get(iter_body, "(&s&s&s&s&s)",
360                                 &shortcut.package_name, &shortcut.icon, &shortcut.name, &shortcut.extra_key, &shortcut.extra_data);
361                         SHORTCUT_DBG("call calback : %s", shortcut.package_name);
362                         list_cb(shortcut.package_name, shortcut.icon, shortcut.name, shortcut.extra_key, shortcut.extra_data, data);
363                 }
364                 g_variant_iter_free(iter);
365         } else {
366                 ret = result; /* LCOV_EXCL_LINE */
367         }
368
369         if (reply)
370                 g_object_unref(reply);
371
372         return ret;
373 }
374
375 /* LCOV_EXCL_START */
376 EAPI int add_to_home_shortcut(const char *appid, const char *name, int type, const char *content,
377                 const char *icon, int allow_duplicate, result_internal_cb result_cb, void *data)
378 {
379         CHECK_SHORTCUT_FEATURE();
380         /*Deprecated API */
381         return SHORTCUT_ERROR_NONE;
382 }
383 /* LCOV_EXCL_STOP */
384
385 /* LCOV_EXCL_START */
386 EAPI int add_to_home_dynamicbox(const char *appid, const char *name, int type, const char *content, const char *icon, double period, int allow_duplicate, result_internal_cb result_cb, void *data)
387 {
388         CHECK_SHORTCUT_FEATURE();
389         /*Deprecated API */
390         return SHORTCUT_ERROR_NONE;
391 }
392 /* LCOV_EXCL_STOP */
393
394 /* End of a file */