Move vconf related code to TVPD feature
[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 <sys/statvfs.h>
25 #include <sys/stat.h>
26
27 #ifdef _USE_TVPD_MODE
28 #include <vconf.h>
29 #include <sys/prctl.h>
30 #include <usb-device.h>
31 #endif
32 #include <system_info.h>
33 #include <device/power.h>
34
35 #include "media-util.h"
36 #include "media-server-ipc.h"
37 #include "media-common-dbg.h"
38 #include "media-common-system.h"
39 #include "media-common-utils.h"
40
41 #ifdef _USE_TVPD_MODE
42 bool ms_config_get_int(const char *key, int *value)
43 {
44         int err;
45
46         if (!key || !value) {
47                 MS_DBG_ERR("Arguments key or value is NULL");
48                 return false;
49         }
50
51         err = vconf_get_int(key, value);
52         if (err == VCONF_OK)
53                 return true;
54
55         MS_DBG_ERR("Error code: %d", err);
56
57         return false;
58 }
59
60 bool ms_config_set_int(const char *key, int value)
61 {
62         int err;
63
64         if (!key) {
65                 MS_DBG_ERR("Arguments key is NULL");
66                 return false;
67         }
68
69         err = vconf_set_int(key, value);
70         if (err == VCONF_OK)
71                 return true;
72
73         MS_DBG_ERR("Error code: %d", err);
74
75         return false;
76 }
77
78 int ms_get_remain_space(uint64_t *free_space)
79 {
80         int ret = MS_MEDIA_ERR_NONE;
81         const char *path = "/opt";
82         struct statvfs s;
83
84         ret = statvfs(path, &s);
85         if (ret != 0) {
86                 MS_DBG_ERR("statvfs failed[%d]", ret);
87                 MS_DBG_STRERROR();
88                 return MS_MEDIA_ERR_INTERNAL;
89         }
90
91         /* f_bsize:unsigned long, f_bavail:fsblkcnt_t(unsigned long) */
92         *free_space = (uint64_t)s.f_bsize * (uint64_t)s.f_bavail;
93
94         return MS_MEDIA_ERR_NONE;
95 }
96
97 bool ms_is_support_pvr(void)
98 {
99         bool bSupportPVR = false;
100         if (system_info_get_custom_bool("com.samsung/featureconf/pvr.pvr_support", &bSupportPVR) != SYSTEM_INFO_ERROR_NONE) {
101                 MS_DBG_ERR("Get PVR Support failed");
102                 return false;
103         }
104
105         MS_DBG("PVR Support : [%d]", bSupportPVR);
106
107         return bSupportPVR;
108 }
109 #endif
110
111 bool ms_is_valid_symlink(const char *path)
112 {
113 #ifdef _USE_TVPD_MODE
114         return false;
115 #else
116         g_autofree char *real_path = realpath(path, NULL);
117
118         if (!real_path)
119                 return false;
120
121         return (g_strcmp0(real_path, MEDIA_SHARE_PATH) == 0);
122 #endif
123 }
124
125 int ms_verify_all_parent_dirs(const char *full_path, uid_t uid)
126 {
127         int ret = MS_MEDIA_ERR_NONE;
128         char *dir_path = NULL;
129         char *next = NULL;
130         int next_pos = 0;
131         ms_user_storage_type_e storage_type = MS_USER_STORAGE_INTERNAL;
132
133         ret = ms_user_get_storage_type(uid, full_path, &storage_type);
134         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "Invalid path");
135
136         if (storage_type == MS_USER_STORAGE_INTERNAL) {
137                 ret = ms_user_get_internal_root_path(uid, &dir_path);
138                 MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, ret, "ms_user_get_internal_root_path() fail");
139
140                 next_pos = strlen(dir_path);
141                 g_free(dir_path);
142                 dir_path = NULL;
143         } else {
144                 next_pos = strlen(MEDIA_ROOT_PATH_USB) + 1;
145         }
146
147         while ((next = strstr(full_path + next_pos, "/"))) {
148                 next_pos = (next - full_path);
149                 dir_path = g_strndup(full_path, next_pos);
150                 next_pos++;
151
152                 ret = ms_check_scan_ignore(dir_path, uid);
153                 g_free(dir_path);
154                 if (ret != MS_MEDIA_ERR_NONE)
155                         break;
156         }
157
158         return ret;
159 }
160
161 int ms_check_scan_ignore(char *path, uid_t uid)
162 {
163         int ret = MS_MEDIA_ERR_NONE;
164         const char *ignore_file = ".scan_ignore";
165         char *tmp_path = NULL;
166         char *org_path = NULL;
167         char ignore_path[MS_FILE_PATH_LEN_MAX] = {0, };
168
169 #ifndef _USE_TVPD_MODE
170         char replace[MS_FILE_PATH_LEN_MAX] = {0, };
171         char *mediashared = NULL;
172 #endif
173
174         /* Check for symbolic link */
175         tmp_path = realpath(path, NULL);
176         /* Get trimmed path */
177         org_path = g_canonicalize_filename(path, NULL);
178
179 #ifdef _USE_TVPD_MODE
180         if (g_strcmp0(tmp_path, org_path) != 0) {
181                 MS_SAFE_FREE(tmp_path);
182                 g_free(org_path);
183                 MS_DBG_ERR("symbolic link(directory)");
184                 return MS_MEDIA_ERR_INVALID_PARAMETER;
185         }
186 #else
187         if (g_str_has_prefix(tmp_path, MEDIA_SHARE_PATH)) {
188                 ms_user_get_mediashared_path(uid, &mediashared);
189                 snprintf(replace, MS_FILE_PATH_LEN_MAX, "%s%s", mediashared, tmp_path + strlen(MEDIA_SHARE_PATH));
190                 MS_SAFE_FREE(mediashared);
191                 if (g_strcmp0(replace, org_path) != 0) {
192                         MS_SAFE_FREE(tmp_path);
193                         g_free(org_path);
194                         MS_DBG_ERR("symbolic link(directory)");
195                         return MS_MEDIA_ERR_INVALID_PARAMETER;
196                 }
197         } else {
198                 if (g_strcmp0(tmp_path, org_path) != 0) {
199                         MS_SAFE_FREE(tmp_path);
200                         g_free(org_path);
201                         MS_DBG_ERR("symbolic link(directory)");
202                         return MS_MEDIA_ERR_INVALID_PARAMETER;
203                 }
204         }
205 #endif
206         MS_SAFE_FREE(tmp_path);
207         g_free(org_path);
208
209         if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
210                 snprintf(ignore_path, sizeof(ignore_path), "%s/%s", path, ignore_file);
211
212                 if (g_file_test(ignore_path, G_FILE_TEST_EXISTS)) {
213                         MS_DBG_WARN("scan ignore file exist [%s]", ignore_path);
214                         return MS_MEDIA_ERR_INVALID_PARAMETER;
215                 }
216         } else {
217                 MS_DBG_ERR("g_file_test fails[%s]", path);
218                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
219 #ifdef _USE_TVPD_MODE
220                 if (!MS_STRING_VALID(MEDIA_ROOT_PATH_USB)) {
221                         MS_DBG_ERR("Fail to get USB path");
222                         return ret;
223                 }
224
225                 if (strstr(path, MEDIA_ROOT_PATH_USB) != NULL) {
226                         /*if the directory does not exist, check the device is unmounted*/
227                         if (!ms_storage_mount_status(path)) {
228                                 MS_DBG_ERR("Device is unmounted[%s]", path);
229                                 return MS_MEDIA_ERR_USB_UNMOUNTED;
230                         }
231                 }
232 #endif
233         }
234
235         return ret;
236 }
237
238 #ifdef _USE_TVPD_MODE
239 typedef struct storage_result {
240         char *storage_path;
241         bool result;
242 } storage_result_s;
243
244 static void __ms_check_mount_status(usb_device_h usb_device, void *user_data)
245 {
246         storage_result_s *data = (storage_result_s *)user_data;
247         char *mount_path = NULL;
248
249         mount_path = usb_device_get_mountpath(usb_device);
250         if (!mount_path)
251                 return;
252
253         MS_DBG_SWARN("mount_path [%s]", mount_path);
254         data->result = (g_strcmp0(mount_path, data->storage_path) == 0);
255 }
256
257 bool ms_storage_mount_status(const char *start_path)
258 {
259         bool ret = false;
260         storage_result_s res = {0, };
261         char *remain_path = NULL;
262         int remain_len = 0;
263
264         remain_path = strstr(start_path + strlen(MEDIA_ROOT_PATH_USB) + 1, "/");
265         if (remain_path != NULL)
266                 remain_len = strlen(remain_path);
267
268         res.storage_path = g_strndup(start_path, strlen(start_path) - remain_len);
269
270         MS_DBG_SWARN("storage_path [%s]", res.storage_path);
271
272         usb_mass_storage_foreach(__ms_check_mount_status, &res);
273         g_free(res.storage_path);
274         ret = res.result;
275
276         if (ret)
277                 MS_DBG_SWARN("start path is mounted [%s]", start_path);
278         return ret;
279 }
280
281 int ms_check_size_mediadb(uid_t uid, uint64_t *db_size)
282 {
283         int ret = MS_MEDIA_ERR_NONE;
284         char *db_path = NULL;
285         struct stat buf;
286
287         ret = ms_user_get_media_db_path(uid, &db_path);
288
289         if (stat(db_path, &buf) == 0) {
290                 *db_size = (uint64_t)buf.st_size;
291         } else {
292                 MS_DBG_STRERROR("stat failed");
293                 ret = MS_MEDIA_ERR_INTERNAL;
294         }
295
296         g_free(db_path);
297
298         return ret;
299 }
300
301 int ms_set_db_status(ms_db_status_type_t status)
302 {
303         int ret = MS_MEDIA_ERR_NONE;
304
305         if (status == MS_DB_UPDATING) {
306                 if (!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATING))
307                                 goto ERROR;
308         } else {
309                 if (!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATED))
310                                 goto ERROR;
311         }
312
313         ret = ms_set_power_mode(status);
314         if (ret != MS_MEDIA_ERR_NONE)
315                 MS_DBG_ERR("ms_set_power_mode fail");
316
317         return ret;
318 ERROR:
319         MS_DBG_ERR("ms_config_set_int failed");
320         return MS_MEDIA_ERR_INTERNAL;
321 }
322 #endif
323
324 int ms_set_power_mode(ms_db_status_type_t status)
325 {
326         int res = MS_MEDIA_ERR_NONE;
327         int err;
328
329         switch (status) {
330         case MS_DB_UPDATING:
331                 err = device_power_request_lock(POWER_LOCK_CPU, 0);
332                 if (err != 0)
333                         res = MS_MEDIA_ERR_INTERNAL;
334                 break;
335         case MS_DB_UPDATED:
336                 err = device_power_release_lock(POWER_LOCK_CPU);
337                 if (err != 0)
338                         res = MS_MEDIA_ERR_INTERNAL;
339                 break;
340         default:
341                 MS_DBG_ERR("Unacceptable type : %d", status);
342                 break;
343         }
344
345         return res;
346 }
347
348 void ms_trim_dir_path(char *dir_path)
349 {
350         /* need implementation */
351         /* if dir_path is not NULL terminated, this function will occure crash */
352         int len = strlen(dir_path);
353
354         if (dir_path[len -1] == '/')
355                 dir_path[len -1] = '\0';
356 }
357
358 #ifdef _USE_TVPD_MODE
359 #define PROC_OOM_SCORE_ADJ_PATH         "/proc/%d/oom_score_adj"
360 #define VIP_OOM_SCORE_ADJ                       (-1000)
361 #define PROC_NAME_MAX 1024
362 #define PROC_BUF_MAX 64
363
364 static int ms_get_cmdline_from_proc(pid_t pid, char *cmdline)
365 {
366         char buf[PROC_BUF_MAX];
367         char cmdline_buf[PROC_NAME_MAX];
368         char *filename;
369         FILE *fp;
370
371         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
372         fp = fopen(buf, "r");
373         if (fp == NULL)
374                 return MS_MEDIA_ERR_INTERNAL;
375
376         if (fgets(cmdline_buf, PROC_NAME_MAX-1, fp) == NULL) {
377                 fclose(fp);
378                 return MS_MEDIA_ERR_INTERNAL;
379         }
380         fclose(fp);
381
382         filename = strrchr(cmdline_buf, '/');
383         if (filename == NULL)
384                 filename = cmdline_buf;
385         else
386                 filename = filename + 1;
387
388         SAFE_STRLCPY(cmdline, filename, PROC_NAME_MAX);
389
390         return MS_MEDIA_ERR_NONE;
391 }
392
393 int ms_set_vip_process(void)
394 {
395         char buf[100] = {0};
396         int id = 0;
397         static pid_t pid = 0;
398         static char process_name[PROC_NAME_MAX] = {0};
399         static char *appid = NULL;
400
401         /* Get Pid */
402         pid = getpid();
403         if (ms_get_cmdline_from_proc(pid, process_name)) {
404                 MS_DBG_ERR("%s: Read process name failed pid[%d]", __func__, pid);
405                 return MS_MEDIA_ERR_INTERNAL;
406         }
407         appid = process_name;
408
409         MS_DBG("Process name[%s]:Pid[%d]", appid, pid);
410
411         if (prctl(PR_GET_DUMPABLE) == 0)
412                 prctl(PR_SET_DUMPABLE, 1);
413
414         snprintf(buf, sizeof(buf), PROC_OOM_SCORE_ADJ_PATH, pid);
415         id = open(buf, O_WRONLY, 0777);
416         if (id < 0) {
417                 MS_DBG_ERR("fopen %s failed errno:%d", buf, errno);
418                 return MS_MEDIA_ERR_INTERNAL;
419         }
420         snprintf(buf, sizeof(buf), "%d", VIP_OOM_SCORE_ADJ);
421         if (write(id, buf, strlen(buf)) < 0) {
422                 MS_DBG_ERR("write() failed errno=%d", errno);
423                 close(id);
424                 return MS_MEDIA_ERR_INTERNAL;
425         }
426         close(id);
427         return MS_MEDIA_ERR_NONE;
428 }
429 #endif