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