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