Tizen 2.1 base
[framework/multimedia/media-server.git] / common / media-server-external-storage.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 #include <locale.h>
22 #include <libintl.h>
23 #include <sys/stat.h>
24 #include <dirent.h>
25 #include <malloc.h>
26 #include <vconf.h>
27 #include <notification.h>
28
29 #include "media-util.h"
30 #include "media-server-dbg.h"
31 #include "media-server-utils.h"
32 #include "media-server-ipc.h"
33 #include "media-server-socket.h"
34 #include "media-server-inotify.h"
35 #include "media-server-db-svc.h"
36 #include "media-server-scanner.h"
37 #include "media-server-external-storage.h"
38 #include "media-server-drm.h"
39
40 #define MMC_INFO_SIZE 256
41
42 int mmc_state = 0;
43
44 char default_path[][MS_FILE_NAME_LEN_MAX + 1] = {
45                 {"/opt/storage/sdcard/Images"},
46                 {"/opt/storage/sdcard/Videos"},
47                 {"/opt/storage/sdcard/Sounds"},
48                 {"/opt/storage/sdcard/Downloads"},
49                 {"/opt/storage/sdcard/Camera"}
50 };
51
52 #define DIR_NUM       ((int)(sizeof(default_path)/sizeof(default_path[0])))
53
54 void
55 ms_make_default_path_mmc(void)
56 {
57         int i = 0;
58         int ret = 0;
59         DIR *dp = NULL;
60
61         for (i = 0; i < DIR_NUM; ++i) {
62                 dp = opendir(default_path[i]);
63                 if (dp == NULL) {
64                         ret = mkdir(default_path[i], 0777);
65                         if (ret < 0) {
66                                 MS_DBG("make fail");
67                         } else {
68 #if MS_INOTI_ENABLE
69                                 ms_inoti_add_watch(default_path[i]);
70 #endif
71                                 /*this fuction for emulator*/
72                                 /*at the first time, the directroies are made permission 755*/
73                                 chmod(default_path[i], 0777);
74                                 chown(default_path[i], 5000, 5000);
75                         }
76                 } else {
77                         closedir(dp);
78                 }
79         }
80 }
81
82 int
83 _ms_update_mmc_info(const char *cid)
84 {
85         bool res;
86
87         if (cid == NULL) {
88                 MS_DBG_ERR("Parameters are invalid");
89                 return MS_MEDIA_ERR_INVALID_PARAMETER;
90         }
91
92         res = ms_config_set_str(MS_MMC_INFO_KEY, cid);
93         if (!res) {
94                 MS_DBG_ERR("fail to get MS_MMC_INFO_KEY");
95                 return MS_MEDIA_ERR_VCONF_SET_FAIL;
96         }
97
98         return MS_MEDIA_ERR_NONE;
99 }
100
101 bool
102 _ms_check_mmc_info(const char *cid)
103 {
104         char pre_mmc_info[MMC_INFO_SIZE] = { 0 };
105         bool res = false;
106
107         if (cid == NULL) {
108                 MS_DBG_ERR("Parameters are invalid");
109                 return false;
110         }
111
112         res = ms_config_get_str(MS_MMC_INFO_KEY, pre_mmc_info);
113         if (!res) {
114                 MS_DBG_ERR("fail to get MS_MMC_INFO_KEY");
115                 return false;
116         }
117
118         MS_DBG("Last MMC info   = %s", pre_mmc_info);
119         MS_DBG("Current MMC info = %s", cid);
120
121         if (strcmp(pre_mmc_info, cid) == 0) {
122                 return true;
123         }
124
125         return false;
126 }
127
128 static int
129 _get_contents(const char *filename, char *buf)
130 {
131         FILE *fp;
132
133         fp = fopen(filename, "rt");
134         if (fp == NULL) {
135                 MS_DBG_ERR("fp is NULL. file name : %s", filename);
136                 return MS_MEDIA_ERR_FILE_OPEN_FAIL;
137         }
138         if (fgets(buf, 255, fp) == NULL)
139                 MS_DBG_ERR("fgets failed");
140
141         fclose(fp);
142
143         return MS_MEDIA_ERR_NONE;
144 }
145
146 /*need optimize*/
147 int
148 _ms_get_mmc_info(char *cid)
149 {
150         int i;
151         int j;
152         int len;
153         int err = -1;
154         bool getdata = false;
155         bool bHasColon = false;
156         char path[MS_FILE_PATH_LEN_MAX] = { 0 };
157         char mmcpath[MS_FILE_PATH_LEN_MAX] = { 0 };
158
159         DIR *dp;
160         struct dirent ent;
161         struct dirent *res = NULL;
162
163         /* mmcblk0 and mmcblk1 is reserved for movinand */
164         for (j = 1; j < 3; j++) {
165                 len = snprintf(mmcpath, MS_FILE_PATH_LEN_MAX, "/sys/class/mmc_host/mmc%d/", j);
166                 if (len < 0) {
167                         MS_DBG_ERR("FAIL : snprintf");
168                         return MS_MEDIA_ERR_INTERNAL;
169                 }
170                 else {
171                         mmcpath[len] = '\0';
172                 }
173
174                 dp = opendir(mmcpath);
175                 if (dp == NULL) {
176                         MS_DBG_ERR("dp is NULL");
177                         return MS_MEDIA_ERR_DIR_OPEN_FAIL;
178                 }
179
180                 while (!readdir_r(dp, &ent, &res)) {
181                          /*end of read dir*/
182                         if (res == NULL)
183                                 break;
184
185                         bHasColon = false;
186                         if (ent.d_name[0] == '.')
187                                 continue;
188
189                         if (ent.d_type == DT_DIR) {
190                                 /*ent->d_name is including ':' */
191                                 for (i = 0; i < strlen(ent.d_name); i++) {
192                                         if (ent.d_name[i] == ':') {
193                                                 bHasColon = true;
194                                                 break;
195                                         }
196                                 }
197
198                                 if (bHasColon) {
199                                         /*check serial */
200                                         err = ms_strappend(path, sizeof(path), "%s%s/cid", mmcpath, ent.d_name);
201                                         if (err < 0) {
202                                                 MS_DBG_ERR("ms_strappend error : %d", err);
203                                                 continue;
204                                         }
205
206                                         if (_get_contents(path, cid) != MS_MEDIA_ERR_NONE)
207                                                 break;
208                                         else
209                                                 getdata = true;
210                                 }
211                         }
212                 }
213                 closedir(dp);
214
215                 if (getdata == true) {
216                         break;
217                 }
218         }
219
220         return MS_MEDIA_ERR_NONE;
221 }
222
223 ms_dir_scan_type_t
224 ms_get_mmc_state(void)
225 {
226         char cid[MMC_INFO_SIZE] = { 0 };
227         ms_dir_scan_type_t ret = MS_SCAN_ALL;
228
229         /*get new info */
230         _ms_get_mmc_info(cid);
231
232         /*check it's same mmc */
233         if (_ms_check_mmc_info(cid)) {
234                 ret = MS_SCAN_PART;
235         }
236
237         return ret;
238 }
239
240 int
241 ms_update_mmc_info(void)
242 {
243         int err;
244         char cid[MMC_INFO_SIZE] = { 0 };
245
246         err = _ms_get_mmc_info(cid);
247
248         err = _ms_update_mmc_info(cid);
249
250         /*Active flush */
251         if (!malloc_trim(0))
252                 MS_DBG_ERR("malloc_trim is failed");
253
254         return err;
255 }
256
257 #define _GETSYSTEMSTR(ID)       dgettext("sys_string", (ID))
258
259 void update_lang(void)
260 {
261         char *lang;
262         char *r;
263
264         lang = vconf_get_str(VCONFKEY_LANGSET);
265         if (lang) {
266                 setenv("LANG", lang, 1);
267                 setenv("LC_MESSAGES", lang, 1);
268                 r = setlocale(LC_ALL, "");
269                 if (r == NULL) {
270                         r = setlocale(LC_ALL, vconf_get_str(VCONFKEY_LANGSET));
271                         MS_DBG_ERR("*****appcore setlocale=%s\n", r);
272                 }
273                 free(lang);
274         }
275 }
276
277 int
278 ms_present_mmc_insert(void)
279 {
280         int ret;
281
282         update_lang();
283
284         ret = notification_status_message_post(_GETSYSTEMSTR("IDS_COM_BODY_PREPARING_SD_CARD"));
285         if(ret != NOTIFICATION_ERROR_NONE)
286                 return MS_MEDIA_ERR_INTERNAL;
287
288         return MS_MEDIA_ERR_NONE;
289 }
290
291 void
292 ms_mmc_vconf_cb(void *data)
293 {
294         int status = 0;
295
296         if (!ms_config_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &status)) {
297                 MS_DBG_ERR("Get VCONFKEY_SYSMAN_MMC_STATUS failed.");
298         }
299
300         MS_DBG("VCONFKEY_SYSMAN_MMC_STATUS :%d", status);
301
302         mmc_state = status;
303
304         /* If scanner is not working, media server executes media scanner and sends request. */ 
305         /* If scanner is working, it detects changing status of SD card. */
306         if (mmc_state == VCONFKEY_SYSMAN_MMC_REMOVED ||
307                 mmc_state == VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED) {
308
309                 /*remove added watch descriptors */
310 #if MS_INOTI_ENABLE
311                 ms_inoti_remove_watch_recursive(MEDIA_ROOT_PATH_SDCARD);
312                 ms_inoti_delete_mmc_ignore_file();
313 #endif
314                 if (!ms_get_scanner_status()) {
315                         if (!ms_drm_extract_ext_memory())
316                                 MS_DBG_ERR("ms_drm_extract_ext_memory failed");
317
318                         ms_send_storage_scan_request(MS_STORAGE_EXTERNAL, MS_SCAN_INVALID);
319                 }
320         } else if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED) {
321
322                 ms_make_default_path_mmc();
323 #if MS_INOTI_ENABLE
324                 ms_inoti_add_watch_all_directory(MS_STORAGE_EXTERNAL);
325 #endif
326                 ms_present_mmc_insert();
327
328                 if (!ms_get_scanner_status()) {
329                         if (!ms_drm_insert_ext_memory())
330                                 MS_DBG_ERR("ms_drm_insert_ext_memory failed");
331
332                         ms_send_storage_scan_request(MS_STORAGE_EXTERNAL, ms_get_mmc_state());
333                 }
334         }
335
336         return;
337 }
338