Release version 0.9.1
[platform/core/api/app-manager.git] / src / app_manager_event.c
1 /*
2  * Copyright (c) 2016 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 <stdlib.h>
18 #include <sys/types.h>
19
20 #include <dlog.h>
21 #include <package-manager.h>
22
23 #include "app_manager_internal.h"
24
25 #ifdef LOG_TAG
26 #undef LOG_TAG
27 #endif
28
29 #define LOG_TAG "CAPI_APPFW_APP_MANAGER"
30
31 static int __remove_app_manager_event_info(app_manager_event_info **head, int req_id)
32 {
33         app_manager_event_info *prev;
34         app_manager_event_info *current;
35
36         current = prev = *head;
37         if (current == NULL)
38                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
39
40         while (current) {
41                 if (current->req_id == req_id) {
42                         if (prev == current)
43                                 *head = current->next;
44                         prev->next = current->next;
45                         free(current);
46                         return APP_MANAGER_ERROR_NONE;
47                 }
48                 prev = current;
49                 current = current->next;
50         }
51
52         return APP_MANAGER_ERROR_NONE;
53 }
54
55 static int __find_app_manager_event_info(app_manager_event_info **head,
56                 int req_id, app_manager_event_type_e *event_type)
57 {
58         app_manager_event_info *tmp;
59
60         tmp = *head;
61
62         if (tmp == NULL) {
63                 LOGE("head is null");
64                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
65         }
66
67         while (tmp) {
68                 if (tmp->req_id == req_id) {
69                         *event_type = tmp->event_type;
70                         return APP_MANAGER_ERROR_NONE;
71                 }
72                 tmp = tmp->next;
73         }
74
75         return APP_MANAGER_ERROR_REQUEST_FAILED;
76 }
77
78 static int __add_app_manager_event_info(app_manager_event_info **head,
79                 int req_id, app_manager_event_type_e event_type)
80 {
81         app_manager_event_info *event_info;
82         app_manager_event_info *current;
83         app_manager_event_info *prev;
84
85         event_info = (app_manager_event_info *)calloc(1, sizeof(app_manager_event_info));
86         if (event_info == NULL)
87                 return APP_MANAGER_ERROR_OUT_OF_MEMORY;
88
89         event_info->req_id = req_id;
90         event_info->event_type = event_type;
91         event_info->next = NULL;
92
93         if (*head == NULL) {
94                 *head = event_info;
95         } else {
96                 current = prev = *head;
97                 while (current) {
98                         prev = current;
99                         current = current->next;
100                 }
101                 prev->next = event_info;
102         }
103
104         return APP_MANAGER_ERROR_NONE;
105 }
106
107 static int __get_app_manager_event_type(const char *key, app_manager_event_type_e *event_type)
108 {
109         if (key == NULL)
110                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
111
112         if (strcasecmp(key, "disable_app") == 0 ||
113                         strcasecmp(key, "disable_global_app_for_uid") == 0)
114                 *event_type = APP_MANAGER_EVENT_DISABLE_APP;
115         else if (strcasecmp(key, "enable_app") == 0 ||
116                         strcasecmp(key, "enable_global_app_for_uid") == 0)
117                 *event_type = APP_MANAGER_EVENT_ENABLE_APP;
118         else
119                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
120         return APP_MANAGER_ERROR_NONE;
121 }
122
123 void remove_app_manager_event_info_list(app_manager_event_info *head)
124 {
125         if (head == NULL)
126                 return;
127
128         app_manager_event_info *current = head;
129
130         if (current->next != NULL)
131                 remove_app_manager_event_info_list(current->next);
132
133         free(current);
134         return;
135 }
136
137 int app_event_handler(uid_t target_uid, int req_id,
138                                 const char *pkg_type, const char *pkgid, const char *appid,
139                                 const char *key, const char *val, const void *pmsg, void *data)
140 {
141         app_manager_event *app_evt = (app_manager_event *)data;
142         app_manager_event_type_e event_type = -1;
143         int ret = -1;
144
145         LOGI("app_event_handler called");
146
147         if (app_evt == NULL || app_evt->event_cb == NULL)
148                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
149
150         if (strcasecmp(key, "start") == 0) {
151                 ret = __get_app_manager_event_type(val, &event_type);
152                 if (ret != APP_MANAGER_ERROR_NONE)
153                         return APP_MANAGER_ERROR_INVALID_PARAMETER;
154
155                 ret = __add_app_manager_event_info(&(app_evt->head), req_id, event_type);
156                 if (ret != APP_MANAGER_ERROR_NONE)
157                         return APP_MANAGER_ERROR_REQUEST_FAILED;
158
159                 app_evt->event_cb(pkg_type, appid, event_type,
160                                 APP_MANAGER_EVENT_STATE_STARTED, app_evt, app_evt->user_data);
161         } else if (strcasecmp(key, "end") == 0) {
162                 if (__find_app_manager_event_info(&(app_evt->head), req_id, &event_type)
163                                 != APP_MANAGER_ERROR_NONE)
164                         return APP_MANAGER_ERROR_REQUEST_FAILED;
165
166                 if (strcasecmp(val, "ok") == 0) {
167                         app_evt->event_cb(pkg_type, appid, event_type,
168                                         APP_MANAGER_EVENT_STATE_COMPLETED, app_evt, app_evt->user_data);
169                 } else if (strcasecmp(val, "fail") == 0) {
170                         /* LCOV_EXCL_START */
171                         app_evt->event_cb(pkg_type, appid, event_type,
172                                         APP_MANAGER_EVENT_STATE_FAILED, app_evt, app_evt->user_data);
173                         /* LCOV_EXCL_STOP */
174                 }
175
176                 ret = __remove_app_manager_event_info(&(app_evt->head), req_id);
177                 if (ret != APP_MANAGER_ERROR_NONE) {
178                         /* LCOV_EXCL_START */
179                         LOGE("failed to remove app event info");
180                         return APP_MANAGER_ERROR_REQUEST_FAILED;
181                         /* LCOV_EXCL_STOP */
182                 }
183
184         } else {
185                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
186         }
187
188         return APP_MANAGER_ERROR_NONE;
189 }
190
191 int convert_status_type(int status_type)
192 {
193         int result = 0;
194
195         if (status_type == 0)
196                 return PKGMGR_CLIENT_STATUS_ALL;
197
198         if ((status_type & APP_MANAGER_EVENT_STATUS_TYPE_ENABLE)
199                         == APP_MANAGER_EVENT_STATUS_TYPE_ENABLE)
200                 result += PKGMGR_CLIENT_STATUS_ENABLE_APP;
201
202         if ((status_type & APP_MANAGER_EVENT_STATUS_TYPE_DISABLE)
203                         == APP_MANAGER_EVENT_STATUS_TYPE_DISABLE)
204                 result += PKGMGR_CLIENT_STATUS_DISABLE_APP;
205
206         return result;
207 }
208