Code clean up of included header files
[platform/core/multimedia/media-server.git] / src / common / media-common-utils.c
1 /*
2  * Media Server
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <sys/types.h>
23 #include <fcntl.h>
24 #include <vconf.h>
25 #include <sys/statvfs.h>
26 #include <sys/stat.h>
27
28 #ifdef _SET_VIP_PROCESS
29 #include <sys/prctl.h>
30 #endif
31 #include <system_info.h>
32 #include <dd-display.h>
33
34 #ifndef _USE_DEVICED_DBUS
35 #include <usb-device.h>
36 #endif
37
38 #include "media-util.h"
39 #include "media-server-ipc.h"
40 #include "media-common-dbg.h"
41 #include "media-common-system.h"
42 #include "media-common-utils.h"
43
44 int ms_strappend(char *res, const int size, const char *pattern, const char *str1, const char *str2)
45 {
46         int len = 0;
47         int real_size = size - 1;
48
49         if (!res || !pattern || !str1 || !str2)
50                 return MS_MEDIA_ERR_INVALID_PARAMETER;
51
52         if (real_size < (int)(strlen(str1) + strlen(str2)))
53                 return MS_MEDIA_ERR_INVALID_PARAMETER;
54
55         len = snprintf(res, real_size, pattern, str1, str2);
56         if (len < 0)
57                 return MS_MEDIA_ERR_INVALID_PARAMETER;
58
59         res[len] = '\0';
60
61         return MS_MEDIA_ERR_NONE;
62 }
63
64 bool ms_config_get_int(const char *key, int *value)
65 {
66         int err;
67
68         if (!key || !value) {
69                 MS_DBG_ERR("Arguments key or value is NULL");
70                 return false;
71         }
72
73         err = vconf_get_int(key, value);
74         if (err == 0)
75                 return true;
76         else if (err == -1)
77                 return false;
78         else
79                 MS_DBG_ERR("Unexpected error code: %d", err);
80
81         return false;
82 }
83
84 bool ms_config_set_int(const char *key, int value)
85 {
86         int err;
87
88         if (!key) {
89                 MS_DBG_ERR("Arguments key is NULL");
90                 return false;
91         }
92
93         err = vconf_set_int(key, value);
94         if (err == 0)
95                 return true;
96         else if (err == -1)
97                 return false;
98         else
99                 MS_DBG_ERR("Unexpected error code: %d", err);
100
101         return false;
102 }
103
104 bool ms_config_get_str(const char *key, char **value)
105 {
106         char *res = NULL;
107
108         if (key == NULL || value == NULL) {
109                 MS_DBG_ERR("Arguments key or value is NULL");
110                 return false;
111         }
112
113         res = vconf_get_str(key);
114         if (MS_STRING_VALID(res)) {
115                 *value = strdup(res);
116                 MS_SAFE_FREE(res);
117                 return true;
118         }
119
120         return false;
121 }
122
123 int ms_get_remain_space(double *free_space)
124 {
125         int ret = MS_MEDIA_ERR_NONE;
126         const char *path = "/opt";
127         struct statvfs s;
128
129         ret = statvfs(path, &s);
130         if (ret != 0) {
131                 MS_DBG_ERR("statvfs failed[%d]", ret);
132                 MS_DBG_STRERROR();
133                 return MS_MEDIA_ERR_INTERNAL;
134         }
135
136         /* f_bsize:unsigned long, f_bavail:fsblkcnt_t(unsigned long) */
137         *free_space = (double)(s.f_bsize * s.f_bavail);
138
139         return MS_MEDIA_ERR_NONE;
140 }
141
142 #ifdef _USE_RECORDED_CONTENT
143 bool ms_is_support_pvr(void)
144 {
145
146         int nSupportPVR = 0;
147         if (system_info_get_value_int(SYSTEM_INFO_KEY_PVR_SUPPORTED, &nSupportPVR) != SYSTEM_INFO_ERROR_NONE) {
148                 MS_DBG_ERR("Get PVR Support failed");
149                 return false;
150         }
151
152         MS_DBG("PVR Support : [%d]", nSupportPVR);
153
154         return (nSupportPVR != 0);
155 }
156 #endif
157
158 #ifdef _USE_SENIOR_MODE
159 bool ms_is_support_senior_mode()
160 {
161         bool bSupportSeniorMode = false;
162
163         if (system_info_get_value_bool(SYSTEM_INFO_KEY_GET_SENIOR_MODE_SUPPORTED, &bSupportSeniorMode) != SYSTEM_INFO_ERROR_NONE) {
164                 MS_DBG_ERR("Get senior mode support failed");
165                 return false;
166         }
167
168         MS_DBG("Senior mode support : [%d]", bSupportSeniorMode);
169
170         return bSupportSeniorMode;
171 }
172 #endif
173
174 int ms_check_file_path(const char *file_path, uid_t uid)
175 {
176         ms_user_storage_type_e storage_type = -1;
177         int ret = MS_MEDIA_ERR_NONE;
178
179         if (!MS_STRING_VALID(file_path)) {
180                 MS_DBG_ERR("Invalid path");
181                 return MS_MEDIA_ERR_INVALID_PARAMETER;
182         }
183
184         ret = ms_user_get_storage_type(uid, file_path, &storage_type);
185         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, MS_MEDIA_ERR_INVALID_PATH, "Invalid path");
186
187         if (!g_file_test(file_path, G_FILE_TEST_IS_REGULAR)) {
188                 MS_DBG_SERR("g_file_test fail [%s]", file_path);
189                 return MS_MEDIA_ERR_INVALID_PATH;
190         }
191
192         return MS_MEDIA_ERR_NONE;
193 }
194
195 int ms_check_ignore_dir(const char *full_path, uid_t uid)
196 {
197         int ret = MS_MEDIA_ERR_NONE;
198         char *dir_path = NULL;
199         char *leaf_path = NULL;
200         char *usr_path = NULL;
201
202         ret = ms_check_file_path(full_path, uid);
203         if (ret != MS_MEDIA_ERR_NONE) {
204                 MS_DBG_ERR("invalid path : %s", full_path);
205                 return MS_MEDIA_ERR_INVALID_PATH;
206         }
207
208         dir_path = g_path_get_dirname(full_path);
209         if (dir_path == NULL || strcmp(dir_path, ".") == 0) {
210                 MS_DBG_ERR("getting directory path is failed : %s", full_path);
211                 MS_SAFE_FREE(dir_path);
212                 return MS_MEDIA_ERR_INVALID_PATH;
213         }
214
215         ret = ms_user_get_internal_root_path(uid, &usr_path);
216         if (ret != MS_MEDIA_ERR_NONE) {
217                 MS_DBG_ERR("ms_user_get_internal_root_path() fail");
218                 MS_SAFE_FREE(dir_path);
219                 return MS_MEDIA_ERR_INTERNAL;
220         }
221
222         while (1) {
223                 if (ms_check_scan_ignore(dir_path) != MS_MEDIA_ERR_NONE) {
224                         ret = MS_MEDIA_ERR_INVALID_PATH;
225                         break;
226                 }
227
228 #ifdef _USE_SENIOR_MODE
229                 if (ms_is_support_senior_mode()) {
230                         if (strcmp(dir_path, MEDIA_ROOT_PATH_SENIOR_MODE) == 0)
231                                 break;
232                 }
233 #endif
234                 if (strcmp(dir_path, usr_path) == 0)
235                         break;
236                 else if (MS_STRING_VALID(MEDIA_ROOT_PATH_SDCARD) && (strncmp(dir_path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0))
237                         break;
238                 else if (MS_STRING_VALID(MEDIA_ROOT_PATH_USB) && (strncmp(dir_path, MEDIA_ROOT_PATH_USB, strlen(MEDIA_ROOT_PATH_USB)) == 0))
239                         break;
240                 else if (MS_STRING_VALID(MEDIA_ROOT_PATH_DISC) && (strncmp(dir_path, MEDIA_ROOT_PATH_DISC, strlen(MEDIA_ROOT_PATH_DISC)) == 0))
241                         break;
242
243                 leaf_path = strrchr(dir_path, '/');
244                 if (leaf_path != NULL) {
245                                 int seek_len = leaf_path -dir_path;
246                                 dir_path[seek_len] = '\0';
247                 } else {
248                         MS_DBG_ERR("Fail to find leaf path");
249                         ret = MS_MEDIA_ERR_INVALID_PATH;
250                         break;
251                 }
252         }
253
254         MS_SAFE_FREE(dir_path);
255         MS_SAFE_FREE(usr_path);
256
257         return ret;
258 }
259
260 int ms_check_scan_ignore(char * path)
261 {
262         int ret = MS_MEDIA_ERR_NONE;
263         const char *ignore_file = ".scan_ignore";
264         char ignore_path[MS_FILE_PATH_LEN_MAX] = {0, };
265
266         if (strstr(path, "/.")) {
267                 MS_DBG_ERR("hidden path");
268                 return MS_MEDIA_ERR_INVALID_PATH;
269         }
270
271         if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
272                 memset(ignore_path, 0, sizeof(ignore_path));
273                 snprintf(ignore_path, sizeof(ignore_path), "%s/%s", path, ignore_file);
274
275                 if (g_file_test(ignore_path, G_FILE_TEST_EXISTS)) {
276                         MS_DBG_WARN("scan ignore file exist [%s]", ignore_path);
277                         return MS_MEDIA_ERR_INVALID_PATH;
278                 }
279         } else {
280                 MS_DBG_ERR("g_file_test fails[%s]", path);
281                 ret = MS_MEDIA_ERR_INVALID_PATH;
282
283                 if (!MS_STRING_VALID(MEDIA_ROOT_PATH_USB)) {
284                         MS_DBG_ERR("Fail to get USB path");
285                         return ret;
286                 }
287
288                 if (strstr(path, MEDIA_ROOT_PATH_USB) != NULL) {
289                         /*if the directory does not exist, check the device is unmounted*/
290                         if (!ms_storage_mount_status(path)) {
291                                 MS_DBG_ERR("Device is unmounted[%s]", path);
292                                 return MS_MEDIA_ERR_USB_UNMOUNTED;
293                         }
294                 }
295         }
296
297         return ret;
298 }
299
300 bool ms_storage_mount_status(const char* start_path)
301 {
302         bool ret = false;
303 #ifndef _USE_DEVICED_DBUS
304         int count = 0;
305         int err = 0;
306         usb_device_list_h list;
307         usb_device_h device;
308         char *mount_path = NULL;
309
310         char *storage_path = NULL;
311         char *remain_path = NULL;
312         int remain_len = 0;
313
314         remain_path = strstr(start_path+strlen(MEDIA_ROOT_PATH_USB) +1, "/");
315         if (remain_path != NULL)
316                 remain_len = strlen(remain_path);
317
318         storage_path = strndup(start_path, strlen(start_path) - remain_len);
319
320         MS_DBG_WARN("storage_path [%s]", storage_path);
321
322         err = usb_device_get_device_list(USB_MASS_STORAGE, &list);
323         if (err == 0) {
324                 count = usb_device_list_get_count(list);
325                 if (count > 0) {
326                         err = usb_device_list_get_first(list, &device);
327                         if (err != USB_ERROR_LIST_FAILED_TO_GET && device != NULL) {
328                                 mount_path = usb_device_get_mountpath(device);
329                                 if (mount_path != NULL) {
330                                         MS_DBG_WARN("mount_path [%s]", mount_path);
331                                         if (strlen(mount_path) == strlen(storage_path)) {
332                                                 if (strncmp(mount_path, storage_path, strlen(mount_path)) == 0) {
333                                                         MS_DBG_WARN("start path is mounted [%s]", start_path);
334                                                         ret = true;
335                                                 }
336                                         }
337                                 }
338                         }
339
340                         if (ret != true) {
341                                 while (usb_device_list_get_next(list, &device) == 0) {
342                                         if (device != NULL) {
343                                                 mount_path = usb_device_get_mountpath(device);
344                                                 if (mount_path != NULL) {
345                                                         MS_DBG_WARN("mount_path [%s]", mount_path);
346                                                         if (strlen(mount_path) == strlen(storage_path)) {
347                                                                 if (strncmp(mount_path, storage_path, strlen(mount_path)) == 0) {
348                                                                         MS_DBG_WARN("start path is mounted [%s]", start_path);
349                                                                         ret = true;
350                                                                         break;
351                                                                 }
352                                                         }
353                                                 }
354                                         }
355                                 }
356                         }
357                 }
358
359                 usb_device_free_device_list(list);
360         } else {
361                 MS_DBG_ERR("usb_device_get_device_list falied [%d]", err);
362         }
363
364         MS_SAFE_FREE(storage_path);
365 #endif
366         return ret;
367 }
368
369 int ms_set_db_status(ms_db_status_type_t status, ms_storage_type_t storage_type)
370 {
371         int res = MS_MEDIA_ERR_NONE;
372         int err = 0;
373
374         if (status == MS_DB_UPDATING) {
375                 if (!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATING)) {
376                         res = MS_MEDIA_ERR_VCONF_SET_FAIL;
377                         MS_DBG_ERR("ms_config_set_int failed");
378                 }
379
380                 if (storage_type == MS_STORAGE_EXTERNAL) {
381                         if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADING)) {
382                                 res = MS_MEDIA_ERR_VCONF_SET_FAIL;
383                                 MS_DBG_ERR("ms_config_set_int failed");
384                         }
385                 }
386         } else {
387                 if (!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATED)) {
388                         res = MS_MEDIA_ERR_VCONF_SET_FAIL;
389                         MS_DBG_ERR("ms_config_set_int failed");
390                 }
391
392                 if (storage_type == MS_STORAGE_EXTERNAL) {
393                         if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADED)) {
394                                 res = MS_MEDIA_ERR_VCONF_SET_FAIL;
395                                 MS_DBG_ERR("ms_config_set_int failed");
396                         }
397                 }
398         }
399
400         err = ms_set_power_mode(status);
401         if (err != MS_MEDIA_ERR_NONE) {
402                 MS_DBG_ERR("ms_set_power_mode fail");
403                 res = err;
404         }
405
406         return res;
407 }
408
409 int ms_set_power_mode(ms_db_status_type_t status)
410 {
411         int res = MS_MEDIA_ERR_NONE;
412         int err;
413
414         switch (status) {
415         case MS_DB_UPDATING:
416                 err = display_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
417                 if (err != 0)
418                         res = MS_MEDIA_ERR_INTERNAL;
419                 break;
420         case MS_DB_UPDATED:
421                 err = display_unlock_state(LCD_OFF, PM_RESET_TIMER);
422                 if (err != 0)
423                         res = MS_MEDIA_ERR_INTERNAL;
424                 break;
425         default:
426                 MS_DBG_ERR("Unacceptable type : %d", status);
427                 break;
428         }
429
430         return res;
431 }
432
433 void ms_trim_dir_path(char *dir_path)
434 {
435         /* need implementation */
436         /* if dir_path is not NULL terminated, this function will occure crash */
437         int len = strlen(dir_path);
438
439         if (dir_path[len -1] == '/')
440                 dir_path[len -1] = '\0';
441 }
442
443 int ms_check_size_mediadb(uid_t uid, double *db_size)
444 {
445         int ret = MS_MEDIA_ERR_NONE;
446         char *db_path = NULL;
447         struct stat buf;
448
449         ret = ms_user_get_media_db_path(uid, &db_path);
450
451         if (stat(db_path, &buf) == 0) {
452                 *db_size = buf.st_size;
453         } else {
454                 MS_DBG_STRERROR("stat failed");
455                 ret = MS_MEDIA_ERR_INTERNAL;
456         }
457
458         MS_SAFE_FREE(db_path);
459
460         return ret;
461 }
462
463 #ifdef _SET_VIP_PROCESS
464 #define PROC_OOM_SCORE_ADJ_PATH         "/proc/%d/oom_score_adj"
465 #define VIP_OOM_SCORE_ADJ                       (-1000)
466 #define PROC_NAME_MAX 1024
467 #define PROC_BUF_MAX 64
468
469 static int ms_get_cmdline_from_proc(pid_t pid, char *cmdline)
470 {
471         char buf[PROC_BUF_MAX];
472         char cmdline_buf[PROC_NAME_MAX];
473         char *filename;
474         FILE *fp;
475
476         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
477         fp = fopen(buf, "r");
478         if (fp == NULL)
479                 return MS_MEDIA_ERR_INTERNAL;
480
481         if (fgets(cmdline_buf, PROC_NAME_MAX-1, fp) == NULL) {
482                 fclose(fp);
483                 return MS_MEDIA_ERR_INTERNAL;
484         }
485         fclose(fp);
486
487         filename = strrchr(cmdline_buf, '/');
488         if (filename == NULL)
489                 filename = cmdline_buf;
490         else
491                 filename = filename + 1;
492
493         SAFE_STRLCPY(cmdline, filename, PROC_NAME_MAX);
494
495         return MS_MEDIA_ERR_NONE;
496 }
497
498 int ms_set_vip_process(void)
499 {
500         char buf[100] = {0};
501         int id = 0;
502         static pid_t pid = 0;
503         static char process_name[PROC_NAME_MAX] = {0};
504         static char *appid = NULL;
505
506         /* Get Pid */
507         pid = getpid();
508         if (ms_get_cmdline_from_proc(pid, process_name)) {
509                 MS_DBG_ERR("%s: Read process name failed pid[%d]", __func__, pid);
510                 return MS_MEDIA_ERR_INTERNAL;
511         }
512         appid = process_name;
513
514         MS_DBG("Process name[%s]:Pid[%d]", appid, pid);
515
516         if (prctl(PR_GET_DUMPABLE) == 0)
517                 prctl(PR_SET_DUMPABLE, 1);
518
519         snprintf(buf, sizeof(buf), PROC_OOM_SCORE_ADJ_PATH, pid);
520         id = open(buf, O_WRONLY, 0777);
521         if (id < 0) {
522                 MS_DBG_ERR("fopen %s failed errno:%d", buf, errno);
523                 return MS_MEDIA_ERR_INTERNAL;
524         }
525         snprintf(buf, sizeof(buf), "%d", VIP_OOM_SCORE_ADJ);
526         if (write(id, buf, strlen(buf)) < 0) {
527                 MS_DBG_ERR("write() failed errno=%d", errno);
528                 close(id);
529                 return MS_MEDIA_ERR_INTERNAL;
530         }
531         close(id);
532         return MS_MEDIA_ERR_NONE;
533 }
534 #endif