Move function definition to aul header
[platform/core/appfw/aul-1.git] / src / widget.c
1 /*
2  * Copyright (c) 2000 - 2015 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 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <stdbool.h>
21 #include <string.h>
22 #include <ctype.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <glib.h>
27 #include <bundle.h>
28 #include <bundle_internal.h>
29 #include <tzplatform_config.h>
30
31 #include "aul.h"
32 #include "aul_api.h"
33 #include "aul_app_com.h"
34 #include "aul_cmd.h"
35 #include "aul_error.h"
36 #include "aul_sock.h"
37 #include "aul_util.h"
38 #include "aul_widget.h"
39 #include "launch.h"
40
41 struct aul_widget_info_s {
42         char *widget_id;
43         char *instance_id;
44         char *app_id;
45         char *package_id;
46         char *app_path;
47         unsigned int surf;
48         pid_t pid;
49 };
50
51 struct widget_cb_info {
52         aul_widget_info_cb callback;
53         void *user_data;
54 };
55
56 struct widget_event_s {
57         aul_app_com_connection_h conn;
58         aul_widget_event_cb callback;
59         void *user_data;
60 };
61
62 #define WIDGET_LOG_BUFFER_SIZE 10000
63 #define WIDGET_LOG_BUFFER_STRING_SIZE 256
64
65 static int __log_index;
66 static int __log_fd;
67 static bool __log_init = false;
68 static struct widget_event_s __event;
69
70 static int __init_log(void)
71 {
72         int offset;
73         char buffer[512] = {0, };
74         char caller[255] = {0, };
75         int ret;
76
77         ret = aul_app_get_appid_bypid(getpid(), caller, sizeof(caller));
78         if (ret != AUL_R_OK) {
79                 _E("Failed to get appid by pid(%d)", getpid());
80                 return -1;
81         }
82
83         snprintf(buffer, sizeof(buffer),
84                         "/run/aul/log/widget/%d/widget_%s.log", getuid(), caller);
85         __log_fd = open(buffer, O_CREAT | O_WRONLY, 0644);
86         if (__log_fd < 0) {
87                 _E("Failed to open %s - %d", buffer, errno);
88                 return -1;
89         }
90
91         offset = lseek(__log_fd, 0, SEEK_END);
92         if (offset != 0) {
93                 __log_index = (int)(offset / WIDGET_LOG_BUFFER_STRING_SIZE);
94                 if (__log_index >= WIDGET_LOG_BUFFER_SIZE) {
95                         __log_index = 0;
96                         lseek(__log_fd, 0, SEEK_SET);
97                 }
98         }
99         __log_init = true;
100
101         return 0;
102 }
103
104 API int aul_widget_write_log(const char *tag, const char *format, ...)
105 {
106         int ret;
107         int offset;
108         time_t now;
109         char time_buf[32] = {0,};
110         char format_buffer[WIDGET_LOG_BUFFER_STRING_SIZE];
111         char buffer[WIDGET_LOG_BUFFER_SIZE];
112         va_list ap;
113
114         if (!__log_init)
115                 __init_log();
116
117         if (__log_fd < 0) {
118                 _E("Invalid file descriptor");
119                 return -1;
120         }
121
122         time(&now);
123         ctime_r(&now, time_buf);
124         if (__log_index != 0)
125                 offset = lseek(__log_fd, 0, SEEK_CUR);
126         else
127                 offset = lseek(__log_fd, 0, SEEK_SET);
128
129         if (offset == -1)
130                 _E("error in lseek: %d", errno);
131
132
133         va_start(ap, format);
134         vsnprintf(format_buffer, sizeof(format_buffer), format, ap);
135         va_end(ap);
136
137         snprintf(buffer, sizeof(buffer), "[%-6d][%-5d] %-15s %-50s %s",
138                         getpid(), __log_index, tag, format_buffer, time_buf);
139
140         ret = write(__log_fd, buffer, strlen(buffer));
141         if (ret < 0) {
142                 _E("Cannot write the amd log: %d", ret);
143                 return -1;
144         }
145
146         if (++__log_index >= WIDGET_LOG_BUFFER_SIZE)
147                 __log_index = 0;
148
149         return 0;
150 }
151
152 static const char *__to_appid(const char *widget_id)
153 {
154         const char *appid;
155         appid = g_strstr_len(widget_id, strlen(widget_id), "@") + 1;
156         if (appid != (const char *)1) {
157                 if (appid > widget_id + (sizeof(char) * strlen(widget_id)))
158                         appid = (char *)widget_id;
159         } else {
160                 appid = (char *)widget_id;
161         }
162
163         return appid;
164 }
165
166 API int aul_widget_instance_add(const char *widget_id, const char *instance_id)
167 {
168         int ret;
169         bundle *kb;
170
171         if (widget_id == NULL || instance_id == NULL)
172                 return AUL_R_EINVAL;
173
174         kb = bundle_create();
175         if (kb == NULL) {
176                 _E("out of memory");
177                 return AUL_R_ERROR;
178         }
179
180         bundle_add_str(kb, AUL_K_WIDGET_ID, widget_id);
181         bundle_add_str(kb, AUL_K_WIDGET_INSTANCE_ID, instance_id);
182
183         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), WIDGET_ADD, kb,
184                 AUL_SOCK_NONE);
185
186         bundle_free(kb);
187         if (ret < 0)
188                 return aul_error_convert(ret);
189
190         return AUL_R_OK;
191 }
192
193 API int aul_widget_instance_del(const char *widget_id, const char *instance_id)
194 {
195         int ret;
196         bundle *kb;
197
198         if (widget_id == NULL || instance_id == NULL)
199                 return AUL_R_EINVAL;
200
201         kb = bundle_create();
202         if (kb == NULL) {
203                 _E("out of memory");
204                 return AUL_R_ERROR;
205         }
206
207         bundle_add_str(kb, AUL_K_WIDGET_ID, widget_id);
208         bundle_add_str(kb, AUL_K_WIDGET_INSTANCE_ID, instance_id);
209
210         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), WIDGET_DEL, kb,
211                 AUL_SOCK_NONE);
212
213         bundle_free(kb);
214         if (ret < 0)
215                 return aul_error_convert(ret);
216
217         return AUL_R_OK;
218 }
219
220 struct __cb_data {
221         aul_widget_instance_foreach_cb cb;
222         void *data;
223 };
224
225 static void __foreach_cb(const char *key, const int type,
226                 const bundle_keyval_t *kv, void *user_data)
227 {
228         struct __cb_data *cb_data = (struct __cb_data *)user_data;
229
230         cb_data->cb(key, cb_data->data);
231 }
232
233 API int aul_widget_instance_foreach(const char *widget_id,
234                 aul_widget_instance_foreach_cb cb, void *data)
235 {
236         int ret;
237         int fd;
238         bundle *kb;
239         app_pkt_t *pkt = NULL;
240         bundle *list_kb = NULL;
241         struct __cb_data cb_data;
242
243         if (widget_id == NULL)
244                 return AUL_R_EINVAL;
245
246         kb = bundle_create();
247         if (kb == NULL) {
248                 _E("out of memory");
249                 return AUL_R_ERROR;
250         }
251
252         bundle_add_str(kb, AUL_K_APPID, __to_appid(widget_id));
253         bundle_add_str(kb, AUL_K_WIDGET_ID, widget_id);
254
255         fd = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), WIDGET_LIST, kb,
256                 AUL_SOCK_ASYNC);
257
258         if (fd > 0) {
259                 ret = aul_sock_recv_reply_pkt(fd, &pkt);
260                 if (ret < 0 || pkt == NULL) {
261                         _E("failed to get instance list of %s", widget_id);
262                 } else {
263                         list_kb = bundle_decode(pkt->data, pkt->len);
264                         if (list_kb) {
265                                 cb_data.cb = cb;
266                                 cb_data.data = data;
267                                 bundle_foreach(list_kb, __foreach_cb, &cb_data);
268                                 bundle_free(list_kb);
269                         }
270                 }
271         } else {
272                 ret = fd;
273         }
274
275         if (pkt)
276                 free(pkt);
277
278         bundle_free(kb);
279
280         if (ret < 0)
281                 return aul_error_convert(ret);
282
283         return AUL_R_OK;
284 }
285
286 API int aul_widget_instance_update(const char *widget_id,
287                 const char *instance_id, bundle *param)
288 {
289         int ret;
290         bundle *kb = param;
291         const char *appid;
292
293         if (widget_id == NULL)
294                 return AUL_R_EINVAL;
295
296         if (kb == NULL)
297                 kb = bundle_create();
298
299         if (kb == NULL) {
300                 _E("out of memory");
301                 return AUL_R_ERROR;
302         }
303
304         appid = __to_appid(widget_id);
305
306         bundle_add_str(kb, AUL_K_WIDGET_ID, widget_id);
307
308         if (instance_id)
309                 bundle_add_str(kb, AUL_K_WIDGET_INSTANCE_ID, instance_id);
310
311         ret = app_request_to_launchpad_for_uid(WIDGET_UPDATE, appid, kb,
312                         getuid());
313
314         if (param == NULL)
315                 bundle_free(kb);
316
317         return ret;
318 }
319
320 API int aul_widget_instance_get_content(const char *widget_id,
321                 const char *instance_id, char **content)
322 {
323         int ret;
324         bundle *kb;
325         int fd[2] = { 0, };
326         app_pkt_t *pkt = NULL;
327
328         if (widget_id == NULL || instance_id == NULL || content == NULL)
329                 return AUL_R_EINVAL;
330
331         kb = bundle_create();
332         if (kb == NULL) {
333                 _E("out of memory");
334                 return AUL_R_ERROR;
335         }
336
337         bundle_add_str(kb, AUL_K_APPID, __to_appid(widget_id));
338         bundle_add_str(kb, AUL_K_WIDGET_ID, widget_id);
339         bundle_add_str(kb, AUL_K_WIDGET_INSTANCE_ID, instance_id);
340
341         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), WIDGET_GET_CONTENT,
342                         kb, AUL_SOCK_ASYNC);
343         if (ret > 0) {
344                 ret = aul_sock_recv_reply_sock_fd(ret, &fd, 1);
345                 if (ret == 0) {
346                         ret = aul_sock_recv_reply_pkt(fd[0], &pkt);
347                         if (ret == 0 && pkt && pkt->cmd == 0) {
348                                 *content = strdup((const char *)pkt->data);
349                                 _D("recieved content: %s", *content);
350                         } else {
351                                 if (pkt)
352                                         ret = pkt->cmd;
353
354                                 _E("failed to get content");
355                         }
356                 } else {
357                         _E("failed to get socket fd:%d", ret);
358                 }
359         }
360
361         bundle_free(kb);
362
363         if (pkt)
364                 free(pkt);
365         if (ret < 0)
366                 ret = aul_error_convert(ret);
367
368         return ret;
369 }
370
371 API int aul_widget_instance_count(const char *widget_id)
372 {
373         int ret;
374         bundle *kb;
375
376         if (widget_id == NULL)
377                 return AUL_R_EINVAL;
378
379         kb = bundle_create();
380         if (kb == NULL) {
381                 _E("out of memory");
382                 return AUL_R_ERROR;
383         }
384
385         bundle_add_str(kb, AUL_K_WIDGET_ID, widget_id);
386         ret = app_send_cmd(AUL_UTIL_PID, WIDGET_COUNT, kb);
387         bundle_free(kb);
388
389         return ret;
390 }
391
392 static void __foreach_widget_info(app_pkt_t *pkt, void *user_data)
393 {
394         struct widget_cb_info *cb_info = (struct widget_cb_info *)user_data;
395         struct aul_widget_info_s info = { 0, };
396         bundle *b = NULL;
397         const char *val;
398
399         if (pkt == NULL || cb_info == NULL) {
400                 _E("Invalid parameter");
401                 return;
402         }
403
404         if (pkt->cmd == APP_GET_INFO_ERROR) {
405                 _E("Failed to get widget info");
406                 return;
407         }
408
409         if (pkt->opt & AUL_SOCK_BUNDLE)
410                 b = bundle_decode(pkt->data, pkt->len);
411
412         if (b == NULL)
413                 return;
414
415         bundle_get_str(b, AUL_K_WIDGET_ID, &info.widget_id);
416         if (info.widget_id == NULL) {
417                 bundle_free(b);
418                 return;
419         }
420
421         bundle_get_str(b, AUL_K_WIDGET_INSTANCE_ID, &info.instance_id);
422         if (info.instance_id == NULL) {
423                 bundle_free(b);
424                 return;
425         }
426
427         bundle_get_str(b, AUL_K_APPID, &info.app_id);
428         if (info.app_id == NULL) {
429                 bundle_free(b);
430                 return;
431         }
432
433         bundle_get_str(b, AUL_K_PKGID, &info.package_id);
434         if (info.package_id == NULL) {
435                 bundle_free(b);
436                 return;
437         }
438
439         bundle_get_str(b, AUL_K_EXEC, &info.app_path);
440         if (info.app_path == NULL) {
441                 bundle_free(b);
442                 return;
443         }
444
445         val = bundle_get_val(b, AUL_K_WID);
446         if (val && isdigit(*val))
447                 info.surf = strtoul(val, NULL, 10);
448
449         val = bundle_get_val(b, AUL_K_PID);
450         if (val && isdigit(*val))
451                 info.pid = atoi(val);
452
453         cb_info->callback(&info, cb_info->user_data);
454
455         bundle_free(b);
456 }
457
458 API int aul_widget_info_foreach_for_uid(aul_widget_info_cb callback,
459                 void *user_data, uid_t uid)
460 {
461         struct widget_cb_info cb_info = {callback, user_data};
462         char buf[MAX_PID_STR_BUFSZ];
463         bundle *b;
464         int fd;
465         int r;
466
467         if (callback == NULL) {
468                 _E("Invalid parameter");
469                 return AUL_R_EINVAL;
470         }
471
472         b = bundle_create();
473         if (b == NULL) {
474                 _E("Out of memory");
475                 return AUL_R_ERROR;
476         }
477
478         snprintf(buf, sizeof(buf), "%u", uid);
479         r = bundle_add_str(b, AUL_K_TARGET_UID, buf);
480         if (r != BUNDLE_ERROR_NONE) {
481                 _E("Failed to add target uid(%u)", uid);
482                 bundle_free(b);
483                 return AUL_R_ERROR;
484         }
485
486         fd = aul_sock_send_bundle(AUL_UTIL_PID, uid, WIDGET_RUNNING_INFO,
487                         b, AUL_SOCK_ASYNC);
488         if (fd < 0) {
489                 bundle_free(b);
490                 return aul_error_convert(fd);
491         }
492         bundle_free(b);
493
494         r = aul_sock_recv_pkt_with_cb(fd, __foreach_widget_info, &cb_info);
495         if (r < 0)
496                 return aul_error_convert(r);
497
498         return AUL_R_OK;
499 }
500
501 API int aul_widget_info_foreach(aul_widget_info_cb callback, void *user_data)
502 {
503         return aul_widget_info_foreach_for_uid(callback, user_data, getuid());
504 }
505
506 API int aul_widget_info_get_pid(aul_widget_info_h info, pid_t *pid)
507 {
508         if (info == NULL || pid == NULL) {
509                 _E("Invalid parameter");
510                 return AUL_R_EINVAL;
511         }
512
513         *pid = info->pid;
514
515         return AUL_R_OK;
516 }
517
518 API int aul_widget_info_get_surface_id(aul_widget_info_h info,
519                 unsigned int *surf)
520 {
521         if (info == NULL || surf == NULL) {
522                 _E("Invalid parameter");
523                 return AUL_R_EINVAL;
524         }
525
526         *surf = info->surf;
527
528         return AUL_R_OK;
529 }
530
531 API int aul_widget_info_get_widget_id(aul_widget_info_h info, char **widget_id)
532 {
533         if (info == NULL || widget_id == NULL) {
534                 _E("Invalid parameter");
535                 return AUL_R_EINVAL;
536         }
537
538         *widget_id = strdup(info->widget_id);
539         if (*widget_id == NULL) {
540                 _E("Out of memory");
541                 return AUL_R_ERROR;
542         }
543
544         return AUL_R_OK;
545 }
546
547 API int aul_widget_info_get_instance_id(aul_widget_info_h info,
548                 char **instance_id)
549 {
550         if (info == NULL || instance_id == NULL) {
551                 _E("Invalid parameter");
552                 return AUL_R_EINVAL;
553         }
554
555         *instance_id = strdup(info->instance_id);
556         if (*instance_id == NULL) {
557                 _E("Out of memory");
558                 return AUL_R_ERROR;
559         }
560
561         return AUL_R_OK;
562 }
563
564 API int aul_widget_info_get_app_id(aul_widget_info_h info, char **app_id)
565 {
566         if (info == NULL || app_id == NULL) {
567                 _E("Invalid parameter");
568                 return AUL_R_EINVAL;
569         }
570
571         *app_id = strdup(info->app_id);
572         if (*app_id == NULL) {
573                 _E("Out of memory");
574                 return AUL_R_ERROR;
575         }
576
577         return AUL_R_OK;
578 }
579
580 API int aul_widget_info_get_package_id(aul_widget_info_h info,
581                 char **package_id)
582 {
583         if (info == NULL || package_id == NULL) {
584                 _E("Invalid parameter");
585                 return AUL_R_EINVAL;
586         }
587
588         *package_id = strdup(info->package_id);
589         if (*package_id == NULL) {
590                 _E("Out of memory");
591                 return AUL_R_ERROR;
592         }
593
594         return AUL_R_OK;
595 }
596
597 API int aul_widget_info_get_app_path(aul_widget_info_h info, char **app_path)
598 {
599         if (info == NULL || app_path == NULL) {
600                 _E("Invalid parameter");
601                 return AUL_R_EINVAL;
602         }
603
604         *app_path = strdup(info->app_path);
605         if (*app_path == NULL) {
606                 _E("Out of memory");
607                 return AUL_R_ERROR;
608         }
609
610         return AUL_R_OK;
611 }
612
613 API int aul_widget_instance_change_status(const char *widget_id,
614                 const char *status)
615 {
616         int ret;
617         bundle *kb;
618
619         kb = bundle_create();
620         if (kb == NULL) {
621                 _E("out of memory");
622                 return AUL_R_ERROR;
623         }
624
625         bundle_add_str(kb, AUL_K_STATUS, status);
626         bundle_add_str(kb, AUL_K_WIDGET_ID, widget_id);
627         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
628                         WIDGET_CHANGE_STATUS, kb, AUL_SOCK_NOREPLY);
629
630         bundle_free(kb);
631         if (ret < 0) {
632                 _E("send error %d, %s", ret, status);
633                 return aul_error_convert(ret);
634         }
635
636         return AUL_R_OK;
637 }
638
639 API int aul_widget_service_set_disable(const char *widget_id, bool is_disable)
640 {
641         int ret;
642         bundle *kb;
643         char ambient_mode[32] = {0, };
644
645         if (widget_id == NULL)
646                 return AUL_R_EINVAL;
647
648         kb = bundle_create();
649         if (kb == NULL) {
650                 _E("out of memory");
651                 return AUL_R_ERROR;
652         }
653
654         snprintf(ambient_mode, sizeof(ambient_mode), "%d", (int)is_disable);
655
656         bundle_add_str(kb, AUL_K_APPID, __to_appid(widget_id));
657         bundle_add_str(kb, AUL_K_WIDGET_ID, widget_id);
658         bundle_add_str(kb, AUL_K_WIDGET_DISABLE, ambient_mode);
659
660         ret = app_send_cmd(AUL_UTIL_PID, WIDGET_DISABLE, kb);
661         if (ret)
662                 _E("widget disable send cmd error");
663
664         bundle_free(kb);
665
666         return ret;
667 }
668
669 static int __aul_widget_event_cb(const char *endpoint,
670                 aul_app_com_result_e result,
671                 bundle *envelope,
672                 void *user_data)
673 {
674         const char *event_name;
675         const char *event_data_raw;
676         bundle *event_data;
677
678         event_name = bundle_get_val(envelope, AUL_K_EVENT_NAME);
679         if (!event_name) {
680                 _E("Failed to get event name");
681                 return -1;
682         }
683
684         event_data_raw = bundle_get_val(envelope, AUL_K_EVENT_DATA);
685         if (!event_data_raw) {
686                 _E("Failed to get event data");
687                 return -1;
688         }
689
690         event_data = bundle_decode((const bundle_raw *)event_data_raw,
691                         strlen(event_data_raw));
692         if (!event_data) {
693                 _E("Failed to decode event data");
694                 return -1;
695         }
696
697         if (__event.callback)
698                 __event.callback(event_name, event_data, __event.user_data);
699
700         bundle_free(event_data);
701
702         return 0;
703 }
704
705 static int __register_widget_event(void)
706 {
707         int ret;
708
709         if (!__event.conn) {
710                 ret = aul_app_com_create("widget.event", NULL,
711                                 __aul_widget_event_cb, NULL,
712                                 &__event.conn);
713                 if (ret != AUL_R_OK) {
714                         _E("Failed to join aul app com");
715                         return ret;
716                 }
717         }
718
719         return AUL_R_OK;
720 }
721
722 static int __unregister_widget_event(void)
723 {
724         if (__event.conn) {
725                 aul_app_com_leave(__event.conn);
726                 __event.conn = NULL;
727         }
728
729         return AUL_R_OK;
730 }
731
732 API int aul_widget_set_event_cb(aul_widget_event_cb callback, void *user_data)
733 {
734         if (!callback) {
735                 _E("Invalid parameter");
736                 return AUL_R_EINVAL;
737         }
738
739         __event.callback = callback;
740         __event.user_data = user_data;
741
742         return __register_widget_event();
743 }
744
745 API int aul_widget_unset_event_cb(void)
746 {
747         __event.callback = NULL;
748         __event.user_data = NULL;
749
750         return __unregister_widget_event();
751 }
752
753 API int aul_widget_send_event(const char *event_name, bundle *event_data)
754 {
755         bundle *b;
756         bundle_raw *raw = NULL;
757         int len = 0;
758         int ret;
759
760         if (!event_name || !event_data) {
761                 _E("Invalid parameter");
762                 return AUL_R_EINVAL;
763         }
764
765         b = bundle_create();
766         if (!b) {
767                 _E("Out of memory");
768                 return AUL_R_ENOMEM;
769         }
770
771         bundle_add(b, AUL_K_EVENT_NAME, event_name);
772
773         bundle_encode(event_data, &raw, &len);
774         if (!raw) {
775                 _E("Failed to encode event data");
776                 bundle_free(b);
777                 return AUL_R_ERROR;
778         }
779
780         bundle_add(b, AUL_K_EVENT_DATA, (const char *)raw);
781         free(raw);
782
783         ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), WIDGET_EVENT, b,
784                         AUL_SOCK_NOREPLY);
785         bundle_free(b);
786         if (ret != 0) {
787                 _E("Failed to send widget event. error(%d)", ret);
788                 return aul_error_convert(ret);
789         }
790
791         return AUL_R_OK;
792 }
793
794 API int aul_widget_send_status_to_viewer(const char *class_id,
795         const char *instance_id, const char *viewer_endpoint,
796         int status, int err, bundle *extra)
797 {
798         bundle *data;
799         bundle_raw *raw = NULL;
800         int len;
801         char err_str[256];
802         int ret;
803
804         data = bundle_create();
805         if (!data) {
806                 _E("out of memory");
807                 return -1;
808         }
809
810         if (err < 0) {
811                 snprintf(err_str, sizeof(err_str), "%d", err);
812                 bundle_add_str(data, AUL_K_WIDGET_ERROR_CODE, err_str);
813         }
814
815         bundle_add_str(data, AUL_K_WIDGET_ID, class_id);
816         bundle_add_str(data, AUL_K_WIDGET_INSTANCE_ID, instance_id);
817         bundle_add_byte(data, AUL_K_WIDGET_STATUS, &status, sizeof(int));
818
819         if (extra) {
820                 bundle_encode(extra, &raw, &len);
821                 bundle_add_str(data,
822                         "__WIDGET_CONTENT_INFO__", (const char *)raw);
823                 free(raw);
824                 ret = aul_widget_instance_add(class_id, instance_id);
825                 if (ret != 0) {
826                         _E("Failed to add instance. error(%d)", ret);
827                         bundle_free(data);
828                         return aul_error_convert(ret);
829                 }
830         }
831
832         LOGD("send update %s(%d) to %s", instance_id, status, viewer_endpoint);
833         ret = aul_app_com_send(viewer_endpoint, data);
834         bundle_free(data);
835         if (ret != 0) {
836                 _E("Failed to add instance. error(%d)", ret);
837                 return aul_error_convert(ret);
838         }
839
840         return 0;
841 }
842
843 API int aul_widget_send_status_to_service(const char *class_id,
844         const char *instance_id, const char *sender_pkgid, int status)
845 {
846         bundle *data = bundle_create();
847         int ret;
848
849         if (data == NULL) {
850                 _E("out of memory");
851                 return -1;
852         }
853
854         bundle_add_str(data, AUL_K_WIDGET_ID, class_id);
855         bundle_add_str(data, AUL_K_WIDGET_INSTANCE_ID, instance_id);
856         bundle_add_byte(data, AUL_K_WIDGET_STATUS, &status, sizeof(int));
857         bundle_add_str(data, AUL_K_PKGID, sender_pkgid);
858
859         LOGD("send lifecycle %s(%d)", instance_id, status);
860         ret = aul_app_com_send("widget.status", data);
861         if (ret < 0)
862                 _E("send lifecycle error:%d", ret);
863
864         bundle_free(data);
865         return 0;
866 }