upload tizen1.0 source
[framework/api/app-manager.git] / src / app_manager.c
1 /*
2  * Copyright (c) 2011 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
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22
23 #include <aul.h>
24 #include <aul_service.h>
25 #include <vconf.h>
26 #include <ail.h>
27 #include <package-manager.h>
28 #include <dlog.h>
29
30 #include <app_manager_private.h>
31 #include <app_manager.h>
32
33 #ifdef LOG_TAG
34 #undef LOG_TAG
35 #endif
36
37 #define LOG_TAG "TIZEN_N_APP_MANAGER"
38
39 typedef struct {
40         app_manager_app_running_cb cb;
41         void *user_data;
42         bool foreach_break;
43 } running_apps_foreach_cb_context;
44
45 typedef struct {
46         app_manager_app_installed_cb cb;
47         void *user_data;
48 } installed_apps_foreach_cb_context;
49
50 static pkgmgr_client *package_manager = NULL;
51 static app_manager_app_list_changed_cb app_list_changed_cb = NULL;
52 static void *app_list_changed_cb_data = NULL;
53
54 static int foreach_running_app_cb_broker(const aul_app_info * appcore_app_info, void *appcore_user_data)
55 {
56         ail_appinfo_h handle;
57         ail_error_e ret;
58         bool task_manage = false;
59         running_apps_foreach_cb_context *foreach_cb_context = NULL;
60
61         if (appcore_app_info == NULL || appcore_user_data == NULL) 
62         {
63                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid callback context", __FUNCTION__, APP_MANAGER_ERROR_INVALID_PARAMETER);
64                 return 0;
65         }
66
67         ret = ail_package_get_appinfo(appcore_app_info->pkg_name, &handle);
68         if (ret != AIL_ERROR_OK)
69         {
70                 LOGE("[%s] DB_FAILED(0x%08x) : failed to get the app-info", __FUNCTION__, APP_MANAGER_ERROR_DB_FAILED);
71                 return 0;
72         }
73
74         // do not call callback function when X-SLP-TaskManage is set to false
75         ret = ail_appinfo_get_bool(handle, AIL_PROP_X_SLP_TASKMANAGE_BOOL, &task_manage);
76
77         ail_package_destroy_appinfo(handle);
78
79         if (ret != AIL_ERROR_OK || task_manage == false)
80         {
81                 return 0;
82         }
83
84         foreach_cb_context = (running_apps_foreach_cb_context *)appcore_user_data;
85
86         if (foreach_cb_context->cb != NULL && foreach_cb_context->foreach_break == false)
87         {
88                 if (foreach_cb_context->cb(appcore_app_info->pkg_name, foreach_cb_context->user_data) == false)
89                 {
90                         foreach_cb_context->foreach_break = true;
91                 }
92         }
93
94         return 0;
95 }
96
97 static ail_cb_ret_e foreach_installed_app_cb_broker(const ail_appinfo_h appinfo, void *ail_user_data)
98 {
99         installed_apps_foreach_cb_context *foreach_cb_context = NULL;
100         char *package;
101
102         if (appinfo == NULL || ail_user_data == NULL)
103         {
104                 return AIL_CB_RET_CANCEL;
105         }
106
107         foreach_cb_context = (installed_apps_foreach_cb_context *)ail_user_data;
108
109         ail_appinfo_get_str(appinfo, AIL_PROP_PACKAGE_STR, &package);
110
111         if (foreach_cb_context->cb(package, foreach_cb_context->user_data)  == false)
112         {
113                 return AIL_CB_RET_CANCEL;
114         }
115         
116         return AIL_CB_RET_CONTINUE;
117
118 }
119
120
121 static int app_manager_ail_error_handler(ail_error_e ail_error, const char *func)
122 {
123         int error_code;
124         char *error_msg;
125
126         switch(ail_error)
127         {
128                 case AIL_ERROR_FAIL:
129                         error_code = APP_MANAGER_ERROR_INVALID_PARAMETER;
130                         error_msg = "INVALID_PARAMETER";
131                         break;
132
133                 case AIL_ERROR_DB_FAILED:
134                         error_code = APP_MANAGER_ERROR_DB_FAILED;
135                         error_msg = "DB_FAILED";
136                         break;
137
138                 case AIL_ERROR_OUT_OF_MEMORY:
139                         error_code = APP_MANAGER_ERROR_OUT_OF_MEMORY;
140                         error_msg = "OUT_OF_MEMORY";
141                         break;
142
143                 case AIL_ERROR_INVALID_PARAMETER:
144                         error_code = APP_MANAGER_ERROR_INVALID_PARAMETER;
145                         error_msg = "INVALID_PARAMETER";
146                         break;
147                 
148                 case AIL_ERROR_OK:
149                         error_code = APP_MANAGER_ERROR_NONE;
150                         break;
151                         
152                 default:
153                         error_code = APP_MANAGER_ERROR_INVALID_PARAMETER;
154                         error_msg = "INVALID_PARAMETER";
155         }
156
157         if (error_code != APP_MANAGER_ERROR_NONE)
158         {
159                 LOGE("[%s] %s(0x%08x)", func, error_msg, error_code);
160         }
161
162         return error_code;
163 }
164
165
166 int app_manager_foreach_app_running(app_manager_app_running_cb callback, void *user_data)
167 {
168         running_apps_foreach_cb_context foreach_cb_context = {
169                 .cb = callback,
170                 .user_data = user_data,
171                 .foreach_break = false
172         };
173
174         if (callback == NULL)
175         {
176                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid callback", __FUNCTION__, APP_MANAGER_ERROR_INVALID_PARAMETER);
177                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
178         }
179
180         aul_app_get_running_app_info(foreach_running_app_cb_broker, &foreach_cb_context);
181
182         return APP_MANAGER_ERROR_NONE;
183 }
184
185 int app_manager_is_running(const char *package, bool *is_running)
186 {
187         if (package == NULL)
188         {
189                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid package", __FUNCTION__, APP_MANAGER_ERROR_INVALID_PARAMETER);
190                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
191         }
192
193         if (is_running == NULL)
194         {
195                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, APP_MANAGER_ERROR_INVALID_PARAMETER);
196                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
197         }
198
199         *is_running = aul_app_is_running(package);
200
201         return APP_MANAGER_ERROR_NONE;
202 }
203
204  int app_manager_foreach_app_installed(app_manager_app_installed_cb callback, void *user_data)
205 {
206         ail_filter_h filter;
207         ail_error_e ret;
208
209         if (callback == NULL)
210         {
211                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid callback", __FUNCTION__, APP_MANAGER_ERROR_INVALID_PARAMETER);
212                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
213         }
214
215         ret = ail_filter_new(&filter);
216         if (ret != AIL_ERROR_OK)
217         {
218                 return app_manager_ail_error_handler(ret, __FUNCTION__);
219         }
220
221         // Provide visible application to 3rd party developer
222         ret = ail_filter_add_bool(filter, AIL_PROP_NODISPLAY_BOOL, false);
223         if (ret != AIL_ERROR_OK)
224         {
225                 ail_filter_destroy(filter);
226                 return app_manager_ail_error_handler(ret, __FUNCTION__);
227         }
228
229         // Provide task manageable app only to 3rd party developer
230         ret = ail_filter_add_bool(filter, AIL_PROP_X_SLP_TASKMANAGE_BOOL, true);
231         if (ret != AIL_ERROR_OK)
232         {
233                 ail_filter_destroy(filter);
234                 return app_manager_ail_error_handler(ret, __FUNCTION__);
235         }
236
237         installed_apps_foreach_cb_context foreach_cb_context = {
238                 .cb = callback,
239                 .user_data = user_data,
240         };
241
242         ail_filter_list_appinfo_foreach(filter, foreach_installed_app_cb_broker, &foreach_cb_context);
243
244         ail_filter_destroy(filter);
245         
246         return APP_MANAGER_ERROR_NONE;
247 }
248
249 static int app_manager_get_appinfo(const char *package, const char *property, char **value)
250 {
251         ail_error_e ail_error;
252         ail_appinfo_h appinfo;
253         char *appinfo_value;
254         char *appinfo_value_dup;
255
256         ail_error = ail_package_get_appinfo(package, &appinfo);
257         if (ail_error != AIL_ERROR_OK)
258         {
259                 return app_manager_ail_error_handler(ail_error, __FUNCTION__);
260         }
261
262         ail_error = ail_appinfo_get_str(appinfo, property, &appinfo_value);
263         if (ail_error != AIL_ERROR_OK)
264         {
265                 ail_package_destroy_appinfo(appinfo);
266                 return app_manager_ail_error_handler(ail_error, __FUNCTION__);
267         }
268
269         appinfo_value_dup = strdup(appinfo_value);
270
271         ail_package_destroy_appinfo(appinfo);
272
273         if (appinfo_value_dup == NULL)
274         {
275                 LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, APP_MANAGER_ERROR_OUT_OF_MEMORY);
276                 return APP_MANAGER_ERROR_OUT_OF_MEMORY;
277         }
278
279         *value = appinfo_value_dup;
280         
281         return APP_MANAGER_ERROR_NONE;
282 }
283
284 int app_manager_get_app_name(const char *package, char** name)
285 {
286         if (package == NULL)
287         {
288                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid package", __FUNCTION__, APP_MANAGER_ERROR_INVALID_PARAMETER);
289                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
290         }
291
292         return app_manager_get_appinfo(package, AIL_PROP_NAME_STR, name);
293 }
294  
295 int app_manager_get_app_icon_path(const char *package, char** icon_path)
296 {
297         if (package == NULL)
298         {
299                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid package", __FUNCTION__, APP_MANAGER_ERROR_INVALID_PARAMETER);
300                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
301         }
302
303         return app_manager_get_appinfo(package, AIL_PROP_ICON_STR, icon_path);
304 }
305
306 int app_manager_get_app_version(const char *package, char** version)
307 {
308         if (package == NULL)
309         {
310                 LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid package", __FUNCTION__, APP_MANAGER_ERROR_INVALID_PARAMETER);
311                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
312         }
313
314         return app_manager_get_appinfo(package, AIL_PROP_VERSION_STR, version);
315 }
316
317 static app_manger_event_type_e app_manager_app_list_pkgmgr_event(const char *value)
318 {
319         if (!strcasecmp(value, "install"))
320         {
321                 return APP_MANAGER_EVENT_INSTALLED;
322         }
323         else if (!strcasecmp(value, "uninstall"))
324         {
325                 return APP_MANAGER_EVENT_UNINSTALLED;   
326         }
327         else if (!strcasecmp(value, "update"))
328 {
329                 return APP_MANAGER_EVENT_UPDATED;               
330         }
331         else
332         {
333                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
334         }
335 }
336
337 static int app_manager_app_list_changed_cb_broker(int id, const char *type, const char *package, const char *key, const char *val, const void *msg, void *data)
338         {
339         static int event_id = -1;
340         static app_manger_event_type_e event_type;
341
342         if (!strcasecmp(key, "start"))
343         {
344                 event_id = id;
345                 event_type = app_manager_app_list_pkgmgr_event(val);
346 }
347         else if (!strcasecmp(key, "end") && !strcasecmp(val, "ok") && id == event_id)
348         {
349                 if (app_list_changed_cb != NULL && event_type >= 0)
350                 {
351                         app_list_changed_cb(event_type, package, app_list_changed_cb_data);
352                 }
353
354                 event_id = -1;
355                 event_type = -1;
356         }
357
358         return APP_MANAGER_ERROR_NONE;
359 }
360
361 int app_manager_set_app_list_changed_cb(app_manager_app_list_changed_cb callback, void* user_data)
362 {
363        if (callback == NULL) 
364 {
365                 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, APP_MANAGER_ERROR_INVALID_PARAMETER);
366                 return APP_MANAGER_ERROR_INVALID_PARAMETER;
367         }
368
369         if (app_list_changed_cb == NULL)
370         {
371                 package_manager = pkgmgr_client_new(PC_LISTENING);
372
373                 if (package_manager == NULL)
374         {
375                         LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, APP_MANAGER_ERROR_OUT_OF_MEMORY);
376                         return APP_MANAGER_ERROR_OUT_OF_MEMORY;
377         }
378         
379                 pkgmgr_client_listen_status(package_manager, app_manager_app_list_changed_cb_broker, NULL);
380         }
381
382         app_list_changed_cb = callback;
383         app_list_changed_cb_data = user_data;
384
385         return APP_MANAGER_ERROR_NONE;
386         }
387
388 int app_manager_unset_app_list_changed_cb()
389         {
390         if (app_list_changed_cb != NULL)
391         {
392                 pkgmgr_client_free(package_manager);
393                 package_manager = NULL;
394         }
395
396         app_list_changed_cb = NULL;
397         app_list_changed_cb_data = NULL;
398
399         return APP_MANAGER_ERROR_NONE;
400 }
401